コード例 #1
0
ファイル: sawman_draw.c プロジェクト: aHaeseokMaeng/directfb
static void
draw_window_color( SaWManWindow *sawwin,
                   CardState    *state,
                   DFBRegion    *region,
                   bool          alpha_channel,
                   bool          right_eye )
{
     SaWMan                  *sawman;
     CoreWindow              *window;
     DFBSurfaceDrawingFlags   flags = DSDRAW_NOFX;
     DFBRectangle             dst;
     DFBRegion                clip;
     DFBRegion                old_clip;
     DFBColor                 color;
     int                      offset;


     sawman = sawwin->sawman;
     window = sawwin->window;
     dst    = sawwin->dst;

     D_MAGIC_ASSERT( sawman, SaWMan );
     D_ASSERT( window != NULL );

     D_DEBUG_AT( SaWMan_Draw, "%s( %p, %d,%d-%dx%d )\n", __FUNCTION__,
                 sawwin, DFB_RECTANGLE_VALS_FROM_REGION( region ) );

     color = window->config.color;

     /* Modify dst for stereo offset. */
     offset = window->config.z;
     offset *= right_eye ? -1 : 1;
     dfb_rectangle_translate( &dst, offset, 0 );

     /* Setup clipping region. */
     clip = *region;

     if (!dfb_region_rectangle_intersect( &clip, &dst ))
          return;

     /* Backup clipping region. */
     old_clip = state->clip;

     /* Use per pixel alpha blending. */
     if (alpha_channel && (window->config.options & DWOP_ALPHACHANNEL))
          flags |= DSDRAW_BLEND;

     /* we assume the passed color is never premultiplied */
     flags |= DSDRAW_SRC_PREMULTIPLY;

     /* when not opaque, we simply adjust the color */
     if (window->config.opacity != 0xFF) {
          flags   |= DSDRAW_BLEND;
          color.a  = (color.a * window->config.opacity) >> 8;
     }
コード例 #2
0
ファイル: util.c プロジェクト: lelou6666/DirectFB-1.6.3-ab
bool
dfb_unsafe_region_rectangle_intersect( DFBRegion          *region,
                                       const DFBRectangle *rect )
{
     if (region->x1 > region->x2) {
          int temp = region->x1;
          region->x1 = region->x2;
          region->x2 = temp;
     }

     if (region->y1 > region->y2) {
          int temp = region->y1;
          region->y1 = region->y2;
          region->y2 = temp;
     }

     return dfb_region_rectangle_intersect( region, rect );
}
コード例 #3
0
static bool
stretch_hvx( CardState *state, DFBRectangle *srect, DFBRectangle *drect )
{
     GenefxState                *gfxs;
     const StretchFunctionTable *table;
     StretchHVx                  stretch;
     bool                        down = false;
     void                       *dst;
     void                       *src;
     StretchCtx                  ctx;
     int                         idx = STRETCH_NONE;
     u32                         colors[256];

     D_ASSERT( state != NULL );
     DFB_RECTANGLE_ASSERT( srect );
     DFB_RECTANGLE_ASSERT( drect );

     gfxs = state->gfxs;

     if (srect->w > drect->w && srect->h > drect->h)
          down = true;

     if (down) {
          if (!(state->render_options & DSRO_SMOOTH_DOWNSCALE))
               return false;
     }
     else {
          if (!(state->render_options & DSRO_SMOOTH_UPSCALE))
               return false;
     }

     switch (gfxs->dst_format) {
          case DSPF_NV12:
          case DSPF_NV21:
               return stretch_hvx_planar( state, srect, drect, down );

          default:
               break;
     }

     if (state->blittingflags & ~(DSBLIT_COLORKEY_PROTECT | DSBLIT_SRC_COLORKEY | DSBLIT_SRC_PREMULTIPLY))
          return false;

     if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY && !DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format ))
          return false;

     if (DFB_PIXELFORMAT_INDEX(gfxs->dst_format) >= D_ARRAY_SIZE(stretch_tables))
          return false;

     if (DFB_PIXELFORMAT_INDEX(gfxs->src_format) >= D_ARRAY_SIZE((stretch_tables[0])->f))
          return false;

     table = stretch_tables[DFB_PIXELFORMAT_INDEX(gfxs->dst_format)];
     if (!table)
          return false;

     if (state->blittingflags & DSBLIT_SRC_COLORKEY)
          idx |= STRETCH_SRCKEY;

     if (state->blittingflags & DSBLIT_COLORKEY_PROTECT)
          idx |= STRETCH_PROTECT;

     if (down)
          stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].down[idx];
     else
          stretch = table->f[DFB_PIXELFORMAT_INDEX(gfxs->src_format)].up[idx];

     if (!stretch)
          return false;

     ctx.clip = state->clip;

     if (!dfb_region_rectangle_intersect( &ctx.clip, drect ))
          return false;

     dfb_region_translate( &ctx.clip, - drect->x, - drect->y );

     if (DFB_PIXELFORMAT_IS_INDEXED( gfxs->src_format )) {
          int             i;
          const DFBColor *entries;
          u16            *colors16 = (void*) colors;

          D_ASSERT( gfxs->Blut != NULL );

          entries = gfxs->Blut->entries;

          switch (gfxs->dst_format) {
               case DSPF_ARGB:
                    if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) {
                         for (i=0; i<gfxs->Blut->num_entries; i++) {
                              int alpha = entries[i].a + 1;

                              switch (alpha) {
                                   case 0:
                                        colors[i] = 0;
                                        break;

                                   case 255:
                                        colors[i] = PIXEL_ARGB( entries[i].a,
                                                                entries[i].r,
                                                                entries[i].g,
                                                                entries[i].b );
                                        break;

                                   default:
                                        colors[i] = PIXEL_ARGB( entries[i].a,
                                                                (alpha * entries[i].r) >> 8,
                                                                (alpha * entries[i].g) >> 8,
                                                                (alpha * entries[i].b) >> 8 );
                              }
                         }
                    }
                    else {
                         for (i=0; i<gfxs->Blut->num_entries; i++)
                              colors[i] = PIXEL_ARGB( entries[i].a, entries[i].r, entries[i].g, entries[i].b );
                    }
                    break;

               case DSPF_RGB32:
                    for (i=0; i<gfxs->Blut->num_entries; i++)
                         colors[i] = PIXEL_RGB32( entries[i].r, entries[i].g, entries[i].b );
                    break;

               case DSPF_RGB16:
                    for (i=0; i<gfxs->Blut->num_entries; i++)
                         colors16[i] = PIXEL_RGB16( entries[i].r, entries[i].g, entries[i].b );
                    break;

               case DSPF_ARGB4444:
                    if (state->blittingflags & DSBLIT_SRC_PREMULTIPLY) {
                         for (i=0; i<gfxs->Blut->num_entries; i++) {
                              int alpha = entries[i].a + 1;

                              switch (alpha) {
                                   case 0:
                                        colors16[i] = 0;
                                        break;

                                   case 255:
                                        colors16[i] = PIXEL_ARGB4444( entries[i].a,
                                                                      entries[i].r,
                                                                      entries[i].g,
                                                                      entries[i].b );
                                        break;

                                   default:
                                        colors16[i] = PIXEL_ARGB4444( entries[i].a,
                                                                      (alpha * entries[i].r) >> 8,
                                                                      (alpha * entries[i].g) >> 8,
                                                                      (alpha * entries[i].b) >> 8 );
                              }
                         }
                    }
                    else {
                         for (i=0; i<gfxs->Blut->num_entries; i++)
コード例 #4
0
static bool
stretch_hvx_planar( CardState *state, DFBRectangle *srect, DFBRectangle *drect, bool down )
{
     GenefxState *gfxs;
     void        *dst;
     void        *src;
     DFBRegion    clip;

     D_ASSERT( state != NULL );
     DFB_RECTANGLE_ASSERT( srect );
     DFB_RECTANGLE_ASSERT( drect );

     gfxs = state->gfxs;

     if (state->blittingflags)
          return false;

     if (gfxs->dst_format != gfxs->src_format)
          return false;

     clip = state->clip;

     if (!dfb_region_rectangle_intersect( &clip, drect ))
          return false;

     dfb_region_translate( &clip, - drect->x, - drect->y );

     dst = gfxs->dst_org[0] + drect->y * gfxs->dst_pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, drect->x );
     src = gfxs->src_org[0] + srect->y * gfxs->src_pitch + DFB_BYTES_PER_LINE( gfxs->src_format, srect->x );

     switch (gfxs->dst_format) {
          case DSPF_NV12:
          case DSPF_NV21:
               if (down)
                    stretch_hvx_8_down( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                        srect->w, srect->h, drect->w, drect->h, &clip );
               else
                    stretch_hvx_8_up( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                      srect->w, srect->h, drect->w, drect->h, &clip );

               clip.x1 /= 2;
               clip.x2 /= 2;
               clip.y1 /= 2;
               clip.y2 /= 2;

               dst = gfxs->dst_org[1] + drect->y/2 * gfxs->dst_pitch + DFB_BYTES_PER_LINE( gfxs->dst_format, drect->x );
               src = gfxs->src_org[1] + srect->y/2 * gfxs->src_pitch + DFB_BYTES_PER_LINE( gfxs->src_format, srect->x );

               if (down)
                    stretch_hvx_88_down( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                         srect->w/2, srect->h, drect->w/2, drect->h, &clip );
               else
                    stretch_hvx_88_up( dst, gfxs->dst_pitch, src, gfxs->src_pitch,
                                       srect->w/2, srect->h, drect->w/2, drect->h, &clip );
               break;

          default:
               break;
     }

     return true;
}
コード例 #5
0
ファイル: sawman_draw.c プロジェクト: aHaeseokMaeng/directfb
static void
draw_window( SaWManTier   *tier,
             SaWManWindow *sawwin,
             SaWManWindow *sawwin2,
             CardState    *state,
             DFBRegion    *region,
             bool          alpha_channel,
             bool          right_eye )
{
     SaWMan                  *sawman;
     CoreWindow              *window;
     DFBSurfaceBlittingFlags  flags = DSBLIT_NOFX;
     DFBRectangle             dst;
     DFBRectangle             src;
     DFBRegion                clip;
     DFBRegion                old_clip;
     int                      offset;

     D_MAGIC_ASSERT( sawwin,  SaWManWindow );
     D_MAGIC_ASSERT( state, CardState );
     DFB_REGION_ASSERT( region );

     sawman = sawwin->sawman;
     window = sawwin->window;
     dst    = sawwin->dst;
     src    = sawwin->src;

     D_MAGIC_ASSERT( sawman, SaWMan );
     D_ASSERT( window != NULL );
     D_ASSERT( window->surface != NULL );

     D_DEBUG_AT( SaWMan_Draw, "%s( %p, %d,%d-%dx%d )\n", __FUNCTION__,
                 sawwin, DFB_RECTANGLE_VALS_FROM_REGION( region ) );

     if (window->config.options & DWOP_STEREO_SIDE_BY_SIDE_HALF) {
          src.x /= 2;
          src.w /= 2;

          if (right_eye)
               src.x += window->surface->config.size.w / 2;
     }

     /* Modify dst for stereo offset. */
     offset = window->config.z;
     offset *= right_eye ? -1 : 1;
     dfb_rectangle_translate( &dst, offset, 0 );

     /* Setup clipping region. */
     clip = *region;

     if (!dfb_region_rectangle_intersect( &clip, &dst ))
          return;


     sawman_dispatch_blit( sawman, sawwin, right_eye, &sawwin->src, &dst, &clip );

     if (sawwin2)
          sawman_dispatch_blit( sawman, sawwin2, right_eye, &sawwin2->src, &dst, &clip );


     /* Backup clipping region. */
     old_clip = state->clip;

     /* Use per pixel alpha blending. */
     if (alpha_channel && (window->config.options & DWOP_ALPHACHANNEL))
          flags |= DSBLIT_BLEND_ALPHACHANNEL;

     /* Use global alpha blending. */
     if (window->config.opacity != 0xFF) {
          flags |= DSBLIT_BLEND_COLORALPHA;

          if (window->surface->config.caps & DSCAPS_PREMULTIPLIED) {
               /* Need to premultiply source with Ac? */
               flags |= DSBLIT_SRC_PREMULTCOLOR;

               dfb_state_set_src_blend( state, DSBF_ONE );
          }
          else
               dfb_state_set_src_blend( state, DSBF_SRCALPHA );

          /* Set opacity as blending factor. */
          if (state->color.a != window->config.opacity) {
               state->color.a   = window->config.opacity;
               state->modified |= SMF_COLOR;
          }
     }

     /* if we specified some kind of color, we will colorise. no DWCAPS_COLOR here. */
     if (window->config.color.a != 0) {
          DFBColor c;

          flags |= DSBLIT_COLORIZE;

          c   = window->config.color;
          c.a = state->color.a;

          if (! DFB_COLOR_EQUAL( c, state->color )) {
               state->color     = c;
               state->modified |= SMF_COLOR;
          }
     }

     /* Use source color keying. */
     if (window->config.options & DWOP_COLORKEYING) {
          flags |= DSBLIT_SRC_COLORKEY;

          D_DEBUG_AT( SaWMan_Draw, "  -> key 0x%08x\n", window->config.color_key );

          /* Set window color key. */
          dfb_state_set_src_colorkey( state, window->config.color_key );
     }

     /* Use automatic deinterlacing. */
     if (window->surface->config.caps & DSCAPS_INTERLACED)
          flags |= DSBLIT_DEINTERLACE;

     /* Different compositing methods depending on destination format. */
     if (flags & DSBLIT_BLEND_ALPHACHANNEL) {
          if (DFB_PIXELFORMAT_HAS_ALPHA( state->destination->config.format )) {
               /*
                * Always use compliant Porter/Duff SRC_OVER,
                * if the destination has an alpha channel.
                *
                * Cd = destination color  (non-premultiplied)
                * Ad = destination alpha
                *
                * Cs = source color       (non-premultiplied)
                * As = source alpha
                *
                * Ac = color alpha
                *
                * cd = Cd * Ad            (premultiply destination)
                * cs = Cs * As            (premultiply source)
                *
                * The full equation to calculate resulting color and alpha (premultiplied):
                *
                * cx = cd * (1-As*Ac) + cs * Ac
                * ax = Ad * (1-As*Ac) + As * Ac
                */
               dfb_state_set_src_blend( state, DSBF_ONE );

               /* Need to premultiply source with As*Ac or only with Ac? */
               if (! (window->surface->config.caps & DSCAPS_PREMULTIPLIED))
                    flags |= DSBLIT_SRC_PREMULTIPLY;
               else if (flags & DSBLIT_BLEND_COLORALPHA)
                    flags |= DSBLIT_SRC_PREMULTCOLOR;

               /* Need to premultiply/demultiply destination? */
//               if (! (state->destination->caps & DSCAPS_PREMULTIPLIED))
//                    flags |= DSBLIT_DST_PREMULTIPLY | DSBLIT_DEMULTIPLY;
          }
          else {
               /*
                * We can avoid DSBLIT_SRC_PREMULTIPLY for destinations without an alpha channel
                * by using another blending function, which is more likely that it's accelerated
                * than premultiplication at this point in time.
                *
                * This way the resulting alpha (ax) doesn't comply with SRC_OVER,
                * but as the destination doesn't have an alpha channel it's no problem.
                *
                * As the destination's alpha value is always 1.0 there's no need for
                * premultiplication. The resulting alpha value will also be 1.0 without
                * exceptions, therefore no need for demultiplication.
                *
                * cx = Cd * (1-As*Ac) + Cs*As * Ac  (still same effect as above)
                * ax = Ad * (1-As*Ac) + As*As * Ac  (wrong, but discarded anyways)
                */
               if (window->surface->config.caps & DSCAPS_PREMULTIPLIED) {
                    /* Need to premultiply source with Ac? */
                    if (flags & DSBLIT_BLEND_COLORALPHA)
                         flags |= DSBLIT_SRC_PREMULTCOLOR;

                    dfb_state_set_src_blend( state, DSBF_ONE );
               }
               else
                    dfb_state_set_src_blend( state, DSBF_SRCALPHA );
          }
     }

     /* Use color (key) protection if layer is keyed. */
     if (tier->context->config.options & DLOP_SRC_COLORKEY) {
          flags |= DSBLIT_COLORKEY_PROTECT;

          dfb_state_set_colorkey( state, &tier->key );
     }

     /* Set blitting flags. */
     dfb_state_set_blitting_flags( state, flags );

     /* Set render options. */
     if (sawman->scaling_mode == SWMSM_SMOOTH)
          dfb_state_set_render_options( state, DSRO_SMOOTH_DOWNSCALE | DSRO_SMOOTH_UPSCALE );
     else
          dfb_state_set_render_options( state, DSRO_NONE );

     /* Set blitting source. */
     state->source    = window->surface;
     state->from_eye  = (right_eye && (sawwin->caps & DWCAPS_STEREO)) ? DSSE_RIGHT : DSSE_LEFT;
     state->modified |= SMF_SOURCE | SMF_FROM;

     D_DEBUG_AT( SaWMan_Draw, "  [][] %4d,%4d-%4dx%4d\n", DFB_RECTANGLE_VALS_FROM_REGION( &clip ) );

     /* Change clipping region. */
     dfb_state_set_clip( state, &clip );

     D_DEBUG_AT( SaWMan_Draw, "    => %4d,%4d-%4dx%4d <- %4d,%4d-%4dx%4d\n",
                 DFB_RECTANGLE_VALS( &dst ), DFB_RECTANGLE_VALS( &src ) );

#ifndef OLD_COREWINDOWS_STRUCTURE
     if (sawwin2) {
          CoreWindow   *window2;
          DFBRectangle *src2;
          DFBPoint      p1,p2,p;

          D_MAGIC_ASSERT( sawwin2, SaWManWindow );
          window2 = sawwin2->window;
          D_ASSERT( window2 != NULL );
          D_ASSERT( window2->surface != NULL );
          src2 = &sawwin2->src;

          state->source2  = window2->surface;
          state->modified = SMF_SOURCE2;

          p1.x = src2->x + (sawwin->dst.x - sawwin2->dst.x);
          p1.y = src2->y + (sawwin->dst.y - sawwin2->dst.y);
          p2.x = sawwin->dst.x;
          p2.y = sawwin->dst.y;

          p.x = p1.x;
          p.y = p1.y;

          p1.x = src.x;
          p1.y = src.y;

          src.x = p.x;
          src.y = p.y;

          CoreGraphicsStateClient_Blit2( state->client, &src, &p2, &p1, 1 );
     }
     else
#endif
     {
          /* Scale window to the screen clipped by the region being updated. */
          CoreGraphicsStateClient_StretchBlit( state->client, &src, &dst, 1 );
     }

     /* Restore clipping region. */
     dfb_state_set_clip( state, &old_clip );
}