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