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