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));
203 data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
204 data->drawFlags = DSDRAW_BLEND;
205 SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_DSTCOLOR));
206 SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_INVSRCALPHA));
218 IDirectFBSurface *destsurf =
data->target;
235 r = ((int)
r * (
int)
a) / 255;
236 g = ((int)
g * (
int)
a) / 255;
237 b = ((int)
b * (
int)
a) / 255;
267 if (renddata->size_changed ) {
278 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->
driverdata;
280 DFBDisplayLayerConfig layconf;
283 if (devdata->use_yuv_direct && (dispdata->vidID >= 0)
284 && (!dispdata->vidIDinuse)
287 DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
292 layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE;
296 &dispdata->vidlayer));
298 vidlayer->SetCooperativeLevel(dispdata->vidlayer,
301 if (devdata->use_yuv_underlays) {
302 ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1);
307 vidlayer->SetConfiguration(dispdata->vidlayer,
310 vidlayer->GetSurface(dispdata->vidlayer,
312 dispdata->vidIDinuse = 1;
313 data->display = display;
318 if (dispdata->vidlayer) {
321 vidlayer->SetCooperativeLevel(dispdata->vidlayer,
322 DLSCL_ADMINISTRATIVE));
334 DirectFB_TextureData *
data;
335 DFBSurfaceDescription dsc;
336 DFBSurfacePixelFormat pixelformat;
338 DirectFB_ActivateRenderer(
renderer);
345 if (pixelformat == DSPF_UNKNOWN) {
351 data->pitch =
texture->w * DFB_BYTES_PER_PIXEL(pixelformat);
356 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
362 dsc.width += (dsc.width % 2);
363 dsc.height += (dsc.height % 2);
370 dsc.caps = DSCAPS_PREMULTIPLIED;
373 dsc.caps |= DSCAPS_SYSTEMONLY;
375 dsc.caps |= DSCAPS_VIDEOONLY;
378 dsc.pixelformat = pixelformat;
392 DFBPaletteDescription pal_desc;
393 pal_desc.flags = DPDESC_SIZE;
401 #if (DFB_VERSION_ATLEAST(1,2,0))
402 data->render_options = DSRO_NONE;
427 #if (DFB_VERSION_ATLEAST(1,2,0))
429 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
432 case SDL_SCALEMODE_NONE:
433 case SDL_SCALEMODE_FAST:
434 data->render_options = DSRO_NONE;
436 case SDL_SCALEMODE_SLOW:
437 data->render_options = DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE;
439 case SDL_SCALEMODE_BEST:
440 data->render_options =
441 DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE | DSRO_ANTIALIAS;
444 data->render_options = DSRO_NONE;
445 texture->scaleMode = SDL_SCALEMODE_NONE;
457 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
466 DirectFB_ActivateRenderer(
renderer);
474 DSLF_WRITE | DSLF_READ,
475 ((
void **) &dpixels), &dpitch));
514 DirectFB_TextureData *texturedata =
515 (DirectFB_TextureData *)
texture->driverdata;
517 DirectFB_ActivateRenderer(
renderer);
521 SDL_AddDirtyRect(&texturedata->dirty,
rect);
525 if (texturedata->display) {
530 DSLF_WRITE | DSLF_READ,
536 (
void *) ((
Uint8 *) texturedata->pixels +
537 rect->
y * texturedata->pitch +
539 *pitch = texturedata->pitch;
540 texturedata->isDirty = 1;
551 DirectFB_TextureData *texturedata =
552 (DirectFB_TextureData *)
texture->driverdata;
554 DirectFB_ActivateRenderer(
renderer);
556 if (texturedata->display) {
557 SDL_DFB_CHECK(texturedata->surface->Unlock(texturedata->surface));
558 texturedata->pixels =
NULL;
563 DirectFB_SetTextureScaleMode()
572 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
575 for (
i = 0;
i < numrects; ++
i) {
584 DirectFB_TextureData *tex_data =
NULL;
586 DirectFB_ActivateRenderer(
renderer);
588 tex_data = (DirectFB_TextureData *)
texture->driverdata;
589 data->target = tex_data->surface;
591 data->target = get_dfb_surface(
data->window);
593 data->lastBlendMode = 0;
646 SDLtoDFBRect(srcrect, verts++);
647 SDLtoDFBRect_Float(dstrect, verts);
666 IDirectFBSurface *destsurf =
data->target;
667 DFBRegion clip_region;
670 DirectFB_ActivateRenderer(
renderer);
683 clip_region.x2 = clip_region.x1 +
viewport->
w - 1;
684 clip_region.y2 = clip_region.y1 +
viewport->
h - 1;
685 destsurf->SetClip(destsurf, &clip_region);
693 clip_region.x1 =
rect->
x;
695 clip_region.y1 =
rect->
y;
697 destsurf->SetClip(destsurf, &clip_region);
707 destsurf->Clear(destsurf,
r,
g,
b,
a);
716 const int x =
points[
i].x + clip_region.x1;
717 const int y =
points[
i].y + clip_region.y1;
718 destsurf->DrawLine(destsurf,
x,
y,
x,
y);
729 #if (DFB_VERSION_ATLEAST(1,2,0))
730 destsurf->SetRenderOptions(destsurf, DSRO_ANTIALIAS);
734 const int x1 =
points[
i].x + clip_region.x1;
735 const int y1 =
points[
i].y + clip_region.y1;
736 const int x2 =
points[
i + 1].x + clip_region.x1;
737 const int y2 =
points[
i + 1].y + clip_region.y1;
738 destsurf->DrawLine(destsurf,
x1,
y1,
x2,
y2);
750 destsurf->FillRectangle(destsurf,
rects->x + clip_region.x1,
rects->y + clip_region.y1,
rects->w,
rects->h);
761 DFBRectangle *verts = (DFBRectangle *) (((
Uint8 *) vertices) + cmd->
data.
draw.first);
762 DirectFB_TextureData *texturedata = (DirectFB_TextureData *)
texture->driverdata;
763 DFBRectangle *sr = verts++;
764 DFBRectangle *dr = verts;
766 dr->x += clip_region.x1;
767 dr->y += clip_region.y1;
769 if (texturedata->display) {
772 IDirectFBWindow *dfbwin = get_dfb_window(
window);
775 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->
driverdata;
777 dispdata->vidlayer->SetSourceRectangle(dispdata->vidlayer, sr->x, sr->y, sr->w, sr->h);
778 dfbwin->GetPosition(dfbwin, &px, &py);
779 px += windata->client.x;
780 py += windata->client.y;
781 dispdata->vidlayer->SetScreenRectangle(dispdata->vidlayer, px + dr->x, py + dr->y, dr->w, dr->h);
783 DFBSurfaceBlittingFlags
flags = 0;
784 if (texturedata->isDirty) {
790 flags |= DSBLIT_BLEND_COLORALPHA;
793 if ((
r &
g &
b) != 0xFF) {
794 flags |= DSBLIT_COLORIZE;
797 destsurf->SetColor(destsurf,
r,
g,
b,
a);
801 SetBlendMode(
data,
texture->blendMode, texturedata);
803 destsurf->SetBlittingFlags(destsurf,
data->blitFlags |
flags);
805 #if (DFB_VERSION_ATLEAST(1,2,0))
806 destsurf->SetRenderOptions(destsurf, texturedata->render_options);
809 if (sr->w == dr->w && sr->h == dr->h) {
810 destsurf->Blit(destsurf, texturedata->surface, sr, dr->x, dr->y);
812 destsurf->StretchBlit(destsurf, texturedata->surface, sr, dr);
840 DirectFB_ActivateRenderer(
renderer);
842 if (shape_data && shape_data->
surface) {
844 SDL_DFB_CHECK(windata->window_surface->SetSrcBlendFunction(windata->window_surface, DSBF_ONE));
845 SDL_DFB_CHECK(windata->window_surface->SetDstBlendFunction(windata->window_surface, DSBF_ONE));
846 SDL_DFB_CHECK(windata->window_surface->SetDrawingFlags(windata->window_surface, DSDRAW_BLEND));
847 SDL_DFB_CHECK(windata->window_surface->SetColor(windata->window_surface, 0, 0, 0, 0xff));
848 SDL_DFB_CHECK(windata->window_surface->FillRectangle(windata->window_surface, 0,0, windata->size.w, windata->size.h));
851 SDL_DFB_CHECK(windata->surface->SetSrcBlendFunction(windata->surface, DSBF_DESTCOLOR));
852 SDL_DFB_CHECK(windata->surface->SetDstBlendFunction(windata->surface, DSBF_ZERO));
853 SDL_DFB_CHECK(windata->surface->SetBlittingFlags(windata->surface, DSBLIT_BLEND_ALPHACHANNEL));
854 #if (DFB_VERSION_ATLEAST(1,2,0))
855 SDL_DFB_CHECK(windata->surface->SetRenderOptions(windata->surface, DSRO_NONE));
868 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
870 DirectFB_ActivateRenderer(
renderer);
878 DFB_DisplayData *dispdata =
879 (DFB_DisplayData *)
data->display->driverdata;
880 dispdata->vidIDinuse = 0;
882 SDL_DFB_CHECK(dispdata->vidlayer->SetCooperativeLevel(dispdata->vidlayer,
883 DLSCL_ADMINISTRATIVE));
897 if (display->palette) {
898 SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged,
data);
911 unsigned char* laypixels;
913 DFBSurfacePixelFormat dfb_format;
915 IDirectFBSurface *winsurf =
data->target;
917 DirectFB_ActivateRenderer(
renderer);
919 winsurf->GetPixelFormat(winsurf, &dfb_format);
921 winsurf->Lock(winsurf, DSLF_READ, (
void **) &laypixels, &laypitch);
925 sdl_format, laypixels, laypitch,
928 winsurf->Unlock(winsurf);
941 unsigned char* laypixels;
943 DFBSurfacePixelFormat dfb_format;
945 SDL_DFB_CHECK(windata->surface->GetPixelFormat(windata->surface, &dfb_format));
948 SDL_DFB_CHECK(windata->surface->Lock(windata->surface, DSLF_WRITE, (
void **) &laypixels, &laypitch));
953 sdl_format, laypixels, laypitch);
965 IDirectFBSurface *winsurf = get_dfb_surface(
window);
969 DFBSurfaceCapabilities scaps;
1010 data->target = winsurf;
1012 data->flipflags = DSFLIP_PIPELINE | DSFLIP_BLIT;
1015 data->flipflags |= DSFLIP_WAITFORSYNC | DSFLIP_ONSYNC;
1018 data->flipflags |= DSFLIP_ONSYNC;
1023 if (scaps & DSCAPS_DOUBLE)
1025 else if (scaps & DSCAPS_TRIPLE)
1035 if (display-> palette) {
1036 SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged,
data);
1050 DirectFB_CreateRenderer,