Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

Solved the performance problems by introducing the concept of a singl…

…e-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*
  • Loading branch information
slouken committed Jul 12, 2006
1 parent 9cd5159 commit e665a7f28dd73ec9d03674a82141a4331910fb87
Showing with 184 additions and 96 deletions.
  1. +5 −5 include/SDL_video.h
  2. +7 −15 src/SDL_compat.c
  3. +25 −20 src/video/SDL_renderer_sw.c
  4. +20 −17 src/video/SDL_video.c
  5. +127 −39 src/video/win32/SDL_gdirender.c
@@ -170,14 +170,14 @@ 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_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_PresentVSync = 0x00000010, /**< Present is synchronized with the refresh rate */
SDL_Renderer_RenderTarget = 0x00000020, /**< The renderer can create texture render targets */
SDL_Renderer_Accelerated = 0x00000040, /**< The renderer uses hardware acceleration */
SDL_Renderer_ = 0x00000080, /**< The renderer uses hardware acceleration */
SDL_Renderer_PresentDiscard = 0x00000010, /**< Present leaves the contents of the backbuffer undefined */
SDL_Renderer_PresentVSync = 0x00000020, /**< Present is synchronized with the refresh rate */
SDL_Renderer_RenderTarget = 0x00000040, /**< The renderer can create texture render targets */
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_RendererFlags;

@@ -442,7 +442,8 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
}

/* 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;
}

@@ -517,6 +518,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)

/* Clear the surface for display */
SDL_FillRect(SDL_PublicSurface, NULL, 0);
SDL_UpdateRect(SDL_PublicSurface, 0, 0, 0, 0);

/* We're finally done! */
return SDL_PublicSurface;
@@ -617,21 +619,11 @@ SDL_UpdateRect(SDL_Surface * screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h)
if (screen) {
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 */
rect.x = (Sint16) x;
rect.y = (Sint16) y;
rect.w = (Uint16) w;
rect.h = (Uint16) h;
rect.x = (int) x;
rect.y = (int) y;
rect.w = (int) (w ? w : screen->w);
rect.h = (int) (h ? h : screen->h);
SDL_UpdateRects(screen, 1, &rect);
}
}
@@ -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;
}
if (data->target == data->screens[data->current_screen]) {
data->target = data->screens[new_screen];
data->current_screen = (data->current_screen + 1) % 3;
data->target = data->screens[data->current_screen];
}
data->current_screen = new_screen;
}

static void
@@ -1769,9 +1769,8 @@ SDL_RenderFill(const SDL_Rect * rect, Uint32 color)
return 0;
}
}
rect = &real_rect;

return renderer->RenderFill(renderer, rect, color);
return renderer->RenderFill(renderer, &real_rect, color);
}

int
@@ -1793,25 +1792,26 @@ SDL_RenderCopy(SDL_TextureID textureID, const SDL_Rect * srcrect,
return -1;
}

/* FIXME: implement clipping */
window = SDL_GetWindowFromID(renderer->window);
real_srcrect.x = 0;
real_srcrect.y = 0;
real_srcrect.w = texture->w;
real_srcrect.h = texture->h;
real_dstrect.x = 0;
real_dstrect.y = 0;
real_dstrect.w = window->w;
real_dstrect.h = window->h;
if (!srcrect) {
srcrect = &real_srcrect;
if (srcrect) {
real_srcrect = *srcrect;
} else {
real_srcrect.x = 0;
real_srcrect.y = 0;
real_srcrect.w = texture->w;
real_srcrect.h = texture->h;
}
if (!dstrect) {
dstrect = &real_dstrect;
if (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,
blendMode, scaleMode);
return renderer->RenderCopy(renderer, texture, &real_srcrect,
&real_dstrect, blendMode, scaleMode);
}

int
@@ -1882,6 +1882,9 @@ SDL_RenderPresent(void)
return;
}

if (renderer->SelectRenderTexture) {
renderer->SelectRenderTexture(renderer, NULL);
}
renderer->RenderPresent(renderer);
}

0 comments on commit e665a7f

Please sign in to comment.