21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_DRIVER_DIRECTFB
30 #include "../SDL_sysvideo.h"
31 #include "../../render/SDL_sysrender.h"
33 #ifndef DFB_VERSION_ATLEAST
35 #define DFB_VERSIONNUM(X, Y, Z) \
36 ((X)*1000 + (Y)*100 + (Z))
38 #define DFB_COMPILEDVERSION \
39 DFB_VERSIONNUM(DIRECTFB_MAJOR_VERSION, DIRECTFB_MINOR_VERSION, DIRECTFB_MICRO_VERSION)
41 #define DFB_VERSION_ATLEAST(X, Y, Z) \
42 (DFB_COMPILEDVERSION >= DFB_VERSIONNUM(X, Y, Z))
44 #define SDL_DFB_CHECK(x) x
49 #define USE_DISPLAY_PALETTE (0)
52 #define SDL_DFB_RENDERERDATA(rend) DirectFB_RenderData *renddata = ((rend) ? (DirectFB_RenderData *) (rend)->driverdata : NULL)
53 #define SDL_DFB_WINDOWSURFACE(win) IDirectFBSurface *destsurf = ((DFB_WindowData *) ((win)->driverdata))->surface;
58 DFBSurfaceFlipFlags flipflags;
61 DFBSurfaceBlittingFlags blitFlags;
62 DFBSurfaceDrawingFlags drawFlags;
64 } DirectFB_RenderData;
72 IDirectFBPalette *palette;
77 #if (DFB_VERSION_ATLEAST(1,2,0))
78 DFBSurfaceRenderOptions render_options;
80 } DirectFB_TextureData;
83 SDLtoDFBRect(
const SDL_Rect * sr, DFBRectangle * dr)
91 SDLtoDFBRect_Float(
const SDL_FRect * sr, DFBRectangle * dr)
101 TextureHasAlpha(DirectFB_TextureData *
data)
109 switch (
data->format) {
154 DirectFB_TextureData *
source)
156 IDirectFBSurface *destsurf =
data->target;
163 data->blitFlags = DSBLIT_NOFX;
164 data->drawFlags = DSDRAW_NOFX;
165 SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
166 SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ZERO));
169 case SDL_BLENDMODE_MASK:
170 data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
171 data->drawFlags = DSDRAW_BLEND;
172 SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
173 SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
177 data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
178 data->drawFlags = DSDRAW_BLEND;
179 SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
180 SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
183 data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
184 data->drawFlags = DSDRAW_BLEND;
189 SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
191 SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
192 SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ONE));
195 data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
196 data->drawFlags = DSDRAW_BLEND;
197 SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ZERO));
198 SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_SRCCOLOR));
210 IDirectFBSurface *destsurf =
data->target;
226 r = ((int)
r * (
int)
a) / 255;
227 g = ((int)
g * (
int)
a) / 255;
228 b = ((int)
b * (
int)
a) / 255;
258 if (renddata->size_changed ) {
269 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->
driverdata;
271 DFBDisplayLayerConfig layconf;
274 if (devdata->use_yuv_direct && (dispdata->vidID >= 0)
275 && (!dispdata->vidIDinuse)
278 DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
283 layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE;
287 &dispdata->vidlayer));
289 vidlayer->SetCooperativeLevel(dispdata->vidlayer,
292 if (devdata->use_yuv_underlays) {
293 ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1);
298 vidlayer->SetConfiguration(dispdata->vidlayer,
301 vidlayer->GetSurface(dispdata->vidlayer,
303 dispdata->vidIDinuse = 1;
304 data->display = display;
309 if (dispdata->vidlayer) {
312 vidlayer->SetCooperativeLevel(dispdata->vidlayer,
313 DLSCL_ADMINISTRATIVE));
325 DirectFB_TextureData *
data;
326 DFBSurfaceDescription dsc;
327 DFBSurfacePixelFormat pixelformat;
329 DirectFB_ActivateRenderer(
renderer);
336 if (pixelformat == DSPF_UNKNOWN) {
342 data->pitch =
texture->w * DFB_BYTES_PER_PIXEL(pixelformat);
347 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
353 dsc.width += (dsc.width % 2);
354 dsc.height += (dsc.height % 2);
361 dsc.caps = DSCAPS_PREMULTIPLIED;
364 dsc.caps |= DSCAPS_SYSTEMONLY;
366 dsc.caps |= DSCAPS_VIDEOONLY;
369 dsc.pixelformat = pixelformat;
383 DFBPaletteDescription pal_desc;
384 pal_desc.flags = DPDESC_SIZE;
392 #if (DFB_VERSION_ATLEAST(1,2,0))
393 data->render_options = DSRO_NONE;
418 #if (DFB_VERSION_ATLEAST(1,2,0))
420 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
423 case SDL_SCALEMODE_NONE:
424 case SDL_SCALEMODE_FAST:
425 data->render_options = DSRO_NONE;
427 case SDL_SCALEMODE_SLOW:
428 data->render_options = DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE;
430 case SDL_SCALEMODE_BEST:
431 data->render_options =
432 DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE | DSRO_ANTIALIAS;
435 data->render_options = DSRO_NONE;
436 texture->scaleMode = SDL_SCALEMODE_NONE;
448 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
457 DirectFB_ActivateRenderer(
renderer);
465 DSLF_WRITE | DSLF_READ,
466 ((
void **) &dpixels), &dpitch));
505 DirectFB_TextureData *texturedata =
506 (DirectFB_TextureData *)
texture->driverdata;
508 DirectFB_ActivateRenderer(
renderer);
512 SDL_AddDirtyRect(&texturedata->dirty,
rect);
516 if (texturedata->display) {
521 DSLF_WRITE | DSLF_READ,
527 (
void *) ((
Uint8 *) texturedata->pixels +
528 rect->
y * texturedata->pitch +
530 *pitch = texturedata->pitch;
531 texturedata->isDirty = 1;
542 DirectFB_TextureData *texturedata =
543 (DirectFB_TextureData *)
texture->driverdata;
545 DirectFB_ActivateRenderer(
renderer);
547 if (texturedata->display) {
548 SDL_DFB_CHECK(texturedata->surface->Unlock(texturedata->surface));
549 texturedata->pixels =
NULL;
558 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
561 for (
i = 0;
i < numrects; ++
i) {
570 DirectFB_TextureData *tex_data =
NULL;
572 DirectFB_ActivateRenderer(
renderer);
574 tex_data = (DirectFB_TextureData *)
texture->driverdata;
575 data->target = tex_data->surface;
577 data->target = get_dfb_surface(
data->window);
579 data->lastBlendMode = 0;
632 SDLtoDFBRect(srcrect, verts++);
633 SDLtoDFBRect_Float(dstrect, verts);
652 IDirectFBSurface *destsurf =
data->target;
653 DFBRegion clip_region;
656 DirectFB_ActivateRenderer(
renderer);
669 clip_region.x2 = clip_region.x1 +
viewport->
w - 1;
670 clip_region.y2 = clip_region.y1 +
viewport->
h - 1;
671 destsurf->SetClip(destsurf, &clip_region);
679 clip_region.x1 =
rect->
x;
681 clip_region.y1 =
rect->
y;
683 destsurf->SetClip(destsurf, &clip_region);
693 destsurf->Clear(destsurf,
r,
g,
b,
a);
702 const int x =
points[
i].x + clip_region.x1;
703 const int y =
points[
i].y + clip_region.y1;
704 destsurf->DrawLine(destsurf,
x,
y,
x,
y);
715 #if (DFB_VERSION_ATLEAST(1,2,0))
716 destsurf->SetRenderOptions(destsurf, DSRO_ANTIALIAS);
720 const int x1 =
points[
i].x + clip_region.x1;
721 const int y1 =
points[
i].y + clip_region.y1;
722 const int x2 =
points[
i + 1].x + clip_region.x1;
723 const int y2 =
points[
i + 1].y + clip_region.y1;
724 destsurf->DrawLine(destsurf,
x1,
y1,
x2,
y2);
736 destsurf->FillRectangle(destsurf,
rects->x + clip_region.x1,
rects->y + clip_region.y1,
rects->w,
rects->h);
747 DFBRectangle *verts = (DFBRectangle *) (((
Uint8 *) vertices) + cmd->
data.
draw.first);
748 DirectFB_TextureData *texturedata = (DirectFB_TextureData *)
texture->driverdata;
749 DFBRectangle *sr = verts++;
750 DFBRectangle *dr = verts;
752 dr->x += clip_region.x1;
753 dr->y += clip_region.y1;
755 if (texturedata->display) {
758 IDirectFBWindow *dfbwin = get_dfb_window(
window);
761 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->
driverdata;
763 dispdata->vidlayer->SetSourceRectangle(dispdata->vidlayer, sr->x, sr->y, sr->w, sr->h);
764 dfbwin->GetPosition(dfbwin, &px, &py);
765 px += windata->client.x;
766 py += windata->client.y;
767 dispdata->vidlayer->SetScreenRectangle(dispdata->vidlayer, px + dr->x, py + dr->y, dr->w, dr->h);
769 DFBSurfaceBlittingFlags
flags = 0;
770 if (texturedata->isDirty) {
776 flags |= DSBLIT_BLEND_COLORALPHA;
779 if ((
r &
g &
b) != 0xFF) {
780 flags |= DSBLIT_COLORIZE;
783 destsurf->SetColor(destsurf,
r,
g,
b,
a);
787 SetBlendMode(
data,
texture->blendMode, texturedata);
789 destsurf->SetBlittingFlags(destsurf,
data->blitFlags |
flags);
791 #if (DFB_VERSION_ATLEAST(1,2,0))
792 destsurf->SetRenderOptions(destsurf, texturedata->render_options);
795 if (sr->w == dr->w && sr->h == dr->h) {
796 destsurf->Blit(destsurf, texturedata->surface, sr, dr->x, dr->y);
798 destsurf->StretchBlit(destsurf, texturedata->surface, sr, dr);
826 DirectFB_ActivateRenderer(
renderer);
828 if (shape_data && shape_data->
surface) {
830 SDL_DFB_CHECK(windata->window_surface->SetSrcBlendFunction(windata->window_surface, DSBF_ONE));
831 SDL_DFB_CHECK(windata->window_surface->SetDstBlendFunction(windata->window_surface, DSBF_ONE));
832 SDL_DFB_CHECK(windata->window_surface->SetDrawingFlags(windata->window_surface, DSDRAW_BLEND));
833 SDL_DFB_CHECK(windata->window_surface->SetColor(windata->window_surface, 0, 0, 0, 0xff));
834 SDL_DFB_CHECK(windata->window_surface->FillRectangle(windata->window_surface, 0,0, windata->size.w, windata->size.h));
837 SDL_DFB_CHECK(windata->surface->SetSrcBlendFunction(windata->surface, DSBF_DESTCOLOR));
838 SDL_DFB_CHECK(windata->surface->SetDstBlendFunction(windata->surface, DSBF_ZERO));
839 SDL_DFB_CHECK(windata->surface->SetBlittingFlags(windata->surface, DSBLIT_BLEND_ALPHACHANNEL));
840 #if (DFB_VERSION_ATLEAST(1,2,0))
841 SDL_DFB_CHECK(windata->surface->SetRenderOptions(windata->surface, DSRO_NONE));
854 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
856 DirectFB_ActivateRenderer(
renderer);
864 DFB_DisplayData *dispdata =
865 (DFB_DisplayData *)
data->display->driverdata;
866 dispdata->vidIDinuse = 0;
868 SDL_DFB_CHECK(dispdata->vidlayer->SetCooperativeLevel(dispdata->vidlayer,
869 DLSCL_ADMINISTRATIVE));
883 if (display->palette) {
884 SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged,
data);
897 unsigned char* laypixels;
899 DFBSurfacePixelFormat dfb_format;
901 IDirectFBSurface *winsurf =
data->target;
903 DirectFB_ActivateRenderer(
renderer);
905 winsurf->GetPixelFormat(winsurf, &dfb_format);
907 winsurf->Lock(winsurf, DSLF_READ, (
void **) &laypixels, &laypitch);
911 sdl_format, laypixels, laypitch,
914 winsurf->Unlock(winsurf);
927 unsigned char* laypixels;
929 DFBSurfacePixelFormat dfb_format;
931 SDL_DFB_CHECK(windata->surface->GetPixelFormat(windata->surface, &dfb_format));
934 SDL_DFB_CHECK(windata->surface->Lock(windata->surface, DSLF_WRITE, (
void **) &laypixels, &laypitch));
939 sdl_format, laypixels, laypitch);
951 IDirectFBSurface *winsurf = get_dfb_surface(
window);
955 DFBSurfaceCapabilities scaps;
995 data->target = winsurf;
997 data->flipflags = DSFLIP_PIPELINE | DSFLIP_BLIT;
1000 data->flipflags |= DSFLIP_WAITFORSYNC | DSFLIP_ONSYNC;
1003 data->flipflags |= DSFLIP_ONSYNC;
1008 if (scaps & DSCAPS_DOUBLE)
1010 else if (scaps & DSCAPS_TRIPLE)
1020 if (display-> palette) {
1021 SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged,
data);
1035 DirectFB_CreateRenderer,