src/video/directfb/SDL_DirectFB_render.c
changeset 2721 e82a0e3e9b0e
parent 2244 5234868559fa
child 2722 91f1706b27be
equal deleted inserted replaced
2720:4eb759edddf5 2721:e82a0e3e9b0e
    85       SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
    85       SDL_RENDERER_PRESENTFLIP2 | SDL_RENDERER_PRESENTFLIP3 |
    86       SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED),
    86       SDL_RENDERER_PRESENTDISCARD | SDL_RENDERER_ACCELERATED),
    87      (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
    87      (SDL_TEXTUREMODULATE_NONE | SDL_TEXTUREMODULATE_COLOR |
    88       SDL_TEXTUREMODULATE_ALPHA),
    88       SDL_TEXTUREMODULATE_ALPHA),
    89      (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK |
    89      (SDL_TEXTUREBLENDMODE_NONE | SDL_TEXTUREBLENDMODE_MASK |
    90       SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_MOD),
    90       SDL_TEXTUREBLENDMODE_BLEND | SDL_TEXTUREBLENDMODE_ADD |
       
    91       SDL_TEXTUREBLENDMODE_MOD),
    91      (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST),
    92      (SDL_TEXTURESCALEMODE_NONE | SDL_TEXTURESCALEMODE_FAST),
    92      14,
    93      14,
    93      {
    94      {
    94       SDL_PIXELFORMAT_INDEX8,
    95       SDL_PIXELFORMAT_INDEX8,
    95       SDL_PIXELFORMAT_INDEX4LSB,
    96       SDL_PIXELFORMAT_INDEX4LSB,
   122     IDirectFBSurface *surface;
   123     IDirectFBSurface *surface;
   123     Uint32 format;
   124     Uint32 format;
   124     void *pixels;
   125     void *pixels;
   125     int pitch;
   126     int pitch;
   126     IDirectFBPalette *palette;
   127     IDirectFBPalette *palette;
       
   128     DFB_DisplayData *display;
   127 } DirectFB_TextureData;
   129 } DirectFB_TextureData;
   128 
       
   129 static void
       
   130 UpdateYUVTextureData(SDL_Texture * texture)
       
   131 {
       
   132     /*
       
   133      * Not needed - directfb supports yuv surfaces
       
   134      */
       
   135 }
       
   136 
   130 
   137 void
   131 void
   138 DirectFB_AddRenderDriver(_THIS)
   132 DirectFB_AddRenderDriver(_THIS)
   139 {
   133 {
   140     int i;
   134     int i;
   176     renderer->RenderCopy = DirectFB_RenderCopy;
   170     renderer->RenderCopy = DirectFB_RenderCopy;
   177     renderer->RenderPresent = DirectFB_RenderPresent;
   171     renderer->RenderPresent = DirectFB_RenderPresent;
   178     renderer->DestroyTexture = DirectFB_DestroyTexture;
   172     renderer->DestroyTexture = DirectFB_DestroyTexture;
   179     renderer->DestroyRenderer = DirectFB_DestroyRenderer;
   173     renderer->DestroyRenderer = DirectFB_DestroyRenderer;
   180     renderer->info = DirectFB_RenderDriver.info;
   174     renderer->info = DirectFB_RenderDriver.info;
   181     renderer->window = window->id;      // SDL window id
   175     renderer->window = window->id;      /* SDL window id */
   182     renderer->driverdata = data;
   176     renderer->driverdata = data;
   183 
   177 
   184     renderer->info.flags =
   178     renderer->info.flags =
   185         SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTDISCARD;
   179         SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTDISCARD;
   186 
   180 
   198     else if (scaps & DSCAPS_TRIPLE)
   192     else if (scaps & DSCAPS_TRIPLE)
   199         renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
   193         renderer->info.flags |= SDL_RENDERER_PRESENTFLIP3;
   200     else
   194     else
   201         renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
   195         renderer->info.flags |= SDL_RENDERER_SINGLEBUFFER;
   202 
   196 
   203     data->isyuvdirect = 0;
   197     data->isyuvdirect = 1;      /* default is on! */
   204     p = getenv("SDL_DIRECTFB_YUV_DIRECT");
   198     p = getenv("SDL_DIRECTFB_YUV_DIRECT");
   205     if (p)
   199     if (p)
   206         data->isyuvdirect = atoi(p);
   200         data->isyuvdirect = atoi(p);
   207 
   201 
   208     return renderer;
   202     return renderer;
   291   error:
   285   error:
   292     return -1;
   286     return -1;
   293 }
   287 }
   294 
   288 
   295 static int
   289 static int
   296 DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
   290 DirectFB_AcquireVidLayer(SDL_Renderer * renderer, SDL_Texture * texture)
   297 {
   291 {
   298     SDL_DFB_RENDERERDATA(renderer);
   292     SDL_DFB_RENDERERDATA(renderer);
   299     SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   293     SDL_Window *window = SDL_GetWindowFromID(renderer->window);
   300     SDL_DFB_WINDOWDATA(window);
       
   301     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
   294     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
   302     SDL_DFB_DEVICEDATA(display->device);
   295     SDL_DFB_DEVICEDATA(display->device);
   303     DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
   296     DFB_DisplayData *dispdata = (DFB_DisplayData *) display->driverdata;
   304     DirectFB_TextureData *data;
   297     DirectFB_TextureData *data = texture->driverdata;
   305     DFBResult ret;
       
   306     DFBSurfaceDescription dsc;
       
   307     DFBDisplayLayerDescription laydsc;
       
   308     DFBDisplayLayerConfig layconf;
   298     DFBDisplayLayerConfig layconf;
   309 
   299     int ret;
   310     SDL_DFB_CALLOC(data, 1, sizeof(*data));
   300 
   311     texture->driverdata = data;
       
   312 
       
   313     data->format = texture->format;
       
   314     data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format));
       
   315     data->vidlayer = NULL;
       
   316     if (renddata->isyuvdirect && (dispdata->vidID >= 0)
   301     if (renddata->isyuvdirect && (dispdata->vidID >= 0)
       
   302         && (!dispdata->vidIDinuse)
   317         && SDL_ISPIXELFORMAT_FOURCC(data->format)) {
   303         && SDL_ISPIXELFORMAT_FOURCC(data->format)) {
   318         SDL_DFB_CHECKERR(devdata->dfb->
       
   319                          GetDisplayLayer(devdata->dfb, dispdata->vidID,
       
   320                                          &data->vidlayer));
       
   321         layconf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
   304         layconf.flags = DLCONF_WIDTH | DLCONF_HEIGHT | DLCONF_PIXELFORMAT;
   322         layconf.width = texture->w;
   305         layconf.width = texture->w;
   323         layconf.height = texture->h;
   306         layconf.height = texture->h;
   324         layconf.pixelformat = SDLToDFBPixelFormat(data->format);
   307         layconf.pixelformat = SDLToDFBPixelFormat(data->format);
   325 
   308 
       
   309         SDL_DFB_CHECKERR(devdata->dfb->
       
   310                          GetDisplayLayer(devdata->dfb, dispdata->vidID,
       
   311                                          &data->vidlayer));
   326         SDL_DFB_CHECKERR(data->vidlayer->
   312         SDL_DFB_CHECKERR(data->vidlayer->
   327                          SetCooperativeLevel(data->vidlayer,
   313                          SetCooperativeLevel(data->vidlayer,
   328                                              DLSCL_EXCLUSIVE));
   314                                              DLSCL_EXCLUSIVE));
   329         SDL_DFB_CHECKERR(data->vidlayer->
   315         SDL_DFB_CHECKERR(data->vidlayer->
   330                          SetConfiguration(data->vidlayer, &layconf));
   316                          SetConfiguration(data->vidlayer, &layconf));
   331         SDL_DFB_CHECKERR(data->vidlayer->
   317         SDL_DFB_CHECKERR(data->vidlayer->
   332                          GetSurface(data->vidlayer, &data->surface));
   318                          GetSurface(data->vidlayer, &data->surface));
       
   319         //SDL_DFB_CHECKERR(data->vidlayer->GetDescription(data->vidlayer, laydsc));
       
   320         dispdata->vidIDinuse = 1;
       
   321         data->display = dispdata;
       
   322         SDL_DFB_DEBUG("Created HW YUV surface\n");
       
   323 
       
   324         return 0;
       
   325     }
       
   326     return 1;
       
   327   error:
       
   328     if (data->vidlayer) {
       
   329         SDL_DFB_RELEASE(data->surface);
   333         SDL_DFB_CHECKERR(data->vidlayer->
   330         SDL_DFB_CHECKERR(data->vidlayer->
   334                          GetDescription(data->vidlayer, &laydsc));
   331                          SetCooperativeLevel(data->vidlayer,
   335         SDL_DFB_DEBUG("Created HW YUV surface\n");
   332                                              DLSCL_ADMINISTRATIVE));
   336     }
   333         SDL_DFB_RELEASE(data->vidlayer);
   337     if (!data->vidlayer) {
   334     }
       
   335     return 1;
       
   336 }
       
   337 
       
   338 static int
       
   339 DirectFB_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
       
   340 {
       
   341     SDL_DFB_RENDERERDATA(renderer);
       
   342     SDL_Window *window = SDL_GetWindowFromID(renderer->window);
       
   343     SDL_DFB_WINDOWDATA(window);
       
   344     SDL_VideoDisplay *display = SDL_GetDisplayFromWindow(window);
       
   345     SDL_DFB_DEVICEDATA(display->device);
       
   346     DirectFB_TextureData *data;
       
   347     DFBResult ret;
       
   348     DFBSurfaceDescription dsc;
       
   349     DFBDisplayLayerDescription laydsc;
       
   350     DFBDisplayLayerConfig layconf;
       
   351 
       
   352     SDL_DFB_CALLOC(data, 1, sizeof(*data));
       
   353     texture->driverdata = data;
       
   354 
       
   355     data->format = texture->format;
       
   356     data->pitch = (texture->w * SDL_BYTESPERPIXEL(data->format));
       
   357     data->vidlayer = NULL;
       
   358 
       
   359     if (DirectFB_AcquireVidLayer(renderer, texture) != 0) {
   338         /* fill surface description */
   360         /* fill surface description */
   339         dsc.flags =
   361         dsc.flags =
   340             DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
   362             DSDESC_WIDTH | DSDESC_HEIGHT | DSDESC_PIXELFORMAT | DSDESC_CAPS;
   341         dsc.width = texture->w;
   363         dsc.width = texture->w;
   342         dsc.height = texture->h;
   364         dsc.height = texture->h;
   343         /* Never use DSCAPS_VIDEOONLY here. It kills performance
   365         /* <1.2 Never use DSCAPS_VIDEOONLY here. It kills performance
   344          * No DSCAPS_SYSTEMONLY either - let dfb decide
   366          * No DSCAPS_SYSTEMONLY either - let dfb decide
       
   367          * 1.2: DSCAPS_SYSTEMONLY boosts performance by factor ~8
   345          */
   368          */
   346         dsc.caps = 0;           //DSCAPS_PREMULTIPLIED;
   369         dsc.caps = DSCAPS_PREMULTIPLIED;
       
   370 
       
   371         if (texture->access == SDL_TEXTUREACCESS_STREAMING)
       
   372             dsc.caps |= DSCAPS_SYSTEMONLY;
       
   373         else
       
   374             dsc.caps |= DSCAPS_VIDEOONLY;
   347 
   375 
   348         /* find the right pixelformat */
   376         /* find the right pixelformat */
   349 
   377 
   350         dsc.pixelformat = SDLToDFBPixelFormat(data->format);
   378         dsc.pixelformat = SDLToDFBPixelFormat(data->format);
   351         if (dsc.pixelformat == DSPF_UNKNOWN) {
   379         if (dsc.pixelformat == DSPF_UNKNOWN) {
   467 {
   495 {
   468     switch (texture->blendMode) {
   496     switch (texture->blendMode) {
   469     case SDL_TEXTUREBLENDMODE_NONE:
   497     case SDL_TEXTUREBLENDMODE_NONE:
   470     case SDL_TEXTUREBLENDMODE_MASK:
   498     case SDL_TEXTUREBLENDMODE_MASK:
   471     case SDL_TEXTUREBLENDMODE_BLEND:
   499     case SDL_TEXTUREBLENDMODE_BLEND:
       
   500     case SDL_TEXTUREBLENDMODE_ADD:
   472     case SDL_TEXTUREBLENDMODE_MOD:
   501     case SDL_TEXTUREBLENDMODE_MOD:
   473         return 0;
   502         return 0;
   474     default:
   503     default:
   475         SDL_Unsupported();
   504         SDL_Unsupported();
   476         texture->blendMode = SDL_TEXTUREBLENDMODE_NONE;
   505         texture->blendMode = SDL_TEXTUREBLENDMODE_NONE;
   511     Uint8 *src, *dst;
   540     Uint8 *src, *dst;
   512     int row;
   541     int row;
   513     size_t length;
   542     size_t length;
   514 
   543 
   515     SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
   544     SDL_DFB_CHECKERR(data->surface->Lock(data->surface,
   516                                          DSLF_WRITE | DSLF_READ, &dpixels,
   545                                          DSLF_WRITE | DSLF_READ,
   517                                          &dpitch));
   546                                          ((void **) &dpixels), &dpitch));
   518     src = (Uint8 *) pixels;
   547     src = (Uint8 *) pixels;
   519     dst =
   548     dst =
   520         (Uint8 *) dpixels + rect->y * dpitch +
   549         (Uint8 *) dpixels + rect->y * dpitch +
   521         rect->x * SDL_BYTESPERPIXEL(texture->format);
   550         rect->x * SDL_BYTESPERPIXEL(texture->format);
   522     length = rect->w * SDL_BYTESPERPIXEL(texture->format);
   551     length = rect->w * SDL_BYTESPERPIXEL(texture->format);
   646         dr.h = dstrect->h;
   675         dr.h = dstrect->h;
   647 
   676 
   648         if (texture->
   677         if (texture->
   649             modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA))
   678             modMode & (SDL_TEXTUREMODULATE_COLOR | SDL_TEXTUREMODULATE_ALPHA))
   650         {
   679         {
   651             u8 alpha = 0xFF;
   680             Uint8 alpha = 0xFF;
   652             if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA)
   681             if (texture->modMode & SDL_TEXTUREMODULATE_ALPHA) {
   653                 alpha = texture->a;
   682                 alpha = texture->a;
   654             if (texture->modMode & SDL_TEXTUREMODULATE_COLOR)
   683                 flags |= DSBLIT_SRC_PREMULTCOLOR;
       
   684                 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, 0xFF,
       
   685                                                          0xFF, 0xFF, alpha));
       
   686             }
       
   687             if (texture->modMode & SDL_TEXTUREMODULATE_COLOR) {
   655                 SDL_DFB_CHECKERR(data->surface->
   688                 SDL_DFB_CHECKERR(data->surface->
   656                                  SetColor(data->surface, texture->r,
   689                                  SetColor(data->surface, texture->r,
   657                                           texture->g, texture->b, alpha));
   690                                           texture->g, texture->b, alpha));
   658             else
   691                 /* Only works together .... */
   659                 SDL_DFB_CHECKERR(data->surface->SetColor(data->surface, 0xFF,
   692                 flags |= DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR;
   660                                                          0xFF, 0xFF, alpha));
   693             }
   661             // Only works together ....
       
   662             flags |= DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR;
       
   663         }
   694         }
   664 
   695 
   665         if (texture->
   696         switch (texture->blendMode) {
   666             blendMode & (SDL_TEXTUREBLENDMODE_MASK |
   697         case SDL_TEXTUREBLENDMODE_NONE: /**< No blending */
   667                          SDL_TEXTUREBLENDMODE_BLEND)) {
   698             flags |= DSBLIT_NOFX;
       
   699             data->surface->SetSrcBlendFunction(data->surface, DSBF_ONE);
       
   700             data->surface->SetDstBlendFunction(data->surface, DSBF_ZERO);
       
   701             break;
       
   702         case SDL_TEXTUREBLENDMODE_MASK: /**< dst = A ? src : dst (alpha is mask) */
   668             flags |= DSBLIT_BLEND_ALPHACHANNEL;
   703             flags |= DSBLIT_BLEND_ALPHACHANNEL;
   669         } else {
   704             data->surface->SetSrcBlendFunction(data->surface, DSBF_SRCALPHA);
   670             flags |= DSBLIT_NOFX;
   705             data->surface->SetDstBlendFunction(data->surface,
       
   706                                                DSBF_INVSRCALPHA);
       
   707             break;
       
   708         case SDL_TEXTUREBLENDMODE_BLEND:/**< dst = (src * A) + (dst * (1-A)) */
       
   709             flags |= DSBLIT_BLEND_ALPHACHANNEL;
       
   710             data->surface->SetSrcBlendFunction(data->surface, DSBF_SRCALPHA);
       
   711             data->surface->SetDstBlendFunction(data->surface,
       
   712                                                DSBF_INVSRCALPHA);
       
   713             break;
       
   714         case SDL_TEXTUREBLENDMODE_ADD:  /**< dst = (src * A) + dst */
       
   715             flags |= DSBLIT_BLEND_ALPHACHANNEL;
       
   716             data->surface->SetSrcBlendFunction(data->surface, DSBF_SRCALPHA);
       
   717             data->surface->SetDstBlendFunction(data->surface, DSBF_ONE);
       
   718             break;
       
   719         case SDL_TEXTUREBLENDMODE_MOD:  /**< dst = src * dst */
       
   720             flags |= DSBLIT_BLEND_ALPHACHANNEL;
       
   721             data->surface->SetSrcBlendFunction(data->surface, DSBF_DESTCOLOR);
       
   722             data->surface->SetDstBlendFunction(data->surface, DSBF_ZERO);
       
   723             break;
   671         }
   724         }
       
   725 
   672         SDL_DFB_CHECKERR(data->surface->
   726         SDL_DFB_CHECKERR(data->surface->
   673                          SetBlittingFlags(data->surface, flags));
   727                          SetBlittingFlags(data->surface, flags));
   674         if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
   728         if (srcrect->w == dstrect->w && srcrect->h == dstrect->h) {
   675             SDL_DFB_CHECKERR(data->surface->
   729             SDL_DFB_CHECKERR(data->surface->
   676                              Blit(data->surface, texturedata->surface, &sr,
   730                              Blit(data->surface, texturedata->surface, &sr,
   718     if (!data) {
   772     if (!data) {
   719         return;
   773         return;
   720     }
   774     }
   721     SDL_DFB_RELEASE(data->palette);
   775     SDL_DFB_RELEASE(data->palette);
   722     SDL_DFB_RELEASE(data->surface);
   776     SDL_DFB_RELEASE(data->surface);
       
   777     if (data->display) {
       
   778         data->display->vidIDinuse = 0;
       
   779         data->vidlayer->SetCooperativeLevel(data->vidlayer,
       
   780                                             DLSCL_ADMINISTRATIVE);
       
   781     }
   723     SDL_DFB_RELEASE(data->vidlayer);
   782     SDL_DFB_RELEASE(data->vidlayer);
   724     SDL_free(data);
   783     SDL_free(data);
   725     texture->driverdata = NULL;
   784     texture->driverdata = NULL;
   726 }
   785 }
   727 
   786