Esempio n. 1
0
void
dfb_gfx_copy_stereo( CoreSurface         *source,
                     DFBSurfaceStereoEye  source_eye,
                     CoreSurface         *destination,
                     DFBSurfaceStereoEye  destination_eye,
                     const DFBRectangle  *rect,
                     int                  x,
                     int                  y,
                     bool                 from_back )
{
     DFBRectangle sourcerect = { 0, 0, source->config.size.w, source->config.size.h };

     StateClient *client = state_client_tls.Get();

     D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO );

     client->state.clip.x2     = destination->config.size.w - 1;
     client->state.clip.y2     = destination->config.size.h - 1;
     client->state.source      = source;
     client->state.destination = destination;
     client->state.from        = from_back ? CSBR_BACK : CSBR_FRONT;
     client->state.from_eye    = source_eye;
     client->state.to          = CSBR_BACK;
     client->state.to_eye      = destination_eye;

     if (rect) {
          if (dfb_rectangle_intersect( &sourcerect, rect )) {
               DFBPoint point = { x + sourcerect.x - rect->x, y + sourcerect.y - rect->y };

               CoreGraphicsStateClient_Blit( &client->client, &sourcerect, &point, 1 );
          }
     }
     else {
          DFBPoint point = { x, y };

          CoreGraphicsStateClient_Blit( &client->client, &sourcerect, &point, 1 );
     }

     CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_NONE );

     /* Signal end of sequence. */
     dfb_state_stop_drawing( &client->state );

     client->state.destination = NULL;
     client->state.source      = NULL;
}
Esempio n. 2
0
void
dfb_gfx_copy_regions_stereo( CoreSurface           *source,
                             CoreSurfaceBufferRole  from,
                             DFBSurfaceStereoEye    source_eye,
                             CoreSurface           *destination,
                             CoreSurfaceBufferRole  to,
                             DFBSurfaceStereoEye    destination_eye,
                             const DFBRegion       *regions,
                             unsigned int           num,
                             int                    x,
                             int                    y )
{
     unsigned int i, n = 0;
     DFBRectangle rect = { 0, 0, source->config.size.w, source->config.size.h };
     DFBRectangle rects[num];
     DFBPoint     points[num];

     D_ASSERT( !dfb_config->task_manager );

     for (i=0; i<num; i++) {
          DFB_REGION_ASSERT( &regions[i] );

          rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( &regions[i] );

          if (dfb_rectangle_intersect( &rects[n], &rect )) {
               points[n].x = x + rects[n].x - rect.x;
               points[n].y = y + rects[n].y - rect.y;

               n++;
          }
     }

     if (n > 0) {
          StateClient *client = state_client_tls.Get();

          D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO );

          client->state.clip.x2     = destination->config.size.w - 1;
          client->state.clip.y2     = destination->config.size.h - 1;
          client->state.source      = source;
          client->state.destination = destination;
          client->state.from        = from;
          client->state.from_eye    = source_eye;
          client->state.to          = to;
          client->state.to_eye      = destination_eye;

          CoreGraphicsStateClient_Blit( &client->client, rects, points, n );

          CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_NONE );

          /* Signal end of sequence. */
          dfb_state_stop_drawing( &client->state );

          client->state.destination = NULL;
          client->state.source      = NULL;
     }
}
Esempio n. 3
0
static void
back_to_front_copy( CoreSurface             *surface,
                    DFBSurfaceStereoEye      eye,
                    const DFBRegion         *region,
                    DFBSurfaceBlittingFlags  flags,
                    int                      rotation)
{
     DFBRectangle  rect;
     DFBPoint      point;
     StateClient  *client = state_client_tls.Get();


     if (region) {
          rect.x = region->x1;
          rect.y = region->y1;
          rect.w = region->x2 - region->x1 + 1;
          rect.h = region->y2 - region->y1 + 1;
     }
     else {
          rect.x = 0;
          rect.y = 0;
          rect.w = surface->config.size.w;
          rect.h = surface->config.size.h;
     }

     point.x = rect.x;
     point.y = rect.y;

     if (rotation == 90) {
          point.x = rect.y;
          point.y = surface->config.size.w - rect.w - rect.x;

          D_FLAGS_SET( flags, DSBLIT_ROTATE90 );
     }
     else if (rotation == 180) {
          point.x = surface->config.size.w - rect.w - rect.x;
          point.y = surface->config.size.h - rect.h - rect.y;

          D_FLAGS_SET( flags, DSBLIT_ROTATE180 );
     }
     else if (rotation == 270) {
          point.x = surface->config.size.h - rect.h - rect.y;
          point.y = rect.x;

          D_FLAGS_SET( flags, DSBLIT_ROTATE270 );
     }

     D_FLAGS_SET( client->state.modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO );

     client->state.clip.x2       = surface->config.size.w - 1;
     client->state.clip.y2       = surface->config.size.h - 1;
     client->state.source        = surface;
     client->state.destination   = surface;
     client->state.from          = CSBR_BACK;
     client->state.from_eye      = eye;
     client->state.to            = CSBR_FRONT;
     client->state.to_eye        = eye;
     client->state.blittingflags = flags;

     CoreGraphicsStateClient_Blit( &client->client, &rect, &point, 1 );

     CoreGraphicsStateClient_Flush( &client->client, 0, CGSCFF_FOLLOW_READER );

     /* Signal end of sequence. */
     dfb_state_stop_drawing( &client->state );

     client->state.destination = NULL;
     client->state.source      = NULL;
}
Esempio n. 4
0
void
dfb_gfx_copy_regions_client( CoreSurface             *source,
                             CoreSurfaceBufferRole    from,
                             DFBSurfaceStereoEye      source_eye,
                             CoreSurface             *destination,
                             CoreSurfaceBufferRole    to,
                             DFBSurfaceStereoEye      destination_eye,
                             const DFBRegion         *regions,
                             unsigned int             num,
                             int                      x,
                             int                      y,
                             CoreGraphicsStateClient *_client )
{
     unsigned int             i, n = 0;
     DFBRectangle             rect = { 0, 0, source->config.size.w, source->config.size.h };
     DFBRectangle             rects[num];
     DFBPoint                 points[num];
     CoreGraphicsStateClient *client = _client ? _client : &state_client_tls.Get()->client;
     CardState               *state  = client->state;
     CardState                backup;

     for (i=0; i<num; i++) {
          DFB_REGION_ASSERT( &regions[i] );

          rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( &regions[i] );

          if (dfb_rectangle_intersect( &rects[n], &rect )) {
               points[n].x = x + rects[n].x;
               points[n].y = y + rects[n].y;

               n++;
          }
     }

     if (n > 0) {
          backup.clip          = state->clip;
          backup.source        = state->source;
          backup.destination   = state->destination;
          backup.from          = state->from;
          backup.from_eye      = state->from_eye;
          backup.to            = state->to;
          backup.to_eye        = state->to_eye;
          backup.blittingflags = state->blittingflags;


          D_FLAGS_SET( state->modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO | SMF_BLITTING_FLAGS );

          state->clip.x1     = 0;
          state->clip.y1     = 0;
          state->clip.x2     = destination->config.size.w - 1;
          state->clip.y2     = destination->config.size.h - 1;
          state->source      = source;
          state->destination = destination;
          state->from        = from;
          state->from_eye    = source_eye;
          state->to          = to;
          state->to_eye      = destination_eye;
          state->blittingflags = DSBLIT_NOFX;

          CoreGraphicsStateClient_Blit( client, rects, points, n );

          if (!_client)
               CoreGraphicsStateClient_Flush( client, 0, CGSCFF_NONE );

          D_FLAGS_SET( state->modified, SMF_CLIP | SMF_SOURCE | SMF_DESTINATION | SMF_FROM | SMF_TO | SMF_BLITTING_FLAGS );

          state->clip          = backup.clip;
          state->source        = backup.source;
          state->destination   = backup.destination;
          state->from          = backup.from;
          state->from_eye      = backup.from_eye;
          state->to            = backup.to;
          state->to_eye        = backup.to_eye;
          state->blittingflags = backup.blittingflags;
     }
}
Esempio n. 5
0
void sawman_draw_cursor    ( CoreWindowStack *stack,
                             CardState       *state,
                             CoreSurface     *surface,
                             DFBRegion       *region,
                             int              x,
                             int              y )
{
     DFBRectangle            src;
     DFBRectangle            clip;
     DFBSurfaceBlittingFlags flags = DSBLIT_BLEND_ALPHACHANNEL;

     D_ASSERT( stack != NULL );
     D_MAGIC_ASSERT( state, CardState );
     DFB_REGION_ASSERT( region );

     D_ASSUME( stack->cursor.opacity > 0 );

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

     /* Initialize source rectangle. */
     src.x = region->x1 - x + stack->cursor.hot.x;
     src.y = region->y1 - y + stack->cursor.hot.y;
     src.w = region->x2 - region->x1 + 1;
     src.h = region->y2 - region->y1 + 1;

     D_DEBUG_AT( SaWMan_Draw, "  -> cursor surface %p\n", stack->cursor.surface );

     /* Initialize source clipping rectangle */
     clip.x = clip.y = 0;
     clip.w = stack->cursor.surface->config.size.w;
     clip.h = stack->cursor.surface->config.size.h;

     /* Intersect rectangles */
     if (!dfb_rectangle_intersect( &src, &clip ))
          return;

     /* Set destination. */
     if (surface) {
          state->destination  = surface;
          state->modified    |= SMF_DESTINATION;
     }

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

          if (stack->cursor.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 != stack->cursor.opacity) {
               state->color.a   = stack->cursor.opacity;
               state->modified |= SMF_COLOR;
          }
     }

     /* 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 (! (stack->cursor.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 (stack->cursor.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 );
          }
     }

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

     /* Set blitting source. */
     state->source    = stack->cursor.surface;
     state->from_eye  = DSSE_LEFT;
     state->modified |= SMF_SOURCE | SMF_FROM;

     /* Set clipping region. */
     dfb_state_set_clip( state, region );

     /* Blit from the window to the region being updated. */
     DFBPoint point = {
          region->x1, region->y1
     };
     D_DEBUG_AT( SaWMan_Draw, "  -> client %p\n", state->client );
     CoreGraphicsStateClient_Blit( state->client, &src, &point, 1 );

     /* Reset blitting source. */
     state->source    = NULL;
     state->modified |= SMF_SOURCE;

     /* Reset destination. */
     if (surface) {
          state->destination  = NULL;
          state->modified    |= SMF_DESTINATION;
     }
}