cbgfx: Add blend functions to calculate transparency
Up until now we have no way of adding transparency into our firmware screens. Add set_blend() and clear_blend() functions to store alpha value and rgb values to calculate alpha blending in calculate_colors(). BUG=b:144969091,b:160839199 BRANCH=puff TEST=dut-control power_state:rec press ctrl-d Ensure background is dimmed when dialog pops up Change-Id: I95468f27836d34ab80392727d726a69c09dc168e Signed-off-by: Shelley Chen <shchen@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/43358 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Yu-Ping Wu <yupingso@google.com> Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
parent
df5571dc9d
commit
31a3788739
|
@ -61,6 +61,37 @@ static const struct vector vzero = {
|
||||||
.y = 0,
|
.y = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct blend_value {
|
||||||
|
uint8_t alpha;
|
||||||
|
struct rgb_color rgb;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct blend_value blend = {
|
||||||
|
.alpha = 0,
|
||||||
|
.rgb.red = 0,
|
||||||
|
.rgb.green = 0,
|
||||||
|
.rgb.blue = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
int set_blend(const struct rgb_color *rgb, uint8_t alpha)
|
||||||
|
{
|
||||||
|
if (rgb == NULL)
|
||||||
|
return CBGFX_ERROR_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
blend.alpha = alpha;
|
||||||
|
blend.rgb = *rgb;
|
||||||
|
|
||||||
|
return CBGFX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_blend(void)
|
||||||
|
{
|
||||||
|
blend.alpha = 0;
|
||||||
|
blend.rgb.red = 0;
|
||||||
|
blend.rgb.green = 0;
|
||||||
|
blend.rgb.blue = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void add_vectors(struct vector *out,
|
static void add_vectors(struct vector *out,
|
||||||
const struct vector *v1, const struct vector *v2)
|
const struct vector *v1, const struct vector *v2)
|
||||||
{
|
{
|
||||||
|
@ -135,15 +166,32 @@ static int within_box(const struct vector *v, const struct rect *bound)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function that applies color and opacity from blend struct
|
||||||
|
* into the color.
|
||||||
|
*/
|
||||||
|
static inline uint8_t apply_blend(uint8_t color, uint8_t blend_color)
|
||||||
|
{
|
||||||
|
if (blend.alpha == 0 || color == blend_color)
|
||||||
|
return color;
|
||||||
|
|
||||||
|
return (color * (256 - blend.alpha) +
|
||||||
|
blend_color * blend.alpha) / 256;
|
||||||
|
}
|
||||||
|
|
||||||
static inline uint32_t calculate_color(const struct rgb_color *rgb,
|
static inline uint32_t calculate_color(const struct rgb_color *rgb,
|
||||||
uint8_t invert)
|
uint8_t invert)
|
||||||
{
|
{
|
||||||
uint32_t color = 0;
|
uint32_t color = 0;
|
||||||
color |= (rgb->red >> (8 - fbinfo->red_mask_size))
|
|
||||||
|
color |= (apply_blend(rgb->red, blend.rgb.red)
|
||||||
|
>> (8 - fbinfo->red_mask_size))
|
||||||
<< fbinfo->red_mask_pos;
|
<< fbinfo->red_mask_pos;
|
||||||
color |= (rgb->green >> (8 - fbinfo->green_mask_size))
|
color |= (apply_blend(rgb->green, blend.rgb.green)
|
||||||
|
>> (8 - fbinfo->green_mask_size))
|
||||||
<< fbinfo->green_mask_pos;
|
<< fbinfo->green_mask_pos;
|
||||||
color |= (rgb->blue >> (8 - fbinfo->blue_mask_size))
|
color |= (apply_blend(rgb->blue, blend.rgb.blue)
|
||||||
|
>> (8 - fbinfo->blue_mask_size))
|
||||||
<< fbinfo->blue_mask_pos;
|
<< fbinfo->blue_mask_pos;
|
||||||
if (invert)
|
if (invert)
|
||||||
color ^= 0xffffffff;
|
color ^= 0xffffffff;
|
||||||
|
|
|
@ -210,3 +210,33 @@ int draw_bitmap_direct(const void *bitmap, size_t size,
|
||||||
* in the original size are returned.
|
* in the original size are returned.
|
||||||
*/
|
*/
|
||||||
int get_bitmap_dimension(const void *bitmap, size_t sz, struct scale *dim_rel);
|
int get_bitmap_dimension(const void *bitmap, size_t sz, struct scale *dim_rel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setup alpha and rgb values for alpha blending. When alpha is != 0,
|
||||||
|
* this enables a translucent layer of color (defined by rgb) to be
|
||||||
|
* blended at a given translucency (alpha) to all things drawn. Call
|
||||||
|
* clear_blend() to disable alpha blending.
|
||||||
|
*
|
||||||
|
* @param[in] rgb Color for transparency
|
||||||
|
* @param[in] alpha Opacity of color, from 0-255 where
|
||||||
|
* 0 = completely transparent (no blending)
|
||||||
|
* 255 = max alpha argument
|
||||||
|
*
|
||||||
|
* @return CBGFX_* error codes
|
||||||
|
*/
|
||||||
|
int set_blend(const struct rgb_color *rgb, uint8_t alpha);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear alpha and rgb values, thus disabling any alpha blending.
|
||||||
|
*
|
||||||
|
* @return CBGFX_* error codes
|
||||||
|
*/
|
||||||
|
void clear_blend(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For calculating Alpha value from % opacity
|
||||||
|
* For reference:
|
||||||
|
* 255 = max alpha argument
|
||||||
|
* 0 = min alpha argument, 0% opacity
|
||||||
|
*/
|
||||||
|
#define ALPHA(percentage) MIN(255, (256 * percentage / 100))
|
||||||
|
|
Loading…
Reference in New Issue