Skip to content

Commit

Permalink
DlAttribute base class (flutter#31672)
Browse files Browse the repository at this point in the history
  • Loading branch information
flar authored Feb 25, 2022
1 parent 9495bb7 commit eef4f8e
Show file tree
Hide file tree
Showing 15 changed files with 226 additions and 251 deletions.
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ deps = {
'src': 'https://github.com/flutter/buildroot.git' + '@' + 'e4cee118fc80c7cd3b8f8959aa02747a67c38a63',

'src/flutter/impeller':
Var('github_git') + '/flutter/impeller' + '@' + '827d2f81eac75a64c7f9383d23dfae6b32f1c054',
Var('github_git') + '/flutter/impeller' + '@' + '189a9e74c881929f0c7d74323c8fb94974ac45db',

# Fuchsia compatibility
#
Expand Down
1 change: 1 addition & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ FILE: ../../../flutter/common/task_runners.cc
FILE: ../../../flutter/common/task_runners.h
FILE: ../../../flutter/display_list/display_list.cc
FILE: ../../../flutter/display_list/display_list.h
FILE: ../../../flutter/display_list/display_list_attributes.h
FILE: ../../../flutter/display_list/display_list_benchmarks.cc
FILE: ../../../flutter/display_list/display_list_benchmarks.h
FILE: ../../../flutter/display_list/display_list_benchmarks_canvas_provider.h
Expand Down
1 change: 1 addition & 0 deletions display_list/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ source_set("display_list") {
sources = [
"display_list.cc",
"display_list.h",
"display_list_attributes.h",
"display_list_builder.cc",
"display_list_builder.h",
"display_list_canvas_dispatcher.cc",
Expand Down
120 changes: 120 additions & 0 deletions display_list/display_list_attributes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
// 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_ATTRIBUTES_H_
#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_ATTRIBUTES_H_

#include "flutter/display_list/types.h"

namespace flutter {

// ===========================================================================

// The base class for a family of DisplayList attribute classes.
//
// This class is designed to support the following properties for any
// attribute to facilitate the storage of the attribute in a DisplayList
// and for use in code that inspects or creates DisplayList objects:
//
// - Typed:
// Even though most references and pointers are passed around as the
// attribute's base class, a Type property can be queried using the |type|
// method to determine which type of the attribute is being used. For
// example, the Blend type of ColorFilter will return DlColorFilter::kBlend
// from its type method.
//
// - Inspectable:
// Any parameters required to full specify the action of the attribute are
// provided on the type-specific classes.
//
// - Safely Downcast:
// For the subclasses that have specific data to query, methods are
// provided to safely downcast the reference for inspection. The down
// casting method will either return a pointer to the instance with
// its type-specific class type, or nullptr if it is executed on the
// wrong type of instance.
// (eg. DlColorFilter::asBlend() or DlMaskFilter::asBlur())
//
// - Skiafiable:
// The classes override an |skia_object| method to easily obtain a Skia
// version of the attribute on demand.
//
// - Immutable:
// Neither the base class or any of the subclasses specify any mutation
// methods. Instances are often passed around as const as a reminder,
// but the classes have no mutation methods anyway.
//
// - Flat and Embeddable:
// Bulk freed + bulk compared + zero memory fragmentation.
//
// All of these classes are designed to be stored in the DisplayList
// buffer allocated in-line with the rest of the data to avoid dangling
// pointers that require explicit freeing when the DisplayList goes
// away, or that fragment the memory needed to read the operations in
// the DisplayList. Furthermore, the data in the classes can be bulk
// compared using a |memcmp| when performing a |DisplayList::Equals|.
//
// - Passed by Pointer:
// The data shared via the |Dispatcher::set<Attribute>| calls are stored
// in the buffer itself and so their lifetime is controlled by the
// DisplayList. That memory cannot be shared as by a |shared_ptr|
// because the memory may be freed outside the control of the shared
// pointer. Creating a shared version of the object would require a
// new instantiation which we'd like to avoid on every dispatch call,
// so a raw (const) pointer is shared in those dispatch calls instead,
// with all of the responsibilities of non-ownership in the called method.
//
// But, for methods that need to keep a copy of the data...
//
// - Shared_Ptr-able:
// The classes support a method to return a |std::shared_ptr| version of
// themselves, safely instantiating a new copy of the object into a
// shared_ptr using |std::make_shared|. For those dispatcher objects
// that may want to hold on to the contents of the object (typically
// in a |current_attribute_| field), they can obtain a shared_ptr
// copy safely and easily using the |shared| method.

// ===========================================================================

// |D| is the base type for the attribute
// (i.e. DlColorFilter, etc.)
// |S| is the base type for the Skia version of the attribute
// (i.e. SkColorFilter, etc.)
// |T| is the enum that describes the specific subclasses
// (i.e DlColorFilterType, etc.)
template <class D, class S, typename T>
class DlAttribute {
public:
// Return the recognized specific type of the attribute.
virtual T type() const = 0;

// Return the size of the instantiated data (typically used to allocate)
// storage in the DisplayList buffer.
virtual size_t size() const = 0;

// Return a shared version of |this| attribute. The |shared_ptr| returned
// will reference a copy of this object so that the lifetime of the shared
// version is not tied to the storage of this particular instance.
virtual std::shared_ptr<D> shared() const = 0;

// Return an equivalent sk_sp<Skia> version of this object.
virtual sk_sp<S> skia_object() const = 0;

// Perform a content aware |==| comparison of the ColorFilter.
bool operator==(D const& other) const {
return type() == other.type() && equals_(other);
}
// Perform a content aware |!=| comparison of the ColorFilter.
bool operator!=(D const& other) const { return !(*this == other); }

virtual ~DlAttribute() = default;

protected:
// Virtual comparison method to support |==| and |!=|.
virtual bool equals_(D const& other) const = 0;
};

} // namespace flutter

#endif // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_ATTRIBUTES_H_
18 changes: 9 additions & 9 deletions display_list/display_list_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -141,32 +141,32 @@ void DisplayListBuilder::onSetColorFilter(const DlColorFilter* filter) {
} else {
current_color_filter_ = filter->shared();
switch (filter->type()) {
case DlColorFilter::kBlend: {
case DlColorFilterType::kBlend: {
const DlBlendColorFilter* blend_filter = filter->asBlend();
FML_DCHECK(blend_filter);
void* pod = Push<SetColorFilterOp>(blend_filter->size(), 0);
new (pod) DlBlendColorFilter(blend_filter);
break;
}
case DlColorFilter::kMatrix: {
case DlColorFilterType::kMatrix: {
const DlMatrixColorFilter* matrix_filter = filter->asMatrix();
FML_DCHECK(matrix_filter);
void* pod = Push<SetColorFilterOp>(matrix_filter->size(), 0);
new (pod) DlMatrixColorFilter(matrix_filter);
break;
}
case DlColorFilter::kSrgbToLinearGamma: {
case DlColorFilterType::kSrgbToLinearGamma: {
void* pod = Push<SetColorFilterOp>(filter->size(), 0);
new (pod) DlSrgbToLinearGammaColorFilter();
break;
}
case DlColorFilter::kLinearToSrgbGamma: {
case DlColorFilterType::kLinearToSrgbGamma: {
void* pod = Push<SetColorFilterOp>(filter->size(), 0);
new (pod) DlLinearToSrgbGammaColorFilter();
break;
}
case DlColorFilter::kUnknown: {
Push<SetSkColorFilterOp>(0, 0, filter->sk_filter());
case DlColorFilterType::kUnknown: {
Push<SetSkColorFilterOp>(0, 0, filter->skia_object());
break;
}
}
Expand All @@ -185,15 +185,15 @@ void DisplayListBuilder::onSetMaskFilter(const DlMaskFilter* filter) {
} else {
current_mask_filter_ = filter->shared();
switch (filter->type()) {
case DlMaskFilter::kBlur: {
case DlMaskFilterType::kBlur: {
const DlBlurMaskFilter* blur_filter = filter->asBlur();
FML_DCHECK(blur_filter);
void* pod = Push<SetMaskFilterOp>(blur_filter->size(), 0);
new (pod) DlBlurMaskFilter(blur_filter);
break;
}
case DlMaskFilter::kUnknown:
Push<SetSkMaskFilterOp>(0, 0, filter->sk_filter());
case DlMaskFilterType::kUnknown:
Push<SetSkMaskFilterOp>(0, 0, filter->skia_object());
break;
}
}
Expand Down
10 changes: 5 additions & 5 deletions display_list/display_list_canvas_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ class CanvasCompareTester {
"saveLayer ColorFilter, no bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
save_p.setColorFilter(filter.sk_filter());
save_p.setColorFilter(filter.skia_object());
cv->saveLayer(nullptr, &save_p);
p.setStrokeWidth(5.0);
},
Expand All @@ -861,7 +861,7 @@ class CanvasCompareTester {
"saveLayer ColorFilter and bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
save_p.setColorFilter(filter.sk_filter());
save_p.setColorFilter(filter.skia_object());
cv->saveLayer(RenderBounds, &save_p);
p.setStrokeWidth(5.0);
},
Expand Down Expand Up @@ -1149,7 +1149,7 @@ class CanvasCompareTester {
"ColorFilter == RotateRGB",
[=](SkCanvas*, SkPaint& p) {
p.setColor(SK_ColorYELLOW);
p.setColorFilter(filter.sk_filter());
p.setColorFilter(filter.skia_object());
},
[=](DisplayListBuilder& b) {
b.setColor(SK_ColorYELLOW);
Expand All @@ -1165,7 +1165,7 @@ class CanvasCompareTester {
"ColorFilter == Invert",
[=](SkCanvas*, SkPaint& p) {
p.setColor(SK_ColorYELLOW);
p.setColorFilter(filter.sk_filter());
p.setColorFilter(filter.skia_object());
},
[=](DisplayListBuilder& b) {
b.setColor(SK_ColorYELLOW);
Expand Down Expand Up @@ -1246,7 +1246,7 @@ class CanvasCompareTester {
"MaskFilter == Blur 5",
[=](SkCanvas*, SkPaint& p) {
p.setStrokeWidth(5.0);
p.setMaskFilter(filter.sk_filter());
p.setMaskFilter(filter.skia_object());
},
[=](DisplayListBuilder& b) {
b.setStrokeWidth(5.0);
Expand Down
Loading

0 comments on commit eef4f8e

Please sign in to comment.