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
|
@ -77,12 +77,11 @@ SDL_RenderDriver SDL_SW_RenderDriver = {
|
|||
SDL_SW_CreateRenderer,
|
||||
{
|
||||
"software",
|
||||
(SDL_Renderer_PresentDiscard |
|
||||
SDL_Renderer_PresentCopy |
|
||||
SDL_Renderer_PresentFlip2 |
|
||||
SDL_Renderer_PresentFlip3 | SDL_Renderer_RenderTarget),
|
||||
(SDL_TextureBlendMode_None |
|
||||
SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend),
|
||||
(SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
|
||||
SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 |
|
||||
SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget),
|
||||
(SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask |
|
||||
SDL_TextureBlendMode_Blend),
|
||||
(SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
|
||||
11,
|
||||
{
|
||||
|
@ -108,6 +107,7 @@ typedef struct
|
|||
SDL_Surface *target;
|
||||
SDL_Renderer *renderer;
|
||||
SDL_DirtyRectList dirty;
|
||||
SDL_bool makedirty;
|
||||
} SDL_SW_RenderData;
|
||||
|
||||
SDL_Renderer *
|
||||
|
@ -185,13 +185,16 @@ SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags)
|
|||
}
|
||||
data->current_screen = 0;
|
||||
data->target = data->screens[0];
|
||||
data->makedirty = SDL_TRUE;
|
||||
|
||||
/* Find a render driver that we can use to display data */
|
||||
for (i = 0; i < display->num_render_drivers; ++i) {
|
||||
SDL_RenderDriver *driver = &display->render_drivers[i];
|
||||
if (driver->info.name != SDL_SW_RenderDriver.info.name) {
|
||||
data->renderer =
|
||||
driver->CreateRenderer(window, SDL_Renderer_PresentDiscard);
|
||||
driver->CreateRenderer(window,
|
||||
(SDL_Renderer_SingleBuffer |
|
||||
SDL_Renderer_PresentDiscard));
|
||||
if (data->renderer) {
|
||||
break;
|
||||
}
|
||||
|
@ -351,8 +354,10 @@ SDL_SW_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture)
|
|||
|
||||
if (texture) {
|
||||
data->target = (SDL_Surface *) texture->driverdata;
|
||||
data->makedirty = SDL_FALSE;
|
||||
} else {
|
||||
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;
|
||||
Uint8 r, g, b, a;
|
||||
|
||||
SDL_AddDirtyRect(&data->dirty, rect);
|
||||
if (data->makedirty) {
|
||||
SDL_AddDirtyRect(&data->dirty, rect);
|
||||
}
|
||||
|
||||
a = (Uint8) ((color >> 24) & 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_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
|
||||
|
||||
SDL_AddDirtyRect(&data->dirty, dstrect);
|
||||
if (data->makedirty) {
|
||||
SDL_AddDirtyRect(&data->dirty, dstrect);
|
||||
}
|
||||
|
||||
if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
|
||||
SDL_Surface *target = data->target;
|
||||
|
@ -450,7 +459,9 @@ SDL_SW_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
|
|||
int row;
|
||||
size_t length;
|
||||
|
||||
SDL_AddDirtyRect(&data->dirty, rect);
|
||||
if (data->makedirty) {
|
||||
SDL_AddDirtyRect(&data->dirty, rect);
|
||||
}
|
||||
|
||||
src = (Uint8 *) pixels;
|
||||
dst =
|
||||
|
@ -471,7 +482,6 @@ SDL_SW_RenderPresent(SDL_Renderer * renderer)
|
|||
SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata;
|
||||
SDL_Surface *surface = data->screens[data->current_screen];
|
||||
SDL_DirtyRect *dirty;
|
||||
int new_screen;
|
||||
|
||||
/* Send the data to the display */
|
||||
for (dirty = data->dirty.list; dirty; dirty = dirty->next) {
|
||||
|
@ -485,19 +495,14 @@ SDL_SW_RenderPresent(SDL_Renderer * renderer)
|
|||
SDL_ClearDirtyRects(&data->dirty);
|
||||
data->renderer->RenderPresent(data->renderer);
|
||||
|
||||
|
||||
/* Update the flipping chain, if any */
|
||||
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) {
|
||||
new_screen = (data->current_screen + 1) % 3;
|
||||
} else {
|
||||
new_screen = 0;
|
||||
data->current_screen = (data->current_screen + 1) % 3;
|
||||
data->target = data->screens[data->current_screen];
|
||||
}
|
||||
if (data->target == data->screens[data->current_screen]) {
|
||||
data->target = data->screens[new_screen];
|
||||
}
|
||||
data->current_screen = new_screen;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue