Skip to content

Commit b13ff8d

Browse files
kalenikaliaksandrawesomekling
authored andcommitted
LibWeb: Separate "out of view" check from RecordingPainter commands
1 parent 94f3228 commit b13ff8d

File tree

2 files changed

+69
-55
lines changed

2 files changed

+69
-55
lines changed

Userland/Libraries/LibWeb/Painting/RecordingPainter.cpp

Lines changed: 41 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,7 @@ struct CommandExecutionState {
3333

3434
CommandResult FillRectWithRoundedCorners::execute(CommandExecutionState& state) const
3535
{
36-
if (state.would_be_fully_clipped_by_painter(rect))
37-
return CommandResult::Continue;
38-
3936
auto& painter = state.painter();
40-
4137
Gfx::AntiAliasingPainter aa_painter(painter);
4238
if (aa_translation.has_value())
4339
aa_painter.translate(*aa_translation);
@@ -75,8 +71,6 @@ CommandResult DrawTextRun::execute(CommandExecutionState& state) const
7571

7672
CommandResult FillPathUsingColor::execute(CommandExecutionState& state) const
7773
{
78-
if (state.would_be_fully_clipped_by_painter(bounding_rect))
79-
return CommandResult::Continue;
8074
auto& painter = state.painter();
8175
Gfx::AntiAliasingPainter aa_painter(painter);
8276
if (aa_translation.has_value())
@@ -87,8 +81,6 @@ CommandResult FillPathUsingColor::execute(CommandExecutionState& state) const
8781

8882
CommandResult FillPathUsingPaintStyle::execute(CommandExecutionState& state) const
8983
{
90-
if (state.would_be_fully_clipped_by_painter(bounding_rect))
91-
return CommandResult::Continue;
9284
auto& painter = state.painter();
9385
Gfx::AntiAliasingPainter aa_painter(painter);
9486
if (aa_translation.has_value())
@@ -99,8 +91,6 @@ CommandResult FillPathUsingPaintStyle::execute(CommandExecutionState& state) con
9991

10092
CommandResult StrokePathUsingColor::execute(CommandExecutionState& state) const
10193
{
102-
if (state.would_be_fully_clipped_by_painter(bounding_rect))
103-
return CommandResult::Continue;
10494
auto& painter = state.painter();
10595
Gfx::AntiAliasingPainter aa_painter(painter);
10696
if (aa_translation.has_value())
@@ -111,8 +101,6 @@ CommandResult StrokePathUsingColor::execute(CommandExecutionState& state) const
111101

112102
CommandResult StrokePathUsingPaintStyle::execute(CommandExecutionState& state) const
113103
{
114-
if (state.would_be_fully_clipped_by_painter(bounding_rect))
115-
return CommandResult::Continue;
116104
auto& painter = state.painter();
117105
Gfx::AntiAliasingPainter aa_painter(painter);
118106
if (aa_translation.has_value())
@@ -123,17 +111,13 @@ CommandResult StrokePathUsingPaintStyle::execute(CommandExecutionState& state) c
123111

124112
CommandResult FillRect::execute(CommandExecutionState& state) const
125113
{
126-
if (state.would_be_fully_clipped_by_painter(rect))
127-
return CommandResult::Continue;
128114
auto& painter = state.painter();
129115
painter.fill_rect(rect, color);
130116
return CommandResult::Continue;
131117
}
132118

133119
CommandResult DrawScaledBitmap::execute(CommandExecutionState& state) const
134120
{
135-
if (state.would_be_fully_clipped_by_painter(dst_rect))
136-
return CommandResult::Continue;
137121
auto& painter = state.painter();
138122
painter.draw_scaled_bitmap(dst_rect, bitmap, src_rect, opacity, scaling_mode);
139123
return CommandResult::Continue;
@@ -290,8 +274,6 @@ CommandResult PopStackingContextWithMask::execute(CommandExecutionState& state)
290274

291275
CommandResult PaintLinearGradient::execute(CommandExecutionState& state) const
292276
{
293-
if (state.would_be_fully_clipped_by_painter(gradient_rect))
294-
return CommandResult::Continue;
295277
auto const& data = linear_gradient_data;
296278
state.painter().fill_rect_with_linear_gradient(
297279
gradient_rect, data.color_stops.list,
@@ -301,27 +283,25 @@ CommandResult PaintLinearGradient::execute(CommandExecutionState& state) const
301283

302284
CommandResult PaintRadialGradient::execute(CommandExecutionState& state) const
303285
{
304-
if (state.would_be_fully_clipped_by_painter(rect))
305-
return CommandResult::Continue;
306286
auto& painter = state.painter();
307287
painter.fill_rect_with_radial_gradient(rect, radial_gradient_data.color_stops.list, center, size, radial_gradient_data.color_stops.repeat_length);
308288
return CommandResult::Continue;
309289
}
310290

311291
CommandResult PaintConicGradient::execute(CommandExecutionState& state) const
312292
{
313-
if (state.would_be_fully_clipped_by_painter(rect))
314-
return CommandResult::Continue;
315293
auto& painter = state.painter();
316294
painter.fill_rect_with_conic_gradient(rect, conic_gradient_data.color_stops.list, position, conic_gradient_data.start_angle, conic_gradient_data.color_stops.repeat_length);
317295
return CommandResult::Continue;
318296
}
319297

298+
Gfx::IntRect PaintOuterBoxShadow::bounding_rect() const
299+
{
300+
return get_outer_box_shadow_bounding_rect(outer_box_shadow_params);
301+
}
302+
320303
CommandResult PaintOuterBoxShadow::execute(CommandExecutionState& state) const
321304
{
322-
auto bounding_rect = get_outer_box_shadow_bounding_rect(outer_box_shadow_params);
323-
if (state.would_be_fully_clipped_by_painter(bounding_rect))
324-
return CommandResult::Continue;
325305
auto& painter = state.painter();
326306
paint_outer_box_shadow(painter, outer_box_shadow_params);
327307
return CommandResult::Continue;
@@ -340,9 +320,9 @@ CommandResult PaintTextShadow::execute(CommandExecutionState& state) const
340320
return CommandResult::Continue;
341321

342322
// FIXME: Figure out the maximum bitmap size for all shadows and then allocate it once and reuse it?
343-
auto maybe_shadow_bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, bounding_rect.size());
323+
auto maybe_shadow_bitmap = Gfx::Bitmap::create(Gfx::BitmapFormat::BGRA8888, shadow_bounding_rect.size());
344324
if (maybe_shadow_bitmap.is_error()) {
345-
dbgln("Unable to allocate temporary bitmap {} for text-shadow rendering: {}", bounding_rect.size(), maybe_shadow_bitmap.error());
325+
dbgln("Unable to allocate temporary bitmap {} for text-shadow rendering: {}", shadow_bounding_rect.size(), maybe_shadow_bitmap.error());
346326
return CommandResult::Continue;
347327
}
348328
auto shadow_bitmap = maybe_shadow_bitmap.release_value();
@@ -357,14 +337,12 @@ CommandResult PaintTextShadow::execute(CommandExecutionState& state) const
357337
filter.process_rgba(blur_radius, color);
358338

359339
auto& painter = state.painter();
360-
painter.blit(draw_location, *shadow_bitmap, bounding_rect);
340+
painter.blit(draw_location, *shadow_bitmap, shadow_bounding_rect);
361341
return CommandResult::Continue;
362342
}
363343

364344
CommandResult DrawEllipse::execute(CommandExecutionState& state) const
365345
{
366-
if (state.would_be_fully_clipped_by_painter(rect))
367-
return CommandResult::Continue;
368346
auto& painter = state.painter();
369347
Gfx::AntiAliasingPainter aa_painter(painter);
370348
aa_painter.draw_ellipse(rect, color, thickness);
@@ -373,8 +351,6 @@ CommandResult DrawEllipse::execute(CommandExecutionState& state) const
373351

374352
CommandResult FillElipse::execute(CommandExecutionState& state) const
375353
{
376-
if (state.would_be_fully_clipped_by_painter(rect))
377-
return CommandResult::Continue;
378354
auto& painter = state.painter();
379355
Gfx::AntiAliasingPainter aa_painter(painter);
380356
aa_painter.fill_ellipse(rect, color, blend_mode);
@@ -394,8 +370,6 @@ CommandResult DrawLine::execute(CommandExecutionState& state) const
394370

395371
CommandResult DrawSignedDistanceField::execute(CommandExecutionState& state) const
396372
{
397-
if (state.would_be_fully_clipped_by_painter(rect))
398-
return CommandResult::Continue;
399373
auto& painter = state.painter();
400374
painter.draw_signed_distance_field(rect, color, sdf, smoothing);
401375
return CommandResult::Continue;
@@ -455,8 +429,6 @@ CommandResult ApplyBackdropFilter::execute(CommandExecutionState& state) const
455429

456430
CommandResult DrawRect::execute(CommandExecutionState& state) const
457431
{
458-
if (state.would_be_fully_clipped_by_painter(rect))
459-
return CommandResult::Continue;
460432
auto& painter = state.painter();
461433
painter.draw_rect(rect, color, rough);
462434
return CommandResult::Continue;
@@ -469,19 +441,25 @@ CommandResult DrawTriangleWave::execute(CommandExecutionState& state) const
469441
return CommandResult::Continue;
470442
}
471443

444+
Gfx::IntRect SampleUnderCorners::bounding_rect() const
445+
{
446+
return corner_clipper->border_rect().to_type<int>();
447+
}
448+
472449
CommandResult SampleUnderCorners::execute(CommandExecutionState& state) const
473450
{
474-
if (state.would_be_fully_clipped_by_painter(corner_clipper->border_rect().to_type<int>()))
475-
return CommandResult::Continue;
476451
auto& painter = state.painter();
477452
corner_clipper->sample_under_corners(painter);
478453
return CommandResult::Continue;
479454
}
480455

456+
Gfx::IntRect BlitCornerClipping::bounding_rect() const
457+
{
458+
return corner_clipper->border_rect().to_type<int>();
459+
}
460+
481461
CommandResult BlitCornerClipping::execute(CommandExecutionState& state) const
482462
{
483-
if (state.would_be_fully_clipped_by_painter(corner_clipper->border_rect().to_type<int>()))
484-
return CommandResult::Continue;
485463
auto& painter = state.painter();
486464
corner_clipper->blit_corner_clipping(painter);
487465
return CommandResult::Continue;
@@ -507,9 +485,9 @@ void RecordingPainter::fill_rect(Gfx::IntRect const& rect, Color color)
507485

508486
void RecordingPainter::fill_path(FillPathUsingColorParams params)
509487
{
510-
auto bounding_rect = params.path.bounding_box().translated(params.translation.value_or({})).to_type<int>();
488+
auto path_bounding_rect = params.path.bounding_box().translated(params.translation.value_or({})).to_type<int>();
511489
push_command(FillPathUsingColor {
512-
.bounding_rect = bounding_rect,
490+
.path_bounding_rect = path_bounding_rect,
513491
.path = params.path,
514492
.color = params.color,
515493
.winding_rule = params.winding_rule,
@@ -519,9 +497,9 @@ void RecordingPainter::fill_path(FillPathUsingColorParams params)
519497

520498
void RecordingPainter::fill_path(FillPathUsingPaintStyleParams params)
521499
{
522-
auto bounding_rect = params.path.bounding_box().translated(params.translation.value_or({})).to_type<int>();
500+
auto path_bounding_rect = params.path.bounding_box().translated(params.translation.value_or({})).to_type<int>();
523501
push_command(FillPathUsingPaintStyle {
524-
.bounding_rect = bounding_rect,
502+
.path_bounding_rect = path_bounding_rect,
525503
.path = params.path,
526504
.paint_style = params.paint_style,
527505
.winding_rule = params.winding_rule,
@@ -532,9 +510,9 @@ void RecordingPainter::fill_path(FillPathUsingPaintStyleParams params)
532510

533511
void RecordingPainter::stroke_path(StrokePathUsingColorParams params)
534512
{
535-
auto bounding_rect = params.path.bounding_box().translated(params.translation.value_or({})).to_type<int>();
513+
auto path_bounding_rect = params.path.bounding_box().translated(params.translation.value_or({})).to_type<int>();
536514
push_command(StrokePathUsingColor {
537-
.bounding_rect = bounding_rect,
515+
.path_bounding_rect = path_bounding_rect,
538516
.path = params.path,
539517
.color = params.color,
540518
.thickness = params.thickness,
@@ -544,9 +522,9 @@ void RecordingPainter::stroke_path(StrokePathUsingColorParams params)
544522

545523
void RecordingPainter::stroke_path(StrokePathUsingPaintStyleParams params)
546524
{
547-
auto bounding_rect = params.path.bounding_box().translated(params.translation.value_or({})).to_type<int>();
525+
auto path_bounding_rect = params.path.bounding_box().translated(params.translation.value_or({})).to_type<int>();
548526
push_command(StrokePathUsingPaintStyle {
549-
.bounding_rect = bounding_rect,
527+
.path_bounding_rect = path_bounding_rect,
550528
.path = params.path,
551529
.paint_style = params.paint_style,
552530
.thickness = params.thickness,
@@ -780,7 +758,7 @@ void RecordingPainter::paint_text_shadow(int blur_radius, Gfx::IntRect bounding_
780758
{
781759
push_command(PaintTextShadow {
782760
.blur_radius = blur_radius,
783-
.bounding_rect = bounding_rect,
761+
.shadow_bounding_rect = bounding_rect,
784762
.text_rect = text_rect,
785763
.text = String::from_utf8(text.as_string()).release_value_but_fixme_should_propagate_errors(),
786764
.font = font,
@@ -839,6 +817,17 @@ void RecordingPainter::draw_triangle_wave(Gfx::IntPoint a_p1, Gfx::IntPoint a_p2
839817
.thickness = thickness });
840818
}
841819

820+
static Optional<Gfx::IntRect> command_bounding_rectangle(PaintingCommand const& command)
821+
{
822+
return command.visit(
823+
[&](auto const& command) -> Optional<Gfx::IntRect> {
824+
if constexpr (requires { command.bounding_rect(); })
825+
return command.bounding_rect();
826+
else
827+
return {};
828+
});
829+
}
830+
842831
void RecordingPainter::execute(Gfx::Bitmap& bitmap)
843832
{
844833
CommandExecutionState state;
@@ -851,8 +840,10 @@ void RecordingPainter::execute(Gfx::Bitmap& bitmap)
851840
size_t next_command_index = 0;
852841
while (next_command_index < m_painting_commands.size()) {
853842
auto& command = m_painting_commands[next_command_index++];
843+
auto bounding_rect = command_bounding_rectangle(command);
844+
if (bounding_rect.has_value() && state.would_be_fully_clipped_by_painter(*bounding_rect))
845+
continue;
854846
auto result = command.visit([&](auto const& command) { return command.execute(state); });
855-
856847
if (result == CommandResult::SkipStackingContext) {
857848
auto stacking_context_nesting_level = 1;
858849
while (next_command_index < m_painting_commands.size()) {

0 commit comments

Comments
 (0)