SDL_DirectFB_render.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266
  1. /*
  2. Simple DirectMedia Layer
  3. Copyright (C) 1997-2021 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_internal.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. #define SDL_DFB_WINDOWSURFACE(win) IDirectFBSurface *destsurf = ((DFB_WindowData *) ((win)->driverdata))->surface;
  39. typedef struct
  40. {
  41. SDL_Window *window;
  42. DFBSurfaceFlipFlags flipflags;
  43. int size_changed;
  44. int lastBlendMode;
  45. DFBSurfaceBlittingFlags blitFlags;
  46. DFBSurfaceDrawingFlags drawFlags;
  47. IDirectFBSurface* target;
  48. } DirectFB_RenderData;
  49. typedef struct
  50. {
  51. IDirectFBSurface *surface;
  52. Uint32 format;
  53. void *pixels;
  54. int pitch;
  55. IDirectFBPalette *palette;
  56. int isDirty;
  57. SDL_VideoDisplay *display; /* only for yuv textures */
  58. #if (DFB_VERSION_ATLEAST(1,2,0))
  59. DFBSurfaceRenderOptions render_options;
  60. #endif
  61. } DirectFB_TextureData;
  62. static SDL_INLINE void
  63. SDLtoDFBRect(const SDL_Rect * sr, DFBRectangle * dr)
  64. {
  65. dr->x = sr->x;
  66. dr->y = sr->y;
  67. dr->h = sr->h;
  68. dr->w = sr->w;
  69. }
  70. static SDL_INLINE void
  71. SDLtoDFBRect_Float(const SDL_FRect * sr, DFBRectangle * dr)
  72. {
  73. dr->x = sr->x;
  74. dr->y = sr->y;
  75. dr->h = sr->h;
  76. dr->w = sr->w;
  77. }
  78. static int
  79. TextureHasAlpha(DirectFB_TextureData * data)
  80. {
  81. /* Drawing primitive ? */
  82. if (!data)
  83. return 0;
  84. return (DFB_PIXELFORMAT_HAS_ALPHA(DirectFB_SDLToDFBPixelFormat(data->format)) ? 1 : 0);
  85. #if 0
  86. switch (data->format) {
  87. case SDL_PIXELFORMAT_INDEX4LSB:
  88. case SDL_PIXELFORMAT_INDEX4MSB:
  89. case SDL_PIXELFORMAT_ARGB4444:
  90. case SDL_PIXELFORMAT_ARGB1555:
  91. case SDL_PIXELFORMAT_ARGB8888:
  92. case SDL_PIXELFORMAT_RGBA8888:
  93. case SDL_PIXELFORMAT_ABGR8888:
  94. case SDL_PIXELFORMAT_BGRA8888:
  95. case SDL_PIXELFORMAT_ARGB2101010:
  96. return 1;
  97. default:
  98. return 0;
  99. }
  100. #endif
  101. }
  102. static SDL_INLINE IDirectFBSurface *get_dfb_surface(SDL_Window *window)
  103. {
  104. SDL_SysWMinfo wm_info;
  105. SDL_memset(&wm_info, 0, sizeof(SDL_SysWMinfo));
  106. SDL_VERSION(&wm_info.version);
  107. if (!SDL_GetWindowWMInfo(window, &wm_info)) {
  108. return NULL;
  109. }
  110. return wm_info.info.dfb.surface;
  111. }
  112. static SDL_INLINE IDirectFBWindow *get_dfb_window(SDL_Window *window)
  113. {
  114. SDL_SysWMinfo wm_info;
  115. SDL_memset(&wm_info, 0, sizeof(SDL_SysWMinfo));
  116. SDL_VERSION(&wm_info.version);
  117. if (!SDL_GetWindowWMInfo(window, &wm_info)) {
  118. return NULL;
  119. }
  120. return wm_info.info.dfb.window;
  121. }
  122. static void
  123. SetBlendMode(DirectFB_RenderData * data, int blendMode,
  124. DirectFB_TextureData * source)
  125. {
  126. IDirectFBSurface *destsurf = data->target;
  127. /* FIXME: check for format change */
  128. if (1 || data->lastBlendMode != blendMode) {
  129. switch (blendMode) {
  130. case SDL_BLENDMODE_NONE:
  131. /**< No blending */
  132. data->blitFlags = DSBLIT_NOFX;
  133. data->drawFlags = DSDRAW_NOFX;
  134. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
  135. SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ZERO));
  136. break;
  137. #if 0
  138. case SDL_BLENDMODE_MASK:
  139. data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
  140. data->drawFlags = DSDRAW_BLEND;
  141. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
  142. SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
  143. break;
  144. #endif
  145. case SDL_BLENDMODE_BLEND:
  146. data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
  147. data->drawFlags = DSDRAW_BLEND;
  148. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
  149. SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
  150. break;
  151. case SDL_BLENDMODE_ADD:
  152. data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
  153. data->drawFlags = DSDRAW_BLEND;
  154. /* FIXME: SRCALPHA kills performance on radeon ...
  155. * It will be cheaper to copy the surface to a temporary surface and premultiply
  156. */
  157. if (source && TextureHasAlpha(source))
  158. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
  159. else
  160. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
  161. SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ONE));
  162. break;
  163. case SDL_BLENDMODE_MOD:
  164. data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
  165. data->drawFlags = DSDRAW_BLEND;
  166. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ZERO));
  167. SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_SRCCOLOR));
  168. break;
  169. case SDL_BLENDMODE_MUL:
  170. data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
  171. data->drawFlags = DSDRAW_BLEND;
  172. SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_DESTCOLOR));
  173. SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
  174. break;
  175. }
  176. data->lastBlendMode = blendMode;
  177. }
  178. }
  179. static int
  180. PrepareDraw(SDL_Renderer * renderer, const SDL_RenderCommand *cmd)
  181. {
  182. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  183. IDirectFBSurface *destsurf = data->target;
  184. Uint8 r = cmd->data.draw.r;
  185. Uint8 g = cmd->data.draw.g;
  186. Uint8 b = cmd->data.draw.b;
  187. Uint8 a = cmd->data.draw.a;
  188. SetBlendMode(data, cmd->data.draw.blend, NULL);
  189. SDL_DFB_CHECKERR(destsurf->SetDrawingFlags(destsurf, data->drawFlags));
  190. switch (renderer->blendMode) {
  191. case SDL_BLENDMODE_NONE:
  192. /* case SDL_BLENDMODE_MASK: */
  193. case SDL_BLENDMODE_BLEND:
  194. break;
  195. case SDL_BLENDMODE_ADD:
  196. case SDL_BLENDMODE_MOD:
  197. case SDL_BLENDMODE_MUL:
  198. r = ((int) r * (int) a) / 255;
  199. g = ((int) g * (int) a) / 255;
  200. b = ((int) b * (int) a) / 255;
  201. a = 255;
  202. break;
  203. case SDL_BLENDMODE_INVALID: break;
  204. }
  205. SDL_DFB_CHECKERR(destsurf->SetColor(destsurf, r, g, b, a));
  206. return 0;
  207. error:
  208. return -1;
  209. }
  210. static void
  211. DirectFB_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
  212. {
  213. SDL_DFB_RENDERERDATA(renderer);
  214. if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED) {
  215. /* Rebind the context to the window area and update matrices */
  216. /* SDL_CurrentContext = NULL; */
  217. /* data->updateSize = SDL_TRUE; */
  218. renddata->size_changed = SDL_TRUE;
  219. }
  220. }
  221. static void
  222. DirectFB_ActivateRenderer(SDL_Renderer * renderer)
  223. {
  224. SDL_DFB_RENDERERDATA(renderer);
  225. if (renddata->size_changed /* || windata->wm_needs_redraw */) {
  226. renddata->size_changed = SDL_FALSE;
  227. }
  228. }
  229. static int
  230. DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture)
  231. {
  232. SDL_Window *window = renderer->window;
  233. SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
  234. SDL_DFB_DEVICEDATA(display->device);
  235. DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
  236. DirectFB_TextureData *data = texture->driverdata;
  237. DFBDisplayLayerConfig layconf;
  238. DFBResult ret;
  239. if (devdata->use_yuv_direct && (dispdata->vidID >= 0)
  240. && (!dispdata->vidIDinuse)
  241. && SDL_ISPIXELFORMAT_FOURCC(data->format)) {
  242. layconf.flags =
  243. DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
  244. DLCONF_SURFACE_CAPS;
  245. layconf.width = texture->w;
  246. layconf.height = texture->h;
  247. layconf.pixelformat = DirectFB_SDLToDFBPixelFormat(data->format);
  248. layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE;
  249. SDL_DFB_CHECKERR(devdata->dfb->GetDisplayLayer(devdata->dfb,
  250. dispdata->vidID,
  251. &dispdata->vidlayer));
  252. SDL_DFB_CHECKERR(dispdata->
  253. vidlayer->SetCooperativeLevel(dispdata->vidlayer,
  254. DLSCL_EXCLUSIVE));
  255. if (devdata->use_yuv_underlays) {
  256. ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1);
  257. if (ret != DFB_OK)
  258. SDL_DFB_DEBUG("Underlay Setlevel not supported\n");
  259. }
  260. SDL_DFB_CHECKERR(dispdata->
  261. vidlayer->SetConfiguration(dispdata->vidlayer,
  262. &layconf));
  263. SDL_DFB_CHECKERR(dispdata->
  264. vidlayer->GetSurface(dispdata->vidlayer,
  265. &data->surface));
  266. dispdata->vidIDinuse = 1;
  267. data->display = display;
  268. return 0;
  269. }
  270. return 1;
  271. error:
  272. if (dispdata->vidlayer) {
  273. SDL_DFB_RELEASE(data->surface);
  274. SDL_DFB_CHECKERR(dispdata->
  275. vidlayer->SetCooperativeLevel(dispdata->vidlayer,
  276. DLSCL_ADMINISTRATIVE));
  277. SDL_DFB_RELEASE(dispdata->vidlayer);
  278. }
  279. return 1;
  280. }
  281. /* Copy the SDL_Surface palette to the DirectFB texture palette */
  282. void DirectFB_SetTexturePalette(SDL_Renderer *renderer, SDL_Texture *texture, SDL_Palette *pal)
  283. {
  284. int i;
  285. DFBColor dfbpal[256];
  286. DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
  287. for (i = 0; i < pal->ncolors; i++) {
  288. dfbpal[i].a = pal->colors[i].a;
  289. dfbpal[i].r = pal->colors[i].r;
  290. dfbpal[i].g = pal->colors[i].g;
  291. dfbpal[i].b = pal->colors[i].b;
  292. }
  293. data->palette->SetEntries(data->palette, dfbpal, pal->ncolors, 0);
  294. }
  295. static int
  296. DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
  297. {
  298. SDL_Window *window = renderer->window;
  299. SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);
  300. SDL_DFB_DEVICEDATA(display->device);
  301. DirectFB_TextureData *data;
  302. DFBSurfaceDescription dsc;
  303. DFBSurfacePixelFormat pixelformat;
  304. DirectFB_ActivateRenderer(renderer);
  305. SDL_DFB_ALLOC_CLEAR(data, sizeof(*data));
  306. texture->driverdata = data;
  307. /* find the right pixelformat */
  308. pixelformat = DirectFB_SDLToDFBPixelFormat(texture->format);
  309. if (pixelformat == DSPF_UNKNOWN) {
  310. SDL_SetError("Unknown pixel format %d", data->format);
  311. goto error;
  312. }
  313. data->format = texture->format;
  314. data->pitch = texture->w * DFB_BYTES_PER_PIXEL(pixelformat);
  315. if (DirectFB_AcquireVidLayer(renderer, texture) != 0) {
  316. /* fill surface description */
  317. dsc.flags =
  318. DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
  319. dsc.width = texture->w;
  320. dsc.height = texture->h;
  321. if(texture->format == SDL_PIXELFORMAT_YV12 ||
  322. texture->format == SDL_PIXELFORMAT_IYUV) {
  323. /* dfb has problems with odd sizes -make them even internally */
  324. dsc.width += (dsc.width % 2);
  325. dsc.height += (dsc.height % 2);
  326. }
  327. /* <1.2 Never use DSCAPS_VIDEOONLY here. It kills performance
  328. * No DSCAPS_SYSTEMONLY either - let dfb decide
  329. * 1.2: DSCAPS_SYSTEMONLY boosts performance by factor ~8
  330. * Depends on other settings as well. Let dfb decide.
  331. */
  332. dsc.caps = DSCAPS_PREMULTIPLIED;
  333. #if 0
  334. if (texture->access == SDL_TEXTUREACCESS_STREAMING)
  335. dsc.caps |= DSCAPS_SYSTEMONLY;
  336. else
  337. dsc.caps |= DSCAPS_VIDEOONLY;
  338. #endif
  339. dsc.pixelformat = pixelformat;
  340. data->pixels = NULL;
  341. /* Create the surface */
  342. SDL_DFB_CHECKERR(devdata->dfb->CreateSurface(devdata->dfb, &dsc,
  343. &data->surface));
  344. if (SDL_ISPIXELFORMAT_INDEXED(data->format)
  345. && !SDL_ISPIXELFORMAT_FOURCC(data->format)) {
  346. #if 1
  347. SDL_DFB_CHECKERR(data->surface->GetPalette(data->surface, &data->palette));
  348. #else
  349. /* DFB has issues with blitting LUT8 surfaces.
  350. * Creating a new palette does not help.
  351. */
  352. DFBPaletteDescription pal_desc;
  353. pal_desc.flags = DPDESC_SIZE; /* | DPDESC_ENTRIES */
  354. pal_desc.size = 256;
  355. SDL_DFB_CHECKERR(devdata->dfb->CreatePalette(devdata->dfb, &pal_desc,&data->palette));
  356. SDL_DFB_CHECKERR(data->surface->SetPalette(data->surface, data->palette));
  357. #endif
  358. }
  359. }
  360. #if (DFB_VERSION_ATLEAST(1,2,0))
  361. data->render_options = DSRO_NONE;
  362. #endif
  363. if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
  364. /* 3 plane YUVs return 1 bpp, but we need more space for other planes */
  365. if(texture->format == SDL_PIXELFORMAT_YV12 ||
  366. texture->format == SDL_PIXELFORMAT_IYUV) {
  367. SDL_DFB_ALLOC_CLEAR(data->pixels, (texture->h * data->pitch + ((texture->h + texture->h % 2) * (data->pitch + data->pitch % 2) * 2) / 4));
  368. } else {
  369. SDL_DFB_ALLOC_CLEAR(data->pixels, texture->h * data->pitch);
  370. }
  371. }
  372. return 0;
  373. error:
  374. SDL_DFB_RELEASE(data->palette);
  375. SDL_DFB_RELEASE(data->surface);
  376. SDL_DFB_FREE(texture->driverdata);
  377. return -1;
  378. }
  379. #if 0
  380. static int
  381. DirectFB_SetTextureScaleMode(SDL_Renderer * renderer, SDL_Texture * texture)
  382. {
  383. #if (DFB_VERSION_ATLEAST(1,2,0))
  384. DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
  385. switch (texture->scaleMode) {
  386. case SDL_SCALEMODE_NONE:
  387. case SDL_SCALEMODE_FAST:
  388. data->render_options = DSRO_NONE;
  389. break;
  390. case SDL_SCALEMODE_SLOW:
  391. data->render_options = DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE;
  392. break;
  393. case SDL_SCALEMODE_BEST:
  394. data->render_options =
  395. DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE | DSRO_ANTIALIAS;
  396. break;
  397. default:
  398. data->render_options = DSRO_NONE;
  399. texture->scaleMode = SDL_SCALEMODE_NONE;
  400. return SDL_Unsupported();
  401. }
  402. #endif
  403. return 0;
  404. }
  405. #endif
  406. static int
  407. DirectFB_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
  408. const SDL_Rect * rect, const void *pixels, int pitch)
  409. {
  410. DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
  411. Uint8 *dpixels;
  412. int dpitch;
  413. Uint8 *src, *dst;
  414. int row;
  415. size_t length;
  416. int bpp = DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format));
  417. /* FIXME: SDL_BYTESPERPIXEL(texture->format) broken for yuv yv12 3 planes */
  418. DirectFB_ActivateRenderer(renderer);
  419. if ((texture->format == SDL_PIXELFORMAT_YV12) ||
  420. (texture->format == SDL_PIXELFORMAT_IYUV)) {
  421. bpp = 1;
  422. }
  423. SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
  424. DSLF_WRITE | DSLF_READ,
  425. ((void **) &dpixels), &dpitch));
  426. src = (Uint8 *) pixels;
  427. dst = (Uint8 *) dpixels + rect->y * dpitch + rect->x * bpp;
  428. length = rect->w * bpp;
  429. for (row = 0; row < rect->h; ++row) {
  430. SDL_memcpy(dst, src, length);
  431. src += pitch;
  432. dst += dpitch;
  433. }
  434. /* copy other planes for 3 plane formats */
  435. if ((texture->format == SDL_PIXELFORMAT_YV12) ||
  436. (texture->format == SDL_PIXELFORMAT_IYUV)) {
  437. src = (Uint8 *) pixels + texture->h * pitch;
  438. dst = (Uint8 *) dpixels + texture->h * dpitch + rect->y * dpitch / 4 + rect->x * bpp / 2;
  439. for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) {
  440. SDL_memcpy(dst, src, length / 2);
  441. src += pitch / 2;
  442. dst += dpitch / 2;
  443. }
  444. src = (Uint8 *) pixels + texture->h * pitch + texture->h * pitch / 4;
  445. dst = (Uint8 *) dpixels + texture->h * dpitch + texture->h * dpitch / 4 + rect->y * dpitch / 4 + rect->x * bpp / 2;
  446. for (row = 0; row < rect->h / 2 + (rect->h & 1); ++row) {
  447. SDL_memcpy(dst, src, length / 2);
  448. src += pitch / 2;
  449. dst += dpitch / 2;
  450. }
  451. }
  452. SDL_DFB_CHECKERR(data->surface->Unlock(data->surface));
  453. data->isDirty = 0;
  454. return 0;
  455. error:
  456. return 1;
  457. }
  458. static int
  459. DirectFB_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
  460. const SDL_Rect * rect, void **pixels, int *pitch)
  461. {
  462. DirectFB_TextureData *texturedata =
  463. (DirectFB_TextureData *) texture->driverdata;
  464. DirectFB_ActivateRenderer(renderer);
  465. #if 0
  466. if (markDirty) {
  467. SDL_AddDirtyRect(&texturedata->dirty, rect);
  468. }
  469. #endif
  470. if (texturedata->display) {
  471. void *fdata;
  472. int fpitch;
  473. SDL_DFB_CHECKERR(texturedata->surface->Lock(texturedata->surface,
  474. DSLF_WRITE | DSLF_READ,
  475. &fdata, &fpitch));
  476. *pitch = fpitch;
  477. *pixels = fdata;
  478. } else {
  479. *pixels =
  480. (void *) ((Uint8 *) texturedata->pixels +
  481. rect->y * texturedata->pitch +
  482. rect->x * DFB_BYTES_PER_PIXEL(DirectFB_SDLToDFBPixelFormat(texture->format)));
  483. *pitch = texturedata->pitch;
  484. texturedata->isDirty = 1;
  485. }
  486. return 0;
  487. error:
  488. return -1;
  489. }
  490. static void
  491. DirectFB_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
  492. {
  493. DirectFB_TextureData *texturedata =
  494. (DirectFB_TextureData *) texture->driverdata;
  495. DirectFB_ActivateRenderer(renderer);
  496. if (texturedata->display) {
  497. SDL_DFB_CHECK(texturedata->surface->Unlock(texturedata->surface));
  498. texturedata->pixels = NULL;
  499. }
  500. }
  501. static void
  502. DirectFB_SetTextureScaleMode()
  503. {
  504. }
  505. #if 0
  506. static void
  507. DirectFB_DirtyTexture(SDL_Renderer * renderer, SDL_Texture * texture,
  508. int numrects, const SDL_Rect * rects)
  509. {
  510. DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
  511. int i;
  512. for (i = 0; i < numrects; ++i) {
  513. SDL_AddDirtyRect(&data->dirty, &rects[i]);
  514. }
  515. }
  516. #endif
  517. static int DirectFB_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
  518. {
  519. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  520. DirectFB_TextureData *tex_data = NULL;
  521. DirectFB_ActivateRenderer(renderer);
  522. if (texture) {
  523. tex_data = (DirectFB_TextureData *) texture->driverdata;
  524. data->target = tex_data->surface;
  525. } else {
  526. data->target = get_dfb_surface(data->window);
  527. }
  528. data->lastBlendMode = 0;
  529. return 0;
  530. }
  531. static int
  532. DirectFB_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
  533. {
  534. return 0; /* nothing to do in this backend. */
  535. }
  536. static int
  537. DirectFB_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
  538. {
  539. const size_t len = count * sizeof (SDL_FPoint);
  540. SDL_FPoint *verts = (SDL_FPoint *) SDL_AllocateRenderVertices(renderer, len, 0, &cmd->data.draw.first);
  541. if (!verts) {
  542. return -1;
  543. }
  544. cmd->data.draw.count = count;
  545. SDL_memcpy(verts, points, len);
  546. return 0;
  547. }
  548. static int
  549. DirectFB_QueueGeometry(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture,
  550. const float *xy, int xy_stride, const int *color, int color_stride, const float *uv, int uv_stride,
  551. int num_vertices, const void *indices, int num_indices, int size_indices,
  552. float scale_x, float scale_y)
  553. {
  554. int i;
  555. int count = indices ? num_indices : num_vertices;
  556. float *verts;
  557. int sz = 2 + 4 + (texture ? 2 : 0);
  558. verts = (float *) SDL_AllocateRenderVertices(renderer, count * sz * sizeof (float), 0, &cmd->data.draw.first);
  559. if (!verts) {
  560. return -1;
  561. }
  562. cmd->data.draw.count = count;
  563. size_indices = indices ? size_indices : 0;
  564. for (i = 0; i < count; i++) {
  565. int j;
  566. float *xy_;
  567. SDL_Color col_;
  568. if (size_indices == 4) {
  569. j = ((const Uint32 *)indices)[i];
  570. } else if (size_indices == 2) {
  571. j = ((const Uint16 *)indices)[i];
  572. } else if (size_indices == 1) {
  573. j = ((const Uint8 *)indices)[i];
  574. } else {
  575. j = i;
  576. }
  577. xy_ = (float *)((char*)xy + j * xy_stride);
  578. col_ = *(SDL_Color *)((char*)color + j * color_stride);
  579. *(verts++) = xy_[0] * scale_x;
  580. *(verts++) = xy_[1] * scale_y;
  581. *(verts++) = col_.r;
  582. *(verts++) = col_.g;
  583. *(verts++) = col_.b;
  584. *(verts++) = col_.a;
  585. if (texture) {
  586. float *uv_ = (float *)((char*)uv + j * uv_stride);
  587. *(verts++) = uv_[0];
  588. *(verts++) = uv_[1];
  589. }
  590. }
  591. return 0;
  592. }
  593. static int
  594. DirectFB_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
  595. {
  596. const size_t len = count * sizeof (SDL_FRect);
  597. SDL_FRect *verts = (SDL_FRect *) SDL_AllocateRenderVertices(renderer, len, 0, &cmd->data.draw.first);
  598. if (!verts) {
  599. return -1;
  600. }
  601. cmd->data.draw.count = count;
  602. SDL_memcpy(verts, rects, len);
  603. return 0;
  604. }
  605. static int
  606. DirectFB_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
  607. const SDL_Rect * srcrect, const SDL_FRect * dstrect)
  608. {
  609. DFBRectangle *verts = (DFBRectangle *) SDL_AllocateRenderVertices(renderer, 2 * sizeof (DFBRectangle), 0, &cmd->data.draw.first);
  610. if (!verts) {
  611. return -1;
  612. }
  613. cmd->data.draw.count = 1;
  614. SDLtoDFBRect(srcrect, verts++);
  615. SDLtoDFBRect_Float(dstrect, verts);
  616. return 0;
  617. }
  618. static int
  619. DirectFB_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
  620. {
  621. /* !!! FIXME: there are probably some good optimization wins in here if someone wants to look it over. */
  622. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  623. IDirectFBSurface *destsurf = data->target;
  624. DFBRegion clip_region;
  625. size_t i;
  626. DirectFB_ActivateRenderer(renderer);
  627. SDL_zero(clip_region); /* in theory, this always gets set before use. */
  628. while (cmd) {
  629. switch (cmd->command) {
  630. case SDL_RENDERCMD_SETDRAWCOLOR:
  631. break; /* not used here */
  632. case SDL_RENDERCMD_SETVIEWPORT: {
  633. const SDL_Rect *viewport = &cmd->data.viewport.rect;
  634. clip_region.x1 = viewport->x;
  635. clip_region.y1 = viewport->y;
  636. clip_region.x2 = clip_region.x1 + viewport->w - 1;
  637. clip_region.y2 = clip_region.y1 + viewport->h - 1;
  638. destsurf->SetClip(destsurf, &clip_region);
  639. break;
  640. }
  641. case SDL_RENDERCMD_SETCLIPRECT: {
  642. /* !!! FIXME: how does this SetClip interact with the one in SETVIEWPORT? */
  643. if (cmd->data.cliprect.enabled) {
  644. const SDL_Rect *rect = &cmd->data.cliprect.rect;
  645. clip_region.x1 = rect->x;
  646. clip_region.x2 = rect->x + rect->w;
  647. clip_region.y1 = rect->y;
  648. clip_region.y2 = rect->y + rect->h;
  649. destsurf->SetClip(destsurf, &clip_region);
  650. }
  651. break;
  652. }
  653. case SDL_RENDERCMD_CLEAR: {
  654. const Uint8 r = cmd->data.color.r;
  655. const Uint8 g = cmd->data.color.g;
  656. const Uint8 b = cmd->data.color.b;
  657. const Uint8 a = cmd->data.color.a;
  658. destsurf->Clear(destsurf, r, g, b, a);
  659. break;
  660. }
  661. case SDL_RENDERCMD_DRAW_POINTS: {
  662. const size_t count = cmd->data.draw.count;
  663. const SDL_FPoint *points = (SDL_FPoint *) (((Uint8 *) vertices) + cmd->data.draw.first);
  664. PrepareDraw(renderer, cmd);
  665. for (i = 0; i < count; i++) {
  666. const int x = points[i].x + clip_region.x1;
  667. const int y = points[i].y + clip_region.y1;
  668. destsurf->DrawLine(destsurf, x, y, x, y);
  669. }
  670. break;
  671. }
  672. case SDL_RENDERCMD_DRAW_LINES: {
  673. const SDL_FPoint *points = (SDL_FPoint *) (((Uint8 *) vertices) + cmd->data.draw.first);
  674. const size_t count = cmd->data.draw.count;
  675. PrepareDraw(renderer, cmd);
  676. #if (DFB_VERSION_ATLEAST(1,2,0)) /* !!! FIXME: should this be set once, somewhere else? */
  677. destsurf->SetRenderOptions(destsurf, DSRO_ANTIALIAS);
  678. #endif
  679. for (i = 0; i < count - 1; i++) {
  680. const int x1 = points[i].x + clip_region.x1;
  681. const int y1 = points[i].y + clip_region.y1;
  682. const int x2 = points[i + 1].x + clip_region.x1;
  683. const int y2 = points[i + 1].y + clip_region.y1;
  684. destsurf->DrawLine(destsurf, x1, y1, x2, y2);
  685. }
  686. break;
  687. }
  688. case SDL_RENDERCMD_FILL_RECTS: {
  689. const SDL_FRect *rects = (SDL_FRect *) (((Uint8 *) vertices) + cmd->data.draw.first);
  690. const size_t count = cmd->data.draw.count;
  691. PrepareDraw(renderer, cmd);
  692. for (i = 0; i < count; i++, rects++) {
  693. destsurf->FillRectangle(destsurf, rects->x + clip_region.x1, rects->y + clip_region.y1, rects->w, rects->h);
  694. }
  695. break;
  696. }
  697. case SDL_RENDERCMD_COPY: {
  698. SDL_Texture *texture = cmd->data.draw.texture;
  699. const Uint8 r = cmd->data.draw.r;
  700. const Uint8 g = cmd->data.draw.g;
  701. const Uint8 b = cmd->data.draw.b;
  702. const Uint8 a = cmd->data.draw.a;
  703. DFBRectangle *verts = (DFBRectangle *) (((Uint8 *) vertices) + cmd->data.draw.first);
  704. DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata;
  705. DFBRectangle *sr = verts++;
  706. DFBRectangle *dr = verts;
  707. dr->x += clip_region.x1;
  708. dr->y += clip_region.y1;
  709. if (texturedata->display) {
  710. int px, py;
  711. SDL_Window *window = renderer->window;
  712. IDirectFBWindow *dfbwin = get_dfb_window(window);
  713. SDL_DFB_WINDOWDATA(window);
  714. SDL_VideoDisplay *display = texturedata->display;
  715. DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
  716. dispdata->vidlayer->SetSourceRectangle(dispdata->vidlayer, sr->x, sr->y, sr->w, sr->h);
  717. dfbwin->GetPosition(dfbwin, &px, &py);
  718. px += windata->client.x;
  719. py += windata->client.y;
  720. dispdata->vidlayer->SetScreenRectangle(dispdata->vidlayer, px + dr->x, py + dr->y, dr->w, dr->h);
  721. } else {
  722. DFBSurfaceBlittingFlags flags = 0;
  723. if (texturedata->isDirty) {
  724. const SDL_Rect rect = { 0, 0, texture->w, texture->h };
  725. DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch);
  726. }
  727. if (a != 0xFF) {
  728. flags |= DSBLIT_BLEND_COLORALPHA;
  729. }
  730. if ((r & g & b) != 0xFF) {
  731. flags |= DSBLIT_COLORIZE;
  732. }
  733. destsurf->SetColor(destsurf, r, g, b, a);
  734. /* ???? flags |= DSBLIT_SRC_PREMULTCOLOR; */
  735. SetBlendMode(data, texture->blendMode, texturedata);
  736. destsurf->SetBlittingFlags(destsurf, data->blitFlags | flags);
  737. #if (DFB_VERSION_ATLEAST(1,2,0))
  738. destsurf->SetRenderOptions(destsurf, texturedata->render_options);
  739. #endif
  740. if (sr->w == dr->w && sr->h == dr->h) {
  741. destsurf->Blit(destsurf, texturedata->surface, sr, dr->x, dr->y);
  742. } else {
  743. destsurf->StretchBlit(destsurf, texturedata->surface, sr, dr);
  744. }
  745. }
  746. break;
  747. }
  748. case SDL_RENDERCMD_GEOMETRY: {
  749. const float *verts = (float *) (((Uint8 *) vertices) + cmd->data.draw.first);
  750. SDL_Texture *texture = cmd->data.draw.texture;
  751. const size_t count = cmd->data.draw.count;
  752. Uint8 save_r = cmd->data.draw.r;
  753. Uint8 save_g = cmd->data.draw.g;
  754. Uint8 save_b = cmd->data.draw.b;
  755. Uint8 save_a = cmd->data.draw.a;
  756. int j;
  757. for (j = 0; j < count; j += 3)
  758. {
  759. float x1, y1, r1, g1, b1, a1, u1, v1;
  760. float x2, y2, r2, g2, b2, a2, u2, v2;
  761. float x3, y3, r3, g3, b3, a3, u3, v3;
  762. x1 = *(verts++);
  763. y1 = *(verts++);
  764. r1 = *(verts++);
  765. g1 = *(verts++);
  766. b1 = *(verts++);
  767. a1 = *(verts++);
  768. if (texture) {
  769. u1 = *(verts++);
  770. v1 = *(verts++);
  771. }
  772. x2 = *(verts++);
  773. y2 = *(verts++);
  774. r2 = *(verts++);
  775. g2 = *(verts++);
  776. b2 = *(verts++);
  777. a2 = *(verts++);
  778. if (texture) {
  779. u2 = *(verts++);
  780. v2 = *(verts++);
  781. }
  782. x3 = *(verts++);
  783. y3 = *(verts++);
  784. r3 = *(verts++);
  785. g3 = *(verts++);
  786. b3 = *(verts++);
  787. a3 = *(verts++);
  788. if (texture) {
  789. u3 = *(verts++);
  790. v3 = *(verts++);
  791. }
  792. if (texture) {
  793. DFBVertex vertices[3];
  794. DirectFB_TextureData *texturedata = (DirectFB_TextureData *) texture->driverdata;
  795. DFBSurfaceBlittingFlags flags = 0;
  796. int r = (r1 + r2 + r3) / 3;
  797. int g = (g1 + g2 + g3) / 3;
  798. int b = (b1 + b2 + b3) / 3;
  799. int a = (a1 + a2 + a3) / 3;
  800. if (texturedata->isDirty) {
  801. const SDL_Rect rect = { 0, 0, texture->w, texture->h };
  802. DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch);
  803. }
  804. if (a != 0xFF) {
  805. flags |= DSBLIT_BLEND_COLORALPHA;
  806. }
  807. if ((r & g & b) != 0xFF) {
  808. flags |= DSBLIT_COLORIZE;
  809. }
  810. destsurf->SetColor(destsurf, r, g, b, a);
  811. /* ???? flags |= DSBLIT_SRC_PREMULTCOLOR; */
  812. SetBlendMode(data, texture->blendMode, texturedata);
  813. destsurf->SetBlittingFlags(destsurf, data->blitFlags | flags);
  814. #if (DFB_VERSION_ATLEAST(1,2,0))
  815. destsurf->SetRenderOptions(destsurf, texturedata->render_options);
  816. #endif
  817. vertices[0].x = x1;
  818. vertices[0].y = y1;
  819. vertices[0].z = 0;
  820. vertices[0].w = 0;
  821. vertices[0].s = u1;
  822. vertices[0].t = v1;
  823. vertices[1].x = x2;
  824. vertices[1].y = y2;
  825. vertices[1].z = 0;
  826. vertices[1].w = 0;
  827. vertices[1].s = u2;
  828. vertices[1].t = v2;
  829. vertices[2].x = x3;
  830. vertices[2].y = y3;
  831. vertices[2].z = 0;
  832. vertices[2].w = 0;
  833. vertices[2].s = u3;
  834. vertices[2].t = v3;
  835. destsurf->TextureTriangles(destsurf, texturedata->surface, vertices, NULL, 3, DTTF_LIST);
  836. } else {
  837. DFBTriangle tris;
  838. tris.x1 = x1;
  839. tris.y1 = y1;
  840. tris.x2 = x2;
  841. tris.y2 = y2;
  842. tris.x3 = x3;
  843. tris.y3 = y3;
  844. cmd->data.draw.r = (r1 + r2 + r3) / 3;
  845. cmd->data.draw.g = (g1 + g2 + g3) / 3;
  846. cmd->data.draw.b = (b1 + b2 + b3) / 3;
  847. cmd->data.draw.a = (a1 + a2 + a3) / 3;
  848. PrepareDraw(renderer, cmd);
  849. destsurf->FillTriangles(destsurf, &tris, 1);
  850. }
  851. }
  852. cmd->data.draw.r = save_r;
  853. cmd->data.draw.g = save_g;
  854. cmd->data.draw.b = save_b;
  855. cmd->data.draw.a = save_a;
  856. break;
  857. }
  858. case SDL_RENDERCMD_COPY_EX: /* unused */
  859. break;
  860. case SDL_RENDERCMD_NO_OP:
  861. break;
  862. }
  863. cmd = cmd->next;
  864. }
  865. return 0;
  866. }
  867. static void
  868. DirectFB_RenderPresent(SDL_Renderer * renderer)
  869. {
  870. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  871. SDL_Window *window = renderer->window;
  872. SDL_DFB_WINDOWDATA(window);
  873. SDL_ShapeData *shape_data = (window->shaper ? window->shaper->driverdata : NULL);
  874. DirectFB_ActivateRenderer(renderer);
  875. if (shape_data && shape_data->surface) {
  876. /* saturate the window surface alpha channel */
  877. SDL_DFB_CHECK(windata->window_surface->SetSrcBlendFunction(windata->window_surface, DSBF_ONE));
  878. SDL_DFB_CHECK(windata->window_surface->SetDstBlendFunction(windata->window_surface, DSBF_ONE));
  879. SDL_DFB_CHECK(windata->window_surface->SetDrawingFlags(windata->window_surface, DSDRAW_BLEND));
  880. SDL_DFB_CHECK(windata->window_surface->SetColor(windata->window_surface, 0, 0, 0, 0xff));
  881. SDL_DFB_CHECK(windata->window_surface->FillRectangle(windata->window_surface, 0,0, windata->size.w, windata->size.h));
  882. /* blit the mask */
  883. SDL_DFB_CHECK(windata->surface->SetSrcBlendFunction(windata->surface, DSBF_DESTCOLOR));
  884. SDL_DFB_CHECK(windata->surface->SetDstBlendFunction(windata->surface, DSBF_ZERO));
  885. SDL_DFB_CHECK(windata->surface->SetBlittingFlags(windata->surface, DSBLIT_BLEND_ALPHACHANNEL));
  886. #if (DFB_VERSION_ATLEAST(1,2,0))
  887. SDL_DFB_CHECK(windata->surface->SetRenderOptions(windata->surface, DSRO_NONE));
  888. #endif
  889. SDL_DFB_CHECK(windata->surface->Blit(windata->surface, shape_data->surface, NULL, 0, 0));
  890. }
  891. /* Send the data to the display */
  892. SDL_DFB_CHECK(windata->window_surface->Flip(windata->window_surface, NULL,
  893. data->flipflags));
  894. }
  895. static void
  896. DirectFB_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
  897. {
  898. DirectFB_TextureData *data = (DirectFB_TextureData *) texture->driverdata;
  899. DirectFB_ActivateRenderer(renderer);
  900. if (!data) {
  901. return;
  902. }
  903. SDL_DFB_RELEASE(data->palette);
  904. SDL_DFB_RELEASE(data->surface);
  905. if (data->display) {
  906. DFB_DisplayData *dispdata =
  907. (DFB_DisplayData *) data->display->driverdata;
  908. dispdata->vidIDinuse = 0;
  909. /* FIXME: Shouldn't we reset the cooperative level */
  910. SDL_DFB_CHECK(dispdata->vidlayer->SetCooperativeLevel(dispdata->vidlayer,
  911. DLSCL_ADMINISTRATIVE));
  912. SDL_DFB_RELEASE(dispdata->vidlayer);
  913. }
  914. SDL_DFB_FREE(data->pixels);
  915. SDL_free(data);
  916. texture->driverdata = NULL;
  917. }
  918. static void
  919. DirectFB_DestroyRenderer(SDL_Renderer * renderer)
  920. {
  921. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  922. #if 0
  923. SDL_VideoDisplay *display = SDL_GetDisplayForWindow(data->window);
  924. if (display->palette) {
  925. SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged, data);
  926. }
  927. #endif
  928. SDL_free(data);
  929. SDL_free(renderer);
  930. }
  931. static int
  932. DirectFB_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
  933. Uint32 format, void * pixels, int pitch)
  934. {
  935. Uint32 sdl_format;
  936. unsigned char* laypixels;
  937. int laypitch;
  938. DFBSurfacePixelFormat dfb_format;
  939. DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->driverdata;
  940. IDirectFBSurface *winsurf = data->target;
  941. DirectFB_ActivateRenderer(renderer);
  942. winsurf->GetPixelFormat(winsurf, &dfb_format);
  943. sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format);
  944. winsurf->Lock(winsurf, DSLF_READ, (void **) &laypixels, &laypitch);
  945. laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) );
  946. SDL_ConvertPixels(rect->w, rect->h,
  947. sdl_format, laypixels, laypitch,
  948. format, pixels, pitch);
  949. winsurf->Unlock(winsurf);
  950. return 0;
  951. }
  952. #if 0
  953. static int
  954. DirectFB_RenderWritePixels(SDL_Renderer * renderer, const SDL_Rect * rect,
  955. Uint32 format, const void * pixels, int pitch)
  956. {
  957. SDL_Window *window = renderer->window;
  958. SDL_DFB_WINDOWDATA(window);
  959. Uint32 sdl_format;
  960. unsigned char* laypixels;
  961. int laypitch;
  962. DFBSurfacePixelFormat dfb_format;
  963. SDL_DFB_CHECK(windata->surface->GetPixelFormat(windata->surface, &dfb_format));
  964. sdl_format = DirectFB_DFBToSDLPixelFormat(dfb_format);
  965. SDL_DFB_CHECK(windata->surface->Lock(windata->surface, DSLF_WRITE, (void **) &laypixels, &laypitch));
  966. laypixels += (rect->y * laypitch + rect->x * SDL_BYTESPERPIXEL(sdl_format) );
  967. SDL_ConvertPixels(rect->w, rect->h,
  968. format, pixels, pitch,
  969. sdl_format, laypixels, laypitch);
  970. SDL_DFB_CHECK(windata->surface->Unlock(windata->surface));
  971. return 0;
  972. }
  973. #endif
  974. SDL_Renderer *
  975. DirectFB_CreateRenderer(SDL_Window * window, Uint32 flags)
  976. {
  977. IDirectFBSurface *winsurf = get_dfb_surface(window);
  978. /*SDL_VideoDisplay *display = SDL_GetDisplayForWindow(window);*/
  979. SDL_Renderer *renderer = NULL;
  980. DirectFB_RenderData *data = NULL;
  981. DFBSurfaceCapabilities scaps;
  982. if (!winsurf) {
  983. return NULL;
  984. }
  985. SDL_DFB_ALLOC_CLEAR(renderer, sizeof(*renderer));
  986. SDL_DFB_ALLOC_CLEAR(data, sizeof(*data));
  987. renderer->WindowEvent = DirectFB_WindowEvent;
  988. renderer->CreateTexture = DirectFB_CreateTexture;
  989. renderer->UpdateTexture = DirectFB_UpdateTexture;
  990. renderer->LockTexture = DirectFB_LockTexture;
  991. renderer->UnlockTexture = DirectFB_UnlockTexture;
  992. renderer->SetTextureScaleMode = DirectFB_SetTextureScaleMode;
  993. renderer->QueueSetViewport = DirectFB_QueueSetViewport;
  994. renderer->QueueSetDrawColor = DirectFB_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
  995. renderer->QueueDrawPoints = DirectFB_QueueDrawPoints;
  996. renderer->QueueDrawLines = DirectFB_QueueDrawPoints; /* lines and points queue vertices the same way. */
  997. renderer->QueueGeometry = DirectFB_QueueGeometry;
  998. renderer->QueueFillRects = DirectFB_QueueFillRects;
  999. renderer->QueueCopy = DirectFB_QueueCopy;
  1000. renderer->RunCommandQueue = DirectFB_RunCommandQueue;
  1001. renderer->RenderPresent = DirectFB_RenderPresent;
  1002. /* FIXME: Yet to be tested */
  1003. renderer->RenderReadPixels = DirectFB_RenderReadPixels;
  1004. /* renderer->RenderWritePixels = DirectFB_RenderWritePixels; */
  1005. renderer->DestroyTexture = DirectFB_DestroyTexture;
  1006. renderer->DestroyRenderer = DirectFB_DestroyRenderer;
  1007. renderer->SetRenderTarget = DirectFB_SetRenderTarget;
  1008. renderer->info = DirectFB_RenderDriver.info;
  1009. renderer->window = window; /* SDL window */
  1010. renderer->driverdata = data;
  1011. renderer->info.flags =
  1012. SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
  1013. data->window = window;
  1014. data->target = winsurf;
  1015. data->flipflags = DSFLIP_PIPELINE | DSFLIP_BLIT;
  1016. if (flags & SDL_RENDERER_PRESENTVSYNC) {
  1017. data->flipflags |= DSFLIP_WAITFORSYNC | DSFLIP_ONSYNC;
  1018. renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
  1019. } else
  1020. data->flipflags |= DSFLIP_ONSYNC;
  1021. SDL_DFB_CHECKERR(winsurf->GetCapabilities(winsurf, &scaps));
  1022. #if 0
  1023. if (scaps & DSCAPS_DOUBLE)
  1024. renderer->info.flags |= SDL_RENDERER_PRESENTFLIP2;
  1025. else if (scaps & DSCAPS_TRIPLE)
  1026. renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
  1027. else
  1028. renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
  1029. #endif
  1030. DirectFB_SetSupportedPixelFormats(&renderer->info);
  1031. #if 0
  1032. /* Set up a palette watch on the display palette */
  1033. if (display-> palette) {
  1034. SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data);
  1035. }
  1036. #endif
  1037. return renderer;
  1038. error:
  1039. SDL_DFB_FREE(renderer);
  1040. SDL_DFB_FREE(data);
  1041. return NULL;
  1042. }
  1043. SDL_RenderDriver DirectFB_RenderDriver = {
  1044. DirectFB_CreateRenderer,
  1045. {
  1046. "directfb",
  1047. (SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED),
  1048. /* (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
  1049. SDL_TEXTUREMODULATE_ALPHA),
  1050. (SDL_BLENDMODE_NONE | SDL_BLENDMODE_MASK | SDL_BLENDMODE_BLEND |
  1051. SDL_BLENDMODE_ADD | SDL_BLENDMODE_MOD),
  1052. (SDL_SCALEMODE_NONE | SDL_SCALEMODE_FAST |
  1053. SDL_SCALEMODE_SLOW | SDL_SCALEMODE_BEST), */
  1054. 0,
  1055. {
  1056. /* formats filled in later */
  1057. },
  1058. 0,
  1059. 0}
  1060. };
  1061. #endif /* SDL_VIDEO_DRIVER_DIRECTFB */
  1062. /* vi: set ts=4 sw=4 expandtab: */