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

Commit

Permalink
[Impeller] DlCanvas implementation wrapping Aiks canvas (#44248)
Browse files Browse the repository at this point in the history
Fixes flutter/flutter#130141

The primary goal of this patch is to move dispatching of `dart:ui` `Canvas` commands to the UI thread.

Before this patch, the architecture is something like:

## UI Thread
- `dart:ui` talks to `DisplayListBuilder`, a `DlCanvas` implementation.
- `DisplayListBuilder` does some clip/bounds tracking and creates a `DisplayList` object that is held by `dart:ui`'s `Picture` objects.
- `DisplayList`s are added to `DisplayListLayer`s in `flow`. 

## Raster Thread
- `flow` flattens the various operations into a single `DisplayList` via another `DisplayListBuilder`.
- A `DlOpReceiver`implementation converts that `DisplayList` into an `Aiks` `Canvas`/`Picture`.

After this patch, the architecture instead looks like:

## UI Thread

- No change for Skia.
- If Impeller, use a new `DlCanvasImplementation` that talks to `Aiks`'s `Canvas`.
- If Impeller, `dart:ui` Picture's now hold an `Aiks` `Picture`, which get shared into `AiksLayer`s in `flow`.

## Raster thread

- No change for Skia, but some light refactoring for places that assumed a `DisplayListBuilder` where they really just needed a `DlCanvas`.
- The `Aiks` `Picture`s are combined using new API on `DlCanvas` and still backed by `Aiks`.

These changes show significant improvement on raster times on Android and only very small regressions on UI times in local testing, see https://gist.github.com/dnfield/26528090194c9f5abdbac13cdcbf4f79 for old gallery transition perf numbers.

Many of the other changes in this patch are related to the following:

- Making `DlRTree` usable for Impeller.
  - It would be nice to have a version of DlRTree that speaks `impeller::Rect`.
- Creating the requisite classes to support `EmbeddedViews` so that Desktop works.

This patch does not remove the `impeller::DlDispatcher`, which now would only be used in tests.
  • Loading branch information
dnfield authored Aug 4, 2023
1 parent 5e51aa9 commit 6e90446
Show file tree
Hide file tree
Showing 78 changed files with 2,512 additions and 403 deletions.
2 changes: 1 addition & 1 deletion ci/licenses_golden/excluded_files
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
../../../flutter/display_list/benchmarking/dl_complexity_unittests.cc
../../../flutter/display_list/display_list_unittests.cc
../../../flutter/display_list/dl_color_unittests.cc
../../../flutter/display_list/dl_op_spy_unittests.cc
../../../flutter/display_list/dl_paint_unittests.cc
../../../flutter/display_list/dl_vertices_unittests.cc
../../../flutter/display_list/effects/dl_color_filter_unittests.cc
Expand Down Expand Up @@ -215,7 +216,6 @@
../../../flutter/runtime/type_conversions_unittests.cc
../../../flutter/shell/common/animator_unittests.cc
../../../flutter/shell/common/context_options_unittests.cc
../../../flutter/shell/common/dl_op_spy_unittests.cc
../../../flutter/shell/common/engine_unittests.cc
../../../flutter/shell/common/fixtures
../../../flutter/shell/common/input_events_unittests.cc
Expand Down
16 changes: 12 additions & 4 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,8 @@ ORIGIN: ../../../flutter/display_list/dl_op_receiver.cc + ../../../flutter/LICEN
ORIGIN: ../../../flutter/display_list/dl_op_receiver.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/dl_op_records.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/dl_op_records.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/dl_op_spy.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/dl_op_spy.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/dl_paint.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/dl_paint.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/dl_sampling_options.h + ../../../flutter/LICENSE
Expand Down Expand Up @@ -787,6 +789,8 @@ ORIGIN: ../../../flutter/flow/instrumentation.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/flow/instrumentation.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/flow/layer_snapshot_store.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/flow/layer_snapshot_store.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/flow/layers/aiks_layer.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/flow/layers/aiks_layer.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/flow/layers/backdrop_filter_layer.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/flow/layers/backdrop_filter_layer.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/flow/layers/cacheable_layer.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -1153,6 +1157,8 @@ ORIGIN: ../../../flutter/impeller/core/texture_descriptor.cc + ../../../flutter/
ORIGIN: ../../../flutter/impeller/core/texture_descriptor.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/vertex_buffer.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/core/vertex_buffer.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/display_list/dl_aiks_canvas.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/display_list/dl_aiks_canvas.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/display_list/dl_dispatcher.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/display_list/dl_dispatcher.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/display_list/dl_image_impeller.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -2210,8 +2216,6 @@ ORIGIN: ../../../flutter/shell/common/display.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/display.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/display_manager.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/display_manager.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/dl_op_spy.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/dl_op_spy.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/engine.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/engine.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/common/pipeline.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -3441,6 +3445,8 @@ FILE: ../../../flutter/display_list/dl_op_receiver.cc
FILE: ../../../flutter/display_list/dl_op_receiver.h
FILE: ../../../flutter/display_list/dl_op_records.cc
FILE: ../../../flutter/display_list/dl_op_records.h
FILE: ../../../flutter/display_list/dl_op_spy.cc
FILE: ../../../flutter/display_list/dl_op_spy.h
FILE: ../../../flutter/display_list/dl_paint.cc
FILE: ../../../flutter/display_list/dl_paint.h
FILE: ../../../flutter/display_list/dl_sampling_options.h
Expand Down Expand Up @@ -3497,6 +3503,8 @@ FILE: ../../../flutter/flow/instrumentation.cc
FILE: ../../../flutter/flow/instrumentation.h
FILE: ../../../flutter/flow/layer_snapshot_store.cc
FILE: ../../../flutter/flow/layer_snapshot_store.h
FILE: ../../../flutter/flow/layers/aiks_layer.cc
FILE: ../../../flutter/flow/layers/aiks_layer.h
FILE: ../../../flutter/flow/layers/backdrop_filter_layer.cc
FILE: ../../../flutter/flow/layers/backdrop_filter_layer.h
FILE: ../../../flutter/flow/layers/cacheable_layer.cc
Expand Down Expand Up @@ -3863,6 +3871,8 @@ FILE: ../../../flutter/impeller/core/texture_descriptor.cc
FILE: ../../../flutter/impeller/core/texture_descriptor.h
FILE: ../../../flutter/impeller/core/vertex_buffer.cc
FILE: ../../../flutter/impeller/core/vertex_buffer.h
FILE: ../../../flutter/impeller/display_list/dl_aiks_canvas.cc
FILE: ../../../flutter/impeller/display_list/dl_aiks_canvas.h
FILE: ../../../flutter/impeller/display_list/dl_dispatcher.cc
FILE: ../../../flutter/impeller/display_list/dl_dispatcher.h
FILE: ../../../flutter/impeller/display_list/dl_image_impeller.cc
Expand Down Expand Up @@ -4925,8 +4935,6 @@ FILE: ../../../flutter/shell/common/display.cc
FILE: ../../../flutter/shell/common/display.h
FILE: ../../../flutter/shell/common/display_manager.cc
FILE: ../../../flutter/shell/common/display_manager.h
FILE: ../../../flutter/shell/common/dl_op_spy.cc
FILE: ../../../flutter/shell/common/dl_op_spy.h
FILE: ../../../flutter/shell/common/engine.cc
FILE: ../../../flutter/shell/common/engine.h
FILE: ../../../flutter/shell/common/pipeline.cc
Expand Down
3 changes: 3 additions & 0 deletions display_list/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ source_set("display_list") {
"dl_op_receiver.h",
"dl_op_records.cc",
"dl_op_records.h",
"dl_op_spy.cc",
"dl_op_spy.h",
"dl_paint.cc",
"dl_paint.h",
"dl_sampling_options.h",
Expand Down Expand Up @@ -107,6 +109,7 @@ if (enable_unittests) {
"benchmarking/dl_complexity_unittests.cc",
"display_list_unittests.cc",
"dl_color_unittests.cc",
"dl_op_spy_unittests.cc",
"dl_paint_unittests.cc",
"dl_vertices_unittests.cc",
"effects/dl_color_filter_unittests.cc",
Expand Down
2 changes: 1 addition & 1 deletion display_list/display_list.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ DisplayList::DisplayList(DisplayListStorage&& storage,
bool can_apply_group_opacity,
bool is_ui_thread_safe,
bool modifies_transparent_black,
sk_sp<const DlRTree> rtree)
std::shared_ptr<const DlRTree> rtree)
: storage_(std::move(storage)),
byte_count_(byte_count),
op_count_(op_count),
Expand Down
6 changes: 3 additions & 3 deletions display_list/display_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ class DisplayList : public SkRefCnt {
const SkRect& bounds() const { return bounds_; }

bool has_rtree() const { return rtree_ != nullptr; }
sk_sp<const DlRTree> rtree() const { return rtree_; }
std::shared_ptr<const DlRTree> rtree() const { return rtree_; }

bool Equals(const DisplayList* other) const;
bool Equals(const DisplayList& other) const { return Equals(&other); }
Expand Down Expand Up @@ -288,7 +288,7 @@ class DisplayList : public SkRefCnt {
bool can_apply_group_opacity,
bool is_ui_thread_safe,
bool modifies_transparent_black,
sk_sp<const DlRTree> rtree);
std::shared_ptr<const DlRTree> rtree);

static uint32_t next_unique_id();

Expand All @@ -308,7 +308,7 @@ class DisplayList : public SkRefCnt {
const bool is_ui_thread_safe_;
const bool modifies_transparent_black_;

const sk_sp<const DlRTree> rtree_;
const std::shared_ptr<const DlRTree> rtree_;

void Dispatch(DlOpReceiver& ctx,
uint8_t* ptr,
Expand Down
2 changes: 1 addition & 1 deletion display_list/display_list_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2130,7 +2130,7 @@ TEST_F(DisplayListTest, FlatDrawPointsProducesBounds) {
}
}

static void test_rtree(const sk_sp<const DlRTree>& rtree,
static void test_rtree(const std::shared_ptr<const DlRTree>& rtree,
const SkRect& query,
std::vector<SkRect> expected_rects,
const std::vector<int>& expected_indices) {
Expand Down
7 changes: 7 additions & 0 deletions display_list/dl_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1208,6 +1208,13 @@ void DisplayListBuilder::DrawAtlas(const sk_sp<DlImage>& atlas,
}
}

void DisplayListBuilder::DrawImpellerPicture(
const std::shared_ptr<const impeller::Picture>& picture,
SkScalar opacity) {
FML_LOG(ERROR) << "Cannot draw Impeller Picture in to a a display list.";
FML_DCHECK(false);
}

void DisplayListBuilder::DrawDisplayList(const sk_sp<DisplayList> display_list,
SkScalar opacity) {
if (!SkScalarIsFinite(opacity) || opacity <= SK_ScalarNearlyZero ||
Expand Down
8 changes: 7 additions & 1 deletion display_list/dl_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,12 @@ class DisplayListBuilder final : public virtual DlCanvas,
DlImageSampling sampling,
const SkRect* cullRect,
const DlPaint* paint = nullptr) override;

// |DlCanvas|
void DrawImpellerPicture(
const std::shared_ptr<const impeller::Picture>& picture,
SkScalar opacity = SK_Scalar1) override;

// |DlCanvas|
void DrawDisplayList(const sk_sp<DisplayList> display_list,
SkScalar opacity = SK_Scalar1) override;
Expand Down Expand Up @@ -701,7 +707,7 @@ class DisplayListBuilder final : public virtual DlCanvas,
return accumulator_->bounds();
}

sk_sp<DlRTree> rtree() {
std::shared_ptr<DlRTree> rtree() {
FML_DCHECK(layer_stack_.size() == 1);
if (is_unbounded()) {
FML_LOG(INFO) << "returning partial rtree for unbounded DisplayList";
Expand Down
14 changes: 13 additions & 1 deletion display_list/dl_canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkTextBlob.h"

namespace impeller {
struct Picture;
} // namespace impeller

namespace flutter {

// The primary class used to express rendering operations in the
Expand Down Expand Up @@ -59,7 +63,12 @@ class DlCanvas {
const DlImageFilter* backdrop = nullptr) = 0;
virtual void Restore() = 0;
virtual int GetSaveCount() const = 0;
virtual void RestoreToCount(int restore_count) = 0;
virtual void RestoreToCount(int restore_count) {
FML_DCHECK(restore_count <= GetSaveCount());
while (restore_count < GetSaveCount() && GetSaveCount() > 1) {
Restore();
}
}

virtual void Translate(SkScalar tx, SkScalar ty) = 0;
virtual void Scale(SkScalar sx, SkScalar sy) = 0;
Expand Down Expand Up @@ -199,6 +208,9 @@ class DlCanvas {
const DlPaint* paint = nullptr) = 0;
virtual void DrawDisplayList(const sk_sp<DisplayList> display_list,
SkScalar opacity = SK_Scalar1) = 0;
virtual void DrawImpellerPicture(
const std::shared_ptr<const impeller::Picture>& picture,
SkScalar opacity = SK_Scalar1) = 0;
virtual void DrawTextBlob(const sk_sp<SkTextBlob>& blob,
SkScalar x,
SkScalar y,
Expand Down
2 changes: 1 addition & 1 deletion shell/common/dl_op_spy.cc → display_list/dl_op_spy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/shell/common/dl_op_spy.h"
#include "flutter/display_list/dl_op_spy.h"

namespace flutter {

Expand Down
5 changes: 1 addition & 4 deletions shell/common/dl_op_spy.h → display_list/dl_op_spy.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_DISPLAY_LIST_DL_OP_SPY_H_
#define FLUTTER_DISPLAY_LIST_DL_OP_SPY_H_
#pragma once

#include "flutter/display_list/dl_op_receiver.h"
#include "flutter/display_list/utils/dl_receiver_utils.h"
Expand Down Expand Up @@ -105,5 +104,3 @@ class DlOpSpy final : public virtual DlOpReceiver,
};

} // namespace flutter

#endif // FLUTTER_DISPLAY_LIST_DL_OP_SPY_H_
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include "flutter/display_list/display_list.h"
#include "flutter/display_list/dl_builder.h"
#include "flutter/shell/common/dl_op_spy.h"
#include "flutter/display_list/dl_op_spy.h"
#include "flutter/testing/testing.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/skia/include/core/SkRSXform.h"
Expand Down
2 changes: 1 addition & 1 deletion display_list/geometry/dl_rtree.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ namespace flutter {
/// - Query for a set of non-overlapping rectangles that are joined
/// from the original rectangles that intersect a query rect
/// @see |searchAndConsolidateRects|
class DlRTree : public SkRefCnt {
class DlRTree {
private:
static constexpr int kMaxChildren = 11;

Expand Down
7 changes: 7 additions & 0 deletions display_list/skia/dl_sk_canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,13 @@ void DlSkCanvasAdapter::DrawAtlas(const sk_sp<DlImage>& atlas,
ToSk(sampling), cullRect, sk_paint());
}

void DlSkCanvasAdapter::DrawImpellerPicture(
const std::shared_ptr<const impeller::Picture>& picture,
SkScalar opacity) {
FML_LOG(ERROR) << "Cannot draw Impeller Picture in to a Skia canvas.";
FML_DCHECK(false);
}

void DlSkCanvasAdapter::DrawDisplayList(const sk_sp<DisplayList> display_list,
SkScalar opacity) {
const int restore_count = delegate_->getSaveCount();
Expand Down
3 changes: 3 additions & 0 deletions display_list/skia/dl_sk_canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ class DlSkCanvasAdapter final : public virtual DlCanvas {
DlImageSampling sampling,
const SkRect* cullRect,
const DlPaint* paint = nullptr) override;
void DrawImpellerPicture(
const std::shared_ptr<const impeller::Picture>& picture,
SkScalar opacity = SK_Scalar1) override;
void DrawDisplayList(const sk_sp<DisplayList> display_list,
SkScalar opacity = SK_Scalar1) override;
void DrawTextBlob(const sk_sp<SkTextBlob>& blob,
Expand Down
7 changes: 4 additions & 3 deletions display_list/utils/dl_bounds_accumulator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,11 @@ SkRect RTreeBoundsAccumulator::bounds() const {
return accumulator.bounds();
}

sk_sp<DlRTree> RTreeBoundsAccumulator::rtree() const {
std::shared_ptr<DlRTree> RTreeBoundsAccumulator::rtree() const {
FML_DCHECK(saved_offsets_.empty());
return sk_make_sp<DlRTree>(rects_.data(), rects_.size(), rect_indices_.data(),
[](int id) { return id >= 0; });
return std::make_shared<DlRTree>(rects_.data(), rects_.size(),
rect_indices_.data(),
[](int id) { return id >= 0; });
}

} // namespace flutter
6 changes: 3 additions & 3 deletions display_list/utils/dl_bounds_accumulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class BoundsAccumulator {

virtual SkRect bounds() const = 0;

virtual sk_sp<DlRTree> rtree() const = 0;
virtual std::shared_ptr<DlRTree> rtree() const = 0;

virtual BoundsAccumulatorType type() const = 0;
};
Expand Down Expand Up @@ -112,7 +112,7 @@ class RectBoundsAccumulator final : public virtual BoundsAccumulator {
return BoundsAccumulatorType::kRect;
}

sk_sp<DlRTree> rtree() const override { return nullptr; }
std::shared_ptr<DlRTree> rtree() const override { return nullptr; }

private:
class AccumulationRect {
Expand Down Expand Up @@ -151,7 +151,7 @@ class RTreeBoundsAccumulator final : public virtual BoundsAccumulator {

SkRect bounds() const override;

sk_sp<DlRTree> rtree() const override;
std::shared_ptr<DlRTree> rtree() const override;

BoundsAccumulatorType type() const override {
return BoundsAccumulatorType::kRTree;
Expand Down
2 changes: 2 additions & 0 deletions flow/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ source_set("flow") {
"instrumentation.h",
"layer_snapshot_store.cc",
"layer_snapshot_store.h",
"layers/aiks_layer.cc",
"layers/aiks_layer.h",
"layers/backdrop_filter_layer.cc",
"layers/backdrop_filter_layer.h",
"layers/cacheable_layer.cc",
Expand Down
Loading

0 comments on commit 6e90446

Please sign in to comment.