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)
64 void **
pixels,
int *pitch);
68 int firstcolor,
int ncolors);
72 int firstcolor,
int ncolors);
84 const void *
pixels,
int pitch);
88 void **
pixels,
int *pitch);
122 #define SDL_DFB_WINDOWSURFACE(win) IDirectFBSurface *destsurf = ((DFB_WindowData *) ((win)->driverdata))->surface;
125 DirectFB_CreateRenderer,
146 DFBSurfaceFlipFlags flipflags;
149 DFBSurfaceBlittingFlags blitFlags;
150 DFBSurfaceDrawingFlags drawFlags;
152 } DirectFB_RenderData;
160 IDirectFBPalette *palette;
165 #if (DFB_VERSION_ATLEAST(1,2,0))
166 DFBSurfaceRenderOptions render_options;
168 } DirectFB_TextureData;
171 SDLtoDFBRect(
const SDL_Rect * sr, DFBRectangle * dr)
179 SDLtoDFBRect_Float(
const SDL_FRect * sr, DFBRectangle * dr)
189 TextureHasAlpha(DirectFB_TextureData *
data)
197 switch (
data->format) {
242 DirectFB_TextureData *
source)
244 IDirectFBSurface *destsurf =
data->target;
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));
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));
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));
271 data->blitFlags = DSBLIT_BLEND_ALPHACHANNEL;
272 data->drawFlags = DSDRAW_BLEND;
277 SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_SRCALPHA));
279 SDL_DFB_CHECK(destsurf->SetSrcBlendFunction(destsurf, DSBF_ONE));
280 SDL_DFB_CHECK(destsurf->SetDstBlendFunction(destsurf, DSBF_ONE));
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));
295 DisplayPaletteChanged(
void *userdata,
SDL_Palette * palette)
297 #if USE_DISPLAY_PALETTE
298 DirectFB_RenderData *
data = (DirectFB_RenderData *) userdata;
299 SDL_DFB_WINDOWSURFACE(
data->window);
300 IDirectFBPalette *surfpal;
304 DFBColor entries[256];
311 for (
i = 0;
i < ncolors; ++
i) {
343 IDirectFBSurface *destsurf =
data->target;
345 DirectFB_ActivateRenderer(
renderer);
357 IDirectFBSurface *winsurf = get_dfb_surface(
window);
361 DFBSurfaceCapabilities scaps;
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;
415 data->target = winsurf;
417 data->flipflags = DSFLIP_PIPELINE | DSFLIP_BLIT;
420 data->flipflags |= DSFLIP_WAITFORSYNC | DSFLIP_ONSYNC;
423 data->flipflags |= DSFLIP_ONSYNC;
428 if (scaps & DSCAPS_DOUBLE)
430 else if (scaps & DSCAPS_TRIPLE)
440 if (display-> palette) {
441 SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged,
data);
460 if (renddata->size_changed ) {
472 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->
driverdata;
474 DFBDisplayLayerConfig layconf;
477 if (devdata->use_yuv_direct && (dispdata->vidID >= 0)
478 && (!dispdata->vidIDinuse)
481 DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
486 layconf.surface_caps = DSCAPS_VIDEOONLY | DSCAPS_DOUBLE;
490 &dispdata->vidlayer));
492 vidlayer->SetCooperativeLevel(dispdata->vidlayer,
495 if (devdata->use_yuv_underlays) {
496 ret = dispdata->vidlayer->SetLevel(dispdata->vidlayer, -1);
501 vidlayer->SetConfiguration(dispdata->vidlayer,
504 vidlayer->GetSurface(dispdata->vidlayer,
506 dispdata->vidIDinuse = 1;
507 data->display = display;
512 if (dispdata->vidlayer) {
515 vidlayer->SetCooperativeLevel(dispdata->vidlayer,
516 DLSCL_ADMINISTRATIVE));
528 DirectFB_TextureData *
data;
529 DFBSurfaceDescription dsc;
530 DFBSurfacePixelFormat pixelformat;
532 DirectFB_ActivateRenderer(
renderer);
539 if (pixelformat == DSPF_UNKNOWN) {
545 data->pitch =
texture->w * DFB_BYTES_PER_PIXEL(pixelformat);
550 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
556 dsc.width += (dsc.width % 2);
557 dsc.height += (dsc.height % 2);
564 dsc.caps = DSCAPS_PREMULTIPLIED;
567 dsc.caps |= DSCAPS_SYSTEMONLY;
569 dsc.caps |= DSCAPS_VIDEOONLY;
572 dsc.pixelformat = pixelformat;
586 DFBPaletteDescription pal_desc;
587 pal_desc.flags = DPDESC_SIZE;
595 #if (DFB_VERSION_ATLEAST(1,2,0))
596 data->render_options = DSRO_NONE;
621 DirectFB_TextureData *texturedata =
622 (DirectFB_TextureData *)
texture->driverdata;
624 if (texturedata->display) {
627 *
pixels = texturedata->pixels;
628 *pitch = texturedata->pitch;
639 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
642 DFBColor entries[256];
648 for (
i = 0;
i < ncolors; ++
i) {
655 palette->SetEntries(
data->palette, entries, ncolors, firstcolor));
658 return SDL_SetError(
"YUV textures don't have a palette");
667 int firstcolor,
int ncolors)
669 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
673 DFBColor entries[256];
677 palette->GetEntries(
data->palette, entries, ncolors,
680 for (
i = 0;
i < ncolors; ++
i) {
688 return SDL_SetError(
"YUV textures don't have a palette");
742 #if (DFB_VERSION_ATLEAST(1,2,0))
744 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
747 case SDL_SCALEMODE_NONE:
748 case SDL_SCALEMODE_FAST:
749 data->render_options = DSRO_NONE;
751 case SDL_SCALEMODE_SLOW:
752 data->render_options = DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE;
754 case SDL_SCALEMODE_BEST:
755 data->render_options =
756 DSRO_SMOOTH_UPSCALE | DSRO_SMOOTH_DOWNSCALE | DSRO_ANTIALIAS;
759 data->render_options = DSRO_NONE;
760 texture->scaleMode = SDL_SCALEMODE_NONE;
772 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
781 DirectFB_ActivateRenderer(
renderer);
789 DSLF_WRITE | DSLF_READ,
790 ((
void **) &dpixels), &dpitch));
829 DirectFB_TextureData *texturedata =
830 (DirectFB_TextureData *)
texture->driverdata;
832 DirectFB_ActivateRenderer(
renderer);
836 SDL_AddDirtyRect(&texturedata->dirty,
rect);
840 if (texturedata->display) {
845 DSLF_WRITE | DSLF_READ,
851 (
void *) ((
Uint8 *) texturedata->pixels +
852 rect->
y * texturedata->pitch +
854 *pitch = texturedata->pitch;
855 texturedata->isDirty = 1;
866 DirectFB_TextureData *texturedata =
867 (DirectFB_TextureData *)
texture->driverdata;
869 DirectFB_ActivateRenderer(
renderer);
871 if (texturedata->display) {
872 SDL_DFB_CHECK(texturedata->surface->Unlock(texturedata->surface));
873 texturedata->pixels =
NULL;
882 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
885 for (
i = 0;
i < numrects; ++
i) {
894 DirectFB_TextureData *tex_data =
NULL;
896 DirectFB_ActivateRenderer(
renderer);
898 tex_data = (DirectFB_TextureData *)
texture->driverdata;
899 data->target = tex_data->surface;
901 data->target = get_dfb_surface(
data->window);
903 data->lastBlendMode = 0;
912 IDirectFBSurface *destsurf =
data->target;
931 r = ((int)
r * (
int)
a) / 255;
932 g = ((int)
g * (
int)
a) / 255;
933 b = ((int)
b * (
int)
a) / 255;
948 IDirectFBSurface *destsurf =
data->target;
949 DFBRegion clip_region;
952 DirectFB_ActivateRenderer(
renderer);
955 destsurf->GetClip(destsurf, &clip_region);
957 int x =
points[
i].x + clip_region.x1;
958 int y =
points[
i].y + clip_region.y1;
970 IDirectFBSurface *destsurf =
data->target;
971 DFBRegion clip_region;
974 DirectFB_ActivateRenderer(
renderer);
978 #if (DFB_VERSION_ATLEAST(1,2,0))
982 destsurf->GetClip(destsurf, &clip_region);
986 int x2 =
points[
i + 1].x + clip_region.x1;
987 int y2 =
points[
i + 1].y + clip_region.y1;
1000 IDirectFBSurface *destsurf =
data->target;
1001 DFBRegion clip_region;
1004 DirectFB_ActivateRenderer(
renderer);
1008 destsurf->GetClip(destsurf, &clip_region);
1011 dst.x += clip_region.x1;
1012 dst.y += clip_region.y1;
1026 IDirectFBSurface *destsurf =
data->target;
1027 DFBRegion clip_region;
1030 DirectFB_ActivateRenderer(
renderer);
1034 destsurf->GetClip(destsurf, &clip_region);
1037 dst.x += clip_region.x1;
1038 dst.y += clip_region.y1;
1053 IDirectFBSurface *destsurf =
data->target;
1054 DirectFB_TextureData *texturedata =
1055 (DirectFB_TextureData *)
texture->driverdata;
1057 DFBRegion clip_region;
1058 DFBRectangle sr, dr;
1060 DirectFB_ActivateRenderer(
renderer);
1062 SDLtoDFBRect(srcrect, &sr);
1063 SDLtoDFBRect_Float(dstrect, &dr);
1065 destsurf->GetClip(destsurf, &clip_region);
1066 dr.x += clip_region.x1;
1067 dr.y += clip_region.y1;
1069 if (texturedata->display) {
1072 IDirectFBWindow *dfbwin = get_dfb_window(
window);
1075 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->
driverdata;
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;
1084 vidlayer->SetScreenRectangle(dispdata->vidlayer,
1090 DFBSurfaceBlittingFlags
flags = 0;
1093 if (texturedata->dirty.list) {
1094 SDL_DirtyRect *dirty;
1097 int pitch = texturedata->pitch;
1099 for (dirty = texturedata->dirty.list; dirty; dirty = dirty->next) {
1102 (
void *) ((
Uint8 *) texturedata->pixels +
1106 texturedata->pitch);
1108 SDL_ClearDirtyRects(&texturedata->dirty);
1111 if (texturedata->isDirty)
1120 DirectFB_UpdateTexture(
renderer,
texture, &
rect, texturedata->pixels, texturedata->pitch);
1126 flags |= DSBLIT_BLEND_COLORALPHA;
1133 flags |= DSBLIT_COLORIZE;
1136 SetColor(destsurf,
r,
g,
b,
alpha));
1140 SetBlendMode(
data,
texture->blendMode, texturedata);
1145 #if (DFB_VERSION_ATLEAST(1,2,0))
1151 if (srcrect->
w == dstrect->
w && srcrect->
h == dstrect->
h) {
1153 texturedata->surface,
1157 texturedata->surface,
1174 DirectFB_ActivateRenderer(
renderer);
1176 if (shape_data && shape_data->
surface) {
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));
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));
1202 DirectFB_TextureData *
data = (DirectFB_TextureData *)
texture->driverdata;
1204 DirectFB_ActivateRenderer(
renderer);
1211 if (
data->display) {
1212 DFB_DisplayData *dispdata =
1213 (DFB_DisplayData *)
data->display->driverdata;
1214 dispdata->vidIDinuse = 0;
1216 SDL_DFB_CHECK(dispdata->vidlayer->SetCooperativeLevel(dispdata->vidlayer,
1217 DLSCL_ADMINISTRATIVE));
1231 if (display->palette) {
1232 SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged,
data);
1244 IDirectFBSurface *winsurf =
data->target;
1252 winsurf->SetClip(winsurf, &dreg);
1261 IDirectFBSurface *destsurf = get_dfb_surface(
data->window);
1265 region.x1 =
rect->
x;
1267 region.y1 =
rect->
y;
1283 unsigned char* laypixels;
1285 DFBSurfacePixelFormat dfb_format;
1287 IDirectFBSurface *winsurf =
data->target;
1289 DirectFB_ActivateRenderer(
renderer);
1291 winsurf->GetPixelFormat(winsurf, &dfb_format);
1293 winsurf->Lock(winsurf, DSLF_READ, (
void **) &laypixels, &laypitch);
1297 sdl_format, laypixels, laypitch,
1300 winsurf->Unlock(winsurf);
1313 unsigned char* laypixels;
1315 DFBSurfacePixelFormat dfb_format;
1317 SDL_DFB_CHECK(windata->surface->GetPixelFormat(windata->surface, &dfb_format));
1320 SDL_DFB_CHECK(windata->surface->Lock(windata->surface, DSLF_WRITE, (
void **) &laypixels, &laypitch));
1325 sdl_format, laypixels, laypitch);