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; }
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( ®ions[i] ); rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( ®ions[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; } }
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; }
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( ®ions[i] ); rects[n] = DFB_RECTANGLE_INIT_FROM_REGION( ®ions[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; } }
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; } }