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 {