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) {
153 SetBlendMode(DirectFB_RenderData * data,
int blendMode,
154 DirectFB_TextureData *
source)
156 IDirectFBSurface *destsurf = data->target;
159 if (1 || data->lastBlendMode != blendMode) {
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;
188 if (source && TextureHasAlpha(source))
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));
209 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->
driverdata;
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;
243 SDL_DFB_RENDERERDATA(renderer);
256 SDL_DFB_RENDERERDATA(renderer);
258 if (renddata->size_changed ) {
269 DFB_DisplayData *dispdata = (DFB_DisplayData *) display->
driverdata;
270 DirectFB_TextureData *data = texture->
driverdata;
271 DFBDisplayLayerConfig layconf;
274 if (devdata->use_yuv_direct && (dispdata->vidID >= 0)
275 && (!dispdata->vidIDinuse)
278 DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT |
280 layconf.width = texture->
w;
281 layconf.height = texture->
h;
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) {
341 data->format = texture->
format;
342 data->pitch = texture->
w * DFB_BYTES_PER_PIXEL(pixelformat);
344 if (DirectFB_AcquireVidLayer(renderer, texture) != 0) {
347 DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
348 dsc.width = texture->
w;
349 dsc.height = texture->
h;
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;
386 SDL_DFB_CHECKERR(devdata->dfb->CreatePalette(devdata->dfb, &pal_desc,&data->palette));
392 #if (DFB_VERSION_ATLEAST(1,2,0)) 393 data->render_options = DSRO_NONE;
399 SDL_DFB_ALLOC_CLEAR(data->pixels, (texture->
h * data->pitch + ((texture->
h + texture->
h % 2) * (data->pitch + data->pitch % 2) * 2) / 4));
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;
448 DirectFB_TextureData *data = (DirectFB_TextureData *) texture->
driverdata;
457 DirectFB_ActivateRenderer(renderer);
465 DSLF_WRITE | DSLF_READ,
466 ((
void **) &dpixels), &dpitch));
467 src = (
Uint8 *) pixels;
468 dst = (
Uint8 *) dpixels + rect->
y * dpitch + rect->
x * bpp;
478 src = (
Uint8 *) pixels + texture->
h * pitch;
479 dst = (
Uint8 *) dpixels + texture->
h * dpitch + rect->
y * dpitch / 4 + rect->
x * bpp / 2;
480 for (
row = 0;
row < rect->
h / 2 + (rect->
h & 1); ++
row) {
485 src = (
Uint8 *) pixels + texture->
h * pitch + texture->
h * pitch / 4;
486 dst = (
Uint8 *) dpixels + texture->
h * dpitch + texture->
h * dpitch / 4 + rect->
y * dpitch / 4 + rect->
x * bpp / 2;
487 for (
row = 0;
row < rect->
h / 2 + (rect->
h & 1); ++
row) {
503 const SDL_Rect * rect,
void **pixels,
int *pitch)
505 DirectFB_TextureData *texturedata =
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 =
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) {
562 SDL_AddDirtyRect(&data->dirty, &rects[
i]);
569 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->
driverdata;
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;
608 const size_t len = count *
sizeof (
SDL_FRect);
632 SDLtoDFBRect(srcrect, verts++);
633 SDLtoDFBRect_Float(dstrect, verts);
651 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->
driverdata;
652 IDirectFBSurface *destsurf = data->target;
653 DFBRegion clip_region;
656 DirectFB_ActivateRenderer(renderer);
667 clip_region.x1 = viewport->
x;
668 clip_region.y1 = viewport->
y;
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;
680 clip_region.x2 = rect->
x + rect->
w;
681 clip_region.y1 = rect->
y;
682 clip_region.y2 = rect->
y + rect->
h;
683 destsurf->SetClip(destsurf, &clip_region);
693 destsurf->Clear(destsurf, r, g, b, a);
698 const size_t count = cmd->
data.
draw.count;
700 PrepareDraw(renderer, cmd);
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);
711 const size_t count = cmd->
data.
draw.count;
713 PrepareDraw(renderer, cmd);
715 #if (DFB_VERSION_ATLEAST(1,2,0)) 716 destsurf->SetRenderOptions(destsurf, DSRO_ANTIALIAS);
719 for (
i = 0;
i < count - 1;
i++) {
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);
731 const size_t count = cmd->
data.
draw.count;
733 PrepareDraw(renderer, cmd);
735 for (
i = 0;
i <
count;
i++, rects++) {
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) {
771 const SDL_Rect rect = { 0, 0, texture->
w, texture->
h };
772 DirectFB_UpdateTexture(renderer, texture, &rect, texturedata->pixels, texturedata->pitch);
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);
821 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->
driverdata;
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));
880 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->
driverdata;
883 if (display->palette) {
884 SDL_DelPaletteWatch(display->palette, DisplayPaletteChanged, data);
897 unsigned char* laypixels;
899 DFBSurfacePixelFormat dfb_format;
900 DirectFB_RenderData *data = (DirectFB_RenderData *) renderer->
driverdata;
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,
912 format, pixels, pitch);
914 winsurf->Unlock(winsurf);
922 Uint32 format,
const void * pixels,
int pitch)
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));
938 format, pixels, pitch,
939 sdl_format, laypixels, laypitch);
951 IDirectFBSurface *winsurf = get_dfb_surface(window);
954 DirectFB_RenderData *data =
NULL;
955 DFBSurfaceCapabilities scaps;
974 renderer->
QueueCopy = DirectFB_QueueCopy;
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)
1009 renderer->
info.
flags |= SDL_RENDERER_PRESENTFLIP2;
1010 else if (scaps & DSCAPS_TRIPLE)
1011 renderer->
info.
flags |= SDL_RENDERER_PRESENTFLIP3;
1013 renderer->
info.
flags |= SDL_RENDERER_SINGLEBUFFER;
1020 if (display-> palette) {
1021 SDL_AddPaletteWatch(display->palette, DisplayPaletteChanged, data);
1035 DirectFB_CreateRenderer,
GLdouble GLdouble GLdouble r
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
GLuint GLfloat GLfloat GLfloat x1
struct SDL_RenderCommand::@30::@31 viewport
void DirectFB_SetSupportedPixelFormats(SDL_RendererInfo *ri)
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
GLint GLint GLint GLint GLint x
struct SDL_RenderCommand::@30::@32 cliprect
#define SDL_ISPIXELFORMAT_INDEXED(format)
struct wl_surface * surface
SDL_RenderDriver DirectFB_RenderDriver
GLuint GLuint GLsizei count
void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
struct SDL_RenderCommand::@30::@34 color
DFBSurfacePixelFormat DirectFB_SDLToDFBPixelFormat(Uint32 format)
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
GLfixed GLfixed GLfixed y2
int(* QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
#define SDL_BYTESPERPIXEL(X)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
IDirectFBSurface * surface
Uint32 DirectFB_DFBToSDLPixelFormat(DFBSurfacePixelFormat pixelformat)
void(* DestroyRenderer)(SDL_Renderer *renderer)
GLfixed GLfixed GLint GLint GLfixed points
#define SDL_DFB_RELEASE(x)
#define SDL_VERSION(x)
Macro to determine SDL version program was compiled against.
static SDL_BlendMode blendMode
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
int(* QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
GLenum GLenum GLuint texture
#define SDL_DFB_DEVICEDATA(dev)
struct SDL_RenderCommand::@30::@33 draw
static SDL_Renderer * renderer
SDL_WindowShaper * shaper
int(* QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
GLsizei GLsizei GLchar * source
GLint GLint GLint GLint GLint GLint y
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
int(* QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
int(* RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
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)
Window state change event data (event.window.*)
#define SDL_GetWindowWMInfo
#define SDL_DFB_ALLOC_CLEAR(r, s)
#define SDL_DFB_CHECKERR(x...)
#define SDL_DFB_WINDOWDATA(win)
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
SDL_VideoDisplay * SDL_GetDisplayForWindow(SDL_Window *window)
EGLSurface EGLNativeWindowType * window
#define SDL_DFB_CHECK(x...)
SDL_RenderCommandType command
The type used to identify a window.
union SDL_RenderCommand::@30 data
union SDL_SysWMinfo::@17 info
#define SDL_DFB_DEBUG(x...)
int(* QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
#define SDL_ConvertPixels
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* RenderPresent)(SDL_Renderer *renderer)
#define SDL_ISPIXELFORMAT_FOURCC(format)
EGLSurface EGLint * rects
GLuint GLsizei GLsizei * length
struct SDL_RenderCommand * next
GLboolean GLboolean GLboolean GLboolean a
GLboolean GLboolean GLboolean b
#define SDL_Unsupported()
A rectangle, with the origin at the upper left (floating point).
The structure that defines a point (floating point)
A rectangle, with the origin at the upper left (integer).