Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 1f2d059

Browse files
committed
Reduce number of platform view layers
1 parent 97292b1 commit 1f2d059

File tree

10 files changed

+316
-219
lines changed

10 files changed

+316
-219
lines changed

flow/embedded_views.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ void DisplayListEmbedderViewSlice::end_recording() {
2121
builder_ = nullptr;
2222
}
2323

24-
std::list<SkRect> DisplayListEmbedderViewSlice::searchNonOverlappingDrawnRects(
25-
const SkRect& query) const {
26-
return display_list_->rtree()->searchAndConsolidateRects(query);
24+
const DlRegion& DisplayListEmbedderViewSlice::getRegion() const {
25+
return display_list_->rtree()->region();
2726
}
2827

2928
void DisplayListEmbedderViewSlice::render_into(DlCanvas* canvas) {

flow/embedded_views.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -337,20 +337,23 @@ class EmbedderViewSlice {
337337
virtual ~EmbedderViewSlice() = default;
338338
virtual DlCanvas* canvas() = 0;
339339
virtual void end_recording() = 0;
340-
virtual std::list<SkRect> searchNonOverlappingDrawnRects(
341-
const SkRect& query) const = 0;
340+
virtual const DlRegion& getRegion() const = 0;
341+
DlRegion region(const SkRect& query) const {
342+
return DlRegion::MakeIntersection(getRegion(), DlRegion(query.roundOut()));
343+
}
344+
342345
virtual void render_into(DlCanvas* canvas) = 0;
343346
};
344347

345348
class DisplayListEmbedderViewSlice : public EmbedderViewSlice {
346349
public:
347-
DisplayListEmbedderViewSlice(SkRect view_bounds);
350+
explicit DisplayListEmbedderViewSlice(SkRect view_bounds);
348351
~DisplayListEmbedderViewSlice() override = default;
349352

350353
DlCanvas* canvas() override;
351354
void end_recording() override;
352-
std::list<SkRect> searchNonOverlappingDrawnRects(
353-
const SkRect& query) const override;
355+
const DlRegion& getRegion() const override;
356+
354357
void render_into(DlCanvas* canvas) override;
355358
void dispatch(DlOpReceiver& receiver);
356359
bool is_empty();

shell/platform/android/external_view_embedder/external_view_embedder.cc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,15 @@ void AndroidExternalViewEmbedder::SubmitFrame(
104104
// The rect above the `current_view_rect`
105105
SkRect partial_joined_rect = SkRect::MakeEmpty();
106106
// Each rect corresponds to a native view that renders Flutter UI.
107-
std::list<SkRect> intersection_rects =
108-
slice->searchNonOverlappingDrawnRects(current_view_rect);
107+
std::vector<SkIRect> intersection_rects =
108+
slice->region(current_view_rect).getRects();
109109

110110
// Limit the number of native views, so it doesn't grow forever.
111111
//
112112
// In this case, the rects are merged into a single one that is the union
113113
// of all the rects.
114-
for (const SkRect& rect : intersection_rects) {
115-
partial_joined_rect.join(rect);
114+
for (const SkIRect& rect : intersection_rects) {
115+
partial_joined_rect.join(SkRect::Make(rect));
116116
}
117117
// Get the intersection rect with the `current_view_rect`,
118118
partial_joined_rect.intersect(current_view_rect);

shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -694,8 +694,8 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
694694
for (size_t j = i + 1; j > 0; j--) {
695695
int64_t current_platform_view_id = composition_order_[j - 1];
696696
SkRect platform_view_rect = GetPlatformViewRect(current_platform_view_id);
697-
std::list<SkRect> intersection_rects =
698-
slice->searchNonOverlappingDrawnRects(platform_view_rect);
697+
std::vector<SkIRect> intersection_rects =
698+
slice->region(platform_view_rect.roundOut()).getRects();
699699
auto allocation_size = intersection_rects.size();
700700

701701
// For testing purposes, the overlay id is used to find the overlay view.
@@ -708,27 +708,22 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
708708
// TODO(egarciad): Consider making this configurable.
709709
// https://github.com/flutter/flutter/issues/52510
710710
if (allocation_size > kMaxLayerAllocations) {
711-
SkRect joined_rect = SkRect::MakeEmpty();
712-
for (const SkRect& rect : intersection_rects) {
711+
SkIRect joined_rect = SkRect::MakeEmpty();
712+
for (const SkIRect& rect : intersection_rects) {
713713
joined_rect.join(rect);
714714
}
715715
// Replace the rects in the intersection rects list for a single rect that is
716716
// the union of all the rects in the list.
717717
intersection_rects.clear();
718718
intersection_rects.push_back(joined_rect);
719719
}
720-
for (SkRect& joined_rect : intersection_rects) {
720+
for (SkIRect& joined_rect : intersection_rects) {
721721
// Get the intersection rect between the current rect
722722
// and the platform view rect.
723-
joined_rect.intersect(platform_view_rect);
724-
// Subpixels in the platform may not align with the canvas subpixels.
725-
// To workaround it, round the floating point bounds and make the rect slightly larger.
726-
// For example, {0.3, 0.5, 3.1, 4.7} becomes {0, 0, 4, 5}.
727-
joined_rect.setLTRB(std::floor(joined_rect.left()), std::floor(joined_rect.top()),
728-
std::ceil(joined_rect.right()), std::ceil(joined_rect.bottom()));
723+
joined_rect.intersect(platform_view_rect.roundOut());
729724
// Clip the background canvas, so it doesn't contain any of the pixels drawn
730725
// on the overlay layer.
731-
background_canvas->ClipRect(joined_rect, DlCanvas::ClipOp::kDifference);
726+
background_canvas->ClipRect(SkRect::Make(joined_rect), DlCanvas::ClipOp::kDifference);
732727
// Get a new host layer.
733728
std::shared_ptr<FlutterPlatformViewLayer> layer = GetLayer(gr_context, //
734729
ios_context, //

shell/platform/embedder/embedder_external_view.cc

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ EmbedderExternalView::~EmbedderExternalView() = default;
4343

4444
EmbedderExternalView::RenderTargetDescriptor
4545
EmbedderExternalView::CreateRenderTargetDescriptor() const {
46-
return {view_identifier_, render_surface_size_};
46+
return RenderTargetDescriptor(render_surface_size_);
4747
}
4848

4949
DlCanvas* EmbedderExternalView::GetCanvas() {
@@ -62,9 +62,8 @@ bool EmbedderExternalView::HasPlatformView() const {
6262
return view_identifier_.platform_view_id.has_value();
6363
}
6464

65-
std::list<SkRect> EmbedderExternalView::GetEngineRenderedContentsRegion(
66-
const SkRect& query) const {
67-
return slice_->searchNonOverlappingDrawnRects(query);
65+
const DlRegion& EmbedderExternalView::GetDlRegion() const {
66+
return slice_->getRegion();
6867
}
6968

7069
bool EmbedderExternalView::HasEngineRenderedContents() {
@@ -87,7 +86,8 @@ const EmbeddedViewParams* EmbedderExternalView::GetEmbeddedViewParams() const {
8786
return embedded_view_params_.get();
8887
}
8988

90-
bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) {
89+
bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target,
90+
bool clear_surface) {
9191
TRACE_EVENT0("flutter", "EmbedderExternalView::Render");
9292
TryEndRecording();
9393
FML_DCHECK(HasEngineRenderedContents())
@@ -124,7 +124,9 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) {
124124
DlSkCanvasAdapter dl_canvas(canvas);
125125
int restore_count = dl_canvas.GetSaveCount();
126126
dl_canvas.SetTransform(surface_transformation_);
127-
dl_canvas.Clear(DlColor::kTransparent());
127+
if (clear_surface) {
128+
dl_canvas.Clear(DlColor::kTransparent());
129+
}
128130
slice_->render_into(&dl_canvas);
129131
dl_canvas.RestoreToCount(restore_count);
130132
dl_canvas.Flush();

shell/platform/embedder/embedder_external_view.h

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -46,28 +46,23 @@ class EmbedderExternalView {
4646
};
4747

4848
struct RenderTargetDescriptor {
49-
ViewIdentifier view_identifier;
5049
SkISize surface_size;
5150

52-
RenderTargetDescriptor(ViewIdentifier p_view_identifier,
53-
SkISize p_surface_size)
54-
: view_identifier(p_view_identifier), surface_size(p_surface_size) {}
51+
explicit RenderTargetDescriptor(const SkISize& p_surface_size)
52+
: surface_size(p_surface_size) {}
5553

5654
struct Hash {
5755
constexpr std::size_t operator()(
5856
const RenderTargetDescriptor& desc) const {
5957
return fml::HashCombine(desc.surface_size.width(),
60-
desc.surface_size.height(),
61-
ViewIdentifier::Hash{}(desc.view_identifier));
58+
desc.surface_size.height());
6259
}
6360
};
6461

6562
struct Equal {
6663
bool operator()(const RenderTargetDescriptor& lhs,
6764
const RenderTargetDescriptor& rhs) const {
68-
return lhs.surface_size == rhs.surface_size &&
69-
ViewIdentifier::Equal{}(lhs.view_identifier,
70-
rhs.view_identifier);
65+
return lhs.surface_size == rhs.surface_size;
7166
}
7267
};
7368
};
@@ -107,9 +102,10 @@ class EmbedderExternalView {
107102

108103
SkISize GetRenderSurfaceSize() const;
109104

110-
bool Render(const EmbedderRenderTarget& render_target);
105+
bool Render(const EmbedderRenderTarget& render_target,
106+
bool clear_surface = true);
111107

112-
std::list<SkRect> GetEngineRenderedContentsRegion(const SkRect& query) const;
108+
const DlRegion& GetDlRegion() const;
113109

114110
private:
115111
// End the recording of the slice.

0 commit comments

Comments
 (0)