comparison src/video/win32/SDL_gdirender.c @ 1907:06c27a737b7a

Streamlined the API a bit and optimized the software renderer.
author Sam Lantinga <slouken@libsdl.org>
date Sat, 15 Jul 2006 09:46:36 +0000
parents 36d52b1f0504
children 83420da906a5
comparison
equal deleted inserted replaced
1906:0c49855a7a3e 1907:06c27a737b7a
53 static void SDL_GDI_UnlockTexture(SDL_Renderer * renderer, 53 static void SDL_GDI_UnlockTexture(SDL_Renderer * renderer,
54 SDL_Texture * texture); 54 SDL_Texture * texture);
55 static void SDL_GDI_DirtyTexture(SDL_Renderer * renderer, 55 static void SDL_GDI_DirtyTexture(SDL_Renderer * renderer,
56 SDL_Texture * texture, int numrects, 56 SDL_Texture * texture, int numrects,
57 const SDL_Rect * rects); 57 const SDL_Rect * rects);
58 static void SDL_GDI_SelectRenderTexture(SDL_Renderer * renderer,
59 SDL_Texture * texture);
60 static int SDL_GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, 58 static int SDL_GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect,
61 Uint32 color); 59 Uint32 color);
62 static int SDL_GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, 60 static int SDL_GDI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
63 const SDL_Rect * srcrect, 61 const SDL_Rect * srcrect,
64 const SDL_Rect * dstrect, int blendMode, 62 const SDL_Rect * dstrect, int blendMode,
65 int scaleMode); 63 int scaleMode);
66 static int SDL_GDI_RenderReadPixels(SDL_Renderer * renderer,
67 const SDL_Rect * rect, void *pixels,
68 int pitch);
69 static int SDL_GDI_RenderWritePixels(SDL_Renderer * renderer,
70 const SDL_Rect * rect,
71 const void *pixels, int pitch);
72 static void SDL_GDI_RenderPresent(SDL_Renderer * renderer); 64 static void SDL_GDI_RenderPresent(SDL_Renderer * renderer);
73 static void SDL_GDI_DestroyTexture(SDL_Renderer * renderer, 65 static void SDL_GDI_DestroyTexture(SDL_Renderer * renderer,
74 SDL_Texture * texture); 66 SDL_Texture * texture);
75 static void SDL_GDI_DestroyRenderer(SDL_Renderer * renderer); 67 static void SDL_GDI_DestroyRenderer(SDL_Renderer * renderer);
76 68
79 SDL_GDI_CreateRenderer, 71 SDL_GDI_CreateRenderer,
80 { 72 {
81 "gdi", 73 "gdi",
82 (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy | 74 (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy |
83 SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 | 75 SDL_Renderer_PresentFlip2 | SDL_Renderer_PresentFlip3 |
84 SDL_Renderer_PresentDiscard | SDL_Renderer_RenderTarget), 76 SDL_Renderer_PresentDiscard),
85 (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask | 77 (SDL_TextureBlendMode_None | SDL_TextureBlendMode_Mask |
86 SDL_TextureBlendMode_Blend), 78 SDL_TextureBlendMode_Blend),
87 (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast), 79 (SDL_TextureScaleMode_None | SDL_TextureScaleMode_Fast),
88 11, 80 11,
89 { 81 {
112 LPBITMAPINFO bmi; 104 LPBITMAPINFO bmi;
113 HBITMAP hbm[3]; 105 HBITMAP hbm[3];
114 int current_hbm; 106 int current_hbm;
115 SDL_DirtyRectList dirty; 107 SDL_DirtyRectList dirty;
116 SDL_bool makedirty; 108 SDL_bool makedirty;
117 HBITMAP window_dib;
118 void *window_pixels;
119 int window_pitch;
120 } SDL_GDI_RenderData; 109 } SDL_GDI_RenderData;
121 110
122 typedef struct 111 typedef struct
123 { 112 {
124 SDL_SW_YUVTexture *yuv; 113 SDL_SW_YUVTexture *yuv;
180 renderer->GetTexturePalette = SDL_GDI_GetTexturePalette; 169 renderer->GetTexturePalette = SDL_GDI_GetTexturePalette;
181 renderer->UpdateTexture = SDL_GDI_UpdateTexture; 170 renderer->UpdateTexture = SDL_GDI_UpdateTexture;
182 renderer->LockTexture = SDL_GDI_LockTexture; 171 renderer->LockTexture = SDL_GDI_LockTexture;
183 renderer->UnlockTexture = SDL_GDI_UnlockTexture; 172 renderer->UnlockTexture = SDL_GDI_UnlockTexture;
184 renderer->DirtyTexture = SDL_GDI_DirtyTexture; 173 renderer->DirtyTexture = SDL_GDI_DirtyTexture;
185 renderer->SelectRenderTexture = SDL_GDI_SelectRenderTexture;
186 renderer->RenderFill = SDL_GDI_RenderFill; 174 renderer->RenderFill = SDL_GDI_RenderFill;
187 renderer->RenderCopy = SDL_GDI_RenderCopy; 175 renderer->RenderCopy = SDL_GDI_RenderCopy;
188 renderer->RenderReadPixels = SDL_GDI_RenderReadPixels;
189 renderer->RenderWritePixels = SDL_GDI_RenderWritePixels;
190 renderer->RenderPresent = SDL_GDI_RenderPresent; 176 renderer->RenderPresent = SDL_GDI_RenderPresent;
191 renderer->DestroyTexture = SDL_GDI_DestroyTexture; 177 renderer->DestroyTexture = SDL_GDI_DestroyTexture;
192 renderer->DestroyRenderer = SDL_GDI_DestroyRenderer; 178 renderer->DestroyRenderer = SDL_GDI_DestroyRenderer;
193 renderer->info = SDL_GDI_RenderDriver.info; 179 renderer->info = SDL_GDI_RenderDriver.info;
194 renderer->window = window->id; 180 renderer->window = window->id;
195 renderer->driverdata = data; 181 renderer->driverdata = data;
196 182
197 renderer->info.flags = SDL_Renderer_RenderTarget; 183 renderer->info.flags = SDL_Renderer_Accelerated;
198 184
199 data->hwnd = windowdata->hwnd; 185 data->hwnd = windowdata->hwnd;
200 data->window_hdc = GetDC(data->hwnd); 186 data->window_hdc = GetDC(data->hwnd);
201 data->render_hdc = CreateCompatibleDC(data->window_hdc); 187 data->render_hdc = CreateCompatibleDC(data->window_hdc);
202 data->memory_hdc = CreateCompatibleDC(data->window_hdc); 188 data->memory_hdc = CreateCompatibleDC(data->window_hdc);
216 GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS); 202 GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS);
217 GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS); 203 GetDIBits(data->window_hdc, hbm, 0, 1, NULL, data->bmi, DIB_RGB_COLORS);
218 DeleteObject(hbm); 204 DeleteObject(hbm);
219 205
220 if (flags & SDL_Renderer_SingleBuffer) { 206 if (flags & SDL_Renderer_SingleBuffer) {
221 renderer->info.flags |= SDL_Renderer_SingleBuffer; 207 renderer->info.flags |=
208 (SDL_Renderer_SingleBuffer | SDL_Renderer_PresentCopy);
222 n = 0; 209 n = 0;
223 } else if (flags & SDL_Renderer_PresentFlip2) { 210 } else if (flags & SDL_Renderer_PresentFlip2) {
224 renderer->info.flags |= SDL_Renderer_PresentFlip2; 211 renderer->info.flags |= SDL_Renderer_PresentFlip2;
225 n = 2; 212 n = 2;
226 } else if (flags & SDL_Renderer_PresentFlip3) { 213 } else if (flags & SDL_Renderer_PresentFlip3) {
269 SDL_zerop(data); 256 SDL_zerop(data);
270 257
271 texture->driverdata = data; 258 texture->driverdata = data;
272 259
273 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) { 260 if (SDL_ISPIXELFORMAT_FOURCC(texture->format)) {
274 if (texture->access == SDL_TextureAccess_Render) {
275 SDL_SetError("Rendering to YUV format textures is not supported");
276 return -1;
277 }
278 data->yuv = SDL_SW_CreateYUVTexture(texture); 261 data->yuv = SDL_SW_CreateYUVTexture(texture);
279 if (!data->yuv) { 262 if (!data->yuv) {
280 SDL_GDI_DestroyTexture(renderer, texture); 263 SDL_GDI_DestroyTexture(renderer, texture);
281 return -1; 264 return -1;
282 } 265 }
519 SDL_GDI_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture, 502 SDL_GDI_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
520 int numrects, const SDL_Rect * rects) 503 int numrects, const SDL_Rect * rects)
521 { 504 {
522 } 505 }
523 506
524 static void
525 SDL_GDI_SelectRenderTexture(SDL_Renderer * renderer, SDL_Texture * texture)
526 {
527 SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
528
529 if (texture) {
530 SDL_GDI_TextureData *texturedata =
531 (SDL_GDI_TextureData *) texture->driverdata;
532 SelectObject(data->render_hdc, texturedata->hbm);
533 if (texturedata->hpal) {
534 SelectPalette(data->render_hdc, texturedata->hpal, TRUE);
535 RealizePalette(data->render_hdc);
536 }
537 data->current_hdc = data->render_hdc;
538 data->makedirty = SDL_FALSE;
539 } else if (renderer->info.flags & SDL_Renderer_SingleBuffer) {
540 data->current_hdc = data->window_hdc;
541 data->makedirty = SDL_FALSE;
542 } else {
543 SelectObject(data->render_hdc, data->hbm[data->current_hbm]);
544 data->current_hdc = data->render_hdc;
545 data->makedirty = SDL_TRUE;
546 }
547 }
548
549 static int 507 static int
550 SDL_GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect, 508 SDL_GDI_RenderFill(SDL_Renderer * renderer, const SDL_Rect * rect,
551 Uint32 color) 509 Uint32 color)
552 { 510 {
553 SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata; 511 SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
635 } 593 }
636 } 594 }
637 return 0; 595 return 0;
638 } 596 }
639 597
640 static int
641 CreateWindowDIB(SDL_GDI_RenderData * data, SDL_Window * window)
642 {
643 data->window_pitch = window->w * (data->bmi->bmiHeader.biBitCount / 8);
644 data->bmi->bmiHeader.biWidth = window->w;
645 data->bmi->bmiHeader.biHeight = -window->h;
646 data->bmi->bmiHeader.biSizeImage =
647 window->h * (data->bmi->bmiHeader.biBitCount / 8);
648 data->window_dib =
649 CreateDIBSection(data->window_hdc, data->bmi, DIB_RGB_COLORS,
650 &data->window_pixels, NULL, 0);
651 if (!data->window_dib) {
652 WIN_SetError("CreateDIBSection()");
653 return -1;
654 }
655 return 0;
656 }
657
658 static int
659 SDL_GDI_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
660 void *pixels, int pitch)
661 {
662 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
663 SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
664
665 if (!data->window_dib) {
666 if (CreateWindowDIB(data, window) < 0) {
667 return -1;
668 }
669 }
670
671 SelectObject(data->memory_hdc, data->window_dib);
672 BitBlt(data->memory_hdc, rect->x, rect->y, rect->w, rect->h,
673 data->current_hdc, rect->x, rect->y, SRCCOPY);
674
675 {
676 int bpp = data->bmi->bmiHeader.biBitCount / 8;
677 Uint8 *src =
678 (Uint8 *) data->window_pixels + rect->y * data->window_pitch +
679 rect->x * bpp;
680 Uint8 *dst = (Uint8 *) pixels;
681 int row;
682
683 for (row = 0; row < rect->h; ++row) {
684 SDL_memcpy(dst, src, rect->w * bpp);
685 src += data->window_pitch;
686 dst += pitch;
687 }
688 }
689
690 return 0;
691 }
692
693 static int
694 SDL_GDI_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
695 const void *pixels, int pitch)
696 {
697 SDL_Window *window = SDL_GetWindowFromID(renderer->window);
698 SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
699
700 if (data->makedirty) {
701 SDL_AddDirtyRect(&data->dirty, rect);
702 }
703
704 if (!data->window_dib) {
705 if (CreateWindowDIB(data, window) < 0) {
706 return -1;
707 }
708 }
709
710 {
711 int bpp = data->bmi->bmiHeader.biBitCount / 8;
712 Uint8 *src = (Uint8 *) pixels;
713 Uint8 *dst =
714 (Uint8 *) data->window_pixels + rect->y * data->window_pitch +
715 rect->x * bpp;
716 int row;
717
718 for (row = 0; row < rect->h; ++row) {
719 SDL_memcpy(dst, src, rect->w * bpp);
720 src += pitch;
721 dst += data->window_pitch;
722 }
723 }
724
725 SelectObject(data->memory_hdc, data->window_dib);
726 BitBlt(data->current_hdc, rect->x, rect->y, rect->w, rect->h,
727 data->memory_hdc, rect->x, rect->y, SRCCOPY);
728
729 return 0;
730 }
731
732 static void 598 static void
733 SDL_GDI_RenderPresent(SDL_Renderer * renderer) 599 SDL_GDI_RenderPresent(SDL_Renderer * renderer)
734 { 600 {
735 SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata; 601 SDL_GDI_RenderData *data = (SDL_GDI_RenderData *) renderer->driverdata;
736 SDL_DirtyRect *dirty; 602 SDL_DirtyRect *dirty;
793 if (data->hbm[i]) { 659 if (data->hbm[i]) {
794 DeleteObject(data->hbm[i]); 660 DeleteObject(data->hbm[i]);
795 } 661 }
796 } 662 }
797 SDL_FreeDirtyRects(&data->dirty); 663 SDL_FreeDirtyRects(&data->dirty);
798 if (data->window_dib) {
799 DeleteObject(data->window_dib);
800 }
801 SDL_free(data); 664 SDL_free(data);
802 } 665 }
803 SDL_free(renderer); 666 SDL_free(renderer);
804 } 667 }
805 668