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

Commit be430f9

Browse files
committed
focus SkiaGPUObject wrappers on only those objects that need the protection
1 parent eb3e7d5 commit be430f9

41 files changed

Lines changed: 252 additions & 167 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

display_list/display_list.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ DisplayList::DisplayList()
2121
nested_op_count_(0),
2222
unique_id_(0),
2323
bounds_({0, 0, 0, 0}),
24-
can_apply_group_opacity_(true) {}
24+
can_apply_group_opacity_(true),
25+
is_ui_thread_safe_(true) {}
2526

2627
DisplayList::DisplayList(DisplayListStorage&& storage,
2728
size_t byte_count,
@@ -30,6 +31,7 @@ DisplayList::DisplayList(DisplayListStorage&& storage,
3031
unsigned int nested_op_count,
3132
const SkRect& bounds,
3233
bool can_apply_group_opacity,
34+
bool is_ui_thread_safe,
3335
sk_sp<const DlRTree> rtree)
3436
: storage_(std::move(storage)),
3537
byte_count_(byte_count),
@@ -39,6 +41,7 @@ DisplayList::DisplayList(DisplayListStorage&& storage,
3941
unique_id_(next_unique_id()),
4042
bounds_(bounds),
4143
can_apply_group_opacity_(can_apply_group_opacity),
44+
is_ui_thread_safe_(is_ui_thread_safe),
4245
rtree_(std::move(rtree)) {}
4346

4447
DisplayList::~DisplayList() {

display_list/display_list.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ class DisplayList : public SkRefCnt {
262262
}
263263

264264
bool can_apply_group_opacity() const { return can_apply_group_opacity_; }
265+
bool isUIThreadSafe() const { return is_ui_thread_safe_; }
265266

266267
static void DisposeOps(uint8_t* ptr, uint8_t* end);
267268

@@ -273,6 +274,7 @@ class DisplayList : public SkRefCnt {
273274
unsigned int nested_op_count,
274275
const SkRect& bounds,
275276
bool can_apply_group_opacity,
277+
bool is_ui_thread_safe,
276278
sk_sp<const DlRTree> rtree);
277279

278280
static uint32_t next_unique_id();
@@ -288,6 +290,7 @@ class DisplayList : public SkRefCnt {
288290
const SkRect bounds_;
289291

290292
const bool can_apply_group_opacity_;
293+
const bool is_ui_thread_safe_;
291294
const sk_sp<const DlRTree> rtree_;
292295

293296
void Dispatch(DlOpReceiver& ctx,

display_list/dl_builder.cc

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,10 @@ sk_sp<DisplayList> DisplayListBuilder::Build() {
7373
nested_bytes_ = nested_op_count_ = 0;
7474
storage_.realloc(bytes);
7575
bool compatible = layer_stack_.back().is_group_opacity_compatible();
76-
return sk_sp<DisplayList>(new DisplayList(std::move(storage_), bytes, count,
77-
nested_bytes, nested_count,
78-
bounds(), compatible, rtree()));
76+
bool is_safe = is_ui_thread_safe_;
77+
return sk_sp<DisplayList>(
78+
new DisplayList(std::move(storage_), bytes, count, nested_bytes,
79+
nested_count, bounds(), compatible, is_safe, rtree()));
7980
}
8081

8182
DisplayListBuilder::DisplayListBuilder(const SkRect& cull_rect,
@@ -156,6 +157,7 @@ void DisplayListBuilder::onSetColorSource(const DlColorSource* source) {
156157
Push<ClearColorSourceOp>(0, 0);
157158
} else {
158159
current_.setColorSource(source->shared());
160+
is_ui_thread_safe_ = is_ui_thread_safe_ && source->isUIThreadSafe();
159161
switch (source->type()) {
160162
case DlColorSourceType::kColor: {
161163
const DlColorColorSource* color_source = source->asColor();
@@ -923,6 +925,7 @@ void DisplayListBuilder::drawImage(const sk_sp<DlImage> image,
923925
? Push<DrawImageWithAttrOp>(0, 1, image, point, sampling)
924926
: Push<DrawImageOp>(0, 1, image, point, sampling);
925927
CheckLayerOpacityCompatibility(render_with_attributes);
928+
is_ui_thread_safe_ = is_ui_thread_safe_ && image->isUIThreadSafe();
926929
SkRect bounds = SkRect::MakeXYWH(point.fX, point.fY, //
927930
image->width(), image->height());
928931
DisplayListAttributeFlags flags = render_with_attributes //
@@ -951,6 +954,7 @@ void DisplayListBuilder::drawImageRect(const sk_sp<DlImage> image,
951954
Push<DrawImageRectOp>(0, 1, image, src, dst, sampling, render_with_attributes,
952955
constraint);
953956
CheckLayerOpacityCompatibility(render_with_attributes);
957+
is_ui_thread_safe_ = is_ui_thread_safe_ && image->isUIThreadSafe();
954958
DisplayListAttributeFlags flags = render_with_attributes
955959
? kDrawImageRectWithPaintFlags
956960
: kDrawImageRectFlags;
@@ -979,6 +983,7 @@ void DisplayListBuilder::drawImageNine(const sk_sp<DlImage> image,
979983
? Push<DrawImageNineWithAttrOp>(0, 1, image, center, dst, filter)
980984
: Push<DrawImageNineOp>(0, 1, image, center, dst, filter);
981985
CheckLayerOpacityCompatibility(render_with_attributes);
986+
is_ui_thread_safe_ = is_ui_thread_safe_ && image->isUIThreadSafe();
982987
DisplayListAttributeFlags flags = render_with_attributes
983988
? kDrawImageNineWithPaintFlags
984989
: kDrawImageNineFlags;
@@ -1034,6 +1039,7 @@ void DisplayListBuilder::drawAtlas(const sk_sp<DlImage> atlas,
10341039
// on it to distribute the opacity without overlap without checking all
10351040
// of the transforms and texture rectangles.
10361041
UpdateLayerOpacityCompatibility(false);
1042+
is_ui_thread_safe_ = is_ui_thread_safe_ && atlas->isUIThreadSafe();
10371043

10381044
SkPoint quad[4];
10391045
RectBoundsAccumulator atlasBounds;
@@ -1075,6 +1081,7 @@ void DisplayListBuilder::DrawDisplayList(const sk_sp<DisplayList> display_list,
10751081
SkScalar opacity) {
10761082
DlPaint current_paint = current_;
10771083
Push<DrawDisplayListOp>(0, 1, display_list, opacity);
1084+
is_ui_thread_safe_ = is_ui_thread_safe_ && display_list->isUIThreadSafe();
10781085
// Not really necessary if the developer is interacting with us via
10791086
// our attribute-state-less DlCanvas methods, but this avoids surprises
10801087
// for those who may have been using the stateful Dispatcher methods.

display_list/dl_builder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,8 @@ class DisplayListBuilder final : public virtual DlCanvas,
480480
size_t nested_bytes_ = 0;
481481
int nested_op_count_ = 0;
482482

483+
bool is_ui_thread_safe_ = true;
484+
483485
template <typename T, typename... Args>
484486
void* Push(size_t extra, int op_inc, Args&&... args);
485487

display_list/effects/dl_color_source.h

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,16 @@ class DlColorSource : public DlAttribute<DlColorSource, DlColorSourceType> {
109109

110110
virtual bool is_opaque() const = 0;
111111

112+
//----------------------------------------------------------------------------
113+
/// @brief If the underlying platform data held by this object is
114+
/// held in a way that it can be stored and potentially
115+
/// released from the UI thread, this method returns true.
116+
///
117+
/// @return True if the class has no GPU related resources or if any
118+
/// that it holds are held in a thread-safe manner.
119+
///
120+
virtual bool isUIThreadSafe() const = 0;
121+
112122
// Return a DlColorColorSource pointer to this object iff it is an Color
113123
// type of ColorSource, otherwise return nullptr.
114124
virtual const DlColorColorSource* asColor() const { return nullptr; }
@@ -160,6 +170,8 @@ class DlColorColorSource final : public DlColorSource {
160170
public:
161171
DlColorColorSource(DlColor color) : color_(color) {}
162172

173+
bool isUIThreadSafe() const override { return true; }
174+
163175
std::shared_ptr<DlColorSource> shared() const override {
164176
return std::make_shared<DlColorColorSource>(color_);
165177
}
@@ -215,6 +227,10 @@ class DlImageColorSource final : public SkRefCnt,
215227
vertical_tile_mode_(vertical_tile_mode),
216228
sampling_(sampling) {}
217229

230+
bool isUIThreadSafe() const override {
231+
return image_ ? image_->isUIThreadSafe() : true;
232+
}
233+
218234
const DlImageColorSource* asImage() const override { return this; }
219235

220236
std::shared_ptr<DlColorSource> shared() const override {
@@ -338,6 +354,8 @@ class DlLinearGradientColorSource final : public DlGradientColorSourceBase {
338354
return this;
339355
}
340356

357+
bool isUIThreadSafe() const override { return true; }
358+
341359
DlColorSourceType type() const override {
342360
return DlColorSourceType::kLinearGradient;
343361
}
@@ -399,6 +417,8 @@ class DlRadialGradientColorSource final : public DlGradientColorSourceBase {
399417
return this;
400418
}
401419

420+
bool isUIThreadSafe() const override { return true; }
421+
402422
std::shared_ptr<DlColorSource> shared() const override {
403423
return MakeRadial(center_, radius_, stop_count(), colors(), stops(),
404424
tile_mode(), matrix_ptr());
@@ -460,6 +480,8 @@ class DlConicalGradientColorSource final : public DlGradientColorSourceBase {
460480
return this;
461481
}
462482

483+
bool isUIThreadSafe() const override { return true; }
484+
463485
std::shared_ptr<DlColorSource> shared() const override {
464486
return MakeConical(start_center_, start_radius_, end_center_, end_radius_,
465487
stop_count(), colors(), stops(), tile_mode(),
@@ -534,6 +556,8 @@ class DlSweepGradientColorSource final : public DlGradientColorSourceBase {
534556
return this;
535557
}
536558

559+
bool isUIThreadSafe() const override { return true; }
560+
537561
std::shared_ptr<DlColorSource> shared() const override {
538562
return MakeSweep(center_, start_, end_, stop_count(), colors(), stops(),
539563
tile_mode(), matrix_ptr());
@@ -604,6 +628,15 @@ class DlRuntimeEffectColorSource final : public DlColorSource {
604628
samplers_(std::move(samplers)),
605629
uniform_data_(std::move(uniform_data)) {}
606630

631+
bool isUIThreadSafe() const override {
632+
for (auto sampler : samplers_) {
633+
if (!sampler->isUIThreadSafe()) {
634+
return false;
635+
}
636+
}
637+
return true;
638+
}
639+
607640
const DlRuntimeEffectColorSource* asRuntimeEffect() const override {
608641
return this;
609642
}
@@ -666,6 +699,8 @@ class DlSceneColorSource final : public DlColorSource {
666699
impeller::Matrix camera_matrix)
667700
: node_(std::move(node)), camera_matrix_(camera_matrix) {}
668701

702+
bool isUIThreadSafe() const override { return true; }
703+
669704
const DlSceneColorSource* asScene() const override { return this; }
670705

671706
std::shared_ptr<DlColorSource> shared() const override {

display_list/image/dl_image.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ class DlImage : public SkRefCnt {
6767

6868
virtual bool isTextureBacked() const = 0;
6969

70+
//----------------------------------------------------------------------------
71+
/// @brief If the underlying platform image held by this object has no
72+
/// threading requirements for the release of that image (or if
73+
/// arrangements have already been made to forward that image to
74+
/// the correct thread upon deletion), this method returns true.
75+
///
76+
/// @return True if the underlying image is held in a thread-safe manner.
77+
///
78+
virtual bool isUIThreadSafe() const = 0;
79+
7080
//----------------------------------------------------------------------------
7181
/// @return The dimensions of the pixel grid.
7282
///

display_list/image/dl_image_skia.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,17 @@ bool DlImageSkia::isTextureBacked() const {
3131
return image_ ? image_->isTextureBacked() : false;
3232
}
3333

34+
// |DlImage|
35+
bool DlImageSkia::isUIThreadSafe() const {
36+
// Technically if the image is null then we are thread-safe, and possibly
37+
// if the image is constructed from a heap raster as well, but there
38+
// should never be a leak of an instance of this class into any data that
39+
// is shared with the UI thread, regardless of value.
40+
// All images intended to be shared with the UI thread should be constructed
41+
// via one of the DlImage subclasses designed for that purpose.
42+
return false;
43+
}
44+
3445
// |DlImage|
3546
SkISize DlImageSkia::dimensions() const {
3647
return image_ ? image_->dimensions() : SkISize::MakeEmpty();

display_list/image/dl_image_skia.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ class DlImageSkia final : public DlImage {
2929
// |DlImage|
3030
bool isTextureBacked() const override;
3131

32+
// |DlImage|
33+
bool isUIThreadSafe() const override;
34+
3235
// |DlImage|
3336
SkISize dimensions() const override;
3437

flow/layers/display_list_layer.cc

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,14 @@
1616
namespace flutter {
1717

1818
DisplayListLayer::DisplayListLayer(const SkPoint& offset,
19-
SkiaGPUObject<DisplayList> display_list,
19+
sk_sp<DisplayList> display_list,
2020
bool is_complex,
2121
bool will_change)
2222
: offset_(offset), display_list_(std::move(display_list)) {
23-
if (display_list_.skia_object() != nullptr) {
24-
bounds_ = display_list_.skia_object()->bounds().makeOffset(offset_.x(),
25-
offset_.y());
23+
if (display_list_) {
24+
bounds_ = display_list_->bounds().makeOffset(offset_.x(), offset_.y());
2625
display_list_raster_cache_item_ = DisplayListRasterCacheItem::Make(
27-
display_list_.skia_object(), offset_, is_complex, will_change);
26+
display_list_, offset_, is_complex, will_change);
2827
}
2928
}
3029

@@ -61,8 +60,8 @@ void DisplayListLayer::Diff(DiffContext* context, const Layer* old_layer) {
6160
bool DisplayListLayer::Compare(DiffContext::Statistics& statistics,
6261
const DisplayListLayer* l1,
6362
const DisplayListLayer* l2) {
64-
const auto& dl1 = l1->display_list_.skia_object();
65-
const auto& dl2 = l2->display_list_.skia_object();
63+
const auto& dl1 = l1->display_list_;
64+
const auto& dl2 = l2->display_list_;
6665
if (dl1.get() == dl2.get()) {
6766
statistics.AddSameInstancePicture();
6867
return true;
@@ -105,7 +104,7 @@ void DisplayListLayer::Preroll(PrerollContext* context) {
105104
}
106105

107106
void DisplayListLayer::Paint(PaintContext& context) const {
108-
FML_DCHECK(display_list_.skia_object());
107+
FML_DCHECK(display_list_);
109108
FML_DCHECK(needs_painting(context));
110109

111110
auto mutator = context.state_stack.save();
@@ -143,7 +142,7 @@ void DisplayListLayer::Paint(PaintContext& context) const {
143142
DlAutoCanvasRestore save(canvas, true);
144143
canvas->Clear(DlColor::kTransparent());
145144
canvas->SetTransform(ctm);
146-
canvas->DrawDisplayList(display_list_.skia_object(), opacity);
145+
canvas->DrawDisplayList(display_list_, opacity);
147146
}
148147
canvas->Flush();
149148
}
@@ -158,8 +157,7 @@ void DisplayListLayer::Paint(PaintContext& context) const {
158157
context.layer_snapshot_store->Add(snapshot_data);
159158
}
160159

161-
auto display_list = display_list_.skia_object();
162-
context.canvas->DrawDisplayList(display_list, opacity);
160+
context.canvas->DrawDisplayList(display_list_, opacity);
163161
}
164162

165163
} // namespace flutter

flow/layers/display_list_layer.h

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
#include "flutter/flow/layers/display_list_raster_cache_item.h"
1212
#include "flutter/flow/layers/layer.h"
1313
#include "flutter/flow/raster_cache_item.h"
14-
#include "flutter/flow/skia_gpu_object.h"
1514

1615
namespace flutter {
1716

@@ -20,13 +19,11 @@ class DisplayListLayer : public Layer {
2019
static constexpr size_t kMaxBytesToCompare = 10000;
2120

2221
DisplayListLayer(const SkPoint& offset,
23-
SkiaGPUObject<DisplayList> display_list,
22+
sk_sp<DisplayList> display_list,
2423
bool is_complex,
2524
bool will_change);
2625

27-
DisplayList* display_list() const {
28-
return display_list_.skia_object().get();
29-
}
26+
DisplayList* display_list() const { return display_list_.get(); }
3027

3128
bool IsReplacing(DiffContext* context, const Layer* layer) const override;
3229

@@ -55,7 +52,7 @@ class DisplayListLayer : public Layer {
5552
SkPoint offset_;
5653
SkRect bounds_;
5754

58-
flutter::SkiaGPUObject<DisplayList> display_list_;
55+
sk_sp<DisplayList> display_list_;
5956

6057
static bool Compare(DiffContext::Statistics& statistics,
6158
const DisplayListLayer* l1,

0 commit comments

Comments
 (0)