Solved the performance problems by introducing the concept of a single-buffered
display, which is a fast path used for the whole-surface SDL 1.2 API. Solved the flicker problems by implementing a backbuffer in the GDI renderer. Unfortunately, now using the GDI renderer with a backbuffer and HBITMAPs is significantly slower than SDL's surface code. *sigh* --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%401942
This commit is contained in:
parent
58d76aea10
commit
d1be2d9e1c
5 changed files with 184 additions and 96 deletions
|
@ -170,14 +170,14 @@ typedef enum
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
SDL_Renderer_PresentDiscard = 0x00000001, /**< Present leaves the contents of the backbuffer undefined */
|
SDL_Renderer_SingleBuffer = 0x00000001, /**< Render directly to the window, if possible */
|
||||||
SDL_Renderer_PresentCopy = 0x00000002, /**< Present uses a copy from back buffer to the front buffer */
|
SDL_Renderer_PresentCopy = 0x00000002, /**< Present uses a copy from back buffer to the front buffer */
|
||||||
SDL_Renderer_PresentFlip2 = 0x00000004, /**< Present uses a flip, swapping back buffer and front buffer */
|
SDL_Renderer_PresentFlip2 = 0x00000004, /**< Present uses a flip, swapping back buffer and front buffer */
|
||||||
SDL_Renderer_PresentFlip3 = 0x00000008, /**< Present uses a flip, rotating between two back buffers and a front buffer */
|
SDL_Renderer_PresentFlip3 = 0x00000008, /**< Present uses a flip, rotating between two back buffers and a front buffer */
|
||||||
SDL_Renderer_PresentVSync = 0x00000010, /**< Present is synchronized with the refresh rate */
|
SDL_Renderer_PresentDiscard = 0x00000010, /**< Present leaves the contents of the backbuffer undefined */
|
||||||
SDL_Renderer_RenderTarget = 0x00000020, /**< The renderer can create texture render targets */
|
SDL_Renderer_PresentVSync = 0x00000020, /**< Present is synchronized with the refresh rate */
|
||||||
SDL_Renderer_Accelerated = 0x00000040, /**< The renderer uses hardware acceleration */
|
SDL_Renderer_RenderTarget = 0x00000040, /**< The renderer can create texture render targets */
|
||||||
SDL_Renderer_ = 0x00000080, /**< The renderer uses hardware acceleration */
|
SDL_Renderer_Accelerated = 0x00000080, /**< The renderer uses hardware acceleration */
|
||||||
SDL_Renderer_Minimal = 0x00000100, /**< The renderer only supports the read/write pixel and present functions */
|
SDL_Renderer_Minimal = 0x00000100, /**< The renderer only supports the read/write pixel and present functions */
|
||||||
} SDL_RendererFlags;
|
} SDL_RendererFlags;
|
||||||
|
|
||||||
|
|
|
@ -442,7 +442,8 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a renderer for the window */
|
/* Create a renderer for the window */
|
||||||
if (SDL_CreateRenderer(SDL_VideoWindow, -1, 0) < 0) {
|
if (SDL_CreateRenderer(SDL_VideoWindow, -1, SDL_Renderer_SingleBuffer) <
|
||||||
|
0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,6 +518,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
|
||||||
|
|
||||||
/* Clear the surface for display */
|
/* Clear the surface for display */
|
||||||
SDL_FillRect(SDL_PublicSurface, NULL, 0);
|
SDL_FillRect(SDL_PublicSurface, NULL, 0);
|
||||||
|
SDL_UpdateRect(SDL_PublicSurface, 0, 0, 0, 0);
|
||||||
|
|
||||||
/* We're finally done! */
|
/* We're finally done! */
|
||||||
return SDL_PublicSurface;
|
return SDL_PublicSurface;
|
||||||
|
@ -617,21 +619,11 @@ SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
|
||||||
if (screen) {
|
if (screen) {
|
||||||
SDL_Rect rect;
|
SDL_Rect rect;
|
||||||
|
|
||||||
/* Perform some checking */
|
|
||||||
if (w == 0)
|
|
||||||
w = screen->w;
|
|
||||||
if (h == 0)
|
|
||||||
h = screen->h;
|
|
||||||
if ((int) (x + w) > screen->w)
|
|
||||||
return;
|
|
||||||
if ((int) (y + h) > screen->h)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Fill the rectangle */
|
/* Fill the rectangle */
|
||||||
rect.x = (Sint16) x;
|
rect.x = (int) x;
|
||||||
rect.y = (Sint16) y;
|
rect.y = (int) y;
|
||||||
rect.w = (Uint16) w;
|
rect.w = (int) (w ? w : screen->w);
|
||||||
rect.h = (Uint16) h;
|
rect.h = (int) (h ? h : screen->h);
|
||||||
SDL_UpdateRects(screen, 1, &rect);
|
SDL_UpdateRects(screen, 1, &rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,12 +77,11 @@ SDL_RenderDriver SDL_SW_RenderDriver = {
|
||||||
SDL_SW_CreateRenderer,
|
SDL_SW_CreateRenderer,
|
||||||
{
|
{
|
||||||
"software",
|
"software",
|
||||||
(SDL_Renderer_PresentDiscard |
|
(SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
|
||||||
SDL_Renderer_PresentCopy |
|
SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 |
|
||||||
SDL_Renderer_PresentFlip2 |
|
SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget),
|
||||||
SDL_Renderer_PresentFlip3 | SDL_Renderer_RenderTarget),
|
(SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask |
|
||||||
(SDL_TextureBlendMode_None |
|
SDL_TextureBlendMode_Blend),
|
||||||
SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend),
|
|
||||||
(SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
|
(SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
|
||||||
11,
|
11,
|
||||||
{
|
{
|
||||||
|
@ -108,6 +107,7 @@ typedef struct
|
||||||
SDL_Surface *target;
|
SDL_Surface *target;
|
||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
SDL_DirtyRectList dirty;
|
SDL_DirtyRectList dirty;
|
||||||
|
SDL_bool makedirty;
|
||||||
} SDL_SW_RenderData;
|
} SDL_SW_RenderData;
|
||||||
|
|
||||||
SDL_Renderer *
|
SDL_Renderer *
|
||||||
|
@ -185,13 +185,16 @@ SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||||
}
|
}
|
||||||
data->current_screen = 0;
|
data->current_screen = 0;
|
||||||
data->target = data->screens[0];
|
data->target = data->screens[0];
|
||||||
|
data->makedirty = SDL_TRUE;
|
||||||
|
|
||||||
/* Find a render driver that we can use to display data */
|
/* Find a render driver that we can use to display data */
|
||||||
for (i = 0; i < display->num_render_drivers; ++i) {
|
for (i = 0; i < display->num_render_drivers; ++i) {
|
||||||
SDL_RenderDriver *driver = &display->render_drivers[i];
|
SDL_RenderDriver *driver = &display->render_drivers[i];
|
||||||
if (driver->info.name != SDL_SW_RenderDriver.info.name) {
|
if (driver->info.name != SDL_SW_RenderDriver.info.name) {
|
||||||
data->renderer =
|
data->renderer =
|
||||||
driver->CreateRenderer(window, SDL_Renderer_PresentDiscard);
|
driver->CreateRenderer(window,
|
||||||
|
(SDL_Renderer_SingleBuffer |
|
||||||
|
SDL_Renderer_PresentDiscard));
|
||||||
if (data->renderer) {
|
if (data->renderer) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -351,8 +354,10 @@ SDL_SW_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
|
|
||||||
if (texture) {
|
if (texture) {
|
||||||
data->target = (SDL_Surface *) texture->driverdata;
|
data->target = (SDL_Surface *) texture->driverdata;
|
||||||
|
data->makedirty = SDL_FALSE;
|
||||||
} else {
|
} else {
|
||||||
data->target = data->screens[data->current_screen];
|
data->target = data->screens[data->current_screen];
|
||||||
|
data->makedirty = SDL_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +369,9 @@ SDL_SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||||
SDL_Rect real_rect = *rect;
|
SDL_Rect real_rect = *rect;
|
||||||
Uint8 r, g, b, a;
|
Uint8 r, g, b, a;
|
||||||
|
|
||||||
SDL_AddDirtyRect(&data->dirty, rect);
|
if (data->makedirty) {
|
||||||
|
SDL_AddDirtyRect(&data->dirty, rect);
|
||||||
|
}
|
||||||
|
|
||||||
a = (Uint8) ((color >> 24) & 0xFF);
|
a = (Uint8) ((color >> 24) & 0xFF);
|
||||||
r = (Uint8) ((color >> 16) & 0xFF);
|
r = (Uint8) ((color >> 16) & 0xFF);
|
||||||
|
@ -384,7 +391,9 @@ SDL_SW_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
||||||
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
||||||
|
|
||||||
SDL_AddDirtyRect(&data->dirty, dstrect);
|
if (data->makedirty) {
|
||||||
|
SDL_AddDirtyRect(&data->dirty, dstrect);
|
||||||
|
}
|
||||||
|
|
||||||
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
|
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
|
||||||
SDL_Surface *target = data->target;
|
SDL_Surface *target = data->target;
|
||||||
|
@ -450,7 +459,9 @@ SDL_SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||||
int row;
|
int row;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
||||||
SDL_AddDirtyRect(&data->dirty, rect);
|
if (data->makedirty) {
|
||||||
|
SDL_AddDirtyRect(&data->dirty, rect);
|
||||||
|
}
|
||||||
|
|
||||||
src = (Uint8 *) pixels;
|
src = (Uint8 *) pixels;
|
||||||
dst =
|
dst =
|
||||||
|
@ -471,7 +482,6 @@ SDL_SW_RenderPresent(SDL_Renderer * renderer)
|
||||||
SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata;
|
SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata;
|
||||||
SDL_Surface *surface = data->screens[data->current_screen];
|
SDL_Surface *surface = data->screens[data->current_screen];
|
||||||
SDL_DirtyRect *dirty;
|
SDL_DirtyRect *dirty;
|
||||||
int new_screen;
|
|
||||||
|
|
||||||
/* Send the data to the display */
|
/* Send the data to the display */
|
||||||
for (dirty = data->dirty.list; dirty; dirty = dirty->next) {
|
for (dirty = data->dirty.list; dirty; dirty = dirty->next) {
|
||||||
|
@ -485,19 +495,14 @@ SDL_SW_RenderPresent(SDL_Renderer * renderer)
|
||||||
SDL_ClearDirtyRects(&data->dirty);
|
SDL_ClearDirtyRects(&data->dirty);
|
||||||
data->renderer->RenderPresent(data->renderer);
|
data->renderer->RenderPresent(data->renderer);
|
||||||
|
|
||||||
|
|
||||||
/* Update the flipping chain, if any */
|
/* Update the flipping chain, if any */
|
||||||
if (renderer->info.flags & SDL_Renderer_PresentFlip2) {
|
if (renderer->info.flags & SDL_Renderer_PresentFlip2) {
|
||||||
new_screen = (data->current_screen + 1) % 2;
|
data->current_screen = (data->current_screen + 1) % 2;
|
||||||
|
data->target = data->screens[data->current_screen];
|
||||||
} else if (renderer->info.flags & SDL_Renderer_PresentFlip3) {
|
} else if (renderer->info.flags & SDL_Renderer_PresentFlip3) {
|
||||||
new_screen = (data->current_screen + 1) % 3;
|
data->current_screen = (data->current_screen + 1) % 3;
|
||||||
} else {
|
data->target = data->screens[data->current_screen];
|
||||||
new_screen = 0;
|
|
||||||
}
|
}
|
||||||
if (data->target == data->screens[data->current_screen]) {
|
|
||||||
data->target = data->screens[new_screen];
|
|
||||||
}
|
|
||||||
data->current_screen = new_screen;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -1769,9 +1769,8 @@ SDL_RenderFill(const SDL_Rect * rect, Uint32 color)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rect = &real_rect;
|
|
||||||
|
|
||||||
return renderer->RenderFill(renderer, rect, color);
|
return renderer->RenderFill(renderer, &real_rect, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1793,25 +1792,26 @@ SDL_RenderCopy(SDL_TextureID textureID, const SDL_Rect * srcrect,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: implement clipping */
|
|
||||||
window = SDL_GetWindowFromID(renderer->window);
|
window = SDL_GetWindowFromID(renderer->window);
|
||||||
real_srcrect.x = 0;
|
if (srcrect) {
|
||||||
real_srcrect.y = 0;
|
real_srcrect = *srcrect;
|
||||||
real_srcrect.w = texture->w;
|
} else {
|
||||||
real_srcrect.h = texture->h;
|
real_srcrect.x = 0;
|
||||||
real_dstrect.x = 0;
|
real_srcrect.y = 0;
|
||||||
real_dstrect.y = 0;
|
real_srcrect.w = texture->w;
|
||||||
real_dstrect.w = window->w;
|
real_srcrect.h = texture->h;
|
||||||
real_dstrect.h = window->h;
|
|
||||||
if (!srcrect) {
|
|
||||||
srcrect = &real_srcrect;
|
|
||||||
}
|
}
|
||||||
if (!dstrect) {
|
if (dstrect) {
|
||||||
dstrect = &real_dstrect;
|
real_dstrect = *dstrect;
|
||||||
|
} else {
|
||||||
|
real_dstrect.x = 0;
|
||||||
|
real_dstrect.y = 0;
|
||||||
|
real_dstrect.w = window->w;
|
||||||
|
real_dstrect.h = window->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
return renderer->RenderCopy(renderer, texture, srcrect, dstrect,
|
return renderer->RenderCopy(renderer, texture, &real_srcrect,
|
||||||
blendMode, scaleMode);
|
&real_dstrect, blendMode, scaleMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -1882,6 +1882,9 @@ SDL_RenderPresent(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (renderer->SelectRenderTexture) {
|
||||||
|
renderer->SelectRenderTexture(renderer, NULL);
|
||||||
|
}
|
||||||
renderer->RenderPresent(renderer);
|
renderer->RenderPresent(renderer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#if SDL_VIDEO_RENDER_GDI
|
#if SDL_VIDEO_RENDER_GDI
|
||||||
|
|
||||||
#include "SDL_win32video.h"
|
#include "SDL_win32video.h"
|
||||||
|
#include "../SDL_rect_c.h"
|
||||||
#include "../SDL_yuv_sw_c.h"
|
#include "../SDL_yuv_sw_c.h"
|
||||||
|
|
||||||
/* GDI renderer implementation */
|
/* GDI renderer implementation */
|
||||||
|
@ -78,10 +79,11 @@ SDL_RenderDriver SDL_GDI_RenderDriver = {
|
||||||
SDL_GDI_CreateRenderer,
|
SDL_GDI_CreateRenderer,
|
||||||
{
|
{
|
||||||
"gdi",
|
"gdi",
|
||||||
(SDL_Renderer_PresentDiscard |
|
(SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
|
||||||
SDL_Renderer_PresentCopy | SDL_Renderer_RenderTarget),
|
SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 |
|
||||||
(SDL_TextureBlendMode_None |
|
SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget),
|
||||||
SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend),
|
(SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask |
|
||||||
|
SDL_TextureBlendMode_Blend),
|
||||||
(SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
|
(SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
|
||||||
11,
|
11,
|
||||||
{
|
{
|
||||||
|
@ -108,7 +110,11 @@ typedef struct
|
||||||
HDC memory_hdc;
|
HDC memory_hdc;
|
||||||
HDC current_hdc;
|
HDC current_hdc;
|
||||||
LPBITMAPINFO bmi;
|
LPBITMAPINFO bmi;
|
||||||
HBITMAP window_bmp;
|
HBITMAP hbm[3];
|
||||||
|
int current_hbm;
|
||||||
|
SDL_DirtyRectList dirty;
|
||||||
|
SDL_bool makedirty;
|
||||||
|
HBITMAP window_dib;
|
||||||
void *window_pixels;
|
void *window_pixels;
|
||||||
int window_pitch;
|
int window_pitch;
|
||||||
} SDL_GDI_RenderData;
|
} SDL_GDI_RenderData;
|
||||||
|
@ -151,6 +157,7 @@ SDL_GDI_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||||
SDL_GDI_RenderData *data;
|
SDL_GDI_RenderData *data;
|
||||||
int bmi_size;
|
int bmi_size;
|
||||||
HBITMAP hbm;
|
HBITMAP hbm;
|
||||||
|
int i, n;
|
||||||
|
|
||||||
renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer));
|
renderer = (SDL_Renderer *) SDL_malloc(sizeof(*renderer));
|
||||||
if (!renderer) {
|
if (!renderer) {
|
||||||
|
@ -167,28 +174,6 @@ SDL_GDI_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||||
}
|
}
|
||||||
SDL_zerop(data);
|
SDL_zerop(data);
|
||||||
|
|
||||||
data->hwnd = windowdata->hwnd;
|
|
||||||
data->window_hdc = GetDC(data->hwnd);
|
|
||||||
data->render_hdc = CreateCompatibleDC(data->window_hdc);
|
|
||||||
data->memory_hdc = CreateCompatibleDC(data->window_hdc);
|
|
||||||
data->current_hdc = data->window_hdc;
|
|
||||||
|
|
||||||
/* Fill in the compatible bitmap info */
|
|
||||||
bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
|
|
||||||
data->bmi = (LPBITMAPINFO) SDL_malloc(bmi_size);
|
|
||||||
if (!data->bmi) {
|
|
||||||
SDL_GDI_DestroyRenderer(renderer);
|
|
||||||
SDL_OutOfMemory();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
SDL_memset(data->bmi, 0, bmi_size);
|
|
||||||
data->bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
||||||
|
|
||||||
hbm = CreateCompatibleBitmap(data->window_hdc, 1, 1);
|
|
||||||
GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS);
|
|
||||||
GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS);
|
|
||||||
DeleteObject(hbm);
|
|
||||||
|
|
||||||
renderer->CreateTexture = SDL_GDI_CreateTexture;
|
renderer->CreateTexture = SDL_GDI_CreateTexture;
|
||||||
renderer->QueryTexturePixels = SDL_GDI_QueryTexturePixels;
|
renderer->QueryTexturePixels = SDL_GDI_QueryTexturePixels;
|
||||||
renderer->SetTexturePalette = SDL_GDI_SetTexturePalette;
|
renderer->SetTexturePalette = SDL_GDI_SetTexturePalette;
|
||||||
|
@ -211,6 +196,59 @@ SDL_GDI_CreateRenderer(SDL_Window * window, Uint32 flags)
|
||||||
|
|
||||||
renderer->info.flags = SDL_Renderer_RenderTarget;
|
renderer->info.flags = SDL_Renderer_RenderTarget;
|
||||||
|
|
||||||
|
data->hwnd = windowdata->hwnd;
|
||||||
|
data->window_hdc = GetDC(data->hwnd);
|
||||||
|
data->render_hdc = CreateCompatibleDC(data->window_hdc);
|
||||||
|
data->memory_hdc = CreateCompatibleDC(data->window_hdc);
|
||||||
|
|
||||||
|
/* Fill in the compatible bitmap info */
|
||||||
|
bmi_size = sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD);
|
||||||
|
data->bmi = (LPBITMAPINFO) SDL_malloc(bmi_size);
|
||||||
|
if (!data->bmi) {
|
||||||
|
SDL_GDI_DestroyRenderer(renderer);
|
||||||
|
SDL_OutOfMemory();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
SDL_memset(data->bmi, 0, bmi_size);
|
||||||
|
data->bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
|
||||||
|
hbm = CreateCompatibleBitmap(data->window_hdc, 1, 1);
|
||||||
|
GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS);
|
||||||
|
GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS);
|
||||||
|
DeleteObject(hbm);
|
||||||
|
|
||||||
|
if (flags & SDL_Renderer_SingleBuffer) {
|
||||||
|
renderer->info.flags |= SDL_Renderer_SingleBuffer;
|
||||||
|
n = 0;
|
||||||
|
} else if (flags & SDL_Renderer_PresentFlip2) {
|
||||||
|
renderer->info.flags |= SDL_Renderer_PresentFlip2;
|
||||||
|
n = 2;
|
||||||
|
} else if (flags & SDL_Renderer_PresentFlip3) {
|
||||||
|
renderer->info.flags |= SDL_Renderer_PresentFlip3;
|
||||||
|
n = 3;
|
||||||
|
} else {
|
||||||
|
renderer->info.flags |= SDL_Renderer_PresentCopy;
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
data->hbm[i] =
|
||||||
|
CreateCompatibleBitmap(data->window_hdc, window->w, window->h);
|
||||||
|
if (!data->hbm[i]) {
|
||||||
|
SDL_GDI_DestroyRenderer(renderer);
|
||||||
|
WIN_SetError("CreateCompatibleBitmap()");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (n > 0) {
|
||||||
|
SelectObject(data->render_hdc, data->hbm[0]);
|
||||||
|
data->current_hdc = data->render_hdc;
|
||||||
|
data->makedirty = SDL_TRUE;
|
||||||
|
} else {
|
||||||
|
data->current_hdc = data->window_hdc;
|
||||||
|
data->makedirty = SDL_FALSE;
|
||||||
|
}
|
||||||
|
data->current_hbm = 0;
|
||||||
|
|
||||||
return renderer;
|
return renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +373,7 @@ SDL_GDI_QueryTexturePixels(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch);
|
return SDL_SW_QueryYUVTexturePixels(data->yuv, pixels, pitch);
|
||||||
} else {
|
} else {
|
||||||
*pixels = data->pixels;
|
*pixels = data->pixels;
|
||||||
*pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
|
*pitch = data->pitch;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -494,8 +532,14 @@ SDL_GDI_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
||||||
RealizePalette(data->render_hdc);
|
RealizePalette(data->render_hdc);
|
||||||
}
|
}
|
||||||
data->current_hdc = data->render_hdc;
|
data->current_hdc = data->render_hdc;
|
||||||
|
data->makedirty = SDL_FALSE;
|
||||||
|
} else if (renderer->info.flags & SDL_Renderer_SingleBuffer) {
|
||||||
|
data->current_hdc = data->window_hdc;
|
||||||
|
data->makedirty = SDL_FALSE;
|
||||||
} else {
|
} else {
|
||||||
data->current_hdc = data->current_hdc;
|
SelectObject(data->render_hdc, data->hbm[data->current_hbm]);
|
||||||
|
data->current_hdc = data->render_hdc;
|
||||||
|
data->makedirty = SDL_TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -509,6 +553,10 @@ SDL_GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||||
static HBRUSH brush;
|
static HBRUSH brush;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
if (data->makedirty) {
|
||||||
|
SDL_AddDirtyRect(&data->dirty, rect);
|
||||||
|
}
|
||||||
|
|
||||||
r = (Uint8) ((color >> 16) & 0xFF);
|
r = (Uint8) ((color >> 16) & 0xFF);
|
||||||
g = (Uint8) ((color >> 8) & 0xFF);
|
g = (Uint8) ((color >> 8) & 0xFF);
|
||||||
b = (Uint8) (color & 0xFF);
|
b = (Uint8) (color & 0xFF);
|
||||||
|
@ -540,6 +588,10 @@ SDL_GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
|
||||||
SDL_GDI_TextureData *texturedata =
|
SDL_GDI_TextureData *texturedata =
|
||||||
(SDL_GDI_TextureData *) texture->driverdata;
|
(SDL_GDI_TextureData *) texture->driverdata;
|
||||||
|
|
||||||
|
if (data->makedirty) {
|
||||||
|
SDL_AddDirtyRect(&data->dirty, dstrect);
|
||||||
|
}
|
||||||
|
|
||||||
SelectObject(data->memory_hdc, texturedata->hbm);
|
SelectObject(data->memory_hdc, texturedata->hbm);
|
||||||
if (texturedata->hpal) {
|
if (texturedata->hpal) {
|
||||||
SelectPalette(data->memory_hdc, texturedata->hpal, TRUE);
|
SelectPalette(data->memory_hdc, texturedata->hpal, TRUE);
|
||||||
|
@ -590,10 +642,10 @@ CreateWindowDIB(SDL_GDI_RenderData * data, SDL_Window * window)
|
||||||
data->bmi->bmiHeader.biHeight = -window->h;
|
data->bmi->bmiHeader.biHeight = -window->h;
|
||||||
data->bmi->bmiHeader.biSizeImage =
|
data->bmi->bmiHeader.biSizeImage =
|
||||||
window->h * (data->bmi->bmiHeader.biBitCount / 8);
|
window->h * (data->bmi->bmiHeader.biBitCount / 8);
|
||||||
data->window_bmp =
|
data->window_dib =
|
||||||
CreateDIBSection(data->window_hdc, data->bmi, DIB_RGB_COLORS,
|
CreateDIBSection(data->window_hdc, data->bmi, DIB_RGB_COLORS,
|
||||||
&data->window_pixels, NULL, 0);
|
&data->window_pixels, NULL, 0);
|
||||||
if (!data->window_bmp) {
|
if (!data->window_dib) {
|
||||||
WIN_SetError("CreateDIBSection()");
|
WIN_SetError("CreateDIBSection()");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -607,15 +659,15 @@ SDL_GDI_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||||
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
||||||
SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
|
SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
|
||||||
|
|
||||||
if (!data->window_bmp) {
|
if (!data->window_dib) {
|
||||||
if (CreateWindowDIB(data, window) < 0) {
|
if (CreateWindowDIB(data, window) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectObject(data->memory_hdc, data->window_bmp);
|
SelectObject(data->memory_hdc, data->window_dib);
|
||||||
BitBlt(data->memory_hdc, rect->x, rect->y, rect->w, rect->h,
|
BitBlt(data->memory_hdc, rect->x, rect->y, rect->w, rect->h,
|
||||||
data->window_hdc, rect->x, rect->y, SRCCOPY);
|
data->current_hdc, rect->x, rect->y, SRCCOPY);
|
||||||
|
|
||||||
{
|
{
|
||||||
int bpp = data->bmi->bmiHeader.biBitCount / 8;
|
int bpp = data->bmi->bmiHeader.biBitCount / 8;
|
||||||
|
@ -642,7 +694,11 @@ SDL_GDI_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||||
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
SDL_Window *window = SDL_GetWindowFromID(renderer->window);
|
||||||
SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
|
SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
|
||||||
|
|
||||||
if (!data->window_bmp) {
|
if (data->makedirty) {
|
||||||
|
SDL_AddDirtyRect(&data->dirty, rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data->window_dib) {
|
||||||
if (CreateWindowDIB(data, window) < 0) {
|
if (CreateWindowDIB(data, window) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -663,8 +719,8 @@ SDL_GDI_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectObject(data->memory_hdc, data->window_bmp);
|
SelectObject(data->memory_hdc, data->window_dib);
|
||||||
BitBlt(data->window_hdc, rect->x, rect->y, rect->w, rect->h,
|
BitBlt(data->current_hdc, rect->x, rect->y, rect->w, rect->h,
|
||||||
data->memory_hdc, rect->x, rect->y, SRCCOPY);
|
data->memory_hdc, rect->x, rect->y, SRCCOPY);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -673,6 +729,31 @@ SDL_GDI_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
||||||
static void
|
static void
|
||||||
SDL_GDI_RenderPresent(SDL_Renderer * renderer)
|
SDL_GDI_RenderPresent(SDL_Renderer * renderer)
|
||||||
{
|
{
|
||||||
|
SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
|
||||||
|
SDL_DirtyRect *dirty;
|
||||||
|
int new_hbm;
|
||||||
|
|
||||||
|
/* Send the data to the display */
|
||||||
|
/*
|
||||||
|
if (!(renderer->info.flags & SDL_Renderer_SingleBuffer)) {
|
||||||
|
for (dirty = data->dirty.list; dirty; dirty = dirty->next) {
|
||||||
|
const SDL_Rect *rect = &dirty->rect;
|
||||||
|
BitBlt(data->window_hdc, rect->x, rect->y, rect->w, rect->h,
|
||||||
|
data->render_hdc, rect->x, rect->y, SRCCOPY);
|
||||||
|
}
|
||||||
|
SDL_ClearDirtyRects(&data->dirty);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
BitBlt(data->window_hdc, 0, 0, 640, 480, data->render_hdc, 0, 0, SRCCOPY);
|
||||||
|
|
||||||
|
/* Update the flipping chain, if any */
|
||||||
|
if (renderer->info.flags & SDL_Renderer_PresentFlip2) {
|
||||||
|
data->current_hbm = (data->current_hbm + 1) % 2;
|
||||||
|
SelectObject(data->render_hdc, data->hbm[data->current_hbm]);
|
||||||
|
} else if (renderer->info.flags & SDL_Renderer_PresentFlip3) {
|
||||||
|
data->current_hbm = (data->current_hbm + 1) % 3;
|
||||||
|
SelectObject(data->render_hdc, data->hbm[data->current_hbm]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -700,6 +781,7 @@ void
|
||||||
SDL_GDI_DestroyRenderer(SDL_Renderer * renderer)
|
SDL_GDI_DestroyRenderer(SDL_Renderer * renderer)
|
||||||
{
|
{
|
||||||
SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
|
SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
ReleaseDC(data->hwnd, data->window_hdc);
|
ReleaseDC(data->hwnd, data->window_hdc);
|
||||||
|
@ -708,8 +790,14 @@ SDL_GDI_DestroyRenderer(SDL_Renderer * renderer)
|
||||||
if (data->bmi) {
|
if (data->bmi) {
|
||||||
SDL_free(data->bmi);
|
SDL_free(data->bmi);
|
||||||
}
|
}
|
||||||
if (data->window_bmp) {
|
for (i = 0; i < SDL_arraysize(data->hbm); ++i) {
|
||||||
DeleteObject(data->window_bmp);
|
if (data->hbm[i]) {
|
||||||
|
DeleteObject(data->hbm[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_FreeDirtyRects(&data->dirty);
|
||||||
|
if (data->window_dib) {
|
||||||
|
DeleteObject(data->window_dib);
|
||||||
}
|
}
|
||||||
SDL_free(data);
|
SDL_free(data);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue