DFBResult IGraphicsState_Real__SetColorKey( CoreGraphicsState *obj, const DFBColorKey *key ) { D_DEBUG_AT( DirectFB_CoreGraphicsState, "%s()\n", __FUNCTION__ ); D_ASSERT( key != NULL ); dfb_state_set_colorkey( &obj->state, key ); return DFB_OK; }
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 ); }