mirror of
https://gitlab.freedesktop.org/plymouth/plymouth.git
synced 2026-05-08 13:38:45 +02:00
pixel-buffer: Optimize filling with opaque buffers
If the source buffer is known to be fully opaque and the fill is done at full opacity, simply memcpy the data row-by-row instead of iterating over every pixel and blending it with the target buffer. This could be optimized more, in the future, in some cases, by memcpy of the entire block instead of row-by-row. https://bugs.freedesktop.org/show_bug.cgi?id=87105
This commit is contained in:
parent
00ee03695c
commit
61a26f4216
1 changed files with 49 additions and 20 deletions
|
|
@ -613,6 +613,50 @@ ply_pixel_buffer_fill_with_argb32_data_with_clip (ply_pixel_buffer_t *buffer,
|
|||
data, 1.0);
|
||||
}
|
||||
|
||||
static void
|
||||
ply_pixel_buffer_copy_area (ply_pixel_buffer_t *canvas,
|
||||
ply_pixel_buffer_t *source,
|
||||
int x, int y,
|
||||
ply_rectangle_t *cropped_area)
|
||||
{
|
||||
unsigned long row;
|
||||
|
||||
for (row = y; row < y + cropped_area->height; row++) {
|
||||
memcpy (canvas->bytes + (cropped_area->y + row - y) * canvas->area.width + cropped_area->x,
|
||||
source->bytes + (row * source->area.width) + x,
|
||||
cropped_area->width * 4);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ply_pixel_buffer_blend_area (ply_pixel_buffer_t *canvas,
|
||||
ply_pixel_buffer_t *source,
|
||||
int x, int y,
|
||||
ply_rectangle_t *cropped_area,
|
||||
double opacity)
|
||||
{
|
||||
unsigned long row, column;
|
||||
uint8_t opacity_as_byte = (uint8_t) (opacity * 255.0);
|
||||
|
||||
for (row = y; row < y + cropped_area->height; row++) {
|
||||
for (column = x; column < x + cropped_area->width; column++) {
|
||||
uint32_t pixel_value;
|
||||
|
||||
pixel_value = source->bytes[row * source->area.width + column];
|
||||
|
||||
pixel_value = make_pixel_value_translucent (pixel_value, opacity_as_byte);
|
||||
|
||||
if ((pixel_value >> 24) == 0x00)
|
||||
continue;
|
||||
|
||||
ply_pixel_buffer_blend_value_at_pixel (canvas,
|
||||
cropped_area->x + (column - x),
|
||||
cropped_area->y + (row - y),
|
||||
pixel_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ply_pixel_buffer_fill_with_buffer_at_opacity_with_clip (ply_pixel_buffer_t *canvas,
|
||||
ply_pixel_buffer_t *source,
|
||||
|
|
@ -621,8 +665,6 @@ ply_pixel_buffer_fill_with_buffer_at_opacity_with_clip (ply_pixel_buffer_t *canv
|
|||
ply_rectangle_t *clip_area,
|
||||
float opacity)
|
||||
{
|
||||
unsigned long row, column;
|
||||
uint8_t opacity_as_byte;
|
||||
ply_rectangle_t cropped_area;
|
||||
unsigned long x;
|
||||
unsigned long y;
|
||||
|
|
@ -645,25 +687,12 @@ ply_pixel_buffer_fill_with_buffer_at_opacity_with_clip (ply_pixel_buffer_t *canv
|
|||
|
||||
x = cropped_area.x - x_offset;
|
||||
y = cropped_area.y - y_offset;
|
||||
opacity_as_byte = (uint8_t) (opacity * 255.0);
|
||||
|
||||
for (row = y; row < y + cropped_area.height; row++) {
|
||||
for (column = x; column < x + cropped_area.width; column++) {
|
||||
uint32_t pixel_value;
|
||||
|
||||
pixel_value = source->bytes[row * source->area.width + column];
|
||||
|
||||
pixel_value = make_pixel_value_translucent (pixel_value, opacity_as_byte);
|
||||
|
||||
if ((pixel_value >> 24) == 0x00)
|
||||
continue;
|
||||
|
||||
ply_pixel_buffer_blend_value_at_pixel (canvas,
|
||||
cropped_area.x + (column - x),
|
||||
cropped_area.y + (row - y),
|
||||
pixel_value);
|
||||
}
|
||||
}
|
||||
if (opacity == 1.0 && ply_pixel_buffer_is_opaque (source))
|
||||
ply_pixel_buffer_copy_area (canvas, source, x, y, &cropped_area);
|
||||
else
|
||||
ply_pixel_buffer_blend_area (canvas, source, x, y, &cropped_area,
|
||||
opacity);
|
||||
|
||||
ply_region_add_rectangle (canvas->updated_areas, &cropped_area);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue