Merge pull request #7403 from bparker06/gdi_imp

win32: Improvements to GDI drivers
This commit is contained in:
Twinaphex 2018-10-10 16:13:10 +02:00 committed by GitHub
commit 1fae526337
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 218 additions and 32 deletions

View File

@ -27,6 +27,7 @@ typedef struct gdi
#endif
HDC winDC;
HDC memDC;
HDC texDC;
HBITMAP bmp;
HBITMAP bmp_old;
unsigned video_width;
@ -35,4 +36,17 @@ typedef struct gdi
unsigned screen_height;
} gdi_t;
typedef struct gdi_texture
{
int width;
int height;
int active_width;
int active_height;
enum texture_filter_type type;
void* data;
HBITMAP bmp;
HBITMAP bmp_old;
} gdi_texture_t;
#endif

View File

@ -837,18 +837,18 @@ LRESULT CALLBACK WndProcGDI(HWND hwnd, UINT message,
/* draw menu contents behind a gradient background */
if (gdi && gdi->memDC)
{
RECT rect;
/*RECT rect;
HBRUSH brush = CreateSolidBrush(RGB(1,81,127));
GetClientRect(hwnd, &rect);
GetClientRect(hwnd, &rect);*/
StretchBlt(gdi->winDC,
0, 0,
gdi->screen_width, gdi->screen_height,
gdi->memDC, 0, 0, gdi->video_width, gdi->video_height, SRCCOPY);
FillRect(gdi->memDC, &rect, brush);
DeleteObject(brush);
/*FillRect(gdi->memDC, &rect, brush);
DeleteObject(brush);*/
}
}
else

View File

@ -16,6 +16,7 @@
*/
#include <retro_miscellaneous.h>
#include <formats/image.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
@ -192,6 +193,9 @@ static bool gdi_gfx_frame(void *data, const void *frame,
HWND hwnd = win32_get_window();
BITMAPINFO *info;
/* FIXME */
video_info->xmb_shadows_enable = false;
if (!frame || !frame_width || !frame_height)
return true;
@ -414,9 +418,16 @@ static void gdi_gfx_free(void *data)
if (!gdi)
return;
if (gdi->bmp)
DeleteObject(gdi->bmp);
if (gdi->texDC)
{
DeleteDC(gdi->texDC);
gdi->texDC = 0;
}
if (gdi->memDC)
{
DeleteObject(gdi->bmp);
DeleteDC(gdi->memDC);
gdi->memDC = 0;
}
@ -532,12 +543,61 @@ static void gdi_set_video_mode(void *data, unsigned width, unsigned height,
video_context_driver_set_video_mode(&mode);
}
static uintptr_t gdi_load_texture(void *video_data, void *data,
bool threaded, enum texture_filter_type filter_type)
{
struct texture_image *image = (struct texture_image*)data;
int size = image->width * image->height * sizeof(uint32_t);
gdi_texture_t *texture = NULL;
void *tmpdata = NULL;
if (!image || image->width > 2048 || image->height > 2048)
return 0;
texture = calloc(1, sizeof(*texture));
texture->width = image->width;
texture->height = image->height;
texture->active_width = image->width;
texture->active_height = image->height;
texture->data = calloc(1, texture->width * texture->height * sizeof(uint32_t));
texture->type = filter_type;
if (!texture->data)
{
free(texture);
return 0;
}
memcpy(texture->data, image->pixels, texture->width * texture->height * sizeof(uint32_t));
return (uintptr_t)texture;
}
static void gdi_unload_texture(void *data, uintptr_t handle)
{
struct gdi_texture *texture = (struct gdi_texture*)handle;
if (!texture)
return;
if (texture->data)
free(texture->data);
if (texture->bmp)
{
DeleteObject(texture->bmp);
texture->bmp = NULL;
}
free(texture);
}
static const video_poke_interface_t gdi_poke_interface = {
NULL, /* get_flags */
NULL, /* set_coords */
NULL, /* set_mvp */
NULL,
NULL,
gdi_load_texture,
gdi_unload_texture,
gdi_set_video_mode,
win32_get_refresh_rate,
NULL,

View File

@ -18,6 +18,7 @@
#include <stdlib.h>
#include <string/stdstring.h>
#include <encodings/utf.h>
#include <lists/string_list.h>
#ifdef HAVE_CONFIG_H
#include "../../config.h"
@ -85,65 +86,116 @@ static void gdi_render_msg(
void *data, const char *msg,
const struct font_params *params)
{
float x, y, scale;
unsigned newX, newY, len;
float x, y, scale, drop_mod, alpha, drop_alpha;
int i, drop_x, drop_y, msg_strlen;
unsigned newX, newY, newDropX, newDropY;
unsigned align;
unsigned red;
unsigned green;
unsigned blue;
unsigned red, green, blue;
unsigned drop_red, drop_green, drop_blue;
gdi_raster_t *font = (gdi_raster_t*)data;
unsigned width = video_info->width;
unsigned height = video_info->height;
SIZE textSize = {0};
struct string_list *msg_list = NULL;
if (!font || string_is_empty(msg) || !font->gdi)
return;
if (params)
{
x = params->x;
y = params->y;
scale = params->scale;
align = params->text_align;
x = params->x;
y = params->y;
drop_x = params->drop_x;
drop_y = params->drop_y;
drop_mod = params->drop_mod;
drop_alpha = params->drop_alpha;
scale = params->scale;
align = params->text_align;
red = FONT_COLOR_GET_RED(params->color);
green = FONT_COLOR_GET_GREEN(params->color);
blue = FONT_COLOR_GET_BLUE(params->color);
red = FONT_COLOR_GET_RED(params->color);
green = FONT_COLOR_GET_GREEN(params->color);
blue = FONT_COLOR_GET_BLUE(params->color);
alpha = FONT_COLOR_GET_ALPHA(params->color);
}
else
{
x = video_info->font_msg_pos_x;
y = video_info->font_msg_pos_y;
scale = 1.0f;
align = TEXT_ALIGN_LEFT;
red = video_info->font_msg_color_r * 255.0f;
green = video_info->font_msg_color_g * 255.0f;
blue = video_info->font_msg_color_b * 255.0f;
x = video_info->font_msg_pos_x;
y = video_info->font_msg_pos_y;
drop_x = -2;
drop_y = -2;
drop_mod = 0.3f;
drop_alpha = 1.0f;
scale = 1.0f;
align = TEXT_ALIGN_LEFT;
red = video_info->font_msg_color_r * 255.0f;
green = video_info->font_msg_color_g * 255.0f;
blue = video_info->font_msg_color_b * 255.0f;
alpha = 255;
}
len = utf8len(msg);
msg_strlen = strlen(msg);
GetTextExtentPoint32(font->gdi->memDC, msg, msg_strlen, &textSize);
switch (align)
{
case TEXT_ALIGN_LEFT:
newX = x * width * scale;
newDropX = drop_x * width * scale;
break;
case TEXT_ALIGN_RIGHT:
newX = (x * width * scale) - len;
newX = (x * width * scale) - textSize.cx;
newDropX = (drop_x * width * scale) - textSize.cx;
break;
case TEXT_ALIGN_CENTER:
newX = (x * width * scale) - (len / 2);
newX = (x * width * scale) - (textSize.cx / 2);
newDropX = (drop_x * width * scale) - (textSize.cx / 2);
break;
default:
newX = 0;
newDropX = 0;
break;
}
newY = height - (y * height * scale);
newY = height - (y * height * scale) - textSize.cy;
newDropY = height - (drop_y * height * scale) - textSize.cy;
font->gdi->bmp_old = (HBITMAP)SelectObject(font->gdi->memDC, font->gdi->bmp);
SetBkMode(font->gdi->memDC, TRANSPARENT);
msg_list = string_split(msg, "\n");
if (drop_x || drop_y)
{
float dark_alpha = drop_alpha;
drop_red = red * drop_mod * dark_alpha;
drop_green = green * drop_mod * dark_alpha;
drop_blue = blue * drop_mod * dark_alpha;
SetTextColor(font->gdi->memDC, RGB(drop_red, drop_green, drop_blue));
if (msg_list)
{
for (i = 0; i < msg_list->size; i++)
{
TextOut(font->gdi->memDC, newDropX, newDropY + (textSize.cy * i), msg_list->elems[i].data, utf8len(msg_list->elems[i].data));
}
}
}
SetTextColor(font->gdi->memDC, RGB(red, green, blue));
TextOut(font->gdi->memDC, newX, newY, msg, len);
if (msg_list)
{
for (i = 0; i < msg_list->size; i++)
{
TextOut(font->gdi->memDC, newX, newY + (textSize.cy * i), msg_list->elems[i].data, utf8len(msg_list->elems[i].data));
}
string_list_free(msg_list);
}
SelectObject(font->gdi->memDC, font->gdi->bmp_old);
}

View File

@ -16,17 +16,20 @@
#include <time.h>
#include <clamping.h>
#include <queues/message_queue.h>
#include <retro_miscellaneous.h>
#include "../../config.def.h"
#include "../../gfx/font_driver.h"
#include "../../gfx/video_driver.h"
#include "../../verbosity.h"
#include "../menu_driver.h"
#if defined(_WIN32) && !defined(_XBOX)
#include "../../gfx/common/win32_common.h"
#include "../../gfx/common/gdi_common.h"
#endif
static void *menu_display_gdi_get_default_mvp(video_frame_info_t *video_info)
@ -45,6 +48,63 @@ static void menu_display_gdi_blend_end(video_frame_info_t *video_info)
static void menu_display_gdi_draw(menu_display_ctx_draw_t *draw,
video_frame_info_t *video_info)
{
struct gdi_texture *texture = NULL;
gdi_t *gdi = (gdi_t*)video_driver_get_ptr(false);
BITMAPINFO info = {0};
if (!gdi || !draw || draw->x < 0 || draw->y < 0 || draw->width <= 1 || draw->height <= 1)
return;
texture = (struct gdi_texture*)draw->texture;
if (!texture || texture->width <= 1 || texture->height <= 1)
return;
info.bmiHeader.biBitCount = 32;
info.bmiHeader.biWidth = texture->width;
info.bmiHeader.biHeight = -texture->height;
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biSizeImage = 0;
info.bmiHeader.biCompression = BI_RGB;
if (gdi->memDC)
{
BLENDFUNCTION blend = {0};
if (!gdi->texDC)
gdi->texDC = CreateCompatibleDC(gdi->winDC);
if (texture->bmp)
{
texture->bmp_old = SelectObject(gdi->texDC, texture->bmp);
}
else
{
/* scale texture data into a bitmap we can easily blit later */
texture->bmp = CreateCompatibleBitmap(gdi->winDC, draw->width, draw->height);
texture->bmp_old = SelectObject(gdi->texDC, texture->bmp);
StretchDIBits(gdi->texDC, 0, 0, draw->width, draw->height, 0, 0, texture->width, texture->height, texture->data, &info, DIB_RGB_COLORS, SRCCOPY);
}
gdi->bmp_old = SelectObject(gdi->memDC, gdi->bmp);
blend.BlendOp = AC_SRC_OVER;
blend.BlendFlags = 0;
blend.SourceConstantAlpha = 255;/*clamp_8bit(draw->coords->color[3] * 255.0f);*/
blend.AlphaFormat = AC_SRC_ALPHA;
AlphaBlend(gdi->memDC, draw->x, video_info->height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, blend);
/*TransparentBlt(gdi->memDC, draw->x, video_info->height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, 0);*/
/* To draw without blending: */
/*StretchBlt(gdi->memDC, draw->x, video_info->height - draw->height - draw->y, draw->width, draw->height, gdi->texDC, 0, 0, draw->width, draw->height, SRCCOPY);*/
SelectObject(gdi->memDC, gdi->bmp_old);
SelectObject(gdi->texDC, texture->bmp_old);
}
}
static void menu_display_gdi_draw_pipeline(menu_display_ctx_draw_t *draw,
@ -80,7 +140,7 @@ static bool menu_display_gdi_font_init_first(
font_path, font_size, true,
is_threaded,
FONT_DRIVER_RENDER_GDI)))
return false;
return false;
return true;
}