Mercurial > sdl-ios-xcode
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 |