Skip to content

Commit

Permalink
LibWbe: Skip recording of empty painting commands
Browse files Browse the repository at this point in the history
- Less allocations
- Optimization pass that skips unnecessary sample/blit corner commands
  could be more effecient by ignoring corner radius clipping for empty
  painting commands
  • Loading branch information
kalenikaliaksandr committed May 24, 2024
1 parent f34117f commit 2921bba
Showing 1 changed file with 41 additions and 0 deletions.
41 changes: 41 additions & 0 deletions Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ void RecordingPainter::blit_corner_clipping(u32 id, Gfx::IntRect border_rect)

void RecordingPainter::fill_rect(Gfx::IntRect const& rect, Color color, Vector<Gfx::Path> const& clip_paths)
{
if (rect.is_empty())
return;
append(FillRect {
.rect = state().translation.map(rect),
.color = color,
Expand All @@ -47,6 +49,8 @@ void RecordingPainter::fill_path(FillPathUsingColorParams params)
{
auto aa_translation = state().translation.map(params.translation.value_or(Gfx::FloatPoint {}));
auto path_bounding_rect = params.path.bounding_box().translated(aa_translation).to_type<int>();
if (path_bounding_rect.is_empty())
return;
append(FillPathUsingColor {
.path_bounding_rect = path_bounding_rect,
.path = params.path,
Expand All @@ -60,6 +64,8 @@ void RecordingPainter::fill_path(FillPathUsingPaintStyleParams params)
{
auto aa_translation = state().translation.map(params.translation.value_or(Gfx::FloatPoint {}));
auto path_bounding_rect = params.path.bounding_box().translated(aa_translation).to_type<int>();
if (path_bounding_rect.is_empty())
return;
append(FillPathUsingPaintStyle {
.path_bounding_rect = path_bounding_rect,
.path = params.path,
Expand All @@ -76,6 +82,8 @@ void RecordingPainter::stroke_path(StrokePathUsingColorParams params)
auto path_bounding_rect = params.path.bounding_box().translated(aa_translation).to_type<int>();
// Increase path bounding box by `thickness` to account for stroke.
path_bounding_rect.inflate(params.thickness, params.thickness);
if (path_bounding_rect.is_empty())
return;
append(StrokePathUsingColor {
.path_bounding_rect = path_bounding_rect,
.path = params.path,
Expand All @@ -91,6 +99,8 @@ void RecordingPainter::stroke_path(StrokePathUsingPaintStyleParams params)
auto path_bounding_rect = params.path.bounding_box().translated(aa_translation).to_type<int>();
// Increase path bounding box by `thickness` to account for stroke.
path_bounding_rect.inflate(params.thickness, params.thickness);
if (path_bounding_rect.is_empty())
return;
append(StrokePathUsingPaintStyle {
.path_bounding_rect = path_bounding_rect,
.path = params.path,
Expand All @@ -103,6 +113,8 @@ void RecordingPainter::stroke_path(StrokePathUsingPaintStyleParams params)

void RecordingPainter::draw_ellipse(Gfx::IntRect const& a_rect, Color color, int thickness)
{
if (a_rect.is_empty())
return;
append(DrawEllipse {
.rect = state().translation.map(a_rect),
.color = color,
Expand All @@ -112,6 +124,8 @@ void RecordingPainter::draw_ellipse(Gfx::IntRect const& a_rect, Color color, int

void RecordingPainter::fill_ellipse(Gfx::IntRect const& a_rect, Color color)
{
if (a_rect.is_empty())
return;
append(FillEllipse {
.rect = state().translation.map(a_rect),
.color = color,
Expand All @@ -120,6 +134,8 @@ void RecordingPainter::fill_ellipse(Gfx::IntRect const& a_rect, Color color)

void RecordingPainter::fill_rect_with_linear_gradient(Gfx::IntRect const& gradient_rect, LinearGradientData const& data, Vector<Gfx::Path> const& clip_paths)
{
if (gradient_rect.is_empty())
return;
append(PaintLinearGradient {
.gradient_rect = state().translation.map(gradient_rect),
.linear_gradient_data = data,
Expand All @@ -128,6 +144,8 @@ void RecordingPainter::fill_rect_with_linear_gradient(Gfx::IntRect const& gradie

void RecordingPainter::fill_rect_with_conic_gradient(Gfx::IntRect const& rect, ConicGradientData const& data, Gfx::IntPoint const& position, Vector<Gfx::Path> const& clip_paths)
{
if (rect.is_empty())
return;
append(PaintConicGradient {
.rect = state().translation.map(rect),
.conic_gradient_data = data,
Expand All @@ -137,6 +155,8 @@ void RecordingPainter::fill_rect_with_conic_gradient(Gfx::IntRect const& rect, C

void RecordingPainter::fill_rect_with_radial_gradient(Gfx::IntRect const& rect, RadialGradientData const& data, Gfx::IntPoint center, Gfx::IntSize size, Vector<Gfx::Path> const& clip_paths)
{
if (rect.is_empty())
return;
append(PaintRadialGradient {
.rect = state().translation.map(rect),
.radial_gradient_data = data,
Expand All @@ -147,6 +167,8 @@ void RecordingPainter::fill_rect_with_radial_gradient(Gfx::IntRect const& rect,

void RecordingPainter::draw_rect(Gfx::IntRect const& rect, Color color, bool rough)
{
if (rect.is_empty())
return;
append(DrawRect {
.rect = state().translation.map(rect),
.color = color,
Expand All @@ -155,6 +177,8 @@ void RecordingPainter::draw_rect(Gfx::IntRect const& rect, Color color, bool rou

void RecordingPainter::draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode)
{
if (dst_rect.is_empty())
return;
append(DrawScaledBitmap {
.dst_rect = state().translation.map(dst_rect),
.bitmap = bitmap,
Expand All @@ -165,6 +189,8 @@ void RecordingPainter::draw_scaled_bitmap(Gfx::IntRect const& dst_rect, Gfx::Bit

void RecordingPainter::draw_scaled_immutable_bitmap(Gfx::IntRect const& dst_rect, Gfx::ImmutableBitmap const& bitmap, Gfx::IntRect const& src_rect, Gfx::Painter::ScalingMode scaling_mode, Vector<Gfx::Path> const& clip_paths)
{
if (dst_rect.is_empty())
return;
append(DrawScaledImmutableBitmap {
.dst_rect = state().translation.map(dst_rect),
.bitmap = bitmap,
Expand All @@ -188,6 +214,8 @@ void RecordingPainter::draw_line(Gfx::IntPoint from, Gfx::IntPoint to, Color col

void RecordingPainter::draw_text(Gfx::IntRect const& rect, String raw_text, Gfx::Font const& font, Gfx::TextAlignment alignment, Color color, Gfx::TextElision elision, Gfx::TextWrapping wrapping)
{
if (rect.is_empty())
return;
append(DrawText {
.rect = state().translation.map(rect),
.raw_text = move(raw_text),
Expand All @@ -201,6 +229,8 @@ void RecordingPainter::draw_text(Gfx::IntRect const& rect, String raw_text, Gfx:

void RecordingPainter::draw_signed_distance_field(Gfx::IntRect const& dst_rect, Color color, Gfx::GrayscaleBitmap const& sdf, float smoothing)
{
if (dst_rect.is_empty())
return;
append(DrawSignedDistanceField {
.rect = state().translation.map(dst_rect),
.color = color,
Expand All @@ -211,6 +241,8 @@ void RecordingPainter::draw_signed_distance_field(Gfx::IntRect const& dst_rect,

void RecordingPainter::draw_text_run(Gfx::IntPoint baseline_start, Gfx::GlyphRun const& glyph_run, Color color, Gfx::IntRect const& rect, double scale)
{
if (rect.is_empty())
return;
auto transformed_baseline_start = state().translation.map(baseline_start).to_type<float>();
append(DrawGlyphRun {
.glyph_run = glyph_run,
Expand Down Expand Up @@ -291,6 +323,8 @@ void RecordingPainter::pop_stacking_context()

void RecordingPainter::apply_backdrop_filter(Gfx::IntRect const& backdrop_region, BorderRadiiData const& border_radii_data, CSS::ResolvedBackdropFilter const& backdrop_filter)
{
if (backdrop_region.is_empty())
return;
append(ApplyBackdropFilter {
.backdrop_region = state().translation.map(backdrop_region),
.border_radii_data = border_radii_data,
Expand Down Expand Up @@ -327,6 +361,9 @@ void RecordingPainter::paint_text_shadow(int blur_radius, Gfx::IntRect bounding_

void RecordingPainter::fill_rect_with_rounded_corners(Gfx::IntRect const& rect, Color color, Gfx::AntiAliasingPainter::CornerRadius top_left_radius, Gfx::AntiAliasingPainter::CornerRadius top_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_right_radius, Gfx::AntiAliasingPainter::CornerRadius bottom_left_radius, Vector<Gfx::Path> const& clip_paths)
{
if (rect.is_empty())
return;

if (!top_left_radius && !top_right_radius && !bottom_right_radius && !bottom_left_radius) {
fill_rect(rect, color, clip_paths);
return;
Expand All @@ -345,11 +382,15 @@ void RecordingPainter::fill_rect_with_rounded_corners(Gfx::IntRect const& rect,

void RecordingPainter::fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int radius, Vector<Gfx::Path> const& clip_paths)
{
if (a_rect.is_empty())
return;
fill_rect_with_rounded_corners(a_rect, color, radius, radius, radius, radius, clip_paths);
}

void RecordingPainter::fill_rect_with_rounded_corners(Gfx::IntRect const& a_rect, Color color, int top_left_radius, int top_right_radius, int bottom_right_radius, int bottom_left_radius, Vector<Gfx::Path> const& clip_paths)
{
if (a_rect.is_empty())
return;
fill_rect_with_rounded_corners(a_rect, color,
{ top_left_radius, top_left_radius },
{ top_right_radius, top_right_radius },
Expand Down

0 comments on commit 2921bba

Please sign in to comment.