Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions flow/embedded_views.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,8 @@ void DisplayListEmbedderViewSlice::end_recording() {
builder_ = nullptr;
}

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

void DisplayListEmbedderViewSlice::render_into(DlCanvas* canvas) {
Expand Down
11 changes: 7 additions & 4 deletions flow/embedded_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,11 @@ class EmbedderViewSlice {
virtual ~EmbedderViewSlice() = default;
virtual DlCanvas* canvas() = 0;
virtual void end_recording() = 0;
virtual std::list<SkRect> searchNonOverlappingDrawnRects(
const SkRect& query) const = 0;
virtual const DlRegion& getRegion() const = 0;
DlRegion region(const SkRect& query) const {
return DlRegion::MakeIntersection(getRegion(), DlRegion(query.roundOut()));
}

virtual void render_into(DlCanvas* canvas) = 0;
};

Expand All @@ -350,8 +353,8 @@ class DisplayListEmbedderViewSlice : public EmbedderViewSlice {

DlCanvas* canvas() override;
void end_recording() override;
std::list<SkRect> searchNonOverlappingDrawnRects(
const SkRect& query) const override;
const DlRegion& getRegion() const override;

void render_into(DlCanvas* canvas) override;
void dispatch(DlOpReceiver& receiver);
bool is_empty();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,15 @@ void AndroidExternalViewEmbedder::SubmitFrame(
// The rect above the `current_view_rect`
SkRect partial_joined_rect = SkRect::MakeEmpty();
// Each rect corresponds to a native view that renders Flutter UI.
std::list<SkRect> intersection_rects =
slice->searchNonOverlappingDrawnRects(current_view_rect);
std::vector<SkIRect> intersection_rects =
slice->region(current_view_rect).getRects();

// Limit the number of native views, so it doesn't grow forever.
//
// In this case, the rects are merged into a single one that is the union
// of all the rects.
for (const SkRect& rect : intersection_rects) {
partial_joined_rect.join(rect);
for (const SkIRect& rect : intersection_rects) {
partial_joined_rect.join(SkRect::Make(rect));
}
// Get the intersection rect with the `current_view_rect`,
partial_joined_rect.intersect(current_view_rect);
Expand Down
22 changes: 8 additions & 14 deletions shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm
Original file line number Diff line number Diff line change
Expand Up @@ -705,8 +705,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
for (size_t j = i + 1; j > 0; j--) {
int64_t current_platform_view_id = composition_order_[j - 1];
SkRect platform_view_rect = GetPlatformViewRect(current_platform_view_id);
std::list<SkRect> intersection_rects =
slice->searchNonOverlappingDrawnRects(platform_view_rect);
std::vector<SkIRect> intersection_rects = slice->region(platform_view_rect).getRects();
auto allocation_size = intersection_rects.size();

// For testing purposes, the overlay id is used to find the overlay view.
Expand All @@ -719,27 +718,22 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
// TODO(egarciad): Consider making this configurable.
// https://github.com/flutter/flutter/issues/52510
if (allocation_size > kMaxLayerAllocations) {
SkRect joined_rect = SkRect::MakeEmpty();
for (const SkRect& rect : intersection_rects) {
SkIRect joined_rect = SkIRect::MakeEmpty();
for (const SkIRect& rect : intersection_rects) {
joined_rect.join(rect);
}
// Replace the rects in the intersection rects list for a single rect that is
// the union of all the rects in the list.
intersection_rects.clear();
intersection_rects.push_back(joined_rect);
}
for (SkRect& joined_rect : intersection_rects) {
for (SkIRect& joined_rect : intersection_rects) {
// Get the intersection rect between the current rect
// and the platform view rect.
joined_rect.intersect(platform_view_rect);
// Subpixels in the platform may not align with the canvas subpixels.
// To workaround it, round the floating point bounds and make the rect slightly larger.
// For example, {0.3, 0.5, 3.1, 4.7} becomes {0, 0, 4, 5}.
joined_rect.setLTRB(std::floor(joined_rect.left()), std::floor(joined_rect.top()),
std::ceil(joined_rect.right()), std::ceil(joined_rect.bottom()));
joined_rect.intersect(platform_view_rect.roundOut());
// Clip the background canvas, so it doesn't contain any of the pixels drawn
// on the overlay layer.
background_canvas->ClipRect(joined_rect, DlCanvas::ClipOp::kDifference);
background_canvas->ClipRect(SkRect::Make(joined_rect), DlCanvas::ClipOp::kDifference);
// Get a new host layer.
std::shared_ptr<FlutterPlatformViewLayer> layer =
GetLayer(gr_context, //
Expand Down Expand Up @@ -817,7 +811,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
GrDirectContext* gr_context,
const std::shared_ptr<IOSContext>& ios_context,
EmbedderViewSlice* slice,
SkRect rect,
SkIRect rect,
int64_t view_id,
int64_t overlay_id,
MTLPixelFormat pixel_format) {
Expand Down Expand Up @@ -852,7 +846,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect,
DlCanvas* overlay_canvas = frame->Canvas();
int restore_count = overlay_canvas->GetSaveCount();
overlay_canvas->Save();
overlay_canvas->ClipRect(rect);
overlay_canvas->ClipRect(SkRect::Make(rect));
overlay_canvas->Clear(DlColor::kTransparent());
slice->render_into(overlay_canvas);
overlay_canvas->RestoreToCount(restore_count);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ class FlutterPlatformViewsController {
std::shared_ptr<FlutterPlatformViewLayer> GetLayer(GrDirectContext* gr_context,
const std::shared_ptr<IOSContext>& ios_context,
EmbedderViewSlice* slice,
SkRect rect,
SkIRect rect,
int64_t view_id,
int64_t overlay_id,
MTLPixelFormat pixel_format);
Expand Down
14 changes: 8 additions & 6 deletions shell/platform/embedder/embedder_external_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ EmbedderExternalView::~EmbedderExternalView() = default;

EmbedderExternalView::RenderTargetDescriptor
EmbedderExternalView::CreateRenderTargetDescriptor() const {
return {view_identifier_, render_surface_size_};
return RenderTargetDescriptor(render_surface_size_);
}

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

std::list<SkRect> EmbedderExternalView::GetEngineRenderedContentsRegion(
const SkRect& query) const {
return slice_->searchNonOverlappingDrawnRects(query);
const DlRegion& EmbedderExternalView::GetDlRegion() const {
return slice_->getRegion();
}

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

bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) {
bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target,
bool clear_surface) {
TRACE_EVENT0("flutter", "EmbedderExternalView::Render");
TryEndRecording();
FML_DCHECK(HasEngineRenderedContents())
Expand Down Expand Up @@ -124,7 +124,9 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target) {
DlSkCanvasAdapter dl_canvas(canvas);
int restore_count = dl_canvas.GetSaveCount();
dl_canvas.SetTransform(surface_transformation_);
dl_canvas.Clear(DlColor::kTransparent());
if (clear_surface) {
dl_canvas.Clear(DlColor::kTransparent());
}
slice_->render_into(&dl_canvas);
dl_canvas.RestoreToCount(restore_count);
dl_canvas.Flush();
Expand Down
18 changes: 7 additions & 11 deletions shell/platform/embedder/embedder_external_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,28 +46,23 @@ class EmbedderExternalView {
};

struct RenderTargetDescriptor {
ViewIdentifier view_identifier;
SkISize surface_size;

RenderTargetDescriptor(ViewIdentifier p_view_identifier,
SkISize p_surface_size)
: view_identifier(p_view_identifier), surface_size(p_surface_size) {}
explicit RenderTargetDescriptor(const SkISize& p_surface_size)
: surface_size(p_surface_size) {}

struct Hash {
constexpr std::size_t operator()(
const RenderTargetDescriptor& desc) const {
return fml::HashCombine(desc.surface_size.width(),
desc.surface_size.height(),
ViewIdentifier::Hash{}(desc.view_identifier));
desc.surface_size.height());
}
};

struct Equal {
bool operator()(const RenderTargetDescriptor& lhs,
const RenderTargetDescriptor& rhs) const {
return lhs.surface_size == rhs.surface_size &&
ViewIdentifier::Equal{}(lhs.view_identifier,
rhs.view_identifier);
return lhs.surface_size == rhs.surface_size;
}
};
};
Expand Down Expand Up @@ -107,9 +102,10 @@ class EmbedderExternalView {

SkISize GetRenderSurfaceSize() const;

bool Render(const EmbedderRenderTarget& render_target);
bool Render(const EmbedderRenderTarget& render_target,
bool clear_surface = true);

std::list<SkRect> GetEngineRenderedContentsRegion(const SkRect& query) const;
const DlRegion& GetDlRegion() const;

private:
// End the recording of the slice.
Expand Down
Loading