SDL_DirectFB_render.c 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
  4. This software is provided 'as-is', without any express or implied
  5. warranty. In no event will the authors be held liable for any damages
  6. arising from the use of this software.
  7. Permission is granted to anyone to use this software for any purpose,
  8. including commercial applications, and to alter it and redistribute it
  9. freely, subject to the following restrictions:
  10. 1. The origin of this software must not be misrepresented; you must not
  11. claim that you wrote the original software. If you use this software
  12. in a product, an acknowledgment in the product documentation would be
  13. appreciated but is not required.
  14. 2. Altered source versions must be plainly marked as such, and must not be
  15. misrepresented as being the original software.
  16. 3. This notice may not be removed or altered from any source distribution.
  17. */
  18. #include "SDL_config.h"
  19. #if SDL_VIDEO_DRIVER_DIRECTFB
  20. #include "SDL_DirectFB_window.h"
  21. #include "SDL_DirectFB_modes.h"
  22. #include "SDL_syswm.h"
  23. #include "SDL_DirectFB_shape.h"
  24. #include "../SDL_sysvideo.h"
  25. #include "../../render/SDL_sysrender.h"
  26. #ifndef DFB_VERSION_ATLEAST
  27. #define DFB_VERSIONNUM(X, Y, Z) \
  28. ((X)*1000 + (Y)*100 + (Z))
  29. #define DFB_COMPILEDVERSION \
  30. DFB_VERSIONNUM(DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION)
  31. #define DFB_VERSION_ATLEAST(X, Y, Z) \
  32. (DFB_COMPILEDVERSION >= DFB_VERSIONNUM(X, Y, Z))
  33. #define SDL_DFB_CHECK(x) x
  34. #endif
  35. /* the following is not yet tested ... */
  36. #define USE_DISPLAY_PALETTE (0)
  37. #define SDL_DFB_RENDERERDATA(rend) DirectFB_RenderData *renddata = ((rend) ? (DirectFB_RenderData *) (rend)->driverdata : NULL)
  38. /* GDI renderer implementation */
  39. static SDL_Renderer *DirectFB_CreateRenderer(SDL_Window * window,
  40. Uint32 flags);
  41. static void DirectFB_ActivateRenderer(SDL_Renderer * renderer);
  42. static int DirectFB_CreateTexture(SDL_Renderer * renderer,
  43. SDL_Texture * texture);
  44. static int DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
  45. SDL_Texture * texture,
  46. void **pixels, int *pitch);
  47. static int DirectFB_SetTexturePalette(SDL_Renderer * renderer,
  48. SDL_Texture * texture,
  49. const SDL_Color * colors,
  50. int firstcolor, int ncolors);
  51. static int DirectFB_GetTexturePalette(SDL_Renderer * renderer,
  52. SDL_Texture * texture,
  53. SDL_Color * colors,
  54. int firstcolor, int ncolors);
  55. static int DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer,
  56. SDL_Texture * texture);
  57. static int DirectFB_SetTextureColorMod(SDL_Renderer * renderer,
  58. SDL_Texture * texture);
  59. static int DirectFB_SetTextureBlendMode(SDL_Renderer * renderer,
  60. SDL_Texture * texture);
  61. static int DirectFB_SetTextureScaleMode(SDL_Renderer * renderer,
  62. SDL_Texture * texture);
  63. static int DirectFB_UpdateTexture(SDL_Renderer * renderer,
  64. SDL_Texture * texture,
  65. const SDL_Rect * rect,
  66. const void *pixels, int pitch);
  67. static int DirectFB_LockTexture(SDL_Renderer * renderer,
  68. SDL_Texture * texture,
  69. const SDL_Rect * rect,
  70. void **pixels, int *pitch);
  71. static void DirectFB_UnlockTexture(SDL_Renderer * renderer,
  72. SDL_Texture * texture);
  73. static void DirectFB_DirtyTexture(SDL_Renderer * renderer,
  74. SDL_Texture * texture, int numrects,
  75. const SDL_Rect * rects);
  76. static int DirectFB_SetDrawBlendMode(SDL_Renderer * renderer);
  77. static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer,
  78. const SDL_FPoint * points, int count);
  79. static int DirectFB_RenderDrawLines(SDL_Renderer * renderer,
  80. const SDL_FPoint * points, int count);
  81. static int DirectFB_RenderDrawRects(SDL_Renderer * renderer,
  82. const SDL_Rect ** rects, int count);
  83. static int DirectFB_RenderFillRects(SDL_Renderer * renderer,
  84. const SDL_FRect * rects, int count);
  85. static int DirectFB_RenderCopy(SDL_Renderer * renderer,
  86. SDL_Texture * texture,
  87. const SDL_Rect * srcrect,
  88. const SDL_FRect * dstrect);
  89. static void DirectFB_RenderPresent(SDL_Renderer * renderer);
  90. static void DirectFB_DestroyTexture(SDL_Renderer * renderer,
  91. SDL_Texture * texture);
  92. static void DirectFB_DestroyRenderer(SDL_Renderer * renderer);
  93. static int DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
  94. Uint32 format, void * pixels, int pitch);
  95. static int DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
  96. Uint32 format, const void * pixels, int pitch);
  97. static int DirectFB_UpdateViewport(SDL_Renderer * renderer);
  98. static int DirectFB_UpdateClipRect(SDL_Renderer * renderer);
  99. static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
  100. static int PrepareDraw(SDL_Renderer * renderer);
  101. #define SDL_DFB_WINDOWSURFACE(win) IDirectFBSurface *destsurf = ((DFB_WindowData *) ((win)->driverdata))->surface;
  102. SDL_RenderDriver DirectFB_RenderDriver = {
  103. DirectFB_CreateRenderer,
  104. {
  105. "directfb",
  106. (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
  107. /* (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
  108. SDL_TEXTUREMODULATE_ALPHA),
  109. (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND |
  110. SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
  111. (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST |
  112. SDL_SCALEMODE_SLOW | SDL_SCALEMODE_BEST), */
  113. 0,
  114. {
  115. /* formats filled in later */
  116. },
  117. 0,
  118. 0}
  119. };
  120. typedef struct
  121. {
  122. SDL_Window *window;
  123. DFBSurfaceFlipFlags flipflags;
  124. int size_changed;
  125. int lastBlendMode;
  126. DFBSurfaceBlittingFlags blitFlags;
  127. DFBSurfaceDrawingFlags drawFlags;
  128. IDirectFBSurface* target;
  129. } DirectFB_RenderData;
  130. typedef struct
  131. {
  132. IDirectFBSurface *surface;
  133. Uint32 format;
  134. void *pixels;
  135. int pitch;
  136. IDirectFBPalette *palette;
  137. int isDirty;
  138. SDL_VideoDisplay *display; /* only for yuv textures */
  139. #if (DFB_VERSION_ATLEAST(1,2,0))
  140. DFBSurfaceRenderOptions render_options;
  141. #endif
  142. } DirectFB_TextureData;
  143. static __inline__ void
  144. SDLtoDFBRect(const SDL_Rect * sr, DFBRectangle * dr)
  145. {
  146. dr->x = sr->x;
  147. dr->y = sr->y;
  148. dr->h = sr->h;
  149. dr->w = sr->w;
  150. }
  151. static __inline__ void
  152. SDLtoDFBRect_Float(const SDL_FRect * sr, DFBRectangle * dr)
  153. {
  154. dr->x = sr->x;
  155. dr->y = sr->y;
  156. dr->h = sr->h;
  157. dr->w = sr->w;
  158. }
  159. static int
  160. TextureHasAlpha(DirectFB_TextureData * data)
  161. {
  162. /* Drawing primitive ? */
  163. if (!data)
  164. return 0;
  165. return (DFB_PIXELFORMAT_HAS_ALPHA(DirectFB_SDLToDFBPixelFormat(data->format)) ? 1 : 0);
  166. #if 0
  167. switch (data->format) {
  168. case SDL_PIXELFORMAT_INDEX4LSB:
  169. case SDL_PIXELFORMAT_INDEX4MSB:
  170. case SDL_PIXELFORMAT_ARGB4444:
  171. case SDL_PIXELFORMAT_ARGB1555:
  172. case SDL_PIXELFORMAT_ARGB8888:
  173. case SDL_PIXELFORMAT_RGBA8888:
  174. case SDL_PIXELFORMAT_ABGR8888:
  175. case SDL_PIXELFORMAT_BGRA8888:
  176. case SDL_PIXELFORMAT_ARGB2101010:
  177. return 1;
  178. default:
  179. return 0;
  180. }
  181. #endif
  182. }
  183. static inline IDirectFBSurface *get_dfb_surface(SDL_Window *window)
  184. {
  185. SDL_SysWMinfo wm_info;
  186. SDL_memset(&wm_info, 0, sizeof(SDL_SysWMinfo));
  187. SDL_VERSION(&wm_info.version);
  188. SDL_GetWindowWMInfo(window, &wm_info);
  189. return wm_info.info.dfb.surface;
  190. }
  191. static inline IDirectFBWindow *get_dfb_window(SDL_Window *window)
  192. {
  193. SDL_SysWMinfo wm_info;
  194. SDL_memset(&wm_info, 0, sizeof(SDL_SysWMinfo));
  195. SDL_VERSION(&wm_info.version);
  196. SDL_GetWindowWMInfo(window, &wm_info);
  197. return wm_info.info.dfb.window;
  198. }
  199. static void
  200. SetBlendMode(DirectFB_RenderData * data, int blendMode,
  201. DirectFB_TextureData * source)
  202. {
  203. IDirectFBSurface *destsurf = data->target;
  204. /* FIXME: check for format change */
  205. if (1 || data->lastBlendMode != blendMode) {
  206. switch (blendMode) {
  207. case SDL_BLENDMODE_NONE:
  208. /**< No blending */
  209. data->blitFlags = DSBLIT_NOFX;
  210. data->drawFlags = DSDRAW_NOFX;
  211. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
  212. SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ZERO));
  213. break;
  214. #if 0
  215. case SDL_BLENDMODE_MASK:
  216. data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
  217. data->drawFlags = DSDRAW_BLEND;
  218. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
  219. SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
  220. break;
  221. #endif
  222. case SDL_BLENDMODE_BLEND:
  223. data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
  224. data->drawFlags = DSDRAW_BLEND;
  225. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
  226. SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
  227. break;
  228. case SDL_BLENDMODE_ADD:
  229. data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
  230. data->drawFlags = DSDRAW_BLEND;
  231. /* FIXME: SRCALPHA kills performance on radeon ... */
  232. * It will be cheaper to copy the surface to a temporary surface and premultiply
  233. */
  234. if (source && TextureHasAlpha(source))
  235. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
  236. else
  237. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
  238. SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ONE));
  239. break;
  240. case SDL_BLENDMODE_MOD:
  241. data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
  242. data->drawFlags = DSDRAW_BLEND;
  243. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ZERO));
  244. SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_SRCCOLOR));
  245. break;
  246. }
  247. data->lastBlendMode = blendMode;
  248. }
  249. }
  250. static int
  251. DisplayPaletteChanged(void *userdata, SDL_Palette * palette)
  252. {
  253. #if USE_DISPLAY_PALETTE
  254. DirectFB_RenderData *data = (DirectFB_RenderData *) userdata;
  255. SDL_DFB_WINDOWSURFACE(data->window);
  256. IDirectFBPalette *surfpal;
  257. int i;
  258. int ncolors;
  259. DFBColor entries[256];
  260. SDL_DFB_CHECKERR(destsurf->GetPalette(destsurf, &surfpal));
  261. /* FIXME: number of colors */
  262. ncolors = (palette->ncolors < 256 ? palette->ncolors : 256);
  263. for (i = 0; i < ncolors; ++i) {
  264. entries[i].r = palette->colors[i].r;
  265. entries[i].g = palette->colors[i].g;
  266. entries[i].b = palette->colors[i].b;
  267. entries[i].a = palette->colors[i].unused;
  268. }
  269. SDL_DFB_CHECKERR(surfpal->SetEntries(surfpal, entries, ncolors, 0));
  270. return 0;
  271. error:
  272. #else
  273. SDL_Unsupported();
  274. #endif
  275. return -1;
  276. }
  277. static void
  278. DirectFB_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
  279. {
  280. SDL_DFB_RENDERERDATA(renderer);
  281. if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
  282. /* Rebind the context to the window area and update matrices */
  283. /*SDL_CurrentContext = NULL; */
  284. /*data->updateSize = SDL_TRUE; */
  285. renddata->size_changed = SDL_TRUE;
  286. }
  287. }
  288. int
  289. DirectFB_RenderClear(SDL_Renderer * renderer)
  290. {
  291. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  292. IDirectFBSurface *destsurf = data->target;
  293. DirectFB_ActivateRenderer(renderer);
  294. PrepareDraw(renderer);
  295. destsurf->Clear(destsurf, renderer->r, renderer->g, renderer->b, renderer->a);
  296. return 0;
  297. }
  298. SDL_Renderer *
  299. DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags)
  300. {
  301. IDirectFBSurface *winsurf = get_dfb_surface(window);
  302. SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
  303. SDL_Renderer *renderer = NULL;
  304. DirectFB_RenderData *data = NULL;
  305. DFBSurfaceCapabilities scaps;
  306. SDL_DFB_ALLOC_CLEAR(renderer, sizeof(*renderer));
  307. SDL_DFB_ALLOC_CLEAR(data, sizeof(*data));
  308. renderer->WindowEvent = DirectFB_WindowEvent;
  309. renderer->CreateTexture = DirectFB_CreateTexture;
  310. renderer->SetTextureAlphaMod = DirectFB_SetTextureAlphaMod;
  311. renderer->SetTextureColorMod = DirectFB_SetTextureColorMod;
  312. renderer->SetTextureBlendMode = DirectFB_SetTextureBlendMode;
  313. renderer->UpdateTexture = DirectFB_UpdateTexture;
  314. renderer->LockTexture = DirectFB_LockTexture;
  315. renderer->RenderClear = DirectFB_RenderClear;
  316. renderer->UnlockTexture = DirectFB_UnlockTexture;
  317. renderer->RenderDrawPoints = DirectFB_RenderDrawPoints;
  318. renderer->RenderDrawLines = DirectFB_RenderDrawLines;
  319. /* SetDrawColor - no needed */
  320. renderer->RenderFillRects = DirectFB_RenderFillRects;
  321. renderer->RenderCopy = DirectFB_RenderCopy;
  322. renderer->RenderPresent = DirectFB_RenderPresent;
  323. /* FIXME: Yet to be tested */
  324. renderer->RenderReadPixels = DirectFB_RenderReadPixels;
  325. /*renderer->RenderWritePixels = DirectFB_RenderWritePixels; */
  326. renderer->DestroyTexture = DirectFB_DestroyTexture;
  327. renderer->DestroyRenderer = DirectFB_DestroyRenderer;
  328. renderer->UpdateViewport = DirectFB_UpdateViewport;
  329. renderer->UpdateClipRect = DirectFB_UpdateClipRect;
  330. renderer->SetRenderTarget = DirectFB_SetRenderTarget;
  331. #if 0
  332. renderer->QueryTexturePixels = DirectFB_QueryTexturePixels;
  333. renderer->SetTexturePalette = DirectFB_SetTexturePalette;
  334. renderer->GetTexturePalette = DirectFB_GetTexturePalette;
  335. renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode;
  336. renderer->DirtyTexture = DirectFB_DirtyTexture;
  337. renderer->SetDrawBlendMode = DirectFB_SetDrawBlendMode;
  338. renderer->RenderDrawRects = DirectFB_RenderDrawRects;
  339. #endif
  340. renderer->info = DirectFB_RenderDriver.info;
  341. renderer->window = window; /* SDL window */
  342. renderer->driverdata = data;
  343. renderer->info.flags =
  344. SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
  345. data->window = window;
  346. data->target = winsurf;
  347. data->flipflags = DSFLIP_PIPELINE | DSFLIP_BLIT;
  348. if (flags & SDL_RENDERER_PRESENTVSYNC) {
  349. data->flipflags |= DSFLIP_WAITFORSYNC | DSFLIP_ONSYNC;
  350. renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
  351. } else
  352. data->flipflags |= DSFLIP_ONSYNC;
  353. SDL_DFB_CHECKERR(winsurf->GetCapabilities(winsurf, &scaps));
  354. #if 0
  355. if (scaps & DSCAPS_DOUBLE)
  356. renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
  357. else if (scaps & DSCAPS_TRIPLE)
  358. renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
  359. else
  360. renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
  361. #endif
  362. DirectFB_SetSupportedPixelFormats(&renderer->info);
  363. #if 0
  364. /* Set up a palette watch on the display palette */
  365. if (display-> palette) {
  366. SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data);
  367. }
  368. #endif
  369. return renderer;
  370. error:
  371. SDL_DFB_FREE(renderer);
  372. SDL_DFB_FREE(data);
  373. return NULL;
  374. }
  375. static void
  376. DirectFB_ActivateRenderer(SDL_Renderer * renderer)
  377. {
  378. SDL_DFB_RENDERERDATA(renderer);
  379. SDL_Window *window = renderer->window;
  380. SDL_DFB_WINDOWDATA(window);
  381. if (renddata->size_changed /*|| windata->wm_needs_redraw */) {
  382. renddata->size_changed = SDL_FALSE;
  383. }
  384. }
  385. static int
  386. DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture)
  387. {
  388. SDL_Window *window = renderer->window;
  389. SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
  390. SDL_DFB_DEVICEDATA(display->device);
  391. DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
  392. DirectFB_TextureData *data = texture->driverdata;
  393. DFBDisplayLayerConfig layconf;
  394. DFBResult ret;
  395. if (devdata->use_yuv_direct && (dispdata->vidID >= 0)
  396. && (!dispdata->vidIDinuse)
  397. && SDL_ISPIXELFORMAT_FOURCC(data->format)) {
  398. layconf.flags =
  399. DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
  400. DLCONF_SURFACE_CAPS;
  401. layconf.width = texture->w;
  402. layconf.height = texture->h;
  403. layconf.pixelformat = DirectFB_SDLToDFBPixelFormat(data->format);
  404. layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE;
  405. SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb,
  406. dispdata->vidID,
  407. &dispdata->vidlayer));
  408. SDL_DFB_CHECKERR(dispdata->
  409. vidlayer->SetCooperativeLevel(dispdata->vidlayer,
  410. DLSCL_EXCLUSIVE));
  411. if (devdata->use_yuv_underlays) {
  412. ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1);
  413. if (ret != DFB_OK)
  414. SDL_DFB_DEBUG("Underlay Setlevel not supported\n");
  415. }
  416. SDL_DFB_CHECKERR(dispdata->
  417. vidlayer->SetConfiguration(dispdata->vidlayer,
  418. &layconf));
  419. SDL_DFB_CHECKERR(dispdata->
  420. vidlayer->GetSurface(dispdata->vidlayer,
  421. &data->surface));
  422. dispdata->vidIDinuse = 1;
  423. data->display = display;
  424. return 0;
  425. }
  426. return 1;
  427. error:
  428. if (dispdata->vidlayer) {
  429. SDL_DFB_RELEASE(data->surface);
  430. SDL_DFB_CHECKERR(dispdata->
  431. vidlayer->SetCooperativeLevel(dispdata->vidlayer,
  432. DLSCL_ADMINISTRATIVE));
  433. SDL_DFB_RELEASE(dispdata->vidlayer);
  434. }
  435. return 1;
  436. }
  437. static int
  438. DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
  439. {
  440. SDL_Window *window = renderer->window;
  441. SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
  442. SDL_DFB_DEVICEDATA(display->device);
  443. DirectFB_TextureData *data;
  444. DFBSurfaceDescription dsc;
  445. DFBSurfacePixelFormat pixelformat;
  446. DirectFB_ActivateRenderer(renderer);
  447. SDL_DFB_ALLOC_CLEAR(data, sizeof(*data));
  448. texture->driverdata = data;
  449. /* find the right pixelformat */
  450. pixelformat = DirectFB_SDLToDFBPixelFormat(texture->format);
  451. if (pixelformat == DSPF_UNKNOWN) {
  452. SDL_SetError("Unknown pixel format %d\n", data->format);
  453. goto error;
  454. }
  455. data->format = texture->format;
  456. data->pitch = texture->w * DFB_BYTES_PER_PIXEL(pixelformat);
  457. if (DirectFB_AcquireVidLayer(renderer, texture) != 0) {
  458. /* fill surface description */
  459. dsc.flags =
  460. DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
  461. dsc.width = texture->w;
  462. dsc.height = texture->h;
  463. if(texture->format == SDL_PIXELFORMAT_YV12 ||
  464. texture->format == SDL_PIXELFORMAT_IYUV) {
  465. /* dfb has problems with odd sizes -make them even internally */
  466. dsc.width += (dsc.width % 2);
  467. dsc.height += (dsc.height % 2);
  468. }
  469. /* <1.2 Never use DSCAPS_VIDEOONLY here. It kills performance
  470. * No DSCAPS_SYSTEMONLY either - let dfb decide
  471. * 1.2: DSCAPS_SYSTEMONLY boosts performance by factor ~8
  472. * Depends on other settings as well. Let dfb decide.
  473. */
  474. dsc.caps = DSCAPS_PREMULTIPLIED;
  475. #if 0
  476. if (texture->access == SDL_TEXTUREACCESS_STREAMING)
  477. dsc.caps |= DSCAPS_SYSTEMONLY;
  478. else
  479. dsc.caps |= DSCAPS_VIDEOONLY;
  480. #endif
  481. dsc.pixelformat = pixelformat;
  482. data->pixels = NULL;
  483. /* Create the surface */
  484. SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
  485. &data->surface));
  486. if (SDL_ISPIXELFORMAT_INDEXED(data->format)
  487. && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
  488. #if 1
  489. SDL_DFB_CHECKERR(data->surface->GetPalette(data->surface, &data->palette));
  490. #else
  491. /* DFB has issues with blitting LUT8 surfaces.
  492. * Creating a new palette does not help.
  493. */
  494. DFBPaletteDescription pal_desc;
  495. pal_desc.flags = DPDESC_SIZE; /* | DPDESC_ENTRIES */
  496. pal_desc.size = 256;
  497. SDL_DFB_CHECKERR(devdata->dfb->CreatePalette(devdata->dfb, &pal_desc,&data->palette));
  498. SDL_DFB_CHECKERR(data->surface->SetPalette(data->surface, data->palette));
  499. #endif
  500. }
  501. }
  502. #if (DFB_VERSION_ATLEAST(1,2,0))
  503. data->render_options = DSRO_NONE;
  504. #endif
  505. if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
  506. /* 3 plane YUVs return 1 bpp, but we need more space for other planes */
  507. if(texture->format == SDL_PIXELFORMAT_YV12 ||
  508. texture->format == SDL_PIXELFORMAT_IYUV) {
  509. SDL_DFB_ALLOC_CLEAR(data->pixels, (texture->h * data->pitch + ((texture->h + texture->h % 2) * (data->pitch + data->pitch % 2) * 2) / 4));
  510. } else {
  511. SDL_DFB_ALLOC_CLEAR(data->pixels, texture->h * data->pitch);
  512. }
  513. }
  514. return 0;
  515. error:
  516. SDL_DFB_RELEASE(data->palette);
  517. SDL_DFB_RELEASE(data->surface);
  518. SDL_DFB_FREE(texture->driverdata);
  519. return -1;
  520. }
  521. static int
  522. DirectFB_QueryTexturePixels(SDL_Renderer * renderer,
  523. SDL_Texture * texture, void **pixels, int *pitch)
  524. {
  525. DirectFB_TextureData *texturedata =
  526. (DirectFB_TextureData *) texture->driverdata;
  527. if (texturedata->display) {
  528. return -1;
  529. } else {
  530. *pixels = texturedata->pixels;
  531. *pitch = texturedata->pitch;
  532. }
  533. return 0;
  534. }
  535. static int
  536. DirectFB_SetTexturePalette(SDL_Renderer * renderer,
  537. SDL_Texture * texture,
  538. const SDL_Color * colors, int firstcolor,
  539. int ncolors)
  540. {
  541. DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
  542. if (SDL_ISPIXELFORMAT_INDEXED(data->format)
  543. && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
  544. DFBColor entries[256];
  545. int i;
  546. if (ncolors > 256)
  547. ncolors = 256;
  548. for (i = 0; i < ncolors; ++i) {
  549. entries[i].r = colors[i].r;
  550. entries[i].g = colors[i].g;
  551. entries[i].b = colors[i].b;
  552. entries[i].a = 0xff;
  553. }
  554. SDL_DFB_CHECKERR(data->
  555. palette->SetEntries(data->palette, entries, ncolors, firstcolor));
  556. return 0;
  557. } else {
  558. return SDL_SetError("YUV textures don't have a palette");
  559. }
  560. error:
  561. return -1;
  562. }
  563. static int
  564. DirectFB_GetTexturePalette(SDL_Renderer * renderer,
  565. SDL_Texture * texture, SDL_Color * colors,
  566. int firstcolor, int ncolors)
  567. {
  568. DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
  569. if (SDL_ISPIXELFORMAT_INDEXED(data->format)
  570. && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
  571. DFBColor entries[256];
  572. int i;
  573. SDL_DFB_CHECKERR(data->
  574. palette->GetEntries(data->palette, entries, ncolors,
  575. firstcolor));
  576. for (i = 0; i < ncolors; ++i) {
  577. colors[i].r = entries[i].r;
  578. colors[i].g = entries[i].g;
  579. colors[i].b = entries[i].b;
  580. colors[i].unused = SDL_ALPHA_OPAQUE;
  581. }
  582. return 0;
  583. } else {
  584. return SDL_SetError("YUV textures don't have a palette");
  585. }
  586. error:
  587. return -1;
  588. }
  589. static int
  590. DirectFB_SetTextureAlphaMod(SDL_Renderer * renderer, SDL_Texture * texture)
  591. {
  592. return 0;
  593. }
  594. static int
  595. DirectFB_SetTextureColorMod(SDL_Renderer * renderer, SDL_Texture * texture)
  596. {
  597. return 0;
  598. }
  599. static int
  600. DirectFB_SetTextureBlendMode(SDL_Renderer * renderer, SDL_Texture * texture)
  601. {
  602. switch (texture->blendMode) {
  603. case SDL_BLENDMODE_NONE:
  604. /*case SDL_BLENDMODE_MASK: */
  605. case SDL_BLENDMODE_BLEND:
  606. case SDL_BLENDMODE_ADD:
  607. case SDL_BLENDMODE_MOD:
  608. return 0;
  609. default:
  610. texture->blendMode = SDL_BLENDMODE_NONE;
  611. return SDL_Unsupported();
  612. }
  613. }
  614. static int
  615. DirectFB_SetDrawBlendMode(SDL_Renderer * renderer)
  616. {
  617. switch (renderer->blendMode) {
  618. case SDL_BLENDMODE_NONE:
  619. /*case SDL_BLENDMODE_MASK: */
  620. case SDL_BLENDMODE_BLEND:
  621. case SDL_BLENDMODE_ADD:
  622. case SDL_BLENDMODE_MOD:
  623. return 0;
  624. default:
  625. renderer->blendMode = SDL_BLENDMODE_NONE;
  626. return SDL_Unsupported();
  627. }
  628. }
  629. #if 0
  630. static int
  631. DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
  632. {
  633. #if (DFB_VERSION_ATLEAST(1,2,0))
  634. DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
  635. switch (texture->scaleMode) {
  636. case SDL_SCALEMODE_NONE:
  637. case SDL_SCALEMODE_FAST:
  638. data->render_options = DSRO_NONE;
  639. break;
  640. case SDL_SCALEMODE_SLOW:
  641. data->render_options = DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE;
  642. break;
  643. case SDL_SCALEMODE_BEST:
  644. data->render_options =
  645. DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE | DSRO_ANTIALIAS;
  646. break;
  647. default:
  648. data->render_options = DSRO_NONE;
  649. texture->scaleMode = SDL_SCALEMODE_NONE;
  650. return SDL_Unsupported();
  651. }
  652. #endif
  653. return 0;
  654. }
  655. #endif
  656. static int
  657. DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
  658. const SDL_Rect * rect, const void *pixels, int pitch)
  659. {
  660. DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
  661. Uint8 *dpixels;
  662. int dpitch;
  663. Uint8 *src, *dst;
  664. int row;
  665. size_t length;
  666. int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format));
  667. /* FIXME: SDL_BYTESPERPIXEL(texture->format) broken for yuv yv12 3 planes */
  668. DirectFB_ActivateRenderer(renderer);
  669. if ((texture->format == SDL_PIXELFORMAT_YV12) ||
  670. (texture->format == SDL_PIXELFORMAT_IYUV)) {
  671. bpp = 1;
  672. }
  673. SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
  674. DSLF_WRITE | DSLF_READ,
  675. ((void **) &dpixels), &dpitch));
  676. src = (Uint8 *) pixels;
  677. dst = (Uint8 *) dpixels + rect->y * dpitch + rect->x * bpp;
  678. length = rect->w * bpp;
  679. for (row = 0; row < rect->h; ++row) {
  680. SDL_memcpy(dst, src, length);
  681. src += pitch;
  682. dst += dpitch;
  683. }
  684. /* copy other planes for 3 plane formats */
  685. if ((texture->format == SDL_PIXELFORMAT_YV12) ||
  686. (texture->format == SDL_PIXELFORMAT_IYUV)) {
  687. src = (Uint8 *) pixels + texture->h * pitch;
  688. dst = (Uint8 *) dpixels + texture->h * dpitch + rect->y * dpitch / 4 + rect->x * bpp / 2;
  689. for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) {
  690. SDL_memcpy(dst, src, length / 2);
  691. src += pitch / 2;
  692. dst += dpitch / 2;
  693. }
  694. src = (Uint8 *) pixels + texture->h * pitch + texture->h * pitch / 4;
  695. dst = (Uint8 *) dpixels + texture->h * dpitch + texture->h * dpitch / 4 + rect->y * dpitch / 4 + rect->x * bpp / 2;
  696. for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) {
  697. SDL_memcpy(dst, src, length / 2);
  698. src += pitch / 2;
  699. dst += dpitch / 2;
  700. }
  701. }
  702. SDL_DFB_CHECKERR(data->surface->Unlock(data->surface));
  703. data->isDirty = 0;
  704. return 0;
  705. error:
  706. return 1;
  707. }
  708. static int
  709. DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
  710. const SDL_Rect * rect, void **pixels, int *pitch)
  711. {
  712. DirectFB_TextureData *texturedata =
  713. (DirectFB_TextureData *) texture->driverdata;
  714. DirectFB_ActivateRenderer(renderer);
  715. #if 0
  716. if (markDirty) {
  717. SDL_AddDirtyRect(&texturedata->dirty, rect);
  718. }
  719. #endif
  720. if (texturedata->display) {
  721. void *fdata;
  722. int fpitch;
  723. SDL_DFB_CHECKERR(texturedata->surface->Lock(texturedata->surface,
  724. DSLF_WRITE | DSLF_READ,
  725. &fdata, &fpitch));
  726. *pitch = fpitch;
  727. *pixels = fdata;
  728. } else {
  729. *pixels =
  730. (void *) ((Uint8 *) texturedata->pixels +
  731. rect->y * texturedata->pitch +
  732. rect->x * DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format)));
  733. *pitch = texturedata->pitch;
  734. texturedata->isDirty = 1;
  735. }
  736. return 0;
  737. error:
  738. return -1;
  739. }
  740. static void
  741. DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
  742. {
  743. DirectFB_TextureData *texturedata =
  744. (DirectFB_TextureData *) texture->driverdata;
  745. DirectFB_ActivateRenderer(renderer);
  746. if (texturedata->display) {
  747. SDL_DFB_CHECK(texturedata->surface->Unlock(texturedata->surface));
  748. texturedata->pixels = NULL;
  749. }
  750. }
  751. #if 0
  752. static void
  753. DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
  754. int numrects, const SDL_Rect * rects)
  755. {
  756. DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
  757. int i;
  758. for (i = 0; i < numrects; ++i) {
  759. SDL_AddDirtyRect(&data->dirty, &rects[i]);
  760. }
  761. }
  762. #endif
  763. static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
  764. {
  765. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  766. DirectFB_TextureData *tex_data = NULL;
  767. DirectFB_ActivateRenderer(renderer);
  768. if (texture) {
  769. tex_data = (DirectFB_TextureData *) texture->driverdata;
  770. data->target = tex_data->surface;
  771. } else {
  772. data->target = get_dfb_surface(data->window);
  773. }
  774. data->lastBlendMode = 0;
  775. return 0;
  776. }
  777. static int
  778. PrepareDraw(SDL_Renderer * renderer)
  779. {
  780. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  781. IDirectFBSurface *destsurf = data->target;
  782. Uint8 r, g, b, a;
  783. r = renderer->r;
  784. g = renderer->g;
  785. b = renderer->b;
  786. a = renderer->a;
  787. SetBlendMode(data, renderer->blendMode, NULL);
  788. SDL_DFB_CHECKERR(destsurf->SetDrawingFlags(destsurf, data->drawFlags));
  789. switch (renderer->blendMode) {
  790. case SDL_BLENDMODE_NONE:
  791. /*case SDL_BLENDMODE_MASK: */
  792. case SDL_BLENDMODE_BLEND:
  793. break;
  794. case SDL_BLENDMODE_ADD:
  795. case SDL_BLENDMODE_MOD:
  796. r = ((int) r * (int) a) / 255;
  797. g = ((int) g * (int) a) / 255;
  798. b = ((int) b * (int) a) / 255;
  799. a = 255;
  800. break;
  801. }
  802. SDL_DFB_CHECKERR(destsurf->SetColor(destsurf, r, g, b, a));
  803. return 0;
  804. error:
  805. return -1;
  806. }
  807. static int DirectFB_RenderDrawPoints(SDL_Renderer * renderer,
  808. const SDL_FPoint * points, int count)
  809. {
  810. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  811. IDirectFBSurface *destsurf = data->target;
  812. DFBRegion clip_region;
  813. int i;
  814. DirectFB_ActivateRenderer(renderer);
  815. PrepareDraw(renderer);
  816. destsurf->GetClip(destsurf, &clip_region);
  817. for (i=0; i < count; i++) {
  818. int x = points[i].x + clip_region.x1;
  819. int y = points[i].y + clip_region.y1;
  820. SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, x, y, x, y));
  821. }
  822. return 0;
  823. error:
  824. return -1;
  825. }
  826. static int DirectFB_RenderDrawLines(SDL_Renderer * renderer,
  827. const SDL_FPoint * points, int count)
  828. {
  829. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  830. IDirectFBSurface *destsurf = data->target;
  831. DFBRegion clip_region;
  832. int i;
  833. DirectFB_ActivateRenderer(renderer);
  834. PrepareDraw(renderer);
  835. /* Use antialiasing when available */
  836. #if (DFB_VERSION_ATLEAST(1,2,0))
  837. SDL_DFB_CHECKERR(destsurf->SetRenderOptions(destsurf, DSRO_ANTIALIAS));
  838. #endif
  839. destsurf->GetClip(destsurf, &clip_region);
  840. for (i=0; i < count - 1; i++) {
  841. int x1 = points[i].x + clip_region.x1;
  842. int y1 = points[i].y + clip_region.y1;
  843. int x2 = points[i + 1].x + clip_region.x1;
  844. int y2 = points[i + 1].y + clip_region.y1;
  845. SDL_DFB_CHECKERR(destsurf->DrawLine(destsurf, x1, y1, x2, y2));
  846. }
  847. return 0;
  848. error:
  849. return -1;
  850. }
  851. static int
  852. DirectFB_RenderDrawRects(SDL_Renderer * renderer, const SDL_Rect ** rects, int count)
  853. {
  854. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  855. IDirectFBSurface *destsurf = data->target;
  856. DFBRegion clip_region;
  857. int i;
  858. DirectFB_ActivateRenderer(renderer);
  859. PrepareDraw(renderer);
  860. destsurf->GetClip(destsurf, &clip_region);
  861. for (i=0; i<count; i++) {
  862. SDL_Rect dst = {rects[i]->x, rects[i]->y, rects[i]->w, rects[i]->h};
  863. dst.x += clip_region.x1;
  864. dst.y += clip_region.y1;
  865. SDL_DFB_CHECKERR(destsurf->DrawRectangle(destsurf, dst.x, dst.y,
  866. dst.w, dst.h));
  867. }
  868. return 0;
  869. error:
  870. return -1;
  871. }
  872. static int
  873. DirectFB_RenderFillRects(SDL_Renderer * renderer, const SDL_FRect * rects, int count)
  874. {
  875. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  876. IDirectFBSurface *destsurf = data->target;
  877. DFBRegion clip_region;
  878. int i;
  879. DirectFB_ActivateRenderer(renderer);
  880. PrepareDraw(renderer);
  881. destsurf->GetClip(destsurf, &clip_region);
  882. for (i=0; i<count; i++) {
  883. SDL_Rect dst = {rects[i].x, rects[i].y, rects[i].w, rects[i].h};
  884. dst.x += clip_region.x1;
  885. dst.y += clip_region.y1;
  886. SDL_DFB_CHECKERR(destsurf->FillRectangle(destsurf, dst.x, dst.y,
  887. dst.w, dst.h));
  888. }
  889. return 0;
  890. error:
  891. return -1;
  892. }
  893. static int
  894. DirectFB_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
  895. const SDL_Rect * srcrect, const SDL_FRect * dstrect)
  896. {
  897. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  898. IDirectFBSurface *destsurf = data->target;
  899. DirectFB_TextureData *texturedata =
  900. (DirectFB_TextureData *) texture->driverdata;
  901. Uint8 alpha, r, g, b;
  902. DFBRegion clip_region;
  903. DFBRectangle sr, dr;
  904. DirectFB_ActivateRenderer(renderer);
  905. SDLtoDFBRect(srcrect, &sr);
  906. SDLtoDFBRect_Float(dstrect, &dr);
  907. destsurf->GetClip(destsurf, &clip_region);
  908. dr.x += clip_region.x1;
  909. dr.y += clip_region.y1;
  910. if (texturedata->display) {
  911. int px, py;
  912. SDL_Window *window = renderer->window;
  913. IDirectFBWindow *dfbwin = get_dfb_window(window);
  914. SDL_DFB_WINDOWDATA(window);
  915. SDL_VideoDisplay *display = texturedata->display;
  916. DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
  917. SDL_DFB_CHECKERR(dispdata->
  918. vidlayer->SetSourceRectangle(dispdata->vidlayer,
  919. sr.x, sr.y, sr.w, sr.h));
  920. dfbwin->GetPosition(dfbwin, &px, &py);
  921. px += windata->client.x;
  922. py += windata->client.y;
  923. SDL_DFB_CHECKERR(dispdata->
  924. vidlayer->SetScreenRectangle(dispdata->vidlayer,
  925. px + dr.x,
  926. py + dr.y,
  927. dr.w,
  928. dr.h));
  929. } else {
  930. DFBSurfaceBlittingFlags flags = 0;
  931. #if 0
  932. if (texturedata->dirty.list) {
  933. SDL_DirtyRect *dirty;
  934. void *pixels;
  935. int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format));
  936. int pitch = texturedata->pitch;
  937. for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
  938. SDL_Rect *rect = &dirty->rect;
  939. pixels =
  940. (void *) ((Uint8 *) texturedata->pixels +
  941. rect->y * pitch + rect->x * bpp);
  942. DirectFB_UpdateTexture(renderer, texture, rect,
  943. pixels,
  944. texturedata->pitch);
  945. }
  946. SDL_ClearDirtyRects(&texturedata->dirty);
  947. }
  948. #endif
  949. if (texturedata->isDirty)
  950. {
  951. SDL_Rect rect;
  952. rect.x = 0;
  953. rect.y = 0;
  954. rect.w = texture->w;
  955. rect.h = texture->h;
  956. DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch);
  957. }
  958. alpha = r = g = b = 0xff;
  959. if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA){
  960. alpha = texture->a;
  961. flags |= DSBLIT_BLEND_COLORALPHA;
  962. }
  963. if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
  964. r = texture->r;
  965. g = texture->g;
  966. b = texture->b;
  967. flags |= DSBLIT_COLORIZE;
  968. }
  969. SDL_DFB_CHECKERR(destsurf->
  970. SetColor(destsurf, r, g, b, alpha));
  971. /* ???? flags |= DSBLIT_SRC_PREMULTCOLOR; */
  972. SetBlendMode(data, texture->blendMode, texturedata);
  973. SDL_DFB_CHECKERR(destsurf->SetBlittingFlags(destsurf,
  974. data->blitFlags | flags));
  975. #if (DFB_VERSION_ATLEAST(1,2,0))
  976. SDL_DFB_CHECKERR(destsurf->SetRenderOptions(destsurf,
  977. texturedata->
  978. render_options));
  979. #endif
  980. if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
  981. SDL_DFB_CHECKERR(destsurf->Blit(destsurf,
  982. texturedata->surface,
  983. &sr, dr.x, dr.y));
  984. } else {
  985. SDL_DFB_CHECKERR(destsurf->StretchBlit(destsurf,
  986. texturedata->surface,
  987. &sr, &dr));
  988. }
  989. }
  990. return 0;
  991. error:
  992. return -1;
  993. }
  994. static void
  995. DirectFB_RenderPresent(SDL_Renderer * renderer)
  996. {
  997. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  998. SDL_Window *window = renderer->window;
  999. SDL_DFB_WINDOWDATA(window);
  1000. SDL_ShapeData *shape_data = (window->shaper ? window->shaper->driverdata : NULL);
  1001. DirectFB_ActivateRenderer(renderer);
  1002. if (shape_data && shape_data->surface) {
  1003. /* saturate the window surface alpha channel */
  1004. SDL_DFB_CHECK(windata->window_surface->SetSrcBlendFunction(windata->window_surface, DSBF_ONE));
  1005. SDL_DFB_CHECK(windata->window_surface->SetDstBlendFunction(windata->window_surface, DSBF_ONE));
  1006. SDL_DFB_CHECK(windata->window_surface->SetDrawingFlags(windata->window_surface, DSDRAW_BLEND));
  1007. SDL_DFB_CHECK(windata->window_surface->SetColor(windata->window_surface, 0, 0, 0, 0xff));
  1008. SDL_DFB_CHECK(windata->window_surface->FillRectangle(windata->window_surface, 0,0, windata->size.w, windata->size.h));
  1009. /* blit the mask */
  1010. SDL_DFB_CHECK(windata->surface->SetSrcBlendFunction(windata->surface, DSBF_DESTCOLOR));
  1011. SDL_DFB_CHECK(windata->surface->SetDstBlendFunction(windata->surface, DSBF_ZERO));
  1012. SDL_DFB_CHECK(windata->surface->SetBlittingFlags(windata->surface, DSBLIT_BLEND_ALPHACHANNEL));
  1013. #if (DFB_VERSION_ATLEAST(1,2,0))
  1014. SDL_DFB_CHECK(windata->surface->SetRenderOptions(windata->surface, DSRO_NONE));
  1015. #endif
  1016. SDL_DFB_CHECK(windata->surface->Blit(windata->surface, shape_data->surface, NULL, 0, 0));
  1017. }
  1018. /* Send the data to the display */
  1019. SDL_DFB_CHECK(windata->window_surface->Flip(windata->window_surface, NULL,
  1020. data->flipflags));
  1021. }
  1022. static void
  1023. DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
  1024. {
  1025. DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
  1026. DirectFB_ActivateRenderer(renderer);
  1027. if (!data) {
  1028. return;
  1029. }
  1030. SDL_DFB_RELEASE(data->palette);
  1031. SDL_DFB_RELEASE(data->surface);
  1032. if (data->display) {
  1033. DFB_DisplayData *dispdata =
  1034. (DFB_DisplayData *) data->display->driverdata;
  1035. dispdata->vidIDinuse = 0;
  1036. /* FIXME: Shouldn't we reset the cooperative level */
  1037. SDL_DFB_CHECK(dispdata->vidlayer->SetCooperativeLevel(dispdata->vidlayer,
  1038. DLSCL_ADMINISTRATIVE));
  1039. SDL_DFB_RELEASE(dispdata->vidlayer);
  1040. }
  1041. SDL_DFB_FREE(data->pixels);
  1042. SDL_free(data);
  1043. texture->driverdata = NULL;
  1044. }
  1045. static void
  1046. DirectFB_DestroyRenderer(SDL_Renderer * renderer)
  1047. {
  1048. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  1049. SDL_VideoDisplay *display = SDL_GetDisplayForWindow(data->window);
  1050. #if 0
  1051. if (display->palette) {
  1052. SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged, data);
  1053. }
  1054. #endif
  1055. if (data) {
  1056. SDL_free(data);
  1057. }
  1058. SDL_free(renderer);
  1059. }
  1060. static int
  1061. DirectFB_UpdateViewport(SDL_Renderer * renderer)
  1062. {
  1063. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  1064. IDirectFBSurface *winsurf = data->target;
  1065. DFBRegion dreg;
  1066. dreg.x1 = renderer->viewport.x;
  1067. dreg.y1 = renderer->viewport.y;
  1068. dreg.x2 = dreg.x1 + renderer->viewport.w - 1;
  1069. dreg.y2 = dreg.y1 + renderer->viewport.h - 1;
  1070. winsurf->SetClip(winsurf, &dreg);
  1071. return 0;
  1072. }
  1073. static int
  1074. DirectFB_UpdateClipRect(SDL_Renderer * renderer)
  1075. {
  1076. const SDL_Rect *rect = &renderer->clip_rect;
  1077. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  1078. IDirectFBSurface *destsurf = get_dfb_surface(data->window);
  1079. DFBRegion region;
  1080. if (!SDL_RectEmpty(rect)) {
  1081. region.x1 = rect->x;
  1082. region.x2 = rect->x + rect->w;
  1083. region.y1 = rect->y;
  1084. region.y2 = rect->y + rect->h;
  1085. SDL_DFB_CHECKERR(destsurf->SetClip(destsurf, &region));
  1086. } else {
  1087. SDL_DFB_CHECKERR(destsurf->SetClip(destsurf, NULL));
  1088. }
  1089. return 0;
  1090. error:
  1091. return -1;
  1092. }
  1093. static int
  1094. DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
  1095. Uint32 format, void * pixels, int pitch)
  1096. {
  1097. Uint32 sdl_format;
  1098. void * laypixels;
  1099. int laypitch;
  1100. DFBSurfacePixelFormat dfb_format;
  1101. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  1102. IDirectFBSurface *winsurf = data->target;
  1103. DirectFB_ActivateRenderer(renderer);
  1104. winsurf->GetPixelFormat(winsurf, &dfb_format);
  1105. sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format);
  1106. winsurf->Lock(winsurf, DSLF_READ, (void **) &laypixels, &laypitch);
  1107. laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) );
  1108. SDL_ConvertPixels(rect->w, rect->h,
  1109. sdl_format, laypixels, laypitch,
  1110. format, pixels, pitch);
  1111. winsurf->Unlock(winsurf);
  1112. return 0;
  1113. }
  1114. #if 0
  1115. static int
  1116. DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
  1117. Uint32 format, const void * pixels, int pitch)
  1118. {
  1119. SDL_Window *window = renderer->window;
  1120. SDL_DFB_WINDOWDATA(window);
  1121. Uint32 sdl_format;
  1122. void * laypixels;
  1123. int laypitch;
  1124. DFBSurfacePixelFormat dfb_format;
  1125. SDL_DFB_CHECK(windata->surface->GetPixelFormat(windata->surface, &dfb_format));
  1126. sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format);
  1127. SDL_DFB_CHECK(windata->surface->Lock(windata->surface, DSLF_WRITE, (void **) &laypixels, &laypitch));
  1128. laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) );
  1129. SDL_ConvertPixels(rect->w, rect->h,
  1130. format, pixels, pitch,
  1131. sdl_format, laypixels, laypitch);
  1132. SDL_DFB_CHECK(windata->surface->Unlock(windata->surface));
  1133. return 0;
  1134. }
  1135. #endif
  1136. #endif /* SDL_VIDEO_DRIVER_DIRECTFB */
  1137. /* vi: set ts=4 sw=4 expandtab: */