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
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ FILE: ../../../flutter/display_list/display_list_blend_mode.h
FILE: ../../../flutter/display_list/display_list_builder.cc
FILE: ../../../flutter/display_list/display_list_builder.h
FILE: ../../../flutter/display_list/display_list_builder_benchmarks.cc
FILE: ../../../flutter/display_list/display_list_builder_multiplexer.cc
FILE: ../../../flutter/display_list/display_list_builder_multiplexer.h
FILE: ../../../flutter/display_list/display_list_canvas_dispatcher.cc
FILE: ../../../flutter/display_list/display_list_canvas_dispatcher.h
FILE: ../../../flutter/display_list/display_list_canvas_recorder.cc
Expand Down
2 changes: 2 additions & 0 deletions display_list/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ source_set("display_list") {
"display_list_blend_mode.h",
"display_list_builder.cc",
"display_list_builder.h",
"display_list_builder_multiplexer.cc",
"display_list_builder_multiplexer.h",
"display_list_canvas_dispatcher.cc",
"display_list_canvas_dispatcher.h",
"display_list_canvas_recorder.cc",
Expand Down
28 changes: 28 additions & 0 deletions display_list/display_list_builder_multiplexer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/display_list/display_list_builder_multiplexer.h"

namespace flutter {

void DisplayListBuilderMultiplexer::addBuilder(DisplayListBuilder* builder) {
builders_.push_back(builder);
}

void DisplayListBuilderMultiplexer::saveLayer(
const SkRect* bounds,
const DlPaint* paint,
const DlImageFilter* backdrop_filter) {
for (auto* builder : builders_) {
builder->saveLayer(bounds, paint, backdrop_filter);
}
}

void DisplayListBuilderMultiplexer::restore() {
for (auto* builder : builders_) {
builder->restore();
}
}

} // namespace flutter
36 changes: 36 additions & 0 deletions display_list/display_list_builder_multiplexer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_DISPLAY_LIST_DISPLAY_LIST_BUILDER_MULTIPLEXER_H_
#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_BUILDER_MULTIPLEXER_H_

#include "flutter/display_list/display_list_builder.h"
#include "flutter/display_list/display_list_image_filter.h"
#include "flutter/display_list/display_list_paint.h"
#include "flutter/fml/macros.h"

namespace flutter {

/// A class that mutiplexes some of the DisplayListBuilder calls to multiple
/// other builders. For now it only implements saveLayer and restore as those
/// are needed to create a replacement for PaintContext::internal_nodes_canvas.
class DisplayListBuilderMultiplexer {
public:
DisplayListBuilderMultiplexer() = default;

void addBuilder(DisplayListBuilder* builder);

void saveLayer(const SkRect* bounds,
const DlPaint* paint,
const DlImageFilter* backdrop_filter = nullptr);

void restore();

private:
std::vector<DisplayListBuilder*> builders_;
};

} // namespace flutter

#endif // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_BUILDER_MULTIPLEXER_H_
2 changes: 2 additions & 0 deletions flow/embedded_views.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <vector>

#include "flutter/display_list/display_list_builder.h"
#include "flutter/flow/rtree.h"
#include "flutter/flow/surface_frame.h"
#include "flutter/fml/memory/ref_counted.h"
Expand Down Expand Up @@ -393,6 +394,7 @@ class ExternalViewEmbedder {
}

virtual std::vector<SkCanvas*> GetCurrentCanvases() = 0;
virtual std::vector<DisplayListBuilder*> GetCurrentBuilders() = 0;

// Must be called on the UI thread.
virtual EmbedderPaintContext CompositeEmbeddedView(int view_id) = 0;
Expand Down
4 changes: 4 additions & 0 deletions flow/layers/backdrop_filter_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ void BackdropFilterLayer::Paint(PaintContext& context) const {
AutoCachePaint save_paint(context);
save_paint.setBlendMode(blend_mode_);
if (context.leaf_nodes_builder) {
// Note that we perform a saveLayer directly on the
// leaf_nodes_builder here similar to how the SkCanvas
// path specifies the kLeafNodesCanvas below.
// See https:://flutter.dev/go/backdrop-filter-with-overlay-canvas
context.leaf_nodes_builder->saveLayer(&paint_bounds(),
save_paint.dl_paint(), filter_.get());

Expand Down
7 changes: 4 additions & 3 deletions flow/layers/color_filter_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,11 @@ void ColorFilterLayer::Paint(PaintContext& context) const {
AutoCachePaint cache_paint(context);
cache_paint.setColorFilter(filter_.get());
if (context.leaf_nodes_builder) {
context.leaf_nodes_builder->saveLayer(&paint_bounds(),
cache_paint.dl_paint());
FML_DCHECK(context.builder_multiplexer);
context.builder_multiplexer->saveLayer(&paint_bounds(),
cache_paint.dl_paint());
PaintChildren(context);
context.leaf_nodes_builder->restore();
context.builder_multiplexer->restore();
} else {
Layer::AutoSaveLayer save = Layer::AutoSaveLayer::Create(
context, paint_bounds(), cache_paint.sk_paint());
Expand Down
4 changes: 4 additions & 0 deletions flow/layers/layer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <vector>

#include "flutter/common/graphics/texture.h"
#include "flutter/display_list/display_list_builder_multiplexer.h"
#include "flutter/flow/diff_context.h"
#include "flutter/flow/embedded_views.h"
#include "flutter/flow/instrumentation.h"
Expand All @@ -29,7 +30,9 @@
#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/utils/SkNWayCanvas.h"

namespace flutter {

namespace testing {
class MockLayer;
} // namespace testing
Expand Down Expand Up @@ -150,6 +153,7 @@ struct PaintContext {
// a |kSrcOver| blend mode.
SkScalar inherited_opacity = SK_Scalar1;
DisplayListBuilder* leaf_nodes_builder = nullptr;
DisplayListBuilderMultiplexer* builder_multiplexer = nullptr;
};

// Represents a single composited layer. Created on the UI thread but then
Expand Down
16 changes: 15 additions & 1 deletion flow/layers/layer_tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame,
internal_nodes_canvas.addCanvas(overlay_canvases[i]);
}
}
DisplayListBuilder* builder = frame.display_list_builder();
DisplayListBuilderMultiplexer builder_multiplexer;
if (builder) {
builder_multiplexer.addBuilder(builder);
if (frame.view_embedder()) {
for (auto* view_builder : frame.view_embedder()->GetCurrentBuilders()) {
builder_multiplexer.addBuilder(view_builder);
}
}
}

// clear the previous snapshots.
LayerSnapshotStore* snapshot_store = nullptr;
Expand Down Expand Up @@ -146,7 +156,8 @@ void LayerTree::Paint(CompositorContext::ScopedFrame& frame,
.layer_snapshot_store = snapshot_store,
.enable_leaf_layer_tracing = enable_leaf_layer_tracing_,
.inherited_opacity = SK_Scalar1,
.leaf_nodes_builder = frame.display_list_builder(),
.leaf_nodes_builder = builder,
.builder_multiplexer = builder ? &builder_multiplexer : nullptr,
// clang-format on
};

Expand Down Expand Up @@ -191,6 +202,8 @@ sk_sp<DisplayList> LayerTree::Flatten(const SkRect& bounds) {
SkISize canvas_size = builder.getBaseLayerSize();
SkNWayCanvas internal_nodes_canvas(canvas_size.width(), canvas_size.height());
internal_nodes_canvas.addCanvas(&builder);
DisplayListBuilderMultiplexer multiplexer;
multiplexer.addBuilder(builder.builder().get());

PaintContext paint_context = {
// clang-format off
Expand All @@ -208,6 +221,7 @@ sk_sp<DisplayList> LayerTree::Flatten(const SkRect& bounds) {
.layer_snapshot_store = nullptr,
.enable_leaf_layer_tracing = false,
.leaf_nodes_builder = builder.builder().get(),
.builder_multiplexer = &multiplexer,
// clang-format on
};

Expand Down
1 change: 1 addition & 0 deletions flow/layers/layer_tree_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ TEST_F(LayerTreeTest, PaintContextInitialization) {

EXPECT_EQ(context.inherited_opacity, SK_Scalar1);
EXPECT_EQ(context.leaf_nodes_builder, nullptr);
EXPECT_EQ(context.builder_multiplexer, nullptr);
};

// These 4 initializers are required because they are handled by reference
Expand Down
6 changes: 6 additions & 0 deletions flow/testing/layer_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <utility>
#include <vector>

#include "flutter/display_list/display_list_builder_multiplexer.h"
#include "flutter/flow/testing/mock_raster_cache.h"
#include "flutter/fml/macros.h"
#include "flutter/testing/canvas_test.h"
Expand Down Expand Up @@ -92,6 +93,7 @@ class LayerTestBase : public CanvasTestBase<BaseT> {
.checkerboard_offscreen_layers = false,
.frame_device_pixel_ratio = 1.0f,
.leaf_nodes_builder = display_list_recorder_.builder().get(),
.builder_multiplexer = &display_list_multiplexer_,
// clang-format on
},
check_board_context_{
Expand All @@ -109,6 +111,8 @@ class LayerTestBase : public CanvasTestBase<BaseT> {
// clang-format on
} {
internal_display_list_canvas_.addCanvas(&display_list_recorder_);
display_list_multiplexer_.addBuilder(
display_list_recorder_.builder().get());
use_null_raster_cache();
}

Expand Down Expand Up @@ -183,6 +187,7 @@ class LayerTestBase : public CanvasTestBase<BaseT> {
display_list_paint_context_.leaf_nodes_canvas = nullptr;
display_list_paint_context_.internal_nodes_canvas = nullptr;
display_list_paint_context_.leaf_nodes_builder = nullptr;
display_list_paint_context_.builder_multiplexer = nullptr;
}
return display_list_;
}
Expand Down Expand Up @@ -214,6 +219,7 @@ class LayerTestBase : public CanvasTestBase<BaseT> {
PrerollContext preroll_context_;
PaintContext paint_context_;
DisplayListCanvasRecorder display_list_recorder_;
DisplayListBuilderMultiplexer display_list_multiplexer_;
sk_sp<DisplayList> display_list_;
SkNWayCanvas internal_display_list_canvas_;
PaintContext display_list_paint_context_;
Expand Down
5 changes: 5 additions & 0 deletions flow/testing/mock_embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ std::vector<SkCanvas*> MockViewEmbedder::GetCurrentCanvases() {
return std::vector<SkCanvas*>({});
}

// |ExternalViewEmbedder|
std::vector<DisplayListBuilder*> MockViewEmbedder::GetCurrentBuilders() {
return std::vector<DisplayListBuilder*>({});
}

// |ExternalViewEmbedder|
EmbedderPaintContext MockViewEmbedder::CompositeEmbeddedView(int view_id) {
return {nullptr, nullptr};
Expand Down
3 changes: 3 additions & 0 deletions flow/testing/mock_embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ class MockViewEmbedder : public ExternalViewEmbedder {
// |ExternalViewEmbedder|
std::vector<SkCanvas*> GetCurrentCanvases() override;

// |ExternalViewEmbedder|
std::vector<DisplayListBuilder*> GetCurrentBuilders() override;

// |ExternalViewEmbedder|
EmbedderPaintContext CompositeEmbeddedView(int view_id) override;
};
Expand Down
1 change: 1 addition & 0 deletions shell/common/rasterizer_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class MockExternalViewEmbedder : public ExternalViewEmbedder {
PostPrerollResult(
fml::RefPtr<fml::RasterThreadMerger> raster_thread_merger));
MOCK_METHOD0(GetCurrentCanvases, std::vector<SkCanvas*>());
MOCK_METHOD0(GetCurrentBuilders, std::vector<DisplayListBuilder*>());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test failed in here:
note: unimplemented pure virtual method 'GetCurrentBuilders' in 'MockExternalViewEmbedder'

MOCK_METHOD1(CompositeEmbeddedView, EmbedderPaintContext(int view_id));
MOCK_METHOD2(SubmitFrame,
void(GrDirectContext* context,
Expand Down
6 changes: 6 additions & 0 deletions shell/common/shell_test_external_view_embedder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ std::vector<SkCanvas*> ShellTestExternalViewEmbedder::GetCurrentCanvases() {
return {};
}

// |ExternalViewEmbedder|
std::vector<DisplayListBuilder*>
ShellTestExternalViewEmbedder::GetCurrentBuilders() {
return {};
}

// |ExternalViewEmbedder|
void ShellTestExternalViewEmbedder::PushVisitedPlatformView(int64_t view_id) {
visited_platform_views_.push_back(view_id);
Expand Down
3 changes: 3 additions & 0 deletions shell/common/shell_test_external_view_embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder {
// |ExternalViewEmbedder|
std::vector<SkCanvas*> GetCurrentCanvases() override;

// |ExternalViewEmbedder|
std::vector<DisplayListBuilder*> GetCurrentBuilders() override;

// |ExternalViewEmbedder|
EmbedderPaintContext CompositeEmbeddedView(int view_id) override;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,19 @@ std::vector<SkCanvas*> AndroidExternalViewEmbedder::GetCurrentCanvases() {
return canvases;
}

// |ExternalViewEmbedder|
std::vector<DisplayListBuilder*>
AndroidExternalViewEmbedder::GetCurrentBuilders() {
std::vector<DisplayListBuilder*> builders;
for (size_t i = 0; i < composition_order_.size(); i++) {
int64_t view_id = composition_order_[i];
if (slices_.count(view_id) == 1) {
builders.push_back(slices_.at(view_id)->builder());
}
}
return builders;
}

SkRect AndroidExternalViewEmbedder::GetViewRect(int view_id) const {
const EmbeddedViewParams& params = view_params_.at(view_id);
// TODO(egarciad): The rect should be computed from the mutator stack.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder {
// |ExternalViewEmbedder|
std::vector<SkCanvas*> GetCurrentCanvases() override;

// |ExternalViewEmbedder|
// Similar call to GetCurrentCanvases but will return the array of
// builders being used by PlatformViews on platforms that provide
// optional DisplayListBuilder objects for rendering.
std::vector<DisplayListBuilder*> GetCurrentBuilders() override;

// |ExternalViewEmbedder|
void SubmitFrame(GrDirectContext* context,
std::unique_ptr<SurfaceFrame> frame) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,9 @@ TEST(AndroidExternalViewEmbedder, GetCurrentCanvases) {
ASSERT_EQ(2UL, canvases.size());
ASSERT_EQ(SkISize::Make(10, 20), canvases[0]->getBaseLayerSize());
ASSERT_EQ(SkISize::Make(10, 20), canvases[1]->getBaseLayerSize());

auto builders = embedder->GetCurrentBuilders();
ASSERT_EQ(2UL, builders.size());
}

TEST(AndroidExternalViewEmbedder, GetCurrentCanvasesCompositeOrder) {
Expand All @@ -149,6 +152,9 @@ TEST(AndroidExternalViewEmbedder, GetCurrentCanvasesCompositeOrder) {
ASSERT_EQ(2UL, canvases.size());
ASSERT_EQ(embedder->CompositeEmbeddedView(0).canvas, canvases[0]);
ASSERT_EQ(embedder->CompositeEmbeddedView(1).canvas, canvases[1]);

auto builders = embedder->GetCurrentBuilders();
ASSERT_EQ(2UL, builders.size());
}

TEST(AndroidExternalViewEmbedder, CompositeEmbeddedView) {
Expand Down Expand Up @@ -178,6 +184,9 @@ TEST(AndroidExternalViewEmbedder, CancelFrame) {

auto canvases = embedder->GetCurrentCanvases();
ASSERT_EQ(0UL, canvases.size());

auto builders = embedder->GetCurrentBuilders();
ASSERT_EQ(0UL, builders.size());
}

TEST(AndroidExternalViewEmbedder, RasterizerRunsOnPlatformThread) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,15 @@ - (BOOL)flt_hasFirstResponderInViewHierarchySubtree {
return canvases;
}

std::vector<DisplayListBuilder*> FlutterPlatformViewsController::GetCurrentBuilders() {
std::vector<DisplayListBuilder*> builders;
for (size_t i = 0; i < composition_order_.size(); i++) {
int64_t view_id = composition_order_[i];
builders.push_back(slices_[view_id]->builder());
}
return builders;
}

int FlutterPlatformViewsController::CountClips(const MutatorsStack& mutators_stack) {
std::vector<std::shared_ptr<Mutator>>::const_reverse_iterator iter = mutators_stack.Bottom();
int clipCount = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1076,16 +1076,19 @@ - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder {
flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams1));
flutterPlatformViewsController->CompositeEmbeddedView(0);
XCTAssertEqual(flutterPlatformViewsController->GetCurrentCanvases().size(), 1UL);
XCTAssertEqual(flutterPlatformViewsController->GetCurrentBuilders().size(), 1UL);

// Second frame, |GetCurrentCanvases| should be empty at the start
flutterPlatformViewsController->BeginFrame(SkISize::Make(300, 300));
XCTAssertTrue(flutterPlatformViewsController->GetCurrentCanvases().empty());
XCTAssertTrue(flutterPlatformViewsController->GetCurrentBuilders().empty());

auto embeddedViewParams2 =
std::make_unique<flutter::EmbeddedViewParams>(finalMatrix, SkSize::Make(300, 300), stack);
flutterPlatformViewsController->PrerollCompositeEmbeddedView(0, std::move(embeddedViewParams2));
flutterPlatformViewsController->CompositeEmbeddedView(0);
XCTAssertEqual(flutterPlatformViewsController->GetCurrentCanvases().size(), 1UL);
XCTAssertEqual(flutterPlatformViewsController->GetCurrentBuilders().size(), 1UL);
}

- (void)testThreadMergeAtEndFrame {
Expand Down
Loading