Mercurial > sdl-ios-xcode
comparison src/video/SDL_renderer_sw.c @ 1897:c2a27da60b18
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*
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 12 Jul 2006 06:39:26 +0000 |
parents | c121d94672cb |
children | 06c27a737b7a |
comparison
equal
deleted
inserted
replaced
1896:4a74fa359e7e | 1897:c2a27da60b18 |
---|---|
75 | 75 |
76 SDL_RenderDriver SDL_SW_RenderDriver = { | 76 SDL_RenderDriver SDL_SW_RenderDriver = { |
77 SDL_SW_CreateRenderer, | 77 SDL_SW_CreateRenderer, |
78 { | 78 { |
79 "software", | 79 "software", |
80 (SDL_Renderer_PresentDiscard | | 80 (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | |
81 SDL_Renderer_PresentCopy | | 81 SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | |
82 SDL_Renderer_PresentFlip2 | | 82 SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget), |
83 SDL_Renderer_PresentFlip3 | SDL_Renderer_RenderTarget), | 83 (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask | |
84 (SDL_TextureBlendMode_None | | 84 SDL_TextureBlendMode_Blend), |
85 SDL_TextureBlendMode_Mask | SDL_TextureBlendMode_Blend), | |
86 (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast), | 85 (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast), |
87 11, | 86 11, |
88 { | 87 { |
89 SDL_PixelFormat_Index8, | 88 SDL_PixelFormat_Index8, |
90 SDL_PixelFormat_RGB555, | 89 SDL_PixelFormat_RGB555, |
106 int current_screen; | 105 int current_screen; |
107 SDL_Surface *screens[3]; | 106 SDL_Surface *screens[3]; |
108 SDL_Surface *target; | 107 SDL_Surface *target; |
109 SDL_Renderer *renderer; | 108 SDL_Renderer *renderer; |
110 SDL_DirtyRectList dirty; | 109 SDL_DirtyRectList dirty; |
110 SDL_bool makedirty; | |
111 } SDL_SW_RenderData; | 111 } SDL_SW_RenderData; |
112 | 112 |
113 SDL_Renderer * | 113 SDL_Renderer * |
114 SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags) | 114 SDL_SW_CreateRenderer(SDL_Window * window, Uint32 flags) |
115 { | 115 { |
183 } | 183 } |
184 SDL_SetSurfacePalette(data->screens[i], display->palette); | 184 SDL_SetSurfacePalette(data->screens[i], display->palette); |
185 } | 185 } |
186 data->current_screen = 0; | 186 data->current_screen = 0; |
187 data->target = data->screens[0]; | 187 data->target = data->screens[0]; |
188 data->makedirty = SDL_TRUE; | |
188 | 189 |
189 /* Find a render driver that we can use to display data */ | 190 /* Find a render driver that we can use to display data */ |
190 for (i = 0; i < display->num_render_drivers; ++i) { | 191 for (i = 0; i < display->num_render_drivers; ++i) { |
191 SDL_RenderDriver *driver = &display->render_drivers[i]; | 192 SDL_RenderDriver *driver = &display->render_drivers[i]; |
192 if (driver->info.name != SDL_SW_RenderDriver.info.name) { | 193 if (driver->info.name != SDL_SW_RenderDriver.info.name) { |
193 data->renderer = | 194 data->renderer = |
194 driver->CreateRenderer(window, SDL_Renderer_PresentDiscard); | 195 driver->CreateRenderer(window, |
196 (SDL_Renderer_SingleBuffer | | |
197 SDL_Renderer_PresentDiscard)); | |
195 if (data->renderer) { | 198 if (data->renderer) { |
196 break; | 199 break; |
197 } | 200 } |
198 } | 201 } |
199 } | 202 } |
349 { | 352 { |
350 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | 353 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; |
351 | 354 |
352 if (texture) { | 355 if (texture) { |
353 data->target = (SDL_Surface *) texture->driverdata; | 356 data->target = (SDL_Surface *) texture->driverdata; |
357 data->makedirty = SDL_FALSE; | |
354 } else { | 358 } else { |
355 data->target = data->screens[data->current_screen]; | 359 data->target = data->screens[data->current_screen]; |
360 data->makedirty = SDL_TRUE; | |
356 } | 361 } |
357 } | 362 } |
358 | 363 |
359 static int | 364 static int |
360 SDL_SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, | 365 SDL_SW_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, |
362 { | 367 { |
363 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | 368 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; |
364 SDL_Rect real_rect = *rect; | 369 SDL_Rect real_rect = *rect; |
365 Uint8 r, g, b, a; | 370 Uint8 r, g, b, a; |
366 | 371 |
367 SDL_AddDirtyRect(&data->dirty, rect); | 372 if (data->makedirty) { |
373 SDL_AddDirtyRect(&data->dirty, rect); | |
374 } | |
368 | 375 |
369 a = (Uint8) ((color >> 24) & 0xFF); | 376 a = (Uint8) ((color >> 24) & 0xFF); |
370 r = (Uint8) ((color >> 16) & 0xFF); | 377 r = (Uint8) ((color >> 16) & 0xFF); |
371 g = (Uint8) ((color >> 8) & 0xFF); | 378 g = (Uint8) ((color >> 8) & 0xFF); |
372 b = (Uint8) (color & 0xFF); | 379 b = (Uint8) (color & 0xFF); |
382 { | 389 { |
383 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | 390 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; |
384 SDL_Window *window = SDL_GetWindowFromID(renderer->window); | 391 SDL_Window *window = SDL_GetWindowFromID(renderer->window); |
385 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); | 392 SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window); |
386 | 393 |
387 SDL_AddDirtyRect(&data->dirty, dstrect); | 394 if (data->makedirty) { |
395 SDL_AddDirtyRect(&data->dirty, dstrect); | |
396 } | |
388 | 397 |
389 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { | 398 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { |
390 SDL_Surface *target = data->target; | 399 SDL_Surface *target = data->target; |
391 void *pixels = | 400 void *pixels = |
392 (Uint8 *) target->pixels + dstrect->y * target->pitch + | 401 (Uint8 *) target->pixels + dstrect->y * target->pitch + |
448 SDL_Surface *surface = data->target; | 457 SDL_Surface *surface = data->target; |
449 Uint8 *src, *dst; | 458 Uint8 *src, *dst; |
450 int row; | 459 int row; |
451 size_t length; | 460 size_t length; |
452 | 461 |
453 SDL_AddDirtyRect(&data->dirty, rect); | 462 if (data->makedirty) { |
463 SDL_AddDirtyRect(&data->dirty, rect); | |
464 } | |
454 | 465 |
455 src = (Uint8 *) pixels; | 466 src = (Uint8 *) pixels; |
456 dst = | 467 dst = |
457 (Uint8 *) surface->pixels + rect->y * surface->pitch + | 468 (Uint8 *) surface->pixels + rect->y * surface->pitch + |
458 rect->x * surface->format->BytesPerPixel; | 469 rect->x * surface->format->BytesPerPixel; |
469 SDL_SW_RenderPresent(SDL_Renderer * renderer) | 480 SDL_SW_RenderPresent(SDL_Renderer * renderer) |
470 { | 481 { |
471 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; | 482 SDL_SW_RenderData *data = (SDL_SW_RenderData *) renderer->driverdata; |
472 SDL_Surface *surface = data->screens[data->current_screen]; | 483 SDL_Surface *surface = data->screens[data->current_screen]; |
473 SDL_DirtyRect *dirty; | 484 SDL_DirtyRect *dirty; |
474 int new_screen; | |
475 | 485 |
476 /* Send the data to the display */ | 486 /* Send the data to the display */ |
477 for (dirty = data->dirty.list; dirty; dirty = dirty->next) { | 487 for (dirty = data->dirty.list; dirty; dirty = dirty->next) { |
478 void *pixels = | 488 void *pixels = |
479 (void *) ((Uint8 *) surface->pixels + | 489 (void *) ((Uint8 *) surface->pixels + |
483 pixels, surface->pitch); | 493 pixels, surface->pitch); |
484 } | 494 } |
485 SDL_ClearDirtyRects(&data->dirty); | 495 SDL_ClearDirtyRects(&data->dirty); |
486 data->renderer->RenderPresent(data->renderer); | 496 data->renderer->RenderPresent(data->renderer); |
487 | 497 |
488 | |
489 /* Update the flipping chain, if any */ | 498 /* Update the flipping chain, if any */ |
490 if (renderer->info.flags & SDL_Renderer_PresentFlip2) { | 499 if (renderer->info.flags & SDL_Renderer_PresentFlip2) { |
491 new_screen = (data->current_screen + 1) % 2; | 500 data->current_screen = (data->current_screen + 1) % 2; |
501 data->target = data->screens[data->current_screen]; | |
492 } else if (renderer->info.flags & SDL_Renderer_PresentFlip3) { | 502 } else if (renderer->info.flags & SDL_Renderer_PresentFlip3) { |
493 new_screen = (data->current_screen + 1) % 3; | 503 data->current_screen = (data->current_screen + 1) % 3; |
494 } else { | 504 data->target = data->screens[data->current_screen]; |
495 new_screen = 0; | 505 } |
496 } | |
497 if (data->target == data->screens[data->current_screen]) { | |
498 data->target = data->screens[new_screen]; | |
499 } | |
500 data->current_screen = new_screen; | |
501 } | 506 } |
502 | 507 |
503 static void | 508 static void |
504 SDL_SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) | 509 SDL_SW_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture) |
505 { | 510 { |