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