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

Commit 1fc99b2

Browse files
committed
Reduce number of platform view layers
1 parent 49665b8 commit 1fc99b2

File tree

10 files changed

+344
-216
lines changed

10 files changed

+344
-216
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
@@ -348,20 +348,23 @@ class EmbedderViewSlice {
348348
virtual ~EmbedderViewSlice() = default;
349349
virtual DlCanvas* canvas() = 0;
350350
virtual void end_recording() = 0;
351-
virtual std::list<SkRect> searchNonOverlappingDrawnRects(
352-
const SkRect& query) const = 0;
351+
virtual const DlRegion& getRegion() const = 0;
352+
DlRegion region(const SkRect& query) const {
353+
return DlRegion::MakeIntersection(getRegion(), DlRegion(query.roundOut()));
354+
}
355+
353356
virtual void render_into(DlCanvas* canvas) = 0;
354357
};
355358

356359
class DisplayListEmbedderViewSlice : public EmbedderViewSlice {
357360
public:
358-
DisplayListEmbedderViewSlice(SkRect view_bounds);
361+
explicit DisplayListEmbedderViewSlice(SkRect view_bounds);
359362
~DisplayListEmbedderViewSlice() override = default;
360363

361364
DlCanvas* canvas() override;
362365
void end_recording() override;
363-
std::list<SkRect> searchNonOverlappingDrawnRects(
364-
const SkRect& query) const override;
366+
const DlRegion& getRegion() const override;
367+
365368
void render_into(DlCanvas* canvas) override;
366369
void dispatch(DlOpReceiver& receiver);
367370
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
@@ -695,8 +695,8 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
695695
for (size_t j = i + 1; j > 0; j--) {
696696
int64_t current_platform_view_id = composition_order_[j - 1];
697697
SkRect platform_view_rect = GetPlatformViewRect(current_platform_view_id);
698-
std::list<SkRect> intersection_rects =
699-
slice->searchNonOverlappingDrawnRects(platform_view_rect);
698+
std::vector<SkIRect> intersection_rects =
699+
slice->region(platform_view_rect.roundOut()).getRects();
700700
auto allocation_size = intersection_rects.size();
701701

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