void dfb_gfx_copy_to( CoreSurface *source, CoreSurface *destination, const DFBRectangle *rect, int x, int y, bool from_back ) { DFBRectangle sourcerect = { 0, 0, source->config.size.w, source->config.size.h }; pthread_mutex_lock( ©_lock ); if (!copy_state_inited) { dfb_state_init( ©_state, NULL ); copy_state_inited = true; } copy_state.modified |= SMF_CLIP | SMF_SOURCE | SMF_DESTINATION; copy_state.clip.x2 = destination->config.size.w - 1; copy_state.clip.y2 = destination->config.size.h - 1; copy_state.source = source; copy_state.destination = destination; copy_state.from = from_back ? CSBR_BACK : CSBR_FRONT; copy_state.to = CSBR_BACK; if (rect) { if (dfb_rectangle_intersect( &sourcerect, rect )) dfb_gfxcard_blit( &sourcerect, x + sourcerect.x - rect->x, y + sourcerect.y - rect->y, ©_state ); } else dfb_gfxcard_blit( &sourcerect, x, y, ©_state ); /* Signal end of sequence. */ dfb_state_stop_drawing( ©_state ); pthread_mutex_unlock( ©_lock ); }
DFBResult IGraphicsState_Real__Blit( CoreGraphicsState *obj, const DFBRectangle *rects, const DFBPoint *points, u32 num ) { D_DEBUG_AT( DirectFB_CoreGraphicsState, "%s()\n", __FUNCTION__ ); D_ASSERT( rects != NULL ); D_ASSERT( points != NULL ); if (!obj->state.destination || !obj->state.source) return DFB_NOCONTEXT; if ((obj->state.blittingflags & (DSBLIT_SRC_MASK_ALPHA | DSBLIT_SRC_MASK_COLOR)) && !obj->state.source_mask) return DFB_NOCONTEXT; // FIXME: remove casts if (num > 1) dfb_gfxcard_batchblit( (DFBRectangle*) rects, (DFBPoint*) points, num, &obj->state ); else dfb_gfxcard_blit( (DFBRectangle*) rects, ((DFBPoint*)points)->x, ((DFBPoint*)points)->y, &obj->state ); return DFB_OK; }
DFBResult CoreGraphicsStateClient_Blit( CoreGraphicsStateClient *client, const DFBRectangle *rects, const DFBPoint *points, unsigned int num ) { D_DEBUG_AT( Core_GraphicsStateClient, "%s( client %p )\n", __FUNCTION__, client ); D_MAGIC_ASSERT( client, CoreGraphicsStateClient ); D_ASSERT( rects != NULL ); D_ASSERT( points != NULL ); if (dfb_core_is_master( client->core ) || !fusion_config->secure_fusion) { // FIXME: will overwrite rects, points if (num > 1) dfb_gfxcard_batchblit( (DFBRectangle*) rects, (DFBPoint*) points, num, client->state ); else dfb_gfxcard_blit( (DFBRectangle*) rects, ((DFBPoint*)points)->x, ((DFBPoint*)points)->y, client->state ); } else { DFBResult ret; CoreGraphicsStateClient_Update( client, DFXL_BLIT, client->state ); ret = CoreGraphicsState_Blit( client->gfx_state, rects, points, num ); if (ret) return ret; } return DFB_OK; }
static void foo_update( StretRegion *region, void *region_data, void *update_data, unsigned long arg, int x, int y, const DFBRegion *updates, int num ) { int i; DFBRegion clip; DFBDimension size; bool visible; WMShared *shared; UniqueContext *context; UniqueWindow *window = region_data; CardState *state = update_data; DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; D_ASSERT( region != NULL ); D_ASSERT( region_data != NULL ); D_ASSERT( update_data != NULL ); D_ASSERT( updates != NULL ); D_MAGIC_ASSERT( window, UniqueWindow ); D_MAGIC_ASSERT( state, CardState ); shared = window->shared; D_MAGIC_ASSERT( shared, WMShared ); D_ASSERT( shared->foo_surface != NULL ); context = window->context; D_MAGIC_ASSERT( context, UniqueContext ); visible = D_FLAGS_IS_SET( window->flags, UWF_VISIBLE ); D_DEBUG_AT( UniQuE_Foo, "foo_update( region %p, window %p, visible %s, num %d )\n", region, window, visible ? "yes" : "no", num ); #if D_DEBUG_ENABLED for (i=0; i<num; i++) { D_DEBUG_AT( UniQuE_Foo, " (%d) %4d,%4d - %4dx%4d\n", i, DFB_RECTANGLE_VALS_FROM_REGION( &updates[i] ) ); } #endif if (!visible) return; stret_region_get_size( region, &size ); /* Use per pixel alpha blending. */ flags |= DSBLIT_BLEND_ALPHACHANNEL; /* Use global alpha blending. */ if (window->opacity != 0xFF) { flags |= DSBLIT_BLEND_COLORALPHA; /* Set opacity as blending factor. */ if (state->color.a != window->opacity) { state->color.a = window->opacity; state->modified |= SMF_COLOR; } } /* Use colorizing if the color is not white. */ if (context->color.r != 0xff || context->color.g != 0xff || context->color.b != 0xff) { flags |= DSBLIT_COLORIZE; state->color.r = context->color.r; state->color.g = context->color.g; state->color.b = context->color.b; state->modified |= SMF_COLOR; } /* Set blitting flags. */ dfb_state_set_blitting_flags( state, flags ); /* Set blitting source. */ state->source = shared->foo_surface; state->modified |= SMF_SOURCE; switch (arg) { case UFI_N: case UFI_E: case UFI_S: case UFI_W: clip = state->clip; /* for (i=0; i<num; i++) { DFBRegion update = DFB_REGION_INIT_TRANSLATED( &updates[i], x, y ); DFBRectangle source = shared->foo_rects[arg]; DFBRectangle dest = { x, y, size.w, size.h }; dfb_state_set_clip( state, &update ); dfb_gfxcard_stretchblit( &source, &dest, state ); }*/ for (i=0; i<num; i++) { DFBRegion update = DFB_REGION_INIT_TRANSLATED( &updates[i], x, y ); DFBRectangle source = shared->foo_rects[arg]; dfb_state_set_clip( state, &update ); dfb_gfxcard_tileblit( &source, x, y, x + size.w - 1, y + size.h - 1, state ); } dfb_state_set_clip( state, &clip ); break; case UFI_NE: case UFI_SE: case UFI_SW: case UFI_NW: for (i=0; i<num; i++) { DFBRectangle rect = DFB_RECTANGLE_INIT_FROM_REGION( &updates[i] ); dfb_rectangle_translate( &rect, shared->foo_rects[arg].x, shared->foo_rects[arg].y ); dfb_gfxcard_blit( &rect, x + updates[i].x1, y + updates[i].y1, state ); } break; default: D_BUG( "invalid arg" ); } /* Reset blitting source. */ state->source = NULL; state->modified |= SMF_SOURCE; }
static void root_update( StretRegion *region, void *region_data, void *update_data, unsigned long arg, int x, int y, const DFBRegion *updates, int num ) { int i; CoreWindowStack *stack; UniqueContext *context = region_data; CardState *state = update_data; D_ASSERT( region != NULL ); D_ASSERT( region_data != NULL ); D_ASSERT( update_data != NULL ); D_ASSERT( updates != NULL ); D_ASSERT( x == 0 ); D_ASSERT( y == 0 ); D_MAGIC_ASSERT( context, UniqueContext ); D_MAGIC_ASSERT( state, CardState ); stack = context->stack; D_ASSERT( stack != NULL ); D_ASSERT( stack->bg.image != NULL || (stack->bg.mode != DLBM_IMAGE && stack->bg.mode != DLBM_TILE) ); D_DEBUG_AT( UniQuE_Root, "root_update( region %p, num %d )\n", region, num ); #if D_DEBUG_ENABLED for (i=0; i<num; i++) { D_DEBUG_AT( UniQuE_Root, " (%d) %4d,%4d - %4dx%4d\n", i, DFB_RECTANGLE_VALS_FROM_REGION( &updates[i] ) ); } #endif switch (stack->bg.mode) { case DLBM_COLOR: { CoreSurface *dest = state->destination; DFBColor *color = &stack->bg.color; DFBRectangle rects[num]; /* Set the background color. */ if (DFB_PIXELFORMAT_IS_INDEXED( dest->config.format )) dfb_state_set_color_index( state, dfb_palette_search( dest->palette, color->r, color->g, color->b, color->a ) ); else dfb_state_set_color( state, color ); for (i=0; i<num; i++) dfb_rectangle_from_region( &rects[i], &updates[i] ); /* Simply fill the background. */ dfb_gfxcard_fillrectangles( rects, num, state ); break; } case DLBM_IMAGE: { CoreSurface *bg = stack->bg.image; /* Set blitting source. */ state->source = bg; state->modified |= SMF_SOURCE; /* Set blitting flags. */ dfb_state_set_blitting_flags( state, DSBLIT_NOFX ); /* Check the size of the background image. */ if (bg->config.size.w == stack->width && bg->config.size.h == stack->height) { for (i=0; i<num; i++) { DFBRectangle dst = DFB_RECTANGLE_INIT_FROM_REGION( &updates[i] ); /* Simple blit for 100% fitting background image. */ dfb_gfxcard_blit( &dst, dst.x, dst.y, state ); } } else { DFBRegion clip = state->clip; for (i=0; i<num; i++) { DFBRectangle src = { 0, 0, bg->config.size.w, bg->config.size.h }; DFBRectangle dst = { 0, 0, stack->width, stack->height }; /* Change clipping region. */ dfb_state_set_clip( state, &updates[i] ); /* Stretch blit for non fitting background images. */ dfb_gfxcard_stretchblit( &src, &dst, state ); } /* Restore clipping region. */ dfb_state_set_clip( state, &clip ); } /* Reset blitting source. */ state->source = NULL; state->modified |= SMF_SOURCE; break; } case DLBM_TILE: { CoreSurface *bg = stack->bg.image; DFBRegion clip = state->clip; /* Set blitting source. */ state->source = bg; state->modified |= SMF_SOURCE; /* Set blitting flags. */ dfb_state_set_blitting_flags( state, DSBLIT_NOFX ); for (i=0; i<num; i++) { DFBRectangle src = { 0, 0, bg->config.size.w, bg->config.size.h }; /* Change clipping region. */ dfb_state_set_clip( state, &updates[i] ); /* Tiled blit (aligned). */ dfb_gfxcard_tileblit( &src, 0, 0, stack->width, stack->height, state ); } /* Restore clipping region. */ dfb_state_set_clip( state, &clip ); /* Reset blitting source. */ state->source = NULL; state->modified |= SMF_SOURCE; break; } case DLBM_DONTCARE: break; default: D_BUG( "unknown background mode" ); break; } }
static void back_to_front_copy( CoreSurface *surface, const DFBRegion *region, DFBSurfaceBlittingFlags flags, int rotation) { DFBRectangle rect; int dx, dy; 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; } dx = rect.x; dy = rect.y; pthread_mutex_lock( &btf_lock ); if (!btf_state_inited) { dfb_state_init( &btf_state, NULL ); btf_state.from = CSBR_BACK; btf_state.to = CSBR_FRONT; btf_state_inited = true; } btf_state.modified |= SMF_CLIP | SMF_SOURCE | SMF_DESTINATION; btf_state.clip.x2 = surface->config.size.w - 1; btf_state.clip.y2 = surface->config.size.h - 1; btf_state.source = surface; btf_state.destination = surface; if (rotation == 90) { dx = rect.y; dy = surface->config.size.w - rect.w - rect.x; flags |= DSBLIT_ROTATE90; } else if (rotation == 180) { dx = surface->config.size.w - rect.w - rect.x; dy = surface->config.size.h - rect.h - rect.y; flags |= DSBLIT_ROTATE180; } else if (rotation == 270) { dx = surface->config.size.h - rect.h - rect.y; dy = rect.x; flags |= DSBLIT_ROTATE270; } dfb_state_set_blitting_flags( &btf_state, flags ); dfb_gfxcard_blit( &rect, dx, dy, &btf_state ); /* Signal end of sequence. */ dfb_state_stop_drawing( &btf_state ); pthread_mutex_unlock( &btf_lock ); }
static void window_update( StretRegion *region, void *region_data, void *update_data, unsigned long arg, int x, int y, const DFBRegion *updates, int num ) { int i; DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; UniqueWindow *window = region_data; CardState *state = update_data; bool alpha = arg; bool visible; D_ASSERT( updates != NULL ); D_MAGIC_ASSERT( region, StretRegion ); D_MAGIC_ASSERT( window, UniqueWindow ); D_MAGIC_ASSERT( state, CardState ); D_ASSERT( window->surface != NULL ); visible = D_FLAGS_IS_SET( window->flags, UWF_VISIBLE ); D_DEBUG_AT( UniQuE_Window, "window_update( region %p, window %p, visible %s, num %d )\n", region, window, visible ? "yes" : "no", num ); #if D_DEBUG_ENABLED for (i=0; i<num; i++) { D_DEBUG_AT( UniQuE_Window, " (%d) %4d,%4d - %4dx%4d\n", i, DFB_RECTANGLE_VALS_FROM_REGION( &updates[i] ) ); } #endif if (!visible) return; /* Use per pixel alpha blending. */ if (alpha && (window->options & DWOP_ALPHACHANNEL)) flags |= DSBLIT_BLEND_ALPHACHANNEL; /* Use global alpha blending. */ if (window->opacity != 0xFF) { flags |= DSBLIT_BLEND_COLORALPHA; /* Set opacity as blending factor. */ if (state->color.a != window->opacity) { state->color.a = window->opacity; state->modified |= SMF_COLOR; } } /* Use source color keying. */ if (window->options & DWOP_COLORKEYING) { flags |= DSBLIT_SRC_COLORKEY; /* Set window color key. */ dfb_state_set_src_colorkey( state, window->color_key ); } /* Use automatic deinterlacing. */ if (window->surface->config.caps & DSCAPS_INTERLACED) flags |= DSBLIT_DEINTERLACE; /* Set blitting flags. */ dfb_state_set_blitting_flags( state, flags ); /* Set blitting source. */ state->source = window->surface; state->modified |= SMF_SOURCE; for (i=0; i<num; i++) { DFBRectangle src = DFB_RECTANGLE_INIT_FROM_REGION( &updates[i] ); /* Blit from the window to the region being updated. */ dfb_gfxcard_blit( &src, x + src.x, y + src.y, state ); } /* Reset blitting source. */ state->source = NULL; state->modified |= SMF_SOURCE; }
static void update_region( CoreWindowStack *stack, CardState *state, int start, int x1, int y1, int x2, int y2 ) { int i = start; DFBRegion region = { x1, y1, x2, y2 }; /* check for empty region */ DFB_ASSERT (x1 <= x2 && y1 <= y2); while (i >= 0) { if (VISIBLE_WINDOW(stack->windows[i])) { int wx2 = stack->windows[i]->x + stack->windows[i]->width - 1; int wy2 = stack->windows[i]->y + stack->windows[i]->height - 1; if (dfb_region_intersect( ®ion, stack->windows[i]->x, stack->windows[i]->y, wx2, wy2 )) break; } i--; } if (i >= 0) { if (TRANSLUCENT_WINDOW(stack->windows[i])) update_region( stack, state, i-1, x1, y1, x2, y2 ); else { /* left */ if (region.x1 != x1) update_region( stack, state, i-1, x1, region.y1, region.x1-1, region.y2 ); /* upper */ if (region.y1 != y1) update_region( stack, state, i-1, x1, y1, x2, region.y1-1 ); /* right */ if (region.x2 != x2) update_region( stack, state, i-1, region.x2+1, region.y1, x2, region.y2 ); /* lower */ if (region.y2 != y2) update_region( stack, state, i-1, x1, region.y2+1, x2, y2 ); } { CoreWindow *window = stack->windows[i]; DFBSurfaceBlittingFlags flags = DSBLIT_NOFX; DFBRectangle srect = { region.x1 - window->x, region.y1 - window->y, region.x2 - region.x1 + 1, region.y2 - region.y1 + 1 }; if (window->options & DWOP_ALPHACHANNEL) flags |= DSBLIT_BLEND_ALPHACHANNEL; if (window->opacity != 0xFF) { flags |= DSBLIT_BLEND_COLORALPHA; if (state->color.a != window->opacity) { state->color.a = window->opacity; state->modified |= SMF_COLOR; } } if (window->options & DWOP_COLORKEYING) { flags |= DSBLIT_SRC_COLORKEY; if (state->src_colorkey != window->color_key) { state->src_colorkey = window->color_key; state->modified |= SMF_SRC_COLORKEY; } } if (state->blittingflags != flags) { state->blittingflags = flags; state->modified |= SMF_BLITTING_FLAGS; } state->source = window->surface; state->modified |= SMF_SOURCE; dfb_gfxcard_blit( &srect, region.x1, region.y1, state ); state->source = NULL; } } else { switch (stack->bg.mode) { case DLBM_COLOR: { DFBRectangle rect = { x1, y1, x2 - x1 + 1, y2 - y1 + 1 }; state->color = stack->bg.color; state->modified |= SMF_COLOR; dfb_gfxcard_fillrectangle( &rect, state ); break; } case DLBM_IMAGE: { DFBRectangle rect = { x1, y1, x2 - x1 + 1, y2 - y1 + 1 }; if (state->blittingflags != DSBLIT_NOFX) { state->blittingflags = DSBLIT_NOFX; state->modified |= SMF_BLITTING_FLAGS; } state->source = stack->bg.image; state->modified |= SMF_SOURCE; dfb_gfxcard_blit( &rect, x1, y1, state ); state->source = NULL; break; } case DLBM_TILE: { DFBRectangle rect = { 0, 0, stack->bg.image->width, stack->bg.image->height }; if (state->blittingflags != DSBLIT_NOFX) { state->blittingflags = DSBLIT_NOFX; state->modified |= SMF_BLITTING_FLAGS; } state->source = stack->bg.image; state->modified |= SMF_SOURCE; dfb_gfxcard_tileblit( &rect, (x1 / rect.w) * rect.w, (y1 / rect.h) * rect.h, (x2 / rect.w + 1) * rect.w, (y2 / rect.h + 1) * rect.h, state ); state->source = NULL; break; } default: ; } } }