Mercurial > sdl-ios-xcode
annotate src/video/win32/SDL_gapirender.c @ 4426:1bceff8f008f
Fixed bug #943
Ozkan Sezer 2010-02-06 12:31:06 PST
Hi:
Here are some small fixes for compiling SDL against mingw-w64.
(see http://mingw-w64.sourceforge.net/ . Despite the name, it
supports both win32 and win64.)
src/audio/windx5/directx.h and src/video/windx5/directx.h (both
SDL-1.2 and SDL-1.3.) I get compilation errors about some union
not having a member named u1 and alike, because of other system
headers being included before this one and them already defining
DUMMYUNIONNAME and stuff. This header probably assumes that those
stuff are defined in windef.h, but mingw-w64 headers define them
in _mingw.h. Easily fixed by moving NONAMELESSUNION definition to
the top of the file.
src/thread/win32/SDL_systhread.c (both SDL-1.2 and SDL-1.3.) :
The __GNUC__ case for pfnSDL_CurrentBeginThread is 32-bit centric
because _beginthreadex returns uintptr_t, not unsigned long which
is 32 bits in win64. Changing the return type to uintptr_t fixes
it.
video/SDL_blit.h (and configure.in) (SDL-1.3-only) : MinGW-w64
uses msvcrt version of _aligned_malloc and _aligned_free and
they are defined in intrin.h (similar to VC). Adding proper
ifdefs fixes it. (Notes about macros to check: __MINGW32__ is
defined for both mingw.org and for mingw-w64 for both win32 and
win64, __MINGW64__ is only defined for _WIN64, so __MINGW64__
can't be used to detect mingw-w64: including _mingw.h and then
checking for __MINGW64_VERSION_MAJOR does the trick.)
SDL_win32video.h (SDL-1.3-only) : Tweaked the VINWER definition
and location in order to avoid multiple redefinition warnings.
Hope these are useful. Thanks.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 10 Mar 2010 15:02:58 +0000 |
parents | f7b03b6838cb |
children | e1664f94f026 |
rev | line source |
---|---|
3168 | 1 /* |
2 SDL - Simple DirectMedia Layer | |
3697 | 3 Copyright (C) 1997-2010 Sam Lantinga |
3168 | 4 |
5 This library is free software; you can redistribute it and/or | |
6 modify it under the terms of the GNU Lesser General Public | |
7 License as published by the Free Software Foundation; either | |
8 version 2.1 of the License, or (at your option) any later version. | |
9 | |
10 This library is distributed in the hope that it will be useful, | |
11 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 Lesser General Public License for more details. | |
14 | |
15 You should have received a copy of the GNU Lesser General Public | |
16 License along with this library; if not, write to the Free Software | |
17 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
18 | |
19 Sam Lantinga | |
20 slouken@libsdl.org | |
21 | |
22 Stefan Klug | |
23 klug.stefan@gmx.de | |
24 */ | |
25 #include "SDL_config.h" | |
26 | |
27 #if SDL_VIDEO_RENDER_GAPI | |
28 | |
29 #include "SDL_win32video.h" | |
30 //#include "../SDL_sysvideo.h" | |
31 #include "../SDL_yuv_sw_c.h" | |
32 #include "../SDL_renderer_sw.h" | |
33 | |
34 #include "SDL_gapirender_c.h" | |
35 | |
36 #define GAPI_RENDERER_DEBUG 1 | |
37 | |
38 /* GAPI renderer implementation */ | |
39 | |
40 static SDL_Renderer *GAPI_CreateRenderer(SDL_Window * window, Uint32 flags); | |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
41 static int GAPI_RenderDrawPoints(SDL_Renderer * renderer, |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
42 const SDL_Point * points, int count); |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
43 static int GAPI_RenderDrawLines(SDL_Renderer * renderer, |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
44 const SDL_Point * points, int count); |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
45 static int GAPI_RenderDrawRects(SDL_Renderer * renderer, |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
46 const SDL_Rect ** rects, int count); |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
47 static int GAPI_RenderFillRects(SDL_Renderer * renderer, |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
48 const SDL_Rect ** rects, int count); |
3168 | 49 static int GAPI_RenderCopy(SDL_Renderer * renderer, |
50 SDL_Texture * texture, | |
51 const SDL_Rect * srcrect, | |
52 const SDL_Rect * dstrect); | |
53 static void GAPI_RenderPresent(SDL_Renderer * renderer); | |
54 static void GAPI_DestroyRenderer(SDL_Renderer * renderer); | |
55 | |
56 | |
57 SDL_RenderDriver GAPI_RenderDriver = { | |
58 GAPI_CreateRenderer, | |
59 { | |
60 "gapi", | |
61 (SDL_RENDERER_SINGLEBUFFER), | |
62 } | |
63 }; | |
64 | |
65 static HMODULE g_hGapiLib = 0; | |
66 | |
67 // for testing with GapiEmu | |
68 #define USE_GAPI_EMU 0 | |
69 #define EMULATE_AXIM_X30 0 | |
70 | |
71 #if 0 | |
72 #define GAPI_LOG(...) printf(__VA_ARGS__) | |
73 #else | |
74 #define GAPI_LOG(...) | |
75 #endif | |
76 | |
77 | |
78 #if USE_GAPI_EMU && !REPORT_VIDEO_INFO | |
79 #pragma message("Warning: Using GapiEmu in release build. I assume you'd like to set USE_GAPI_EMU to zero.") | |
80 #endif | |
81 | |
82 | |
83 static void | |
84 GAPI_SetError(const char *prefix, HRESULT result) | |
85 { | |
86 const char *error; | |
87 | |
88 switch (result) { | |
89 default: | |
90 error = "UNKNOWN"; | |
91 break; | |
92 } | |
93 SDL_SetError("%s: %s", prefix, error); | |
94 } | |
95 | |
96 void | |
97 GAPI_AddRenderDriver(_THIS) | |
98 { | |
3520
83518f8fcd61
Fixed calls to SDL_AddRenderDriver()
Sam Lantinga <slouken@libsdl.org>
parents:
3168
diff
changeset
|
99 int i; |
83518f8fcd61
Fixed calls to SDL_AddRenderDriver()
Sam Lantinga <slouken@libsdl.org>
parents:
3168
diff
changeset
|
100 |
3168 | 101 /* TODO: should we check for support of GetRawFramebuffer here? |
102 */ | |
103 #if USE_GAPI_EMU | |
104 g_hGapiLib = LoadLibrary(L"GAPI_Emu.dll"); | |
105 #else | |
106 g_hGapiLib = LoadLibrary(L"\\Windows\\gx.dll"); | |
107 #endif | |
108 | |
109 if (g_hGapiLib) { | |
110 #define LINK(name,import) gx.name = (PFN##name)GetProcAddress( g_hGapiLib, L##import ); | |
111 | |
112 LINK(GXOpenDisplay, "?GXOpenDisplay@@YAHPAUHWND__@@K@Z") | |
113 LINK(GXCloseDisplay, "?GXCloseDisplay@@YAHXZ") | |
114 LINK(GXBeginDraw, "?GXBeginDraw@@YAPAXXZ") | |
115 LINK(GXEndDraw, "?GXEndDraw@@YAHXZ") | |
116 LINK(GXOpenInput, "?GXOpenInput@@YAHXZ") | |
117 LINK(GXCloseInput, "?GXCloseInput@@YAHXZ") | |
118 LINK(GXGetDisplayProperties, | |
119 "?GXGetDisplayProperties@@YA?AUGXDisplayProperties@@XZ") | |
120 LINK(GXGetDefaultKeys, "?GXGetDefaultKeys@@YA?AUGXKeyList@@H@Z") | |
121 LINK(GXSuspend, "?GXSuspend@@YAHXZ") | |
122 LINK(GXResume, "?GXResume@@YAHXZ") | |
123 LINK(GXSetViewport, "?GXSetViewport@@YAHKKKK@Z") | |
124 LINK(GXIsDisplayDRAMBuffer, "?GXIsDisplayDRAMBuffer@@YAHXZ") | |
125 | |
126 /* wrong gapi.dll */ | |
127 if (!gx.GXOpenDisplay) { | |
128 FreeLibrary(g_hGapiLib); | |
129 g_hGapiLib = 0; | |
130 } | |
131 #undef LINK | |
132 } | |
133 | |
3520
83518f8fcd61
Fixed calls to SDL_AddRenderDriver()
Sam Lantinga <slouken@libsdl.org>
parents:
3168
diff
changeset
|
134 for (i = 0; i < _this->num_displays; ++i) { |
83518f8fcd61
Fixed calls to SDL_AddRenderDriver()
Sam Lantinga <slouken@libsdl.org>
parents:
3168
diff
changeset
|
135 SDL_AddRenderDriver(&_this->displays[i], &GAPI_RenderDriver); |
83518f8fcd61
Fixed calls to SDL_AddRenderDriver()
Sam Lantinga <slouken@libsdl.org>
parents:
3168
diff
changeset
|
136 } |
3168 | 137 } |
138 | |
139 typedef enum | |
140 { | |
141 USAGE_GX_FUNCS = 0x0001, /* enable to use GXOpen/GXClose/GXBeginDraw... */ | |
142 USAGE_DATA_PTR_CONSTANT = 0x0002 /* the framebuffer is at a constant location, don't use values from GXBeginDraw() */ | |
143 } GAPI_UsageFlags; | |
144 | |
145 | |
146 | |
147 typedef struct | |
148 { | |
149 int w; | |
150 int h; | |
151 int xPitch; /* bytes to move to go to the next pixel */ | |
152 int yPitch; /* bytes to move to go to the next line */ | |
153 int offset; /* data offset, to add to the data returned from GetFramebuffer, before processing */ | |
154 | |
155 void *data; | |
156 Uint32 usageFlags; /* these flags contain options to define screen handling and to reliably workarounds */ | |
157 | |
158 Uint32 format; /* pixel format as defined in SDL_pixels.h */ | |
159 | |
160 } GAPI_RenderData; | |
161 | |
162 | |
163 static Uint32 | |
164 GuessPixelFormatFromBpp(int bpp) | |
165 { | |
166 switch (bpp) { | |
167 case 15: | |
168 return SDL_PIXELFORMAT_RGB555; | |
169 case 16: | |
170 return SDL_PIXELFORMAT_RGB565; | |
171 default: | |
172 return SDL_PIXELFORMAT_UNKNOWN; | |
173 break; | |
174 } | |
175 } | |
176 | |
177 static GAPI_RenderData * | |
178 FillRenderDataRawFramebuffer(SDL_Window * window) | |
179 { | |
180 RawFrameBufferInfo rbi; | |
181 GAPI_RenderData *renderdata; | |
182 HDC hdc; | |
183 | |
184 //TODO should we use the hdc of the window? | |
185 hdc = GetDC(NULL); | |
186 int result = ExtEscape(hdc, GETRAWFRAMEBUFFER, 0, NULL, | |
187 sizeof(RawFrameBufferInfo), | |
188 (char *) &rbi); | |
189 ReleaseDC(NULL, hdc); | |
190 | |
191 if (!(result > 0)) { | |
192 return NULL; | |
193 } | |
194 | |
195 /* Asus A696 returns wrong results so we do a sanity check | |
196 See: | |
197 http://groups.google.com/group/microsoft.public.smartphone.developer/browse_thread/thread/4fde5bddd477de81 | |
198 */ | |
199 if (rbi.cxPixels <= 0 || | |
200 rbi.cyPixels <= 0 || | |
201 rbi.cxStride == 0 || rbi.cyStride == 0 || rbi.pFramePointer == 0) { | |
202 return NULL; | |
203 } | |
204 | |
205 | |
206 renderdata = (GAPI_RenderData *) SDL_calloc(1, sizeof(*renderdata)); | |
207 if (!renderdata) { | |
208 SDL_OutOfMemory(); | |
209 return NULL; | |
210 } | |
211 //Try to match the window size | |
212 //TODO add rotation support | |
213 if (rbi.cxPixels != window->w || rbi.cyPixels != window->h) { | |
214 SDL_free(renderdata); | |
215 return NULL; | |
216 } | |
217 //Check that the display uses a known display format | |
218 switch (rbi.wFormat) { | |
219 case FORMAT_565: | |
220 renderdata->format = SDL_PIXELFORMAT_RGB565; | |
221 break; | |
222 case FORMAT_555: | |
223 renderdata->format = SDL_PIXELFORMAT_RGB555; | |
224 break; | |
225 default: | |
226 //TODO we should add support for other formats | |
227 SDL_free(renderdata); | |
228 return NULL; | |
229 } | |
230 | |
231 renderdata->usageFlags = USAGE_DATA_PTR_CONSTANT; | |
232 renderdata->data = rbi.pFramePointer; | |
233 renderdata->w = rbi.cxPixels; | |
234 renderdata->h = rbi.cyPixels; | |
235 renderdata->xPitch = rbi.cxStride; | |
236 renderdata->yPitch = rbi.cyStride; | |
237 | |
238 return renderdata; | |
239 | |
240 } | |
241 | |
242 | |
243 static GAPI_RenderData * | |
244 FillRenderDataGAPI(SDL_Window * window) | |
245 { | |
246 GAPI_RenderData *renderdata; | |
247 struct GXDisplayProperties gxdp; | |
248 int tmp; | |
249 | |
250 #ifdef _ARM_ | |
251 WCHAR oemstr[100]; | |
252 #endif | |
253 | |
254 if (!g_hGapiLib) { | |
255 return NULL; | |
256 } | |
257 | |
258 renderdata = (GAPI_RenderData *) SDL_calloc(1, sizeof(GAPI_RenderData)); | |
259 if (!renderdata) { | |
260 SDL_OutOfMemory(); | |
261 return NULL; | |
262 } | |
263 | |
264 gxdp = gx.GXGetDisplayProperties(); | |
265 renderdata->usageFlags = USAGE_GX_FUNCS; | |
266 renderdata->w = gxdp.cxWidth; | |
267 renderdata->h = gxdp.cyHeight; | |
268 renderdata->xPitch = gxdp.cbxPitch; | |
269 renderdata->yPitch = gxdp.cbyPitch; | |
270 | |
271 //Check that the display uses a known display format | |
272 if (gxdp.ffFormat & kfDirect565) { | |
273 renderdata->format = SDL_PIXELFORMAT_RGB565; | |
274 } else if (gxdp.ffFormat & kfDirect555) { | |
275 renderdata->format = SDL_PIXELFORMAT_RGB555; | |
276 } else { | |
277 renderdata->format = SDL_PIXELFORMAT_UNKNOWN; | |
278 } | |
279 | |
280 /* apply some device specific corrections */ | |
281 #ifdef _ARM_ | |
282 SystemParametersInfo(SPI_GETOEMINFO, sizeof(oemstr), oemstr, 0); | |
283 | |
284 // buggy iPaq38xx | |
285 if ((oemstr[12] == 'H') && (oemstr[13] == '3') | |
286 && (oemstr[14] == '8') | |
287 && (gxdp.cbxPitch > 0)) { | |
288 renderdata->data = (void *) 0xac0755a0; | |
289 renderdata->xPitch = -640; | |
290 renderdata->yPitch = 2; | |
291 } | |
292 #if (EMULATE_AXIM_X30 == 0) | |
293 // buggy Dell Axim X30 | |
294 if (_tcsncmp(oemstr, L"Dell Axim X30", 13) == 0) | |
295 #endif | |
296 { | |
297 GXDeviceInfo gxInfo = { 0 }; | |
298 HDC hdc = GetDC(NULL); | |
299 int result; | |
300 | |
301 gxInfo.Version = 100; | |
302 result = | |
303 ExtEscape(hdc, GETGXINFO, 0, NULL, sizeof(gxInfo), | |
304 (char *) &gxInfo); | |
305 if (result > 0) { | |
306 renderdata->usageFlags = USAGE_DATA_PTR_CONSTANT; /* no more GAPI usage from now */ | |
307 renderdata->data = gxInfo.pvFrameBuffer; | |
308 this->hidden->needUpdate = 0; | |
309 renderdata->xPitch = 2; | |
310 renderdata->yPitch = 480; | |
311 renderdata->w = gxInfo.cxWidth; | |
312 renderdata->h = gxInfo.cyHeight; | |
313 | |
314 //Check that the display uses a known display format | |
315 switch (rbi->wFormat) { | |
316 case FORMAT_565: | |
317 renderdata->format = SDL_PIXELFORMAT_RGB565; | |
318 break; | |
319 case FORMAT_555: | |
320 renderdata->format = SDL_PIXELFORMAT_RGB555; | |
321 break; | |
322 default: | |
323 //TODO we should add support for other formats | |
324 SDL_free(renderdata); | |
325 return NULL; | |
326 } | |
327 } | |
328 } | |
329 #endif | |
330 | |
331 | |
332 if (renderdata->format == SDL_PIXELFORMAT_UNKNOWN) { | |
333 SDL_SetError("Gapi Pixelformat is unknown"); | |
334 SDL_free(renderdata); | |
335 return NULL; | |
336 } | |
337 | |
338 /* Gapi always returns values in standard orientation, so we manually apply | |
339 the current orientation | |
340 */ | |
341 | |
342 DEVMODE settings; | |
343 SDL_memset(&settings, 0, sizeof(DEVMODE)); | |
344 settings.dmSize = sizeof(DEVMODE); | |
345 | |
346 settings.dmFields = DM_DISPLAYORIENTATION; | |
347 ChangeDisplaySettingsEx(NULL, &settings, NULL, CDS_TEST, NULL); | |
348 | |
349 if (settings.dmDisplayOrientation == DMDO_90) { | |
350 | |
351 tmp = renderdata->w; | |
352 renderdata->w = renderdata->h; | |
353 renderdata->h = tmp; | |
354 | |
355 tmp = renderdata->xPitch; | |
356 renderdata->xPitch = -renderdata->yPitch; | |
357 renderdata->yPitch = tmp; | |
358 | |
359 renderdata->offset = -renderdata->w * renderdata->xPitch; | |
360 | |
361 } else if (settings.dmDisplayOrientation == DMDO_180) { | |
362 | |
363 renderdata->xPitch = -renderdata->xPitch; | |
364 renderdata->yPitch = -renderdata->yPitch; | |
365 | |
366 renderdata->offset = -renderdata->h * renderdata->yPitch | |
367 - renderdata->w * renderdata->xPitch; | |
368 | |
369 } else if (settings.dmDisplayOrientation == DMDO_270) { | |
370 | |
371 tmp = renderdata->w; | |
372 renderdata->w = renderdata->h; | |
373 renderdata->h = tmp; | |
374 | |
375 tmp = renderdata->xPitch; | |
376 renderdata->xPitch = renderdata->yPitch; | |
377 renderdata->yPitch = -tmp; | |
378 | |
379 renderdata->offset = -renderdata->h * renderdata->yPitch; | |
380 | |
381 } | |
382 | |
383 if (renderdata->w != window->w || renderdata->h != window->h) { | |
384 GAPI_LOG("GAPI open failed, wrong size %i %i %i %i\n", renderdata->w, | |
385 renderdata->h, renderdata->xPitch, renderdata->yPitch); | |
386 SDL_free(renderdata); | |
387 return NULL; | |
388 } | |
389 | |
390 return renderdata; | |
391 | |
392 } | |
393 | |
394 | |
395 /* This function does the whole encapsulation of Gapi/RAWFRAMEBUFFER | |
396 it should handle all the device dependent details and fill the device INDEPENDENT | |
397 RenderData structure. | |
398 */ | |
399 GAPI_RenderData * | |
400 FillRenderData(SDL_Window * window) | |
401 { | |
402 /* We try to match the requested window to the modes available by GAPI and RAWFRAMEBUFFER. | |
403 First RAWFRAMEBUFFER is tried, as it is the most reliable one | |
404 Look here for detailed discussions: | |
405 http://pdaphonehome.com/forums/samsung-i700/28087-just-saw.html | |
406 http://blogs.msdn.com/windowsmobile/archive/2007/08/13/have-you-migrated-to-directdraw-yet.aspx | |
407 */ | |
408 | |
409 GAPI_RenderData *res; | |
410 | |
411 res = FillRenderDataRawFramebuffer(window); | |
412 GAPI_LOG("FillRenderDataRawFramebuffer: %p\n", res); | |
413 if (res) { | |
414 return res; | |
415 } | |
416 //Now we try gapi | |
417 res = FillRenderDataGAPI(window); | |
418 GAPI_LOG("FillRenderDataGAPI: %p\n", res); | |
419 | |
420 return res; | |
421 } | |
422 | |
423 void * | |
424 GetFramebuffer() | |
425 { | |
426 | |
427 } | |
428 | |
429 | |
430 SDL_Renderer * | |
431 GAPI_CreateRenderer(SDL_Window * window, Uint32 flags) | |
432 { | |
3685
64ce267332c6
Switched from SDL_WindowID and SDL_TextureID to SDL_Window* and SDL_Texture* for code simplicity and improved performance.
Sam Lantinga <slouken@libsdl.org>
parents:
3612
diff
changeset
|
433 SDL_VideoDisplay *display = window->display; |
3168 | 434 SDL_WindowData *windowdata = (SDL_WindowData *) window->driverdata; |
435 SDL_DisplayMode *displayMode = &display->current_mode; | |
436 SDL_Renderer *renderer; | |
437 GAPI_RenderData *data; | |
438 int i, n; | |
439 int bpp; | |
440 Uint32 Rmask, Gmask, Bmask, Amask; | |
441 | |
442 if (!(window->flags & SDL_WINDOW_FULLSCREEN)) { | |
443 SDL_SetError("Gapi supports only fullscreen windows"); | |
444 return NULL; | |
445 } | |
446 | |
447 if (!SDL_PixelFormatEnumToMasks | |
448 (displayMode->format, &bpp, &Rmask, &Gmask, &Bmask, &Amask)) { | |
449 SDL_SetError("Unknown display format"); | |
450 return NULL; | |
451 } | |
452 | |
453 renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer)); | |
454 if (!renderer) { | |
455 SDL_OutOfMemory(); | |
456 return NULL; | |
457 } | |
458 | |
459 data = FillRenderData(window); | |
460 if (!data) { | |
461 GAPI_DestroyRenderer(renderer); | |
462 SDL_OutOfMemory(); | |
463 return NULL; | |
464 } | |
465 | |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
466 renderer->RenderDrawPoints = GAPI_RenderDrawPoints; |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
467 renderer->RenderDrawLines = GAPI_RenderDrawLines; |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
468 renderer->RenderDrawRects = GAPI_RenderDrawRects; |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
469 renderer->RenderFillRects = GAPI_RenderFillRects; |
3168 | 470 renderer->RenderCopy = GAPI_RenderCopy; |
471 renderer->RenderPresent = GAPI_RenderPresent; | |
472 renderer->DestroyRenderer = GAPI_DestroyRenderer; | |
473 renderer->info.name = GAPI_RenderDriver.info.name; | |
474 renderer->info.flags = 0; | |
3685
64ce267332c6
Switched from SDL_WindowID and SDL_TextureID to SDL_Window* and SDL_Texture* for code simplicity and improved performance.
Sam Lantinga <slouken@libsdl.org>
parents:
3612
diff
changeset
|
475 renderer->window = window; |
3168 | 476 renderer->driverdata = data; |
477 | |
478 /* Gapi provides only a framebuffer so lets use software implementation */ | |
479 Setup_SoftwareRenderer(renderer); | |
480 | |
481 #ifdef GAPI_RENDERER_DEBUG | |
482 printf("Created gapi renderer\n"); | |
483 printf("use GX functions: %i\n", data->usageFlags & USAGE_GX_FUNCS); | |
484 printf("framebuffer is constant: %i\n", | |
485 data->usageFlags & USAGE_DATA_PTR_CONSTANT); | |
486 printf("w: %i h: %i\n", data->w, data->h); | |
487 printf("data ptr: %p\n", data->data); /* this can be 0 in case of GAPI usage */ | |
488 printf("xPitch: %i\n", data->xPitch); | |
489 printf("yPitch: %i\n", data->yPitch); | |
490 printf("offset: %i\n", data->offset); | |
491 printf("format: %x\n", data->format); | |
492 #endif | |
493 | |
494 if (data->usageFlags & USAGE_GX_FUNCS) { | |
495 if (gx.GXOpenDisplay(windowdata->hwnd, GX_FULLSCREEN) == 0) { | |
496 GAPI_DestroyRenderer(renderer); | |
497 return NULL; | |
498 } | |
499 } | |
500 | |
501 return renderer; | |
502 } | |
503 | |
504 static int | |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
505 GAPI_RenderDrawPoints(SDL_Renderer * renderer, |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
506 const SDL_Point * points, int count) |
3168 | 507 { |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
508 // TODO implement |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
509 SDL_Unsupported(); |
3168 | 510 return -1; |
511 } | |
512 | |
513 static int | |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
514 GAPI_RenderDrawLines(SDL_Renderer * renderer, |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
515 const SDL_Point * points, int count) |
3168 | 516 { |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
517 // TODO implement |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
518 SDL_Unsupported(); |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
519 return -1; |
3168 | 520 } |
521 | |
522 static int | |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
523 GAPI_RenderDrawRects(SDL_Renderer * renderer, |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
524 const SDL_Rect ** rects, int count) |
3168 | 525 { |
3612
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
526 // TODO implement |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
527 SDL_Unsupported(); |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
528 return -1; |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
529 } |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
530 |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
531 static int |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
532 GAPI_RenderFillRects(SDL_Renderer * renderer, |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
533 const SDL_Rect ** rects, int count) |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
534 { |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
535 // TODO implement |
ce7d4942d18b
I can't compile this, but it should be updated for the new rendering API now.
Sam Lantinga <slouken@libsdl.org>
parents:
3520
diff
changeset
|
536 SDL_Unsupported(); |
3168 | 537 return -1; |
538 } | |
539 | |
540 /* Video memory is very slow so lets optimize as much as possible */ | |
541 static void | |
542 updateLine16to16(char *src, int srcXPitch, int srcYPitch, | |
543 char *dst, int dstXPitch, int dstYPitch, int width, | |
544 int height) | |
545 { | |
546 char *srcLine, *dstLine; | |
547 char *srcPix, *dstPix; | |
548 | |
549 int x, y; | |
550 | |
551 //First dumb solution | |
552 if (srcXPitch == 2 && dstXPitch == 2) { | |
553 srcLine = src; | |
554 dstLine = dst; | |
555 y = height; | |
556 while (y--) { | |
557 SDL_memcpy(dstLine, srcLine, width * sizeof(Uint16)); | |
558 srcLine += srcYPitch; | |
559 dstLine += dstYPitch; | |
560 } | |
561 } else { | |
562 //printf("GAPI uses slow blit path %i, %i\n", dstXPitch, dstYPitch); | |
563 srcLine = src; | |
564 dstLine = dst; | |
565 y = height; | |
566 while (y--) { | |
567 srcPix = srcLine; | |
568 dstPix = dstLine; | |
569 x = width; | |
570 while (x--) { | |
571 *((Uint16 *) dstPix) = *((Uint16 *) srcPix); | |
572 dstPix += dstXPitch; | |
573 srcPix += srcXPitch; | |
574 } | |
575 srcLine += srcYPitch; | |
576 dstLine += dstYPitch; | |
577 } | |
578 } | |
579 } | |
580 | |
581 static int | |
582 GAPI_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, | |
583 const SDL_Rect * srcrect, const SDL_Rect * dstrect) | |
584 { | |
585 GAPI_RenderData *data = (GAPI_RenderData *) renderer->driverdata; | |
586 int bpp; | |
587 int bytespp; | |
588 int status; | |
589 Uint32 Rmask, Gmask, Bmask, Amask; | |
590 | |
591 if (texture->format != data->format) { | |
592 SDL_SetError("Gapi got wrong texture"); | |
593 return -1; | |
594 } | |
595 | |
596 GAPI_LOG("GAPI_RenderCopy\n"); | |
597 | |
598 if (data->usageFlags & USAGE_GX_FUNCS) { | |
599 char *buffer; | |
600 buffer = gx.GXBeginDraw(); | |
601 if (!(data->usageFlags & USAGE_DATA_PTR_CONSTANT)) { | |
602 data->data = buffer; | |
603 } | |
604 } | |
605 | |
606 GAPI_LOG("GAPI_RenderCopy blit\n"); | |
607 /* If our framebuffer has an xPitch which matches the pixelsize, we | |
608 can convert the framebuffer to a SDL_surface and blit there, | |
609 otherwise, we have to use our own blitting routine | |
610 */ | |
611 SDL_PixelFormatEnumToMasks(data->format, &bpp, &Rmask, &Gmask, &Bmask, | |
612 &Amask); | |
613 bytespp = bpp >> 3; | |
614 if (data->xPitch == bytespp && 0) { | |
615 SDL_Surface *screen = | |
616 SDL_CreateRGBSurfaceFrom(data->data, data->w, data->h, | |
617 bpp, data->yPitch, Rmask, Gmask, Bmask, | |
618 Amask); | |
619 status = | |
620 SDL_UpperBlit((SDL_Surface *) texture->driverdata, srcrect, | |
621 screen, dstrect); | |
622 SDL_FreeSurface(screen); | |
623 } else { /* screen is rotated, we have to blit on our own */ | |
624 SDL_Surface *surface = (SDL_Surface *) texture->driverdata; | |
625 | |
626 char *src, *dst; | |
627 src = surface->pixels; | |
628 src += srcrect->y * surface->pitch + srcrect->x * 2; | |
629 | |
630 dst = data->data + data->offset; | |
631 dst += dstrect->y * data->yPitch + dstrect->x * data->xPitch; | |
632 | |
633 updateLine16to16(src, 2, surface->pitch, | |
634 dst, data->xPitch, data->yPitch, | |
635 srcrect->w, srcrect->h); | |
636 | |
637 } | |
638 | |
639 Uint32 ticks = SDL_GetTicks(); | |
640 if (data->usageFlags & USAGE_GX_FUNCS) { | |
641 gx.GXEndDraw(); | |
642 } | |
643 GAPI_LOG("GAPI_RenderCopy %i\n", SDL_GetTicks() - ticks); | |
644 return status; | |
645 } | |
646 | |
647 static void | |
648 GAPI_RenderPresent(SDL_Renderer * renderer) | |
649 { | |
650 /* Nothing todo as we rendered directly to the screen on RenderCopy */ | |
651 } | |
652 | |
653 static void | |
654 GAPI_DestroyRenderer(SDL_Renderer * renderer) | |
655 { | |
656 GAPI_RenderData *data = (GAPI_RenderData *) renderer->driverdata; | |
657 | |
658 if (data->usageFlags & USAGE_GX_FUNCS) { | |
659 gx.GXCloseDisplay(); | |
660 } | |
661 | |
662 if (data) { | |
663 SDL_free(data); | |
664 } | |
665 SDL_free(renderer); | |
666 } | |
667 | |
668 #endif /* SDL_VIDEO_RENDER_GAPI */ | |
669 | |
670 /* vi: set ts=4 sw=4 expandtab: */ |