Reland "Sequester all Skia<->DL interactions into the skia sub-module" (#40435)
Reland "Sequester all Skia<->DL interactions into the skia sub-module"
diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files
index 063e8c3..7d5658d 100644
--- a/ci/licenses_golden/excluded_files
+++ b/ci/licenses_golden/excluded_files
@@ -29,12 +29,10 @@
../../../flutter/build
../../../flutter/ci
../../../flutter/common/README.md
-../../../flutter/display_list/display_list_canvas_unittests.cc
../../../flutter/display_list/display_list_color_filter_unittests.cc
../../../flutter/display_list/display_list_color_source_unittests.cc
../../../flutter/display_list/display_list_color_unittests.cc
../../../flutter/display_list/display_list_complexity_unittests.cc
-../../../flutter/display_list/display_list_enum_unittests.cc
../../../flutter/display_list/display_list_image_filter_unittests.cc
../../../flutter/display_list/display_list_mask_filter_unittests.cc
../../../flutter/display_list/display_list_matrix_clip_tracker_unittests.cc
@@ -42,8 +40,10 @@
../../../flutter/display_list/display_list_path_effect_unittests.cc
../../../flutter/display_list/display_list_rtree_unittests.cc
../../../flutter/display_list/display_list_unittests.cc
-../../../flutter/display_list/display_list_utils_unittests.cc
../../../flutter/display_list/display_list_vertices_unittests.cc
+../../../flutter/display_list/dl_rendering_unittests.cc
+../../../flutter/display_list/skia/dl_sk_conversions_unittests.cc
+../../../flutter/display_list/skia/dl_sk_utils_unittests.cc
../../../flutter/display_list/testing
../../../flutter/docs
../../../flutter/examples
diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter
index dc931e8..5a60d16 100644
--- a/ci/licenses_golden/licenses_flutter
+++ b/ci/licenses_golden/licenses_flutter
@@ -714,8 +714,6 @@
ORIGIN: ../../../flutter/display_list/display_list_builder.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_builder.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_builder_benchmarks.cc + ../../../flutter/LICENSE
-ORIGIN: ../../../flutter/display_list/display_list_canvas_dispatcher.cc + ../../../flutter/LICENSE
-ORIGIN: ../../../flutter/display_list/display_list_canvas_dispatcher.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_color.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_color_filter.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_color_filter.h + ../../../flutter/LICENSE
@@ -729,8 +727,6 @@
ORIGIN: ../../../flutter/display_list/display_list_complexity_helper.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_complexity_metal.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_complexity_metal.h + ../../../flutter/LICENSE
-ORIGIN: ../../../flutter/display_list/display_list_dispatcher.cc + ../../../flutter/LICENSE
-ORIGIN: ../../../flutter/display_list/display_list_dispatcher.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_flags.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_flags.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_image.cc + ../../../flutter/LICENSE
@@ -759,9 +755,18 @@
ORIGIN: ../../../flutter/display_list/display_list_utils.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_vertices.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/display_list_vertices.h + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/display_list/dl_canvas.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/dl_canvas.h + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/display_list/dl_op_receiver.cc + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/display_list/dl_op_receiver.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/skia/dl_sk_canvas.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/skia/dl_sk_canvas.h + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/display_list/skia/dl_sk_conversions.cc + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/display_list/skia/dl_sk_conversions.h + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/display_list/skia/dl_sk_dispatcher.cc + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/display_list/skia/dl_sk_dispatcher.h + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/display_list/skia/dl_sk_utils.cc + ../../../flutter/LICENSE
+ORIGIN: ../../../flutter/display_list/skia/dl_sk_utils.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/display_list/types.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/flow/compositor_context.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/flow/compositor_context.h + ../../../flutter/LICENSE
@@ -3245,8 +3250,6 @@
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_canvas_dispatcher.cc
-FILE: ../../../flutter/display_list/display_list_canvas_dispatcher.h
FILE: ../../../flutter/display_list/display_list_color.h
FILE: ../../../flutter/display_list/display_list_color_filter.cc
FILE: ../../../flutter/display_list/display_list_color_filter.h
@@ -3260,8 +3263,6 @@
FILE: ../../../flutter/display_list/display_list_complexity_helper.h
FILE: ../../../flutter/display_list/display_list_complexity_metal.cc
FILE: ../../../flutter/display_list/display_list_complexity_metal.h
-FILE: ../../../flutter/display_list/display_list_dispatcher.cc
-FILE: ../../../flutter/display_list/display_list_dispatcher.h
FILE: ../../../flutter/display_list/display_list_flags.cc
FILE: ../../../flutter/display_list/display_list_flags.h
FILE: ../../../flutter/display_list/display_list_image.cc
@@ -3290,9 +3291,18 @@
FILE: ../../../flutter/display_list/display_list_utils.h
FILE: ../../../flutter/display_list/display_list_vertices.cc
FILE: ../../../flutter/display_list/display_list_vertices.h
+FILE: ../../../flutter/display_list/dl_canvas.cc
FILE: ../../../flutter/display_list/dl_canvas.h
+FILE: ../../../flutter/display_list/dl_op_receiver.cc
+FILE: ../../../flutter/display_list/dl_op_receiver.h
FILE: ../../../flutter/display_list/skia/dl_sk_canvas.cc
FILE: ../../../flutter/display_list/skia/dl_sk_canvas.h
+FILE: ../../../flutter/display_list/skia/dl_sk_conversions.cc
+FILE: ../../../flutter/display_list/skia/dl_sk_conversions.h
+FILE: ../../../flutter/display_list/skia/dl_sk_dispatcher.cc
+FILE: ../../../flutter/display_list/skia/dl_sk_dispatcher.h
+FILE: ../../../flutter/display_list/skia/dl_sk_utils.cc
+FILE: ../../../flutter/display_list/skia/dl_sk_utils.h
FILE: ../../../flutter/display_list/types.h
FILE: ../../../flutter/flow/compositor_context.cc
FILE: ../../../flutter/flow/compositor_context.h
diff --git a/display_list/BUILD.gn b/display_list/BUILD.gn
index 7af433a..797e4cc 100644
--- a/display_list/BUILD.gn
+++ b/display_list/BUILD.gn
@@ -24,8 +24,6 @@
"display_list_blend_mode.h",
"display_list_builder.cc",
"display_list_builder.h",
- "display_list_canvas_dispatcher.cc",
- "display_list_canvas_dispatcher.h",
"display_list_color.h",
"display_list_color_filter.cc",
"display_list_color_filter.h",
@@ -37,8 +35,6 @@
"display_list_complexity_gl.h",
"display_list_complexity_metal.cc",
"display_list_complexity_metal.h",
- "display_list_dispatcher.cc",
- "display_list_dispatcher.h",
"display_list_flags.cc",
"display_list_flags.h",
"display_list_image.cc",
@@ -67,9 +63,18 @@
"display_list_utils.h",
"display_list_vertices.cc",
"display_list_vertices.h",
+ "dl_canvas.cc",
"dl_canvas.h",
+ "dl_op_receiver.cc",
+ "dl_op_receiver.h",
"skia/dl_sk_canvas.cc",
"skia/dl_sk_canvas.h",
+ "skia/dl_sk_conversions.cc",
+ "skia/dl_sk_conversions.h",
+ "skia/dl_sk_dispatcher.cc",
+ "skia/dl_sk_dispatcher.h",
+ "skia/dl_sk_utils.cc",
+ "skia/dl_sk_utils.h",
"types.h",
]
@@ -99,7 +104,6 @@
"display_list_color_source_unittests.cc",
"display_list_color_unittests.cc",
"display_list_complexity_unittests.cc",
- "display_list_enum_unittests.cc",
"display_list_image_filter_unittests.cc",
"display_list_mask_filter_unittests.cc",
"display_list_matrix_clip_tracker_unittests.cc",
@@ -107,8 +111,9 @@
"display_list_path_effect_unittests.cc",
"display_list_rtree_unittests.cc",
"display_list_unittests.cc",
- "display_list_utils_unittests.cc",
"display_list_vertices_unittests.cc",
+ "skia/dl_sk_conversions_unittests.cc",
+ "skia/dl_sk_utils_unittests.cc",
]
deps = [
@@ -136,7 +141,7 @@
executable("display_list_rendertests") {
testonly = true
- sources = [ "display_list_canvas_unittests.cc" ]
+ sources = [ "dl_rendering_unittests.cc" ]
deps = [
":display_list",
diff --git a/display_list/display_list.cc b/display_list/display_list.cc
index defde8b..5ac4ea5 100644
--- a/display_list/display_list.cc
+++ b/display_list/display_list.cc
@@ -6,7 +6,6 @@
#include "flutter/display_list/display_list.h"
#include "flutter/display_list/display_list_builder.h"
-#include "flutter/display_list/display_list_canvas_dispatcher.h"
#include "flutter/display_list/display_list_ops.h"
#include "flutter/fml/trace_event.h"
@@ -134,38 +133,40 @@
std::vector<int>::const_iterator end_;
};
-void DisplayList::Dispatch(Dispatcher& ctx) const {
+void DisplayList::Dispatch(DlOpReceiver& receiver) const {
uint8_t* ptr = storage_.get();
- Dispatch(ctx, ptr, ptr + byte_count_, NopCuller::instance);
+ Dispatch(receiver, ptr, ptr + byte_count_, NopCuller::instance);
}
-void DisplayList::Dispatch(Dispatcher& ctx, const SkRect& cull_rect) const {
+
+void DisplayList::Dispatch(DlOpReceiver& receiver,
+ const SkRect& cull_rect) const {
if (cull_rect.isEmpty()) {
return;
}
if (cull_rect.contains(bounds())) {
- Dispatch(ctx);
+ Dispatch(receiver);
return;
}
const DlRTree* rtree = this->rtree().get();
FML_DCHECK(rtree != nullptr);
if (rtree == nullptr) {
FML_LOG(ERROR) << "dispatched with culling rect on DL with no rtree";
- Dispatch(ctx);
+ Dispatch(receiver);
return;
}
uint8_t* ptr = storage_.get();
std::vector<int> rect_indices;
rtree->search(cull_rect, &rect_indices);
VectorCuller culler(rtree, rect_indices);
- Dispatch(ctx, ptr, ptr + byte_count_, culler);
+ Dispatch(receiver, ptr, ptr + byte_count_, culler);
}
-void DisplayList::Dispatch(Dispatcher& dispatcher,
+void DisplayList::Dispatch(DlOpReceiver& receiver,
uint8_t* ptr,
uint8_t* end,
Culler& culler) const {
DispatchContext context = {
- .dispatcher = dispatcher,
+ .receiver = receiver,
.cur_index = 0,
// next_render_index will be initialized by culler.init()
.next_restore_index = std::numeric_limits<int>::max(),
@@ -294,27 +295,6 @@
return true;
}
-void DisplayList::RenderTo(DisplayListBuilder* builder) const {
- if (!builder) {
- return;
- }
- if (has_rtree()) {
- Dispatch(builder->asDispatcher(), builder->GetLocalClipBounds());
- } else {
- Dispatch(builder->asDispatcher());
- }
-}
-
-void DisplayList::RenderTo(SkCanvas* canvas, SkScalar opacity) const {
- FML_DCHECK(can_apply_group_opacity() || opacity >= SK_Scalar1);
- DisplayListCanvasDispatcher dispatcher(canvas, opacity);
- if (has_rtree()) {
- Dispatch(dispatcher, canvas->getLocalClipBounds());
- } else {
- Dispatch(dispatcher);
- }
-}
-
bool DisplayList::Equals(const DisplayList* other) const {
if (this == other) {
return true;
diff --git a/display_list/display_list.h b/display_list/display_list.h
index dde2676..a66040a 100644
--- a/display_list/display_list.h
+++ b/display_list/display_list.h
@@ -18,41 +18,36 @@
//
// This file contains the definitions for:
// DisplayList: the base class that holds the information about the
-// sequence of operations and can dispatch them to a Dispatcher
-// Dispatcher: a pure virtual interface which can be implemented to field
-// the requests for purposes such as sending them to an SkCanvas
-// or detecting various rendering optimization scenarios
-// DisplayListBuilder: a class for constructing a DisplayList from the same
-// calls defined in the Dispatcher
+// sequence of operations and can dispatch them to a DlOpReceiver
+// DlOpReceiver: a pure virtual interface which can be implemented to field
+// the requests for purposes such as sending them to an SkCanvas
+// or detecting various rendering optimization scenarios
+// DisplayListBuilder: a class for constructing a DisplayList from DlCanvas
+// method calls and which can act as a DlOpReceiver as well
//
// Other files include various class definitions for dealing with display
// lists, such as:
-// display_list_canvas.h: classes to interact between SkCanvas and DisplayList
-// (SkCanvas->DisplayList adapter and vice versa)
+// skia/dl_sk_*.h: classes to interact between SkCanvas and DisplayList
+// (SkCanvas->DisplayList adapter and vice versa)
//
// display_list_utils.h: various utility classes to ease implementing
-// a Dispatcher, including NOP implementations of
+// a DlOpReceiver, including NOP implementations of
// the attribute, clip, and transform methods,
// classes to track attributes, clips, and transforms
// and a class to compute the bounds of a DisplayList
-// Any class implementing Dispatcher can inherit from
+// Any class implementing DlOpReceiver can inherit from
// these utility classes to simplify its creation
//
// The Flutter DisplayList mechanism is used in a similar manner to the Skia
-// SkPicture mechanism. The primary means of communication into and out
-// of the DisplayList is through the Dispatcher virtual class which
-// provides a nearly 1:1 translation between the records of the DisplayList
-// to method calls.
+// SkPicture mechanism.
//
-// A DisplayList must be created using a DisplayListBuilder using either its
-// stateful methods inherited from Dispatcher, or from its stateless methods
-// inherited from DlCanvas.
+// A DisplayList must be created using a DisplayListBuilder using its stateless
+// methods inherited from DlCanvas.
//
-// A DisplayList can be read back by implementing the Dispatcher virtual
+// A DisplayList can be read back by implementing the DlOpReceiver virtual
// methods (with help from some of the classes in the utils file) and
-// passing an instance to the dispatch() method, or it can be rendered
-// to Skia using a DisplayListCanvasDispatcher or simply by passing an
-// SkCanvas pointer to its renderTo() method.
+// passing an instance to the Dispatch() method, or it can be rendered
+// to Skia using a DlSkCanvasDispatcher.
//
// The mechanism is inspired by the SkLiteDL class that is not directly
// supported by Skia, but has been recommended as a basis for custom
@@ -155,7 +150,7 @@
};
#undef DL_OP_TO_ENUM_VALUE
-class Dispatcher;
+class DlOpReceiver;
class DisplayListBuilder;
class SaveLayerOptions {
@@ -231,7 +226,7 @@
class Culler;
// The base class that contains a sequence of rendering operations
-// for dispatch to a Dispatcher. These objects must be instantiated
+// for dispatch to a DlOpReceiver. These objects must be instantiated
// through an instance of DisplayListBuilder::build().
class DisplayList : public SkRefCnt {
public:
@@ -239,12 +234,8 @@
~DisplayList();
- void Dispatch(Dispatcher& ctx) const;
- void Dispatch(Dispatcher& ctx, const SkRect& cull_rect) const;
-
- void RenderTo(DisplayListBuilder* builder) const;
-
- void RenderTo(SkCanvas* canvas, SkScalar opacity = SK_Scalar1) const;
+ void Dispatch(DlOpReceiver& ctx) const;
+ void Dispatch(DlOpReceiver& ctx, const SkRect& cull_rect) const;
// From historical behavior, SkPicture always included nested bytes,
// but nested ops are only included if requested. The defaults used
@@ -300,7 +291,7 @@
const bool can_apply_group_opacity_;
const sk_sp<const DlRTree> rtree_;
- void Dispatch(Dispatcher& ctx,
+ void Dispatch(DlOpReceiver& ctx,
uint8_t* ptr,
uint8_t* end,
Culler& culler) const;
diff --git a/display_list/display_list_attributes.h b/display_list/display_list_attributes.h
index 051e4ef..aa10863 100644
--- a/display_list/display_list_attributes.h
+++ b/display_list/display_list_attributes.h
@@ -36,10 +36,6 @@
// 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,
@@ -56,7 +52,7 @@
// compared using a |memcmp| when performing a |DisplayList::Equals|.
//
// - Passed by Pointer:
-// The data shared via the |Dispatcher::set<Attribute>| calls are stored
+// The data shared via the |DlOpReceiver::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
@@ -70,7 +66,7 @@
// - 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
+// shared_ptr using |std::make_shared|. For those receiver 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.
@@ -79,11 +75,9 @@
// |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>
+template <class D, typename T>
class DlAttribute {
public:
// Return the recognized specific type of the attribute.
@@ -98,9 +92,6 @@
// 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 Attribute.
bool operator==(D const& other) const {
return type() == other.type() && equals_(other);
diff --git a/display_list/display_list_benchmarks.cc b/display_list/display_list_benchmarks.cc
index d7f7638..b9644ec 100644
--- a/display_list/display_list_benchmarks.cc
+++ b/display_list/display_list_benchmarks.cc
@@ -5,6 +5,7 @@
#include "flutter/display_list/display_list_benchmarks.h"
#include "flutter/display_list/display_list_builder.h"
#include "flutter/display_list/display_list_flags.h"
+#include "flutter/display_list/skia/dl_sk_canvas.h"
#include "third_party/skia/include/core/SkPoint.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -76,27 +77,27 @@
unsigned attributes) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawLineFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawLineFlags);
size_t length = state.range(0);
surface_provider->InitializeSurface(length, length);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
state.counters["DrawCallCount"] = kLinesToDraw;
for (size_t i = 0; i < kLinesToDraw; i++) {
- builder.drawLine(SkPoint::Make(i % length, 0),
- SkPoint::Make(length - i % length, length));
+ builder.DrawLine(SkPoint::Make(i % length, 0),
+ SkPoint::Make(length - i % length, length), paint);
}
auto display_list = builder.Build();
// We only want to time the actual rasterization.
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -114,15 +115,15 @@
unsigned attributes) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawRectFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawRectFlags);
size_t length = state.range(0);
size_t canvas_size = length * 2;
surface_provider->InitializeSurface(canvas_size, canvas_size);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
// As rects have SkScalar dimensions, we want to ensure that we also
// draw rects with non-integer position and size
@@ -131,7 +132,7 @@
state.counters["DrawCallCount"] = kRectsToDraw;
for (size_t i = 0; i < kRectsToDraw; i++) {
- builder.drawRect(rect);
+ builder.DrawRect(rect, paint);
rect.offset(offset, offset);
if (rect.right() > canvas_size) {
rect.offset(-canvas_size, 0);
@@ -145,7 +146,7 @@
// We only want to time the actual rasterization.
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -163,22 +164,22 @@
unsigned attributes) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawOvalFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawOvalFlags);
size_t length = state.range(0);
size_t canvas_size = length * 2;
surface_provider->InitializeSurface(canvas_size, canvas_size);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkRect rect = SkRect::MakeXYWH(0, 0, length * 1.5f, length);
const SkScalar offset = 0.5f;
state.counters["DrawCallCount"] = kOvalsToDraw;
for (size_t i = 0; i < kOvalsToDraw; i++) {
- builder.drawOval(rect);
+ builder.DrawOval(rect, paint);
rect.offset(offset, offset);
if (rect.right() > canvas_size) {
rect.offset(-canvas_size, 0);
@@ -191,7 +192,7 @@
// We only want to time the actual rasterization.
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -209,15 +210,15 @@
unsigned attributes) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawCircleFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawCircleFlags);
size_t length = state.range(0);
size_t canvas_size = length * 2;
surface_provider->InitializeSurface(canvas_size, canvas_size);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkScalar radius = length / 2.0f;
const SkScalar offset = 0.5f;
@@ -226,7 +227,7 @@
state.counters["DrawCallCount"] = kCirclesToDraw;
for (size_t i = 0; i < kCirclesToDraw; i++) {
- builder.drawCircle(center, radius);
+ builder.DrawCircle(center, radius, paint);
center.offset(offset, offset);
if (center.x() + radius > canvas_size) {
center.set(radius, center.y());
@@ -239,7 +240,7 @@
// We only want to time the actual rasterization.
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -258,15 +259,15 @@
SkRRect::Type type) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawRRectFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawRRectFlags);
size_t length = state.range(0);
size_t canvas_size = length * 2;
surface_provider->InitializeSurface(canvas_size, canvas_size);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkVector radii[4] = {};
switch (type) {
@@ -304,7 +305,7 @@
state.counters["DrawCallCount"] = kRRectsToDraw;
for (size_t i = 0; i < kRRectsToDraw; i++) {
- builder.drawRRect(rrect);
+ builder.DrawRRect(rrect, paint);
rrect.offset(offset, offset);
if (rrect.rect().right() > canvas_size) {
rrect.offset(-canvas_size, 0);
@@ -317,7 +318,7 @@
// We only want to time the actual rasterization.
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -339,15 +340,15 @@
SkRRect::Type type) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawDRRectFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawDRRectFlags);
size_t length = state.range(0);
size_t canvas_size = length * 2;
surface_provider->InitializeSurface(canvas_size, canvas_size);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkVector radii[4] = {};
switch (type) {
@@ -386,7 +387,7 @@
state.counters["DrawCallCount"] = kDRRectsToDraw;
for (size_t i = 0; i < kDRRectsToDraw; i++) {
rrect.inset(0.1f * length, 0.1f * length, &rrect_2);
- builder.drawDRRect(rrect, rrect_2);
+ builder.DrawDRRect(rrect, rrect_2, paint);
rrect.offset(offset, offset);
if (rrect.rect().right() > canvas_size) {
rrect.offset(-canvas_size, 0);
@@ -399,7 +400,7 @@
// We only want to time the actual rasterization.
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -413,8 +414,8 @@
unsigned attributes) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawArcNoCenterFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state,
DisplayListOpFlags::kDrawArcNoCenterFlags);
@@ -422,7 +423,7 @@
size_t canvas_size = length * 2;
surface_provider->InitializeSurface(canvas_size, canvas_size);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkScalar starting_angle = 0.0f;
SkScalar offset = 0.5f;
@@ -436,7 +437,7 @@
state.counters["DrawCallCount"] = kArcSweepSetsToDraw * segment_sweeps.size();
for (size_t i = 0; i < kArcSweepSetsToDraw; i++) {
for (SkScalar sweep : segment_sweeps) {
- builder.drawArc(bounds, starting_angle, sweep, false);
+ builder.DrawArc(bounds, starting_angle, sweep, false, paint);
starting_angle += sweep + 5.0f;
}
bounds.offset(offset, offset);
@@ -452,7 +453,7 @@
// We only want to time the actual rasterization.
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -629,14 +630,14 @@
SkPath::Verb type) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawPathFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawPathFlags);
size_t length = kFixedCanvasSize;
surface_provider->InitializeSurface(length, length);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkPath path;
@@ -650,12 +651,12 @@
state.counters["VerbCount"] = path.countVerbs();
state.counters["DrawCallCount"] = 1;
- builder.drawPath(path);
+ builder.DrawPath(path, paint);
auto display_list = builder.Build();
// We only want to time the actual rasterization.
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -767,14 +768,14 @@
DlVertexMode mode) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawVerticesFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawVerticesFlags);
size_t length = kFixedCanvasSize;
surface_provider->InitializeSurface(length, length);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkPoint center = SkPoint::Make(length / 2.0f, length / 2.0f);
@@ -791,7 +792,7 @@
std::shared_ptr<DlVertices> vertices =
GetTestVertices(p, radius, 50, mode, vertex_count);
total_vertex_count += vertex_count;
- builder.drawVertices(vertices, DlBlendMode::kSrc);
+ builder.DrawVertices(vertices.get(), DlBlendMode::kSrc, paint);
}
state.counters["VertexCount"] = total_vertex_count;
@@ -801,7 +802,7 @@
// We only want to time the actual rasterization.
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -863,26 +864,18 @@
DlCanvas::PointMode mode) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- SkPaint paint;
+ DlPaint paint = GetPaintForRun(attributes);
+
switch (mode) {
case DlCanvas::PointMode::kPoints:
- builder.SetAttributesFromPaint(
- GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawPointsAsPointsFlags);
AnnotateAttributes(attributes, state,
DisplayListOpFlags::kDrawPointsAsPointsFlags);
break;
case DlCanvas::PointMode::kLines:
- builder.SetAttributesFromPaint(
- GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawPointsAsLinesFlags);
AnnotateAttributes(attributes, state,
DisplayListOpFlags::kDrawPointsAsLinesFlags);
break;
case DlCanvas::PointMode::kPolygon:
- builder.SetAttributesFromPaint(
- GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawPointsAsPolygonFlags);
AnnotateAttributes(attributes, state,
DisplayListOpFlags::kDrawPointsAsPolygonFlags);
break;
@@ -891,7 +884,7 @@
size_t length = kFixedCanvasSize;
surface_provider->InitializeSurface(length, length);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
size_t point_count = state.range(0);
state.SetComplexityN(point_count);
@@ -900,12 +893,12 @@
std::vector<SkPoint> points =
GetTestPoints(point_count, SkISize::Make(length, length));
- builder.drawPoints(mode, points.size(), points.data());
+ builder.DrawPoints(mode, points.size(), points.data(), paint);
auto display_list = builder.Build();
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -933,8 +926,8 @@
bool upload_bitmap) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawImageWithPaintFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state,
DisplayListOpFlags::kDrawImageWithPaintFlags);
@@ -942,7 +935,7 @@
size_t canvas_size = 2 * bitmap_size;
surface_provider->InitializeSurface(canvas_size, canvas_size);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
sk_sp<SkImage> image;
std::shared_ptr<DlSurfaceInstance> offscreen_instance;
@@ -969,7 +962,7 @@
for (size_t i = 0; i < kImagesToDraw; i++) {
image = upload_bitmap ? ImageFromBitmapWithNewID(bitmap)
: offscreen->makeImageSnapshot();
- builder.drawImage(DlImage::Make(image), dst, options, true);
+ builder.DrawImage(DlImage::Make(image), dst, options, &paint);
dst.offset(offset, offset);
if (dst.x() + bitmap_size > canvas_size) {
@@ -983,7 +976,7 @@
auto display_list = builder.Build();
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -993,11 +986,11 @@
surface_provider->Snapshot(filename);
}
-std::string ConstraintToString(SkCanvas::SrcRectConstraint constraint) {
+std::string ConstraintToString(DlCanvas::SrcRectConstraint constraint) {
switch (constraint) {
- case SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint:
+ case DlCanvas::SrcRectConstraint::kStrict:
return "Strict";
- case SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint:
+ case DlCanvas::SrcRectConstraint::kFast:
return "Fast";
default:
return "Unknown";
@@ -1012,13 +1005,12 @@
BackendType backend_type,
unsigned attributes,
DlImageSampling options,
- SkCanvas::SrcRectConstraint constraint,
+ DlCanvas::SrcRectConstraint constraint,
bool upload_bitmap) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(
- GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawImageRectWithPaintFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state,
DisplayListOpFlags::kDrawImageRectWithPaintFlags);
@@ -1026,7 +1018,7 @@
size_t canvas_size = 2 * bitmap_size;
surface_provider->InitializeSurface(canvas_size, canvas_size);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
sk_sp<SkImage> image;
std::shared_ptr<DlSurfaceInstance> offscreen_instance;
@@ -1056,7 +1048,7 @@
for (size_t i = 0; i < kImagesToDraw; i++) {
image = upload_bitmap ? ImageFromBitmapWithNewID(bitmap)
: offscreen->makeImageSnapshot();
- builder.drawImageRect(DlImage::Make(image), src, dst, options, true,
+ builder.DrawImageRect(DlImage::Make(image), src, dst, options, &paint,
constraint);
dst.offset(offset, offset);
if (dst.right() > canvas_size) {
@@ -1070,7 +1062,7 @@
auto display_list = builder.Build();
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -1104,9 +1096,8 @@
bool upload_bitmap) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(
- GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawImageNineWithPaintFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state,
DisplayListOpFlags::kDrawImageNineWithPaintFlags);
@@ -1114,7 +1105,7 @@
size_t canvas_size = 2 * bitmap_size;
surface_provider->InitializeSurface(canvas_size, canvas_size);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkIRect center = SkIRect::MakeXYWH(bitmap_size / 4, bitmap_size / 4,
bitmap_size / 2, bitmap_size / 2);
@@ -1145,7 +1136,7 @@
for (size_t i = 0; i < kImagesToDraw; i++) {
image = upload_bitmap ? ImageFromBitmapWithNewID(bitmap)
: offscreen->makeImageSnapshot();
- builder.drawImageNine(DlImage::Make(image), center, dst, filter, true);
+ builder.DrawImageNine(DlImage::Make(image), center, dst, filter, &paint);
dst.offset(offset, offset);
if (dst.right() > canvas_size) {
dst.offsetTo(0, dst.y());
@@ -1158,7 +1149,7 @@
auto display_list = builder.Build();
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -1181,15 +1172,15 @@
unsigned attributes) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawTextBlobFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawTextBlobFlags);
size_t draw_calls = state.range(0);
size_t canvas_size = kFixedCanvasSize;
surface_provider->InitializeSurface(canvas_size, canvas_size);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
state.counters["DrawCallCount_Varies"] = draw_calls;
state.counters["GlyphCount"] = draw_calls;
@@ -1198,13 +1189,13 @@
for (size_t i = 0; i < draw_calls; i++) {
character[0] = 'A' + (i % 26);
auto blob = SkTextBlob::MakeFromString(character, SkFont());
- builder.drawTextBlob(blob, 50.0f, 50.0f);
+ builder.DrawTextBlob(blob, 50.0f, 50.0f, paint);
}
auto display_list = builder.Build();
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -1228,14 +1219,14 @@
SkPath::Verb type) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kDrawShadowFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state, DisplayListOpFlags::kDrawShadowFlags);
size_t length = kFixedCanvasSize;
surface_provider->InitializeSurface(length, length);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
SkPath path;
@@ -1264,12 +1255,12 @@
// We can hardcode dpr to 1.0f as we're varying elevation, and dpr is only
// ever used in conjunction with elevation.
- builder.drawShadow(path, SK_ColorBLUE, elevation, transparent_occluder, 1.0f);
+ builder.DrawShadow(path, SK_ColorBLUE, elevation, transparent_occluder, 1.0f);
auto display_list = builder.Build();
// We only want to time the actual rasterization.
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
@@ -1292,14 +1283,14 @@
size_t save_depth) {
auto surface_provider = DlSurfaceProvider::Create(backend_type);
DisplayListBuilder builder;
- builder.SetAttributesFromPaint(GetPaintForRun(attributes),
- DisplayListOpFlags::kSaveLayerFlags);
+ DlPaint paint = GetPaintForRun(attributes);
+
AnnotateAttributes(attributes, state, DisplayListOpFlags::kSaveLayerFlags);
size_t length = kFixedCanvasSize;
surface_provider->InitializeSurface(length, length);
auto surface = surface_provider->GetPrimarySurface()->sk_surface();
- auto canvas = surface->getCanvas();
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
size_t save_layer_calls = state.range(0);
@@ -1311,19 +1302,19 @@
state.counters["DrawCallCount_Varies"] = save_layer_calls * save_depth;
for (size_t i = 0; i < save_layer_calls; i++) {
for (size_t j = 0; j < save_depth; j++) {
- builder.saveLayer(nullptr, false);
- builder.drawRect(rect1);
- builder.drawRect(rect2);
+ builder.SaveLayer(nullptr, nullptr);
+ builder.DrawRect(rect1, paint);
+ builder.DrawRect(rect2, paint);
}
for (size_t j = 0; j < save_depth; j++) {
- builder.restore();
+ builder.Restore();
}
}
auto display_list = builder.Build();
// We only want to time the actual rasterization.
for ([[maybe_unused]] auto _ : state) {
- display_list->RenderTo(canvas);
+ canvas.DrawDisplayList(display_list);
surface->flushAndSubmit(true);
}
diff --git a/display_list/display_list_benchmarks.h b/display_list/display_list_benchmarks.h
index e6df302..4d02664 100644
--- a/display_list/display_list_benchmarks.h
+++ b/display_list/display_list_benchmarks.h
@@ -78,7 +78,7 @@
BackendType backend_type,
unsigned attributes,
DlImageSampling options,
- SkCanvas::SrcRectConstraint constraint,
+ DlCanvas::SrcRectConstraint constraint,
bool upload_bitmap);
void BM_DrawImageNine(benchmark::State& state,
BackendType backend_type,
@@ -343,8 +343,8 @@
BM_DrawImageRect, Texture/Strict/BACKEND, \
BackendType::k##BACKEND##_Backend, \
ATTRIBUTES, \
- DlImageSampling::kNearestNeighbor, \
- SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint, false) \
+ DlImageSampling::kNearestNeighbor, \
+ DlCanvas::SrcRectConstraint::kStrict, false) \
->RangeMultiplier(2) \
->Range(32, 256) \
->UseRealTime() \
@@ -354,8 +354,8 @@
BM_DrawImageRect, Texture/Fast/BACKEND, \
BackendType::k##BACKEND##_Backend, \
ATTRIBUTES, \
- DlImageSampling::kNearestNeighbor, \
- SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint, false) \
+ DlImageSampling::kNearestNeighbor, \
+ DlCanvas::SrcRectConstraint::kFast, false) \
->RangeMultiplier(2) \
->Range(32, 256) \
->UseRealTime() \
@@ -365,8 +365,8 @@
BM_DrawImageRect, Upload/Strict/BACKEND, \
BackendType::k##BACKEND##_Backend, \
ATTRIBUTES, \
- DlImageSampling::kNearestNeighbor, \
- SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint, true) \
+ DlImageSampling::kNearestNeighbor, \
+ DlCanvas::SrcRectConstraint::kStrict, true) \
->RangeMultiplier(2) \
->Range(32, 256) \
->UseRealTime() \
@@ -376,8 +376,8 @@
BM_DrawImageRect, Upload/Fast/BACKEND, \
BackendType::k##BACKEND##_Backend, \
ATTRIBUTES, \
- DlImageSampling::kNearestNeighbor, \
- SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint, true) \
+ DlImageSampling::kNearestNeighbor, \
+ DlCanvas::SrcRectConstraint::kFast, true) \
->RangeMultiplier(2) \
->Range(32, 256) \
->UseRealTime() \
diff --git a/display_list/display_list_blend_mode.h b/display_list/display_list_blend_mode.h
index b1cdbee..2b5daa9 100644
--- a/display_list/display_list_blend_mode.h
+++ b/display_list/display_list_blend_mode.h
@@ -66,14 +66,6 @@
kDefaultMode = kSrcOver,
};
-inline DlBlendMode ToDl(SkBlendMode mode) {
- return static_cast<DlBlendMode>(mode);
-}
-
-inline SkBlendMode ToSk(DlBlendMode mode) {
- return static_cast<SkBlendMode>(mode);
-}
-
} // namespace flutter
#endif // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_BLEND_MODE_H_
diff --git a/display_list/display_list_builder.cc b/display_list/display_list_builder.cc
index 30ca37d..9ab9db3 100644
--- a/display_list/display_list_builder.cc
+++ b/display_list/display_list_builder.cc
@@ -6,7 +6,6 @@
#include "flutter/display_list/display_list.h"
#include "flutter/display_list/display_list_blend_mode.h"
-#include "flutter/display_list/display_list_canvas_dispatcher.h"
#include "flutter/display_list/display_list_color_source.h"
#include "flutter/display_list/display_list_ops.h"
#include "fml/logging.h"
@@ -250,8 +249,8 @@
new (pod) DlMatrixImageFilter(matrix_filter);
break;
}
- case DlImageFilterType::kComposeFilter:
- case DlImageFilterType::kLocalMatrixFilter:
+ case DlImageFilterType::kCompose:
+ case DlImageFilterType::kLocalMatrix:
case DlImageFilterType::kColorFilter: {
Push<SetSharedImageFilterOp>(0, 0, filter);
break;
@@ -843,7 +842,7 @@
}
void* data_ptr;
- FML_DCHECK(count < Dispatcher::kMaxDrawPointsCount);
+ FML_DCHECK(count < DlOpReceiver::kMaxDrawPointsCount);
int bytes = count * sizeof(SkPoint);
RectBoundsAccumulator ptBounds;
for (size_t i = 0; i < count; i++) {
@@ -947,7 +946,7 @@
const SkRect& dst,
DlImageSampling sampling,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) {
+ SrcRectConstraint constraint) {
Push<DrawImageRectOp>(0, 1, image, src, dst, sampling, render_with_attributes,
constraint);
CheckLayerOpacityCompatibility(render_with_attributes);
@@ -961,10 +960,7 @@
const SkRect& dst,
DlImageSampling sampling,
const DlPaint* paint,
- bool enforce_src_edges) {
- SkCanvas::SrcRectConstraint constraint =
- enforce_src_edges ? SkCanvas::kStrict_SrcRectConstraint
- : SkCanvas::kFast_SrcRectConstraint;
+ SrcRectConstraint constraint) {
if (paint != nullptr) {
SetAttributesFromPaint(*paint,
DisplayListOpFlags::kDrawImageRectWithPaintFlags);
@@ -1077,18 +1073,12 @@
void DisplayListBuilder::DrawDisplayList(const sk_sp<DisplayList> display_list,
SkScalar opacity) {
DlPaint current_paint = current_;
- if (opacity < SK_Scalar1) {
- SaveLayer(&display_list->bounds(), &DlPaint().setOpacity(opacity));
- }
- Push<DrawDisplayListOp>(0, 1, display_list);
- if (opacity < SK_Scalar1) {
- Restore();
- // Not really necessary if the developer is interacting with us via
- // our attribute-state-less DlCanvas methods, but this avoids surprises
- // for those who may have been using the stateful Dispatcher methods.
- SetAttributesFromPaint(current_paint,
- DisplayListOpFlags::kSaveLayerWithPaintFlags);
- }
+ Push<DrawDisplayListOp>(0, 1, display_list, opacity);
+ // Not really necessary if the developer is interacting with us via
+ // our attribute-state-less DlCanvas methods, but this avoids surprises
+ // for those who may have been using the stateful Dispatcher methods.
+ SetAttributesFromPaint(current_paint,
+ DisplayListOpFlags::kSaveLayerWithPaintFlags);
const SkRect bounds = display_list->bounds();
switch (accumulator()->type()) {
@@ -1147,8 +1137,8 @@
? Push<DrawShadowTransparentOccluderOp>(0, 1, path, color, elevation, dpr)
: Push<DrawShadowOp>(0, 1, path, color, elevation, dpr);
- SkRect shadow_bounds = DisplayListCanvasDispatcher::ComputeShadowBounds(
- path, elevation, dpr, GetTransform());
+ SkRect shadow_bounds =
+ DlCanvas::ComputeShadowBounds(path, elevation, dpr, GetTransform());
AccumulateOpBounds(shadow_bounds, kDrawShadowFlags);
UpdateLayerOpacityCompatibility(false);
}
@@ -1195,7 +1185,7 @@
pad = std::max(pad, SK_ScalarSqrt2);
}
SkScalar min_stroke_width = 0.01;
- pad *= std::max(getStrokeWidth() * 0.5f, min_stroke_width);
+ pad *= std::max(current_.getStrokeWidth() * 0.5f, min_stroke_width);
bounds.outset(pad, pad);
}
}
@@ -1264,7 +1254,7 @@
// For example, DstIn is used by masking layers.
// https://code.google.com/p/skia/issues/detail?id=1291
// https://crbug.com/401593
- switch (getBlendMode()) {
+ switch (current_.getBlendMode()) {
// For each of the following transfer modes, if the source
// alpha is zero (our transparent black), the resulting
// blended pixel is not necessarily equal to the original
diff --git a/display_list/display_list_builder.h b/display_list/display_list_builder.h
index 58e20f1..4e85207 100644
--- a/display_list/display_list_builder.h
+++ b/display_list/display_list_builder.h
@@ -8,7 +8,6 @@
#include "flutter/display_list/display_list.h"
#include "flutter/display_list/display_list_blend_mode.h"
#include "flutter/display_list/display_list_comparable.h"
-#include "flutter/display_list/display_list_dispatcher.h"
#include "flutter/display_list/display_list_flags.h"
#include "flutter/display_list/display_list_image.h"
#include "flutter/display_list/display_list_matrix_clip_tracker.h"
@@ -17,17 +16,18 @@
#include "flutter/display_list/display_list_sampling_options.h"
#include "flutter/display_list/display_list_utils.h"
#include "flutter/display_list/dl_canvas.h"
+#include "flutter/display_list/dl_op_receiver.h"
#include "flutter/display_list/types.h"
#include "flutter/fml/macros.h"
namespace flutter {
// The primary class used to build a display list. The list of methods
-// here matches the list of methods invoked on a |Dispatcher| combined
+// here matches the list of methods invoked on a |DlOpReceiver| combined
// with the list of methods invoked on a |DlCanvas|.
class DisplayListBuilder final : public virtual DlCanvas,
public SkRefCnt,
- virtual Dispatcher,
+ virtual DlOpReceiver,
DisplayListOpFlags {
public:
static constexpr SkRect kMaxCullRect =
@@ -39,168 +39,331 @@
explicit DisplayListBuilder(const SkRect& cull_rect = kMaxCullRect,
bool prepare_rtree = false);
- SkISize GetBaseLayerSize() const override;
- SkImageInfo GetImageInfo() const override;
-
~DisplayListBuilder();
- Dispatcher& asDispatcher() { return *this; }
+ // |DlCanvas|
+ SkISize GetBaseLayerSize() const override;
+ // |DlCanvas|
+ SkImageInfo GetImageInfo() const override;
+ // |DlCanvas|
+ void Save() override;
+
+ // |DlCanvas|
+ void SaveLayer(const SkRect* bounds,
+ const DlPaint* paint = nullptr,
+ const DlImageFilter* backdrop = nullptr) override;
+ // |DlCanvas|
+ void Restore() override;
+ // |DlCanvas|
+ int GetSaveCount() const override { return layer_stack_.size(); }
+ // |DlCanvas|
+ void RestoreToCount(int restore_count) override;
+
+ // |DlCanvas|
+ void Translate(SkScalar tx, SkScalar ty) override;
+ // |DlCanvas|
+ void Scale(SkScalar sx, SkScalar sy) override;
+ // |DlCanvas|
+ void Rotate(SkScalar degrees) override;
+ // |DlCanvas|
+ void Skew(SkScalar sx, SkScalar sy) override;
+
+ // clang-format off
+ // 2x3 2D affine subset of a 4x4 transform in row major order
+ // |DlCanvas|
+ void Transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt,
+ SkScalar myx, SkScalar myy, SkScalar myt) override;
+ // full 4x4 transform in row major order
+ // |DlCanvas|
+ void TransformFullPerspective(
+ SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
+ SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
+ SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
+ SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override;
+ // clang-format on
+ // |DlCanvas|
+ void TransformReset() override;
+ // |DlCanvas|
+ void Transform(const SkMatrix* matrix) override;
+ // |DlCanvas|
+ void Transform(const SkM44* matrix44) override;
+ // |DlCanvas|
+ void SetTransform(const SkMatrix* matrix) override {
+ TransformReset();
+ Transform(matrix);
+ }
+ // |DlCanvas|
+ void SetTransform(const SkM44* matrix44) override {
+ TransformReset();
+ Transform(matrix44);
+ }
+ using DlCanvas::Transform;
+
+ /// Returns the 4x4 full perspective transform representing all transform
+ /// operations executed so far in this DisplayList within the enclosing
+ /// save stack.
+ // |DlCanvas|
+ SkM44 GetTransformFullPerspective() const override {
+ return tracker_.matrix_4x4();
+ }
+ /// Returns the 3x3 partial perspective transform representing all transform
+ /// operations executed so far in this DisplayList within the enclosing
+ /// save stack.
+ // |DlCanvas|
+ SkMatrix GetTransform() const override { return tracker_.matrix_3x3(); }
+
+ // |DlCanvas|
+ void ClipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override;
+ // |DlCanvas|
+ void ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override;
+ // |DlCanvas|
+ void ClipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override;
+
+ /// Conservative estimate of the bounds of all outstanding clip operations
+ /// measured in the coordinate space within which this DisplayList will
+ /// be rendered.
+ // |DlCanvas|
+ SkRect GetDestinationClipBounds() const override {
+ return tracker_.device_cull_rect();
+ }
+ /// Conservative estimate of the bounds of all outstanding clip operations
+ /// transformed into the local coordinate space in which currently
+ /// recorded rendering operations are interpreted.
+ // |DlCanvas|
+ SkRect GetLocalClipBounds() const override {
+ return tracker_.local_cull_rect();
+ }
+
+ /// Return true iff the supplied bounds are easily shown to be outside
+ /// of the current clip bounds. This method may conservatively return
+ /// false if it cannot make the determination.
+ // |DlCanvas|
+ bool QuickReject(const SkRect& bounds) const override;
+
+ // |DlCanvas|
+ void DrawPaint(const DlPaint& paint) override;
+ // |DlCanvas|
+ void DrawColor(DlColor color, DlBlendMode mode) override;
+ // |DlCanvas|
+ void DrawLine(const SkPoint& p0,
+ const SkPoint& p1,
+ const DlPaint& paint) override;
+ // |DlCanvas|
+ void DrawRect(const SkRect& rect, const DlPaint& paint) override;
+ // |DlCanvas|
+ void DrawOval(const SkRect& bounds, const DlPaint& paint) override;
+ // |DlCanvas|
+ void DrawCircle(const SkPoint& center,
+ SkScalar radius,
+ const DlPaint& paint) override;
+ // |DlCanvas|
+ void DrawRRect(const SkRRect& rrect, const DlPaint& paint) override;
+ // |DlCanvas|
+ void DrawDRRect(const SkRRect& outer,
+ const SkRRect& inner,
+ const DlPaint& paint) override;
+ // |DlCanvas|
+ void DrawPath(const SkPath& path, const DlPaint& paint) override;
+ // |DlCanvas|
+ void DrawArc(const SkRect& bounds,
+ SkScalar start,
+ SkScalar sweep,
+ bool useCenter,
+ const DlPaint& paint) override;
+ // |DlCanvas|
+ void DrawPoints(PointMode mode,
+ uint32_t count,
+ const SkPoint pts[],
+ const DlPaint& paint) override;
+ // |DlCanvas|
+ void DrawVertices(const DlVertices* vertices,
+ DlBlendMode mode,
+ const DlPaint& paint) override;
+ using DlCanvas::DrawVertices;
+ // |DlCanvas|
+ void DrawImage(const sk_sp<DlImage>& image,
+ const SkPoint point,
+ DlImageSampling sampling,
+ const DlPaint* paint = nullptr) override;
+ // |DlCanvas|
+ void DrawImageRect(
+ const sk_sp<DlImage>& image,
+ const SkRect& src,
+ const SkRect& dst,
+ DlImageSampling sampling,
+ const DlPaint* paint = nullptr,
+ SrcRectConstraint constraint = SrcRectConstraint::kFast) override;
+ // |DlCanvas|
+ void DrawImageNine(const sk_sp<DlImage>& image,
+ const SkIRect& center,
+ const SkRect& dst,
+ DlFilterMode filter,
+ const DlPaint* paint = nullptr) override;
+ // |DlCanvas|
+ void DrawAtlas(const sk_sp<DlImage>& atlas,
+ const SkRSXform xform[],
+ const SkRect tex[],
+ const DlColor colors[],
+ int count,
+ DlBlendMode mode,
+ DlImageSampling sampling,
+ const SkRect* cullRect,
+ const DlPaint* paint = nullptr) override;
+ // |DlCanvas|
+ void DrawDisplayList(const sk_sp<DisplayList> display_list,
+ SkScalar opacity = SK_Scalar1) override;
+ // |DlCanvas|
+ void DrawTextBlob(const sk_sp<SkTextBlob>& blob,
+ SkScalar x,
+ SkScalar y,
+ const DlPaint& paint) override;
+ // |DlCanvas|
+ void DrawShadow(const SkPath& path,
+ const DlColor color,
+ const SkScalar elevation,
+ bool transparent_occluder,
+ SkScalar dpr) override;
+
+ // |DlCanvas|
+ void Flush() override {}
+
+ sk_sp<DisplayList> Build();
+
+ private:
+ // This method exposes the internal stateful DlOpReceiver implementation
+ // of the DisplayListBuilder, primarily for testing purposes. Its use
+ // is obsolete and forbidden in every other case and is only shared to a
+ // pair of "friend" accessors in the benchmark/unittest files.
+ DlOpReceiver& asReceiver() { return *this; }
+
+ friend DlOpReceiver& DisplayListBuilderBenchmarkAccessor(
+ DisplayListBuilder& builder);
+ friend DlOpReceiver& DisplayListBuilderTestingAccessor(
+ DisplayListBuilder& builder);
+
+ void SetAttributesFromPaint(const DlPaint& paint,
+ const DisplayListAttributeFlags flags);
+
+ // |DlOpReceiver|
void setAntiAlias(bool aa) override {
if (current_.isAntiAlias() != aa) {
onSetAntiAlias(aa);
}
}
+ // |DlOpReceiver|
void setDither(bool dither) override {
if (current_.isDither() != dither) {
onSetDither(dither);
}
}
+ // |DlOpReceiver|
void setInvertColors(bool invert) override {
if (current_.isInvertColors() != invert) {
onSetInvertColors(invert);
}
}
+ // |DlOpReceiver|
void setStrokeCap(DlStrokeCap cap) override {
if (current_.getStrokeCap() != cap) {
onSetStrokeCap(cap);
}
}
+ // |DlOpReceiver|
void setStrokeJoin(DlStrokeJoin join) override {
if (current_.getStrokeJoin() != join) {
onSetStrokeJoin(join);
}
}
+ // |DlOpReceiver|
void setStyle(DlDrawStyle style) override {
if (current_.getDrawStyle() != style) {
onSetStyle(style);
}
}
+ // |DlOpReceiver|
void setStrokeWidth(float width) override {
if (current_.getStrokeWidth() != width) {
onSetStrokeWidth(width);
}
}
+ // |DlOpReceiver|
void setStrokeMiter(float limit) override {
if (current_.getStrokeMiter() != limit) {
onSetStrokeMiter(limit);
}
}
+ // |DlOpReceiver|
void setColor(DlColor color) override {
if (current_.getColor() != color) {
onSetColor(color);
}
}
+ // |DlOpReceiver|
void setBlendMode(DlBlendMode mode) override {
if (current_.getBlendMode() != mode) {
onSetBlendMode(mode);
}
}
+ // |DlOpReceiver|
void setColorSource(const DlColorSource* source) override {
if (NotEquals(current_.getColorSource(), source)) {
onSetColorSource(source);
}
}
+ // |DlOpReceiver|
void setImageFilter(const DlImageFilter* filter) override {
if (NotEquals(current_.getImageFilter(), filter)) {
onSetImageFilter(filter);
}
}
+ // |DlOpReceiver|
void setColorFilter(const DlColorFilter* filter) override {
if (NotEquals(current_.getColorFilter(), filter)) {
onSetColorFilter(filter);
}
}
+ // |DlOpReceiver|
void setPathEffect(const DlPathEffect* effect) override {
if (NotEquals(current_.getPathEffect(), effect)) {
onSetPathEffect(effect);
}
}
+ // |DlOpReceiver|
void setMaskFilter(const DlMaskFilter* filter) override {
if (NotEquals(current_.getMaskFilter(), filter)) {
onSetMaskFilter(filter);
}
}
- bool isAntiAlias() const { return current_.isAntiAlias(); }
- bool isDither() const { return current_.isDither(); }
- DlDrawStyle getStyle() const { return current_.getDrawStyle(); }
- DlColor getColor() const { return current_.getColor(); }
- float getStrokeWidth() const { return current_.getStrokeWidth(); }
- float getStrokeMiter() const { return current_.getStrokeMiter(); }
- DlStrokeCap getStrokeCap() const { return current_.getStrokeCap(); }
- DlStrokeJoin getStrokeJoin() const { return current_.getStrokeJoin(); }
- std::shared_ptr<const DlColorSource> getColorSource() const {
- return current_.getColorSource();
- }
- std::shared_ptr<const DlColorFilter> getColorFilter() const {
- return current_.getColorFilter();
- }
- bool isInvertColors() const { return current_.isInvertColors(); }
- DlBlendMode getBlendMode() const { return current_.getBlendMode(); }
- std::shared_ptr<const DlPathEffect> getPathEffect() const {
- return current_.getPathEffect();
- }
- std::shared_ptr<const DlMaskFilter> getMaskFilter() const {
- return current_.getMaskFilter();
- }
- std::shared_ptr<const DlImageFilter> getImageFilter() const {
- return current_.getImageFilter();
- }
-
- void Save() override;
+ // |DlOpReceiver|
void save() override { Save(); }
-
// Only the |renders_with_attributes()| option will be accepted here. Any
// other flags will be ignored and calculated anew as the DisplayList is
// built. Alternatively, use the |saveLayer(SkRect, bool)| method.
+ // |DlOpReceiver|
void saveLayer(const SkRect* bounds,
const SaveLayerOptions options,
const DlImageFilter* backdrop) override;
- // Convenience method with just a boolean to indicate whether the saveLayer
- // should apply the rendering attributes.
- void saveLayer(const SkRect* bounds, bool renders_with_attributes) {
- saveLayer(bounds,
- renders_with_attributes ? SaveLayerOptions::kWithAttributes
- : SaveLayerOptions::kNoAttributes,
- nullptr);
- }
- void SaveLayer(const SkRect* bounds,
- const DlPaint* paint = nullptr,
- const DlImageFilter* backdrop = nullptr) override;
- void Restore() override;
+ // |DlOpReceiver|
void restore() override { Restore(); }
- int GetSaveCount() const override { return layer_stack_.size(); }
- void RestoreToCount(int restore_count) override;
- void restoreToCount(int restore_count) { RestoreToCount(restore_count); }
- void Translate(SkScalar tx, SkScalar ty) override;
- void Scale(SkScalar sx, SkScalar sy) override;
- void Rotate(SkScalar degrees) override;
- void Skew(SkScalar sx, SkScalar sy) override;
+ // |DlOpReceiver|
void translate(SkScalar tx, SkScalar ty) override { Translate(tx, ty); }
+ // |DlOpReceiver|
void scale(SkScalar sx, SkScalar sy) override { Scale(sx, sy); }
+ // |DlOpReceiver|
void rotate(SkScalar degrees) override { Rotate(degrees); }
+ // |DlOpReceiver|
void skew(SkScalar sx, SkScalar sy) override { Skew(sx, sy); }
- void SetAttributesFromPaint(const DlPaint& paint,
- const DisplayListAttributeFlags flags);
-
// clang-format off
-
- // 2x3 2D affine subset of a 4x4 transform in row major order
- void Transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt,
- SkScalar myx, SkScalar myy, SkScalar myt) override;
+ // |DlOpReceiver|
void transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt,
SkScalar myx, SkScalar myy, SkScalar myt) override {
Transform2DAffine(mxx, mxy, mxt, myx, myy, myt);
}
- // full 4x4 transform in row major order
- void TransformFullPerspective(
- SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
- SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
- SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
- SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) override;
+ // |DlOpReceiver|
void transformFullPerspective(
SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
@@ -211,148 +374,73 @@
mzx, mzy, mzz, mzt,
mwx, mwy, mwz, mwt);
}
- // clang-format on
- void TransformReset() override;
- void Transform(const SkMatrix* matrix) override;
- void Transform(const SkM44* matrix44) override;
- void SetTransform(const SkMatrix* matrix) override {
- TransformReset();
- Transform(matrix);
- }
- void SetTransform(const SkM44* matrix44) override {
- TransformReset();
- Transform(matrix44);
- }
- using DlCanvas::Transform;
+ // clang-format off
+ // |DlOpReceiver|
void transformReset() override { TransformReset(); }
- void transform(const SkMatrix* matrix) { Transform(matrix); }
- void transform(const SkM44* matrix44) { Transform(matrix44); }
- void transform(const SkMatrix& matrix) { Transform(&matrix); }
- void transform(const SkM44& matrix44) { Transform(&matrix44); }
- /// Returns the 4x4 full perspective transform representing all transform
- /// operations executed so far in this DisplayList within the enclosing
- /// save stack.
- SkM44 GetTransformFullPerspective() const override {
- return tracker_.matrix_4x4();
- }
- /// Returns the 3x3 partial perspective transform representing all transform
- /// operations executed so far in this DisplayList within the enclosing
- /// save stack.
- SkMatrix GetTransform() const override { return tracker_.matrix_3x3(); }
-
- void ClipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override;
- void ClipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override;
- void ClipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override;
+ // |DlOpReceiver|
void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override {
ClipRect(rect, clip_op, is_aa);
}
+ // |DlOpReceiver|
void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override {
ClipRRect(rrect, clip_op, is_aa);
}
+ // |DlOpReceiver|
void clipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override {
ClipPath(path, clip_op, is_aa);
}
- /// Conservative estimate of the bounds of all outstanding clip operations
- /// measured in the coordinate space within which this DisplayList will
- /// be rendered.
- SkRect GetDestinationClipBounds() const override {
- return tracker_.device_cull_rect();
- }
- /// Conservative estimate of the bounds of all outstanding clip operations
- /// transformed into the local coordinate space in which currently
- /// recorded rendering operations are interpreted.
- SkRect GetLocalClipBounds() const override {
- return tracker_.local_cull_rect();
- }
-
- /// Return true iff the supplied bounds are easily shown to be outside
- /// of the current clip bounds. This method may conservatively return
- /// false if it cannot make the determination.
- bool QuickReject(const SkRect& bounds) const override;
-
+ // |DlOpReceiver|
void drawPaint() override;
- void DrawPaint(const DlPaint& paint) override;
- void DrawColor(DlColor color, DlBlendMode mode) override;
+ // |DlOpReceiver|
void drawColor(DlColor color, DlBlendMode mode) override {
DrawColor(color, mode);
}
+ // |DlOpReceiver|
void drawLine(const SkPoint& p0, const SkPoint& p1) override;
- void DrawLine(const SkPoint& p0,
- const SkPoint& p1,
- const DlPaint& paint) override;
+ // |DlOpReceiver|
void drawRect(const SkRect& rect) override;
- void DrawRect(const SkRect& rect, const DlPaint& paint) override;
+ // |DlOpReceiver|
void drawOval(const SkRect& bounds) override;
- void DrawOval(const SkRect& bounds, const DlPaint& paint) override;
+ // |DlOpReceiver|
void drawCircle(const SkPoint& center, SkScalar radius) override;
- void DrawCircle(const SkPoint& center,
- SkScalar radius,
- const DlPaint& paint) override;
+ // |DlOpReceiver|
void drawRRect(const SkRRect& rrect) override;
- void DrawRRect(const SkRRect& rrect, const DlPaint& paint) override;
+ // |DlOpReceiver|
void drawDRRect(const SkRRect& outer, const SkRRect& inner) override;
- void DrawDRRect(const SkRRect& outer,
- const SkRRect& inner,
- const DlPaint& paint) override;
+ // |DlOpReceiver|
void drawPath(const SkPath& path) override;
- void DrawPath(const SkPath& path, const DlPaint& paint) override;
+ // |DlOpReceiver|
void drawArc(const SkRect& bounds,
SkScalar start,
SkScalar sweep,
bool useCenter) override;
- void DrawArc(const SkRect& bounds,
- SkScalar start,
- SkScalar sweep,
- bool useCenter,
- const DlPaint& paint) override;
+ // |DlOpReceiver|
void drawPoints(PointMode mode, uint32_t count, const SkPoint pts[]) override;
- void DrawPoints(PointMode mode,
- uint32_t count,
- const SkPoint pts[],
- const DlPaint& paint) override;
+ // |DlOpReceiver|
void drawVertices(const DlVertices* vertices, DlBlendMode mode) override;
- void drawVertices(const std::shared_ptr<const DlVertices> vertices,
- DlBlendMode mode) {
- drawVertices(vertices.get(), mode);
- }
- void DrawVertices(const DlVertices* vertices,
- DlBlendMode mode,
- const DlPaint& paint) override;
- using DlCanvas::DrawVertices;
+
+ // |DlOpReceiver|
void drawImage(const sk_sp<DlImage> image,
const SkPoint point,
DlImageSampling sampling,
bool render_with_attributes) override;
- void DrawImage(const sk_sp<DlImage>& image,
- const SkPoint point,
- DlImageSampling sampling,
- const DlPaint* paint = nullptr) override;
+ // |DlOpReceiver|
void drawImageRect(
const sk_sp<DlImage> image,
const SkRect& src,
const SkRect& dst,
DlImageSampling sampling,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint =
- SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint) override;
- void DrawImageRect(const sk_sp<DlImage>& image,
- const SkRect& src,
- const SkRect& dst,
- DlImageSampling sampling,
- const DlPaint* paint = nullptr,
- bool enforce_src_edges = false) override;
+ SrcRectConstraint constraint = SrcRectConstraint::kFast) override;
+ // |DlOpReceiver|
void drawImageNine(const sk_sp<DlImage> image,
const SkIRect& center,
const SkRect& dst,
DlFilterMode filter,
bool render_with_attributes) override;
- void DrawImageNine(const sk_sp<DlImage>& image,
- const SkIRect& center,
- const SkRect& dst,
- DlFilterMode filter,
- const DlPaint* paint = nullptr) override;
+ // |DlOpReceiver|
void drawAtlas(const sk_sp<DlImage> atlas,
const SkRSXform xform[],
const SkRect tex[],
@@ -362,32 +450,17 @@
DlImageSampling sampling,
const SkRect* cullRect,
bool render_with_attributes) override;
- void DrawAtlas(const sk_sp<DlImage>& atlas,
- const SkRSXform xform[],
- const SkRect tex[],
- const DlColor colors[],
- int count,
- DlBlendMode mode,
- DlImageSampling sampling,
- const SkRect* cullRect,
- const DlPaint* paint = nullptr) override;
- void DrawDisplayList(const sk_sp<DisplayList> display_list,
- SkScalar opacity) override;
- void drawDisplayList(const sk_sp<DisplayList> display_list) override {
- DrawDisplayList(display_list, SK_Scalar1);
+
+ // |DlOpReceiver|
+ void drawDisplayList(const sk_sp<DisplayList> display_list,
+ SkScalar opacity) override {
+ DrawDisplayList(display_list, opacity);
}
+ // |DlOpReceiver|
void drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y) override;
- void DrawTextBlob(const sk_sp<SkTextBlob>& blob,
- SkScalar x,
- SkScalar y,
- const DlPaint& paint) override;
- void DrawShadow(const SkPath& path,
- const DlColor color,
- const SkScalar elevation,
- bool transparent_occluder,
- SkScalar dpr) override;
+ // |DlOpReceiver|
void drawShadow(const SkPath& path,
const DlColor color,
const SkScalar elevation,
@@ -396,11 +469,6 @@
DrawShadow(path, color, elevation, transparent_occluder, dpr);
}
- void Flush() override {}
-
- sk_sp<DisplayList> Build();
-
- private:
void checkForDeferredSave();
DisplayListStorage storage_;
diff --git a/display_list/display_list_builder_benchmarks.cc b/display_list/display_list_builder_benchmarks.cc
index 7405901..87f4bfc 100644
--- a/display_list/display_list_builder_benchmarks.cc
+++ b/display_list/display_list_builder_benchmarks.cc
@@ -6,6 +6,11 @@
#include "flutter/display_list/testing/dl_test_snippets.h"
namespace flutter {
+
+DlOpReceiver& DisplayListBuilderBenchmarkAccessor(DisplayListBuilder& builder) {
+ return builder.asReceiver();
+}
+
namespace {
static std::vector<testing::DisplayListInvocationGroup> allRenderingOps =
@@ -19,10 +24,11 @@
};
static void InvokeAllRenderingOps(DisplayListBuilder& builder) {
+ DlOpReceiver& receiver = DisplayListBuilderBenchmarkAccessor(builder);
for (auto& group : allRenderingOps) {
for (size_t i = 0; i < group.variants.size(); i++) {
auto& invocation = group.variants[i];
- invocation.Invoke(builder);
+ invocation.Invoke(receiver);
}
}
}
@@ -69,8 +75,8 @@
bool prepare_rtree = NeedPrepareRTree(type);
while (state.KeepRunning()) {
DisplayListBuilder builder(prepare_rtree);
- builder.scale(3.5, 3.5);
- builder.translate(10.3, 6.9);
+ builder.Scale(3.5, 3.5);
+ builder.Translate(10.3, 6.9);
InvokeAllRenderingOps(builder);
Complete(builder, type);
}
@@ -82,7 +88,7 @@
bool prepare_rtree = NeedPrepareRTree(type);
while (state.KeepRunning()) {
DisplayListBuilder builder(prepare_rtree);
- builder.transformFullPerspective(0, 1, 0, 12, 1, 0, 0, 33, 3, 2, 5, 29, 0,
+ builder.TransformFullPerspective(0, 1, 0, 12, 1, 0, 0, 33, 3, 2, 5, 29, 0,
0, 0, 12);
InvokeAllRenderingOps(builder);
Complete(builder, type);
@@ -96,7 +102,7 @@
bool prepare_rtree = NeedPrepareRTree(type);
while (state.KeepRunning()) {
DisplayListBuilder builder(prepare_rtree);
- builder.clipRect(clip_bounds, DlCanvas::ClipOp::kIntersect, true);
+ builder.ClipRect(clip_bounds, DlCanvas::ClipOp::kIntersect, true);
InvokeAllRenderingOps(builder);
Complete(builder, type);
}
@@ -108,12 +114,13 @@
bool prepare_rtree = NeedPrepareRTree(type);
while (state.KeepRunning()) {
DisplayListBuilder builder(prepare_rtree);
+ DlOpReceiver& receiver = DisplayListBuilderBenchmarkAccessor(builder);
for (auto& group : allRenderingOps) {
for (size_t i = 0; i < group.variants.size(); i++) {
auto& invocation = group.variants[i];
- builder.saveLayer(nullptr, false);
- invocation.Invoke(builder);
- builder.restore();
+ builder.SaveLayer(nullptr, nullptr);
+ invocation.Invoke(receiver);
+ builder.Restore();
}
}
Complete(builder, type);
@@ -129,11 +136,12 @@
bool prepare_rtree = NeedPrepareRTree(type);
while (state.KeepRunning()) {
DisplayListBuilder builder(prepare_rtree);
+ DlOpReceiver& receiver = DisplayListBuilderBenchmarkAccessor(builder);
for (auto& group : allRenderingOps) {
for (size_t i = 0; i < group.variants.size(); i++) {
auto& invocation = group.variants[i];
builder.SaveLayer(&layer_bounds, &layer_paint);
- invocation.Invoke(builder);
+ invocation.Invoke(receiver);
builder.Restore();
}
}
diff --git a/display_list/display_list_canvas_dispatcher.cc b/display_list/display_list_canvas_dispatcher.cc
deleted file mode 100644
index 34dbe83..0000000
--- a/display_list/display_list_canvas_dispatcher.cc
+++ /dev/null
@@ -1,305 +0,0 @@
-// 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_canvas_dispatcher.h"
-
-#include "flutter/display_list/display_list_blend_mode.h"
-#include "flutter/fml/trace_event.h"
-
-namespace flutter {
-
-const SkScalar kLightHeight = 600;
-const SkScalar kLightRadius = 800;
-
-static SkClipOp ToSk(DlCanvas::ClipOp op) {
- return static_cast<SkClipOp>(op);
-}
-
-static SkCanvas::PointMode ToSk(DlCanvas::PointMode mode) {
- return static_cast<SkCanvas::PointMode>(mode);
-}
-
-const SkPaint* DisplayListCanvasDispatcher::safe_paint(bool use_attributes) {
- if (use_attributes) {
- // The accumulated SkPaint object will already have incorporated
- // any attribute overrides.
- return &paint();
- } else if (has_opacity()) {
- temp_paint_.setAlphaf(opacity());
- return &temp_paint_;
- } else {
- return nullptr;
- }
-}
-
-void DisplayListCanvasDispatcher::save() {
- canvas_->save();
- // save has no impact on attributes, but it needs to register a record
- // on the restore stack so that the eventual call to restore() will
- // know what to do at that time. We could annotate the restore record
- // with a flag that the record came from a save call, but it is simpler
- // to just pass in the current opacity value as the value to be used by
- // the children and let the utility calls notice that it didn't change.
- save_opacity(opacity());
-}
-void DisplayListCanvasDispatcher::restore() {
- canvas_->restore();
- restore_opacity();
-}
-void DisplayListCanvasDispatcher::saveLayer(const SkRect* bounds,
- const SaveLayerOptions options,
- const DlImageFilter* backdrop) {
- if (bounds == nullptr && options.can_distribute_opacity() &&
- backdrop == nullptr) {
- // We know that:
- // - no bounds is needed for clipping here
- // - no backdrop filter is used to initialize the layer
- // - the current attributes only have an alpha
- // - the children are compatible with individually rendering with
- // an inherited opacity
- // Therefore we can just use a save instead of a saveLayer and pass the
- // intended opacity to the children.
- canvas_->save();
- // If the saveLayer does not use attributes, the children should continue
- // to render with the inherited opacity unmodified. If attributes are to
- // be applied, the children should render with the combination of the
- // inherited opacity combined with the alpha from the current color.
- save_opacity(options.renders_with_attributes() ? combined_opacity()
- : opacity());
- } else {
- TRACE_EVENT0("flutter", "Canvas::saveLayer");
- const SkPaint* paint = safe_paint(options.renders_with_attributes());
- const sk_sp<SkImageFilter> sk_backdrop =
- backdrop ? backdrop->skia_object() : nullptr;
- canvas_->saveLayer(
- SkCanvas::SaveLayerRec(bounds, paint, sk_backdrop.get(), 0));
- // saveLayer will apply the current opacity on behalf of the children
- // so they will inherit an opaque opacity.
- save_opacity(SK_Scalar1);
- }
-}
-
-void DisplayListCanvasDispatcher::translate(SkScalar tx, SkScalar ty) {
- canvas_->translate(tx, ty);
-}
-void DisplayListCanvasDispatcher::scale(SkScalar sx, SkScalar sy) {
- canvas_->scale(sx, sy);
-}
-void DisplayListCanvasDispatcher::rotate(SkScalar degrees) {
- canvas_->rotate(degrees);
-}
-void DisplayListCanvasDispatcher::skew(SkScalar sx, SkScalar sy) {
- canvas_->skew(sx, sy);
-}
-// clang-format off
-// 2x3 2D affine subset of a 4x4 transform in row major order
-void DisplayListCanvasDispatcher::transform2DAffine(
- SkScalar mxx, SkScalar mxy, SkScalar mxt,
- SkScalar myx, SkScalar myy, SkScalar myt) {
- // Internally concat(SkMatrix) gets redirected to concat(SkM44)
- // so we just jump directly to the SkM44 version
- canvas_->concat(SkM44(mxx, mxy, 0, mxt,
- myx, myy, 0, myt,
- 0, 0, 1, 0,
- 0, 0, 0, 1));
-}
-// full 4x4 transform in row major order
-void DisplayListCanvasDispatcher::transformFullPerspective(
- SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
- SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
- SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
- SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
- canvas_->concat(SkM44(mxx, mxy, mxz, mxt,
- myx, myy, myz, myt,
- mzx, mzy, mzz, mzt,
- mwx, mwy, mwz, mwt));
-}
-// clang-format on
-void DisplayListCanvasDispatcher::transformReset() {
- canvas_->setMatrix(original_transform_);
-}
-
-void DisplayListCanvasDispatcher::clipRect(const SkRect& rect,
- ClipOp clip_op,
- bool is_aa) {
- canvas_->clipRect(rect, ToSk(clip_op), is_aa);
-}
-void DisplayListCanvasDispatcher::clipRRect(const SkRRect& rrect,
- ClipOp clip_op,
- bool is_aa) {
- canvas_->clipRRect(rrect, ToSk(clip_op), is_aa);
-}
-void DisplayListCanvasDispatcher::clipPath(const SkPath& path,
- ClipOp clip_op,
- bool is_aa) {
- canvas_->clipPath(path, ToSk(clip_op), is_aa);
-}
-
-void DisplayListCanvasDispatcher::drawPaint() {
- const SkPaint& sk_paint = paint();
- SkImageFilter* filter = sk_paint.getImageFilter();
- if (filter && !filter->asColorFilter(nullptr)) {
- // drawPaint does an implicit saveLayer if an SkImageFilter is
- // present that cannot be replaced by an SkColorFilter.
- TRACE_EVENT0("flutter", "Canvas::saveLayer");
- }
- canvas_->drawPaint(sk_paint);
-}
-void DisplayListCanvasDispatcher::drawColor(DlColor color, DlBlendMode mode) {
- // SkCanvas::drawColor(SkColor) does the following conversion anyway
- // We do it here manually to increase precision on applying opacity
- SkColor4f color4f = SkColor4f::FromColor(color);
- color4f.fA *= opacity();
- canvas_->drawColor(color4f, ToSk(mode));
-}
-void DisplayListCanvasDispatcher::drawLine(const SkPoint& p0,
- const SkPoint& p1) {
- canvas_->drawLine(p0, p1, paint());
-}
-void DisplayListCanvasDispatcher::drawRect(const SkRect& rect) {
- canvas_->drawRect(rect, paint());
-}
-void DisplayListCanvasDispatcher::drawOval(const SkRect& bounds) {
- canvas_->drawOval(bounds, paint());
-}
-void DisplayListCanvasDispatcher::drawCircle(const SkPoint& center,
- SkScalar radius) {
- canvas_->drawCircle(center, radius, paint());
-}
-void DisplayListCanvasDispatcher::drawRRect(const SkRRect& rrect) {
- canvas_->drawRRect(rrect, paint());
-}
-void DisplayListCanvasDispatcher::drawDRRect(const SkRRect& outer,
- const SkRRect& inner) {
- canvas_->drawDRRect(outer, inner, paint());
-}
-void DisplayListCanvasDispatcher::drawPath(const SkPath& path) {
- canvas_->drawPath(path, paint());
-}
-void DisplayListCanvasDispatcher::drawArc(const SkRect& bounds,
- SkScalar start,
- SkScalar sweep,
- bool useCenter) {
- canvas_->drawArc(bounds, start, sweep, useCenter, paint());
-}
-void DisplayListCanvasDispatcher::drawPoints(PointMode mode,
- uint32_t count,
- const SkPoint pts[]) {
- canvas_->drawPoints(ToSk(mode), count, pts, paint());
-}
-void DisplayListCanvasDispatcher::drawVertices(const DlVertices* vertices,
- DlBlendMode mode) {
- canvas_->drawVertices(vertices->skia_object(), ToSk(mode), paint());
-}
-void DisplayListCanvasDispatcher::drawImage(const sk_sp<DlImage> image,
- const SkPoint point,
- DlImageSampling sampling,
- bool render_with_attributes) {
- canvas_->drawImage(image ? image->skia_image() : nullptr, point.fX, point.fY,
- ToSk(sampling), safe_paint(render_with_attributes));
-}
-void DisplayListCanvasDispatcher::drawImageRect(
- const sk_sp<DlImage> image,
- const SkRect& src,
- const SkRect& dst,
- DlImageSampling sampling,
- bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) {
- canvas_->drawImageRect(image ? image->skia_image() : nullptr, src, dst,
- ToSk(sampling), safe_paint(render_with_attributes),
- constraint);
-}
-void DisplayListCanvasDispatcher::drawImageNine(const sk_sp<DlImage> image,
- const SkIRect& center,
- const SkRect& dst,
- DlFilterMode filter,
- bool render_with_attributes) {
- if (!image) {
- return;
- }
- auto skia_image = image->skia_image();
- if (!skia_image) {
- return;
- }
- canvas_->drawImageNine(skia_image.get(), center, dst, ToSk(filter),
- safe_paint(render_with_attributes));
-}
-void DisplayListCanvasDispatcher::drawAtlas(const sk_sp<DlImage> atlas,
- const SkRSXform xform[],
- const SkRect tex[],
- const DlColor colors[],
- int count,
- DlBlendMode mode,
- DlImageSampling sampling,
- const SkRect* cullRect,
- bool render_with_attributes) {
- if (!atlas) {
- return;
- }
- auto skia_atlas = atlas->skia_image();
- if (!skia_atlas) {
- return;
- }
- const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors);
- canvas_->drawAtlas(skia_atlas.get(), xform, tex, sk_colors, count, ToSk(mode),
- ToSk(sampling), cullRect,
- safe_paint(render_with_attributes));
-}
-void DisplayListCanvasDispatcher::drawDisplayList(
- const sk_sp<DisplayList> display_list) {
- int save_count = canvas_->save();
- display_list->RenderTo(canvas_, opacity());
- canvas_->restoreToCount(save_count);
-}
-void DisplayListCanvasDispatcher::drawTextBlob(const sk_sp<SkTextBlob> blob,
- SkScalar x,
- SkScalar y) {
- canvas_->drawTextBlob(blob, x, y, paint());
-}
-
-SkRect DisplayListCanvasDispatcher::ComputeShadowBounds(const SkPath& path,
- float elevation,
- SkScalar dpr,
- const SkMatrix& ctm) {
- SkRect shadow_bounds(path.getBounds());
- SkShadowUtils::GetLocalBounds(
- ctm, path, SkPoint3::Make(0, 0, dpr * elevation),
- SkPoint3::Make(0, -1, 1), kLightRadius / kLightHeight,
- SkShadowFlags::kDirectionalLight_ShadowFlag, &shadow_bounds);
- return shadow_bounds;
-}
-
-void DisplayListCanvasDispatcher::DrawShadow(SkCanvas* canvas,
- const SkPath& path,
- DlColor color,
- float elevation,
- bool transparentOccluder,
- SkScalar dpr) {
- const SkScalar kAmbientAlpha = 0.039f;
- const SkScalar kSpotAlpha = 0.25f;
-
- uint32_t flags = transparentOccluder
- ? SkShadowFlags::kTransparentOccluder_ShadowFlag
- : SkShadowFlags::kNone_ShadowFlag;
- flags |= SkShadowFlags::kDirectionalLight_ShadowFlag;
- SkColor in_ambient = SkColorSetA(color, kAmbientAlpha * SkColorGetA(color));
- SkColor in_spot = SkColorSetA(color, kSpotAlpha * SkColorGetA(color));
- SkColor ambient_color, spot_color;
- SkShadowUtils::ComputeTonalColors(in_ambient, in_spot, &ambient_color,
- &spot_color);
- SkShadowUtils::DrawShadow(canvas, path, SkPoint3::Make(0, 0, dpr * elevation),
- SkPoint3::Make(0, -1, 1),
- kLightRadius / kLightHeight, ambient_color,
- spot_color, flags);
-}
-
-void DisplayListCanvasDispatcher::drawShadow(const SkPath& path,
- const DlColor color,
- const SkScalar elevation,
- bool transparent_occluder,
- SkScalar dpr) {
- DrawShadow(canvas_, path, color, elevation, transparent_occluder, dpr);
-}
-
-} // namespace flutter
diff --git a/display_list/display_list_color.h b/display_list/display_list_color.h
index d84ccd4..855df42 100644
--- a/display_list/display_list_color.h
+++ b/display_list/display_list_color.h
@@ -35,6 +35,7 @@
uint32_t argb;
bool isOpaque() const { return getAlpha() == 0xFF; }
+ bool isTransparent() const { return getAlpha() == 0; }
int getAlpha() const { return argb >> 24; }
int getRed() const { return (argb >> 16) & 0xFF; }
diff --git a/display_list/display_list_color_filter.cc b/display_list/display_list_color_filter.cc
index 6f46b02..778214e 100644
--- a/display_list/display_list_color_filter.cc
+++ b/display_list/display_list_color_filter.cc
@@ -8,16 +8,193 @@
namespace flutter {
+std::shared_ptr<DlColorFilter> DlBlendColorFilter::Make(DlColor color,
+ DlBlendMode mode) {
+ switch (mode) {
+ case DlBlendMode::kDst: {
+ return nullptr;
+ }
+ case DlBlendMode::kSrcOver: {
+ if (color.isTransparent()) {
+ return nullptr;
+ }
+ if (color.isOpaque()) {
+ mode = DlBlendMode::kSrc;
+ }
+ break;
+ }
+ case DlBlendMode::kDstOver:
+ case DlBlendMode::kDstOut:
+ case DlBlendMode::kSrcATop:
+ case DlBlendMode::kXor:
+ case DlBlendMode::kDarken: {
+ if (color.isTransparent()) {
+ return nullptr;
+ }
+ break;
+ }
+ case DlBlendMode::kDstIn: {
+ if (color.isOpaque()) {
+ return nullptr;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return std::make_shared<DlBlendColorFilter>(color, mode);
+}
+
+bool DlBlendColorFilter::modifies_transparent_black() const {
+ switch (mode_) {
+ // These modes all act like kSrc when the dest is all 0s.
+ // So they modify transparent black when the src color is
+ // not transparent.
+ case DlBlendMode::kSrc:
+ case DlBlendMode::kSrcOver:
+ case DlBlendMode::kDstOver:
+ case DlBlendMode::kSrcOut:
+ case DlBlendMode::kDstATop:
+ case DlBlendMode::kXor:
+ case DlBlendMode::kPlus:
+ case DlBlendMode::kScreen:
+ case DlBlendMode::kOverlay:
+ case DlBlendMode::kDarken:
+ case DlBlendMode::kLighten:
+ case DlBlendMode::kColorDodge:
+ case DlBlendMode::kColorBurn:
+ case DlBlendMode::kHardLight:
+ case DlBlendMode::kSoftLight:
+ case DlBlendMode::kDifference:
+ case DlBlendMode::kExclusion:
+ case DlBlendMode::kMultiply:
+ case DlBlendMode::kHue:
+ case DlBlendMode::kSaturation:
+ case DlBlendMode::kColor:
+ case DlBlendMode::kLuminosity:
+ return !color_.isTransparent();
+
+ // These modes are all like kDst when the dest is all 0s.
+ // So they never modify transparent black.
+ case DlBlendMode::kClear:
+ case DlBlendMode::kDst:
+ case DlBlendMode::kSrcIn:
+ case DlBlendMode::kDstIn:
+ case DlBlendMode::kDstOut:
+ case DlBlendMode::kSrcATop:
+ case DlBlendMode::kModulate:
+ return false;
+ }
+}
+
+bool DlBlendColorFilter::can_commute_with_opacity() const {
+ switch (mode_) {
+ case DlBlendMode::kClear:
+ case DlBlendMode::kDst:
+ case DlBlendMode::kSrcIn:
+ case DlBlendMode::kDstIn:
+ case DlBlendMode::kDstOut:
+ case DlBlendMode::kSrcATop:
+ case DlBlendMode::kModulate:
+ return true;
+
+ case DlBlendMode::kSrc:
+ case DlBlendMode::kSrcOver:
+ case DlBlendMode::kDstOver:
+ case DlBlendMode::kSrcOut:
+ case DlBlendMode::kDstATop:
+ case DlBlendMode::kXor:
+ case DlBlendMode::kPlus:
+ case DlBlendMode::kScreen:
+ case DlBlendMode::kOverlay:
+ case DlBlendMode::kDarken:
+ case DlBlendMode::kLighten:
+ case DlBlendMode::kColorDodge:
+ case DlBlendMode::kColorBurn:
+ case DlBlendMode::kHardLight:
+ case DlBlendMode::kSoftLight:
+ case DlBlendMode::kDifference:
+ case DlBlendMode::kExclusion:
+ case DlBlendMode::kMultiply:
+ case DlBlendMode::kHue:
+ case DlBlendMode::kSaturation:
+ case DlBlendMode::kColor:
+ case DlBlendMode::kLuminosity:
+ return color_.isTransparent();
+ }
+}
+
+std::shared_ptr<DlColorFilter> DlMatrixColorFilter::Make(
+ const float matrix[20]) {
+ float product = 0;
+ for (int i = 0; i < 20; i++) {
+ product *= matrix[i];
+ }
+ // If any of the elements of the matrix are infinity or NaN, then
+ // |product| will be NaN, otherwise 0.
+ if (product == 0) {
+ return std::make_shared<DlMatrixColorFilter>(matrix);
+ }
+ return nullptr;
+}
+
+bool DlMatrixColorFilter::modifies_transparent_black() const {
+ // Values are considered in non-premultiplied form when the matrix is
+ // applied, but we only care about this answer for whether it leaves
+ // an incoming color with a transparent alpha as transparent on output.
+ // Thus, we only need to consider the alpha part of the matrix equation,
+ // which is the last row. Since the incoming alpha value is 0, the last
+ // equation ends up becoming A' = matrix_[19]. Negative results will be
+ // clamped to the range [0,1] so we only care about positive values.
+ // Non-finite values are clamped to a zero alpha.
+ return (SkScalarIsFinite(matrix_[19]) && matrix_[19] > 0);
+}
+
+bool DlMatrixColorFilter::can_commute_with_opacity() const {
+ // We need to check if:
+ // filter(color) * opacity == filter(color * opacity).
+ //
+ // filter(RGBA) = R' = [ R*m[ 0] + G*m[ 1] + B*m[ 2] + A*m[ 3] + m[ 4] ]
+ // G' = [ R*m[ 5] + G*m[ 6] + B*m[ 7] + A*m[ 8] + m[ 9] ]
+ // B' = [ R*m[10] + G*m[11] + B*m[12] + A*m[13] + m[14] ]
+ // A' = [ R*m[15] + G*m[16] + B*m[17] + A*m[18] + m[19] ]
+ //
+ // Applying the opacity only affects the alpha value since the operations
+ // are performed on non-premultiplied colors. (If the data is stored in
+ // premultiplied form, though, there may be rounding errors due to
+ // premul->unpremul->premul conversions.)
+
+ // We test for the successful cases and return false if they fail so that
+ // we fail and return false if any matrix values are NaN.
+
+ // If any of the alpha column are non-zero then the prior alpha affects
+ // the result color, so applying opacity before the filter will change
+ // the incoming alpha and therefore the colors that are produced.
+ if (!(matrix_[3] == 0 && // A does not affect R'
+ matrix_[8] == 0 && // A does not affect G'
+ matrix_[13] == 0)) { // A does not affect B'
+ return false;
+ }
+
+ // Similarly, if any of the alpha row are non-zero then the prior colors
+ // affect the result alpha in a way that prevents opacity from commuting
+ // through the filter operation.
+ if (!(matrix_[15] == 0 && // R does not affect A'
+ matrix_[16] == 0 && // G does not affect A'
+ matrix_[17] == 0 && // B does not affect A'
+ matrix_[19] == 0)) { // A' is not offset by an absolute value
+ return false;
+ }
+
+ return true;
+}
+
const std::shared_ptr<DlSrgbToLinearGammaColorFilter>
DlSrgbToLinearGammaColorFilter::instance =
std::make_shared<DlSrgbToLinearGammaColorFilter>();
-const sk_sp<SkColorFilter> DlSrgbToLinearGammaColorFilter::sk_filter_ =
- SkColorFilters::SRGBToLinearGamma();
const std::shared_ptr<DlLinearToSrgbGammaColorFilter>
DlLinearToSrgbGammaColorFilter::instance =
std::make_shared<DlLinearToSrgbGammaColorFilter>();
-const sk_sp<SkColorFilter> DlLinearToSrgbGammaColorFilter::sk_filter_ =
- SkColorFilters::LinearToSRGBGamma();
} // namespace flutter
diff --git a/display_list/display_list_color_filter.h b/display_list/display_list_color_filter.h
index 240f361..b02bad4 100644
--- a/display_list/display_list_color_filter.h
+++ b/display_list/display_list_color_filter.h
@@ -28,8 +28,7 @@
kLinearToSrgbGamma,
};
-class DlColorFilter
- : public DlAttribute<DlColorFilter, SkColorFilter, DlColorFilterType> {
+class DlColorFilter : public DlAttribute<DlColorFilter, DlColorFilterType> {
public:
// Return a boolean indicating whether the color filtering operation will
// modify transparent black. This is typically used to determine if applying
@@ -68,23 +67,18 @@
DlBlendColorFilter(const DlBlendColorFilter* filter)
: DlBlendColorFilter(filter->color_, filter->mode_) {}
+ static std::shared_ptr<DlColorFilter> Make(DlColor color, DlBlendMode mode);
+
DlColorFilterType type() const override { return DlColorFilterType::kBlend; }
size_t size() const override { return sizeof(*this); }
- bool modifies_transparent_black() const override {
- // Look at blend and color to make a faster determination?
- sk_sp<SkColorFilter> sk_filter = skia_object();
- return sk_filter &&
- sk_filter->filterColor(SK_ColorTRANSPARENT) != SK_ColorTRANSPARENT;
- }
+
+ bool modifies_transparent_black() const override;
+ bool can_commute_with_opacity() const override;
std::shared_ptr<DlColorFilter> shared() const override {
return std::make_shared<DlBlendColorFilter>(this);
}
- sk_sp<SkColorFilter> skia_object() const override {
- return SkColorFilters::Blend(color_, ToSk(mode_));
- }
-
const DlBlendColorFilter* asBlend() const override { return this; }
DlColor color() const { return color_; }
@@ -114,6 +108,10 @@
//
// The resulting color [oR,oG,oB,oA] is then clamped to the range of
// valid pixel components before storing in the output.
+//
+// The incoming and outgoing [iR,iG,iB,iA] and [oR,oG,oB,oA] are
+// considered to be non-premultiplied. When working on premultiplied
+// pixel data, the necessary pre<->non-pre conversions must be performed.
class DlMatrixColorFilter final : public DlColorFilter {
public:
DlMatrixColorFilter(const float matrix[20]) {
@@ -124,30 +122,18 @@
DlMatrixColorFilter(const DlMatrixColorFilter* filter)
: DlMatrixColorFilter(filter->matrix_) {}
+ static std::shared_ptr<DlColorFilter> Make(const float matrix[20]);
+
DlColorFilterType type() const override { return DlColorFilterType::kMatrix; }
size_t size() const override { return sizeof(*this); }
- bool modifies_transparent_black() const override {
- // Look at the matrix to make a faster determination?
- // Basically, are the translation components all 0?
- sk_sp<SkColorFilter> sk_filter = skia_object();
- return sk_filter &&
- sk_filter->filterColor(SK_ColorTRANSPARENT) != SK_ColorTRANSPARENT;
- }
- bool can_commute_with_opacity() const override {
- return matrix_[3] == 0 && matrix_[8] == 0 && matrix_[13] == 0 &&
- matrix_[15] == 0 && matrix_[16] == 0 && matrix_[17] == 0 &&
- (matrix_[18] >= 0.0 && matrix_[18] <= 1.0) && matrix_[19] == 0;
- }
+ bool modifies_transparent_black() const override;
+ bool can_commute_with_opacity() const override;
std::shared_ptr<DlColorFilter> shared() const override {
return std::make_shared<DlMatrixColorFilter>(this);
}
- sk_sp<SkColorFilter> skia_object() const override {
- return SkColorFilters::Matrix(matrix_);
- }
-
const DlMatrixColorFilter* asMatrix() const override { return this; }
const float& operator[](int index) const { return matrix_[index]; }
@@ -186,7 +172,6 @@
bool can_commute_with_opacity() const override { return true; }
std::shared_ptr<DlColorFilter> shared() const override { return instance; }
- sk_sp<SkColorFilter> skia_object() const override { return sk_filter_; }
protected:
bool equals_(const DlColorFilter& other) const override {
@@ -195,7 +180,6 @@
}
private:
- static const sk_sp<SkColorFilter> sk_filter_;
friend class DlColorFilter;
};
@@ -219,7 +203,6 @@
bool can_commute_with_opacity() const override { return true; }
std::shared_ptr<DlColorFilter> shared() const override { return instance; }
- sk_sp<SkColorFilter> skia_object() const override { return sk_filter_; }
protected:
bool equals_(const DlColorFilter& other) const override {
@@ -228,7 +211,6 @@
}
private:
- static const sk_sp<SkColorFilter> sk_filter_;
friend class DlColorFilter;
};
diff --git a/display_list/display_list_color_filter_unittests.cc b/display_list/display_list_color_filter_unittests.cc
index 2403a6d..efdd1b5 100644
--- a/display_list/display_list_color_filter_unittests.cc
+++ b/display_list/display_list_color_filter_unittests.cc
@@ -17,18 +17,6 @@
16, 17, 18, 19, 20, //
};
-TEST(DisplayListColorFilter, BuilderSetGet) {
- DlBlendColorFilter filter(DlColor::kRed(), DlBlendMode::kDstATop);
- DisplayListBuilder builder;
- ASSERT_EQ(builder.getColorFilter(), nullptr);
- builder.setColorFilter(&filter);
- ASSERT_NE(builder.getColorFilter(), nullptr);
- ASSERT_TRUE(
- Equals(builder.getColorFilter(), static_cast<DlColorFilter*>(&filter)));
- builder.setColorFilter(nullptr);
- ASSERT_EQ(builder.getColorFilter(), nullptr);
-}
-
TEST(DisplayListColorFilter, BlendConstructor) {
DlBlendColorFilter filter(DlColor::kRed(), DlBlendMode::kDstATop);
}
diff --git a/display_list/display_list_color_source.cc b/display_list/display_list_color_source.cc
index 94c9fbb..01da26d 100644
--- a/display_list/display_list_color_source.cc
+++ b/display_list/display_list_color_source.cc
@@ -19,7 +19,7 @@
::operator delete(p);
}
-std::shared_ptr<DlColorSource> DlColorSource::MakeLinear(
+std::shared_ptr<DlLinearGradientColorSource> DlColorSource::MakeLinear(
const SkPoint start_point,
const SkPoint end_point,
uint32_t stop_count,
@@ -37,10 +37,10 @@
DlLinearGradientColorSource(start_point, end_point, stop_count,
colors, stops, tile_mode, matrix),
DlGradientDeleter);
- return std::move(ret);
+ return ret;
}
-std::shared_ptr<DlColorSource> DlColorSource::MakeRadial(
+std::shared_ptr<DlRadialGradientColorSource> DlColorSource::MakeRadial(
SkPoint center,
SkScalar radius,
uint32_t stop_count,
@@ -57,10 +57,10 @@
ret.reset(new (storage) DlRadialGradientColorSource(
center, radius, stop_count, colors, stops, tile_mode, matrix),
DlGradientDeleter);
- return std::move(ret);
+ return ret;
}
-std::shared_ptr<DlColorSource> DlColorSource::MakeConical(
+std::shared_ptr<DlConicalGradientColorSource> DlColorSource::MakeConical(
SkPoint start_center,
SkScalar start_radius,
SkPoint end_center,
@@ -80,10 +80,10 @@
start_center, start_radius, end_center, end_radius, stop_count,
colors, stops, tile_mode, matrix),
DlGradientDeleter);
- return std::move(ret);
+ return ret;
}
-std::shared_ptr<DlColorSource> DlColorSource::MakeSweep(
+std::shared_ptr<DlSweepGradientColorSource> DlColorSource::MakeSweep(
SkPoint center,
SkScalar start,
SkScalar end,
@@ -102,7 +102,7 @@
DlSweepGradientColorSource(center, start, end, stop_count,
colors, stops, tile_mode, matrix),
DlGradientDeleter);
- return std::move(ret);
+ return ret;
}
std::shared_ptr<DlRuntimeEffectColorSource> DlColorSource::MakeRuntimeEffect(
diff --git a/display_list/display_list_color_source.h b/display_list/display_list_color_source.h
index 7705893..8c93dc8 100644
--- a/display_list/display_list_color_source.h
+++ b/display_list/display_list_color_source.h
@@ -63,10 +63,9 @@
#endif // IMPELLER_ENABLE_3D
};
-class DlColorSource
- : public DlAttribute<DlColorSource, SkShader, DlColorSourceType> {
+class DlColorSource : public DlAttribute<DlColorSource, DlColorSourceType> {
public:
- static std::shared_ptr<DlColorSource> MakeLinear(
+ static std::shared_ptr<DlLinearGradientColorSource> MakeLinear(
const SkPoint start_point,
const SkPoint end_point,
uint32_t stop_count,
@@ -75,7 +74,7 @@
DlTileMode tile_mode,
const SkMatrix* matrix = nullptr);
- static std::shared_ptr<DlColorSource> MakeRadial(
+ static std::shared_ptr<DlRadialGradientColorSource> MakeRadial(
SkPoint center,
SkScalar radius,
uint32_t stop_count,
@@ -84,7 +83,7 @@
DlTileMode tile_mode,
const SkMatrix* matrix = nullptr);
- static std::shared_ptr<DlColorSource> MakeConical(
+ static std::shared_ptr<DlConicalGradientColorSource> MakeConical(
SkPoint start_center,
SkScalar start_radius,
SkPoint end_center,
@@ -95,7 +94,7 @@
DlTileMode tile_mode,
const SkMatrix* matrix = nullptr);
- static std::shared_ptr<DlColorSource> MakeSweep(
+ static std::shared_ptr<DlSweepGradientColorSource> MakeSweep(
SkPoint center,
SkScalar start,
SkScalar end,
@@ -112,11 +111,6 @@
virtual bool is_opaque() const = 0;
- virtual std::shared_ptr<DlColorSource> with_sampling(
- DlImageSampling options) const {
- return shared();
- }
-
// Return a DlColorColorSource pointer to this object iff it is an Color
// type of ColorSource, otherwise return nullptr.
virtual const DlColorColorSource* asColor() const { return nullptr; }
@@ -190,10 +184,6 @@
DlColor color() const { return color_; }
- sk_sp<SkShader> skia_object() const override {
- return SkShaders::Color(color_);
- }
-
protected:
bool equals_(DlColorSource const& other) const override {
FML_DCHECK(other.type() == DlColorSourceType::kColor);
@@ -242,8 +232,7 @@
return with_sampling(sampling_);
}
- std::shared_ptr<DlColorSource> with_sampling(
- DlImageSampling sampling) const override {
+ std::shared_ptr<DlColorSource> with_sampling(DlImageSampling sampling) const {
return std::make_shared<DlImageColorSource>(image_, horizontal_tile_mode_,
vertical_tile_mode_, sampling,
matrix_ptr());
@@ -263,15 +252,6 @@
DlTileMode vertical_tile_mode() const { return vertical_tile_mode_; }
DlImageSampling sampling() const { return sampling_; }
- virtual sk_sp<SkShader> skia_object() const override {
- if (!image_->skia_image()) {
- return nullptr;
- }
- return image_->skia_image()->makeShader(ToSk(horizontal_tile_mode_),
- ToSk(vertical_tile_mode_),
- ToSk(sampling_), matrix_ptr());
- }
-
protected:
bool equals_(DlColorSource const& other) const override {
FML_DCHECK(other.type() == DlColorSourceType::kImage);
@@ -386,13 +366,6 @@
const SkPoint& start_point() const { return start_point_; }
const SkPoint& end_point() const { return end_point_; }
- sk_sp<SkShader> skia_object() const override {
- SkPoint pts[] = {start_point_, end_point_};
- const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors());
- return SkGradientShader::MakeLinear(pts, sk_colors, stops(), stop_count(),
- ToSk(tile_mode()), 0, matrix_ptr());
- }
-
protected:
virtual const void* pod() const override { return this + 1; }
@@ -454,13 +427,6 @@
SkPoint center() const { return center_; }
SkScalar radius() const { return radius_; }
- sk_sp<SkShader> skia_object() const override {
- const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors());
- return SkGradientShader::MakeRadial(center_, radius_, sk_colors, stops(),
- stop_count(), ToSk(tile_mode()), 0,
- matrix_ptr());
- }
-
protected:
virtual const void* pod() const override { return this + 1; }
@@ -525,13 +491,6 @@
SkPoint end_center() const { return end_center_; }
SkScalar end_radius() const { return end_radius_; }
- sk_sp<SkShader> skia_object() const override {
- const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors());
- return SkGradientShader::MakeTwoPointConical(
- start_center_, start_radius_, end_center_, end_radius_, sk_colors,
- stops(), stop_count(), ToSk(tile_mode()), 0, matrix_ptr());
- }
-
protected:
virtual const void* pod() const override { return this + 1; }
@@ -604,13 +563,6 @@
SkScalar start() const { return start_; }
SkScalar end() const { return end_; }
- sk_sp<SkShader> skia_object() const override {
- const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors());
- return SkGradientShader::MakeSweep(center_.x(), center_.y(), sk_colors,
- stops(), stop_count(), ToSk(tile_mode()),
- start_, end_, 0, matrix_ptr());
- }
-
protected:
virtual const void* pod() const override { return this + 1; }
@@ -693,35 +645,6 @@
return uniform_data_;
}
- sk_sp<SkShader> skia_object() const override {
- if (!runtime_effect_) {
- return nullptr;
- }
- if (!runtime_effect_->skia_runtime_effect()) {
- return nullptr;
- }
- std::vector<sk_sp<SkShader>> sk_samplers(samplers_.size());
- for (size_t i = 0; i < samplers_.size(); i++) {
- auto sampler = samplers_[i];
- if (sampler == nullptr) {
- return nullptr;
- }
- sk_samplers[i] = sampler->skia_object();
- }
-
- auto ref = new std::shared_ptr<std::vector<uint8_t>>(uniform_data_);
- auto uniform_data = SkData::MakeWithProc(
- uniform_data_->data(), uniform_data_->size(),
- [](const void* ptr, void* context) {
- delete reinterpret_cast<std::shared_ptr<std::vector<uint8_t>>*>(
- context);
- },
- ref);
-
- return runtime_effect_->skia_runtime_effect()->makeShader(
- uniform_data, sk_samplers.data(), sk_samplers.size());
- }
-
protected:
bool equals_(DlColorSource const& other) const override {
FML_DCHECK(other.type() == DlColorSourceType::kRuntimeEffect);
@@ -773,8 +696,6 @@
impeller::Matrix camera_matrix() const { return camera_matrix_; }
- sk_sp<SkShader> skia_object() const override { return nullptr; }
-
protected:
bool equals_(DlColorSource const& other) const override {
FML_DCHECK(other.type() == DlColorSourceType::kScene);
diff --git a/display_list/display_list_color_source_unittests.cc b/display_list/display_list_color_source_unittests.cc
index a4c982c..582d723 100644
--- a/display_list/display_list_color_source_unittests.cc
+++ b/display_list/display_list_color_source_unittests.cc
@@ -86,19 +86,6 @@
SkPoint::Make(107, 118),
};
-TEST(DisplayListColorSource, BuilderSetGet) {
- DlImageColorSource source(kTestImage1, DlTileMode::kClamp, DlTileMode::kClamp,
- DlImageSampling::kLinear, &kTestMatrix1);
- DisplayListBuilder builder;
- ASSERT_EQ(builder.getColorSource(), nullptr);
- builder.setColorSource(&source);
- ASSERT_NE(builder.getColorSource(), nullptr);
- ASSERT_TRUE(
- Equals(builder.getColorSource(), static_cast<DlColorSource*>(&source)));
- builder.setColorSource(nullptr);
- ASSERT_EQ(builder.getColorSource(), nullptr);
-}
-
TEST(DisplayListColorSource, ColorConstructor) {
DlColorColorSource source(SK_ColorRED);
}
@@ -763,23 +750,11 @@
ASSERT_EQ(source1->asConicalGradient(), nullptr);
ASSERT_EQ(source1->asSweepGradient(), nullptr);
- ASSERT_NE(source1->skia_object(), nullptr);
- ASSERT_EQ(source3->skia_object(), nullptr);
-
TestEquals(source1, source1);
TestEquals(source3, source3);
TestNotEquals(source1, source2, "SkRuntimeEffect differs");
TestNotEquals(source2, source3, "SkRuntimeEffect differs");
}
-TEST(DisplayListColorSource, RuntimeEffectWithNullSampler) {
- std::shared_ptr<DlRuntimeEffectColorSource> source1 =
- DlColorSource::MakeRuntimeEffect(
- kTestRuntimeEffect1, {nullptr},
- std::make_shared<std::vector<uint8_t>>());
-
- ASSERT_EQ(source1->skia_object(), nullptr);
-}
-
} // namespace testing
} // namespace flutter
diff --git a/display_list/display_list_complexity_gl.cc b/display_list/display_list_complexity_gl.cc
index 40c3bde..165744d 100644
--- a/display_list/display_list_complexity_gl.cc
+++ b/display_list/display_list_complexity_gl.cc
@@ -114,7 +114,7 @@
//
// There is also a kStrokeAndFill_Style that Skia exposes, but we do not
// currently use it anywhere in Flutter.
- if (Style() == SkPaint::Style::kFill_Style) {
+ if (DrawStyle() == DlDrawStyle::kFill) {
// No real difference for AA with filled styles
unsigned int area = rect.width() * rect.height();
@@ -165,7 +165,7 @@
// There is also a kStrokeAndFill_Style that Skia exposes, but we do not
// currently use it anywhere in Flutter.
- if (Style() == SkPaint::Style::kFill_Style) {
+ if (DrawStyle() == DlDrawStyle::kFill) {
// With filled styles, there is no significant AA penalty.
// m = 1/6000
// c = 0
@@ -199,7 +199,7 @@
// There is also a kStrokeAndFill_Style that Skia exposes, but we do not
// currently use it anywhere in Flutter.
- if (Style() == SkPaint::Style::kFill_Style) {
+ if (DrawStyle() == DlDrawStyle::kFill) {
// We can ignore pi here
unsigned int area = radius * radius;
// m = 1/525
@@ -245,7 +245,7 @@
// These values were worked out by creating a straight line graph (y=mx+c)
// approximately matching the measured data, normalising the data so that
// 0.0005ms resulted in a score of 100 then simplifying down the formula.
- if (Style() == SkPaint::Style::kFill_Style ||
+ if (DrawStyle() == DlDrawStyle::kFill ||
((rrect.getType() == SkRRect::Type::kSimple_Type) && IsAntiAliased())) {
unsigned int area = rrect.width() * rrect.height();
// m = 1/3200
@@ -295,7 +295,7 @@
//
// There is also a kStrokeAndFill_Style that Skia exposes, but we do not
// currently use it anywhere in Flutter.
- if (Style() == SkPaint::Style::kFill_Style) {
+ if (DrawStyle() == DlDrawStyle::kFill) {
unsigned int area = outer.width() * outer.height();
if (outer.getType() == SkRRect::Type::kComplex_Type) {
// m = 1/500
@@ -382,7 +382,7 @@
//
// There is also a kStrokeAndFill_Style that Skia exposes, but we do not
// currently use it anywhere in Flutter.
- if (Style() == SkPaint::Style::kStroke_Style) {
+ if (DrawStyle() == DlDrawStyle::kStroke) {
if (IsAntiAliased()) {
// m = 1/3800
// c = 12
@@ -550,7 +550,7 @@
const SkISize& size,
bool texture_backed,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) {
+ bool enforce_src_edges) {
if (IsComplex()) {
return;
}
@@ -563,10 +563,8 @@
// approximately matching the measured data, normalising the data so that
// 0.0005ms resulted in a score of 100 then simplifying down the formula.
unsigned int complexity;
- if (!texture_backed ||
- (texture_backed && render_with_attributes &&
- constraint == SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint &&
- IsAntiAliased())) {
+ if (!texture_backed || (texture_backed && render_with_attributes &&
+ enforce_src_edges && IsAntiAliased())) {
unsigned int area = size.width() * size.height();
// m = 1/4000
// c = 5
@@ -610,11 +608,15 @@
}
void DisplayListGLComplexityCalculator::GLHelper::drawDisplayList(
- const sk_sp<DisplayList> display_list) {
+ const sk_sp<DisplayList> display_list,
+ SkScalar opacity) {
if (IsComplex()) {
return;
}
GLHelper helper(Ceiling() - CurrentComplexityScore());
+ if (opacity < SK_Scalar1 && !display_list->can_apply_group_opacity()) {
+ helper.saveLayer(nullptr, SaveLayerOptions::kWithAttributes, nullptr);
+ }
display_list->Dispatch(helper);
AccumulateComplexity(helper.ComplexityScore());
}
diff --git a/display_list/display_list_complexity_gl.h b/display_list/display_list_complexity_gl.h
index 9756943..821c696 100644
--- a/display_list/display_list_complexity_gl.h
+++ b/display_list/display_list_complexity_gl.h
@@ -65,7 +65,8 @@
const SkRect& dst,
DlFilterMode filter,
bool render_with_attributes) override;
- void drawDisplayList(const sk_sp<DisplayList> display_list) override;
+ void drawDisplayList(const sk_sp<DisplayList> display_list,
+ SkScalar opacity) override;
void drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y) override;
@@ -79,7 +80,7 @@
void ImageRect(const SkISize& size,
bool texture_backed,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) override;
+ bool enforce_src_edges) override;
unsigned int BatchedComplexity() override;
diff --git a/display_list/display_list_complexity_helper.h b/display_list/display_list_complexity_helper.h
index eb738b9..488dc32 100644
--- a/display_list/display_list_complexity_helper.h
+++ b/display_list/display_list_complexity_helper.h
@@ -7,8 +7,8 @@
#include "flutter/display_list/display_list_blend_mode.h"
#include "flutter/display_list/display_list_complexity.h"
-#include "flutter/display_list/display_list_dispatcher.h"
#include "flutter/display_list/display_list_utils.h"
+#include "flutter/display_list/dl_op_receiver.h"
namespace flutter {
@@ -92,7 +92,7 @@
// y = 4x
class ComplexityCalculatorHelper
- : public virtual Dispatcher,
+ : public virtual DlOpReceiver,
public virtual IgnoreClipDispatchHelper,
public virtual IgnoreTransformDispatchHelper {
public:
@@ -121,7 +121,7 @@
void setAntiAlias(bool aa) override { current_paint_.setAntiAlias(aa); }
void setStyle(DlDrawStyle style) override {
- current_paint_.setStyle(ToSk(style));
+ current_paint_.setDrawStyle(style);
}
void setStrokeWidth(SkScalar width) override {
@@ -145,17 +145,18 @@
AccumulateComplexity(50);
}
- void drawImageRect(const sk_sp<DlImage> image,
- const SkRect& src,
- const SkRect& dst,
- DlImageSampling sampling,
- bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) override {
+ void drawImageRect(
+ const sk_sp<DlImage> image,
+ const SkRect& src,
+ const SkRect& dst,
+ DlImageSampling sampling,
+ bool render_with_attributes,
+ SrcRectConstraint constraint = SrcRectConstraint::kFast) override {
if (IsComplex()) {
return;
}
ImageRect(image->dimensions(), image->isTextureBacked(),
- render_with_attributes, constraint);
+ render_with_attributes, constraint == SrcRectConstraint::kStrict);
}
void drawAtlas(const sk_sp<DlImage> atlas,
@@ -174,8 +175,7 @@
// This is equivalent to calling drawImageRect lots of times
for (int i = 0; i < count; i++) {
ImageRect(SkISize::Make(tex[i].width(), tex[i].height()), true,
- render_with_attributes,
- SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint);
+ render_with_attributes, true);
}
}
@@ -211,7 +211,7 @@
inline bool IsAntiAliased() { return current_paint_.isAntiAlias(); }
inline bool IsHairline() { return current_paint_.getStrokeWidth() == 0.0f; }
- inline SkPaint::Style Style() { return current_paint_.getStyle(); }
+ inline DlDrawStyle DrawStyle() { return current_paint_.getDrawStyle(); }
inline bool IsComplex() { return is_complex_; }
inline unsigned int Ceiling() { return ceiling_; }
inline unsigned int CurrentComplexityScore() { return complexity_score_; }
@@ -248,7 +248,7 @@
virtual void ImageRect(const SkISize& size,
bool texture_backed,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) = 0;
+ bool enforce_src_edges) = 0;
// This calculates and returns the cost of draw calls which are batched and
// thus have a time cost proportional to the number of draw calls made, such
@@ -256,7 +256,7 @@
virtual unsigned int BatchedComplexity() = 0;
private:
- SkPaint current_paint_;
+ DlPaint current_paint_;
// If we exceed the ceiling (defaults to the largest number representable
// by unsigned int), then set the is_complex_ bool and we no longer
diff --git a/display_list/display_list_complexity_metal.cc b/display_list/display_list_complexity_metal.cc
index 2cd5c7c..8edb87a 100644
--- a/display_list/display_list_complexity_metal.cc
+++ b/display_list/display_list_complexity_metal.cc
@@ -128,7 +128,7 @@
//
// There is also a kStrokeAndFill_Style that Skia exposes, but we do not
// currently use it anywhere in Flutter.
- if (Style() == SkPaint::Style::kFill_Style) {
+ if (DrawStyle() == DlDrawStyle::kFill) {
// No real difference for AA with filled styles.
unsigned int area = rect.width() * rect.height();
@@ -170,7 +170,7 @@
// There is also a kStrokeAndFill_Style that Skia exposes, but we do not
// currently use it anywhere in Flutter.
- if (Style() == SkPaint::Style::kFill_Style) {
+ if (DrawStyle() == DlDrawStyle::kFill) {
// With filled styles, there is no significant AA penalty.
// m = 1/16000
// c = 0
@@ -204,7 +204,7 @@
// There is also a kStrokeAndFill_Style that Skia exposes, but we do not
// currently use it anywhere in Flutter.
- if (Style() == SkPaint::Style::kFill_Style) {
+ if (DrawStyle() == DlDrawStyle::kFill) {
// We can ignore pi here.
unsigned int area = radius * radius;
// m = 1/1300
@@ -244,7 +244,7 @@
//
// Expensive: All filled style, symmetric w/AA.
bool expensive =
- (Style() == SkPaint::Style::kFill_Style) ||
+ (DrawStyle() == DlDrawStyle::kFill) ||
((rrect.getType() == SkRRect::Type::kSimple_Type) && IsAntiAliased());
unsigned int complexity;
@@ -292,7 +292,7 @@
//
// There is also a kStrokeAndFill_Style that Skia exposes, but we do not
// currently use it anywhere in Flutter.
- if (Style() == SkPaint::Style::kFill_Style) {
+ if (DrawStyle() == DlDrawStyle::kFill) {
unsigned int area = outer.width() * outer.height();
if (outer.getType() == SkRRect::Type::kComplex_Type) {
// m = 1/1000
@@ -374,7 +374,7 @@
//
// There is also a kStrokeAndFill_Style that Skia exposes, but we do not
// currently use it anywhere in Flutter.
- if (Style() == SkPaint::Style::kStroke_Style) {
+ if (DrawStyle() == DlDrawStyle::kStroke) {
if (IsAntiAliased()) {
// m = 1/8500
// c = 16
@@ -493,7 +493,7 @@
const SkISize& size,
bool texture_backed,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) {
+ bool enforce_src_edges) {
if (IsComplex()) {
return;
}
@@ -512,16 +512,12 @@
// m = 1/23000
// c = 2.3
complexity = (area + 52900) * 2 / 115;
- if (render_with_attributes &&
- constraint == SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint &&
- IsAntiAliased()) {
+ if (render_with_attributes && enforce_src_edges && IsAntiAliased()) {
// There's about a 30% performance penalty from the baseline.
complexity *= 1.3f;
}
} else {
- if (render_with_attributes &&
- constraint == SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint &&
- IsAntiAliased()) {
+ if (render_with_attributes && enforce_src_edges && IsAntiAliased()) {
// m = 1/12200
// c = 2.75
complexity = (area + 33550) * 2 / 61;
@@ -556,11 +552,15 @@
}
void DisplayListMetalComplexityCalculator::MetalHelper::drawDisplayList(
- const sk_sp<DisplayList> display_list) {
+ const sk_sp<DisplayList> display_list,
+ SkScalar opacity) {
if (IsComplex()) {
return;
}
MetalHelper helper(Ceiling() - CurrentComplexityScore());
+ if (opacity < SK_Scalar1 && !display_list->can_apply_group_opacity()) {
+ helper.saveLayer(nullptr, SaveLayerOptions::kWithAttributes, nullptr);
+ }
display_list->Dispatch(helper);
AccumulateComplexity(helper.ComplexityScore());
}
diff --git a/display_list/display_list_complexity_metal.h b/display_list/display_list_complexity_metal.h
index 530335e..94d3ca5 100644
--- a/display_list/display_list_complexity_metal.h
+++ b/display_list/display_list_complexity_metal.h
@@ -65,7 +65,8 @@
const SkRect& dst,
DlFilterMode filter,
bool render_with_attributes) override;
- void drawDisplayList(const sk_sp<DisplayList> display_list) override;
+ void drawDisplayList(const sk_sp<DisplayList> display_list,
+ SkScalar opacity) override;
void drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y) override;
@@ -79,7 +80,7 @@
void ImageRect(const SkISize& size,
bool texture_backed,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) override;
+ bool enforce_src_edges) override;
unsigned int BatchedComplexity() override;
diff --git a/display_list/display_list_complexity_unittests.cc b/display_list/display_list_complexity_unittests.cc
index b459a78..3d4f9b0 100644
--- a/display_list/display_list_complexity_unittests.cc
+++ b/display_list/display_list_complexity_unittests.cc
@@ -76,12 +76,13 @@
TEST(DisplayListComplexity, AntiAliasing) {
DisplayListBuilder builder_no_aa;
- builder_no_aa.drawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100));
+ builder_no_aa.DrawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100),
+ DlPaint());
auto display_list_no_aa = builder_no_aa.Build();
DisplayListBuilder builder_aa;
- builder_aa.setAntiAlias(true);
- builder_aa.drawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100));
+ builder_aa.DrawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100),
+ DlPaint().setAntiAlias(true));
auto display_list_aa = builder_aa.Build();
auto calculators = AccumulatorCalculators();
@@ -93,13 +94,13 @@
TEST(DisplayListComplexity, StrokeWidth) {
DisplayListBuilder builder_stroke_0;
- builder_stroke_0.setStrokeWidth(0.0f);
- builder_stroke_0.drawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100));
+ builder_stroke_0.DrawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100),
+ DlPaint().setStrokeWidth(0.0f));
auto display_list_stroke_0 = builder_stroke_0.Build();
DisplayListBuilder builder_stroke_1;
- builder_stroke_1.setStrokeWidth(1.0f);
- builder_stroke_1.drawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100));
+ builder_stroke_0.DrawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100),
+ DlPaint().setStrokeWidth(1.0f));
auto display_list_stroke_1 = builder_stroke_1.Build();
auto calculators = AccumulatorCalculators();
@@ -111,13 +112,13 @@
TEST(DisplayListComplexity, Style) {
DisplayListBuilder builder_filled;
- builder_filled.setStyle(DlDrawStyle::kFill);
- builder_filled.drawRect(SkRect::MakeXYWH(10, 10, 80, 80));
+ builder_filled.DrawRect(SkRect::MakeXYWH(10, 10, 80, 80),
+ DlPaint().setDrawStyle(DlDrawStyle::kFill));
auto display_list_filled = builder_filled.Build();
DisplayListBuilder builder_stroked;
- builder_stroked.setStyle(DlDrawStyle::kStroke);
- builder_stroked.drawRect(SkRect::MakeXYWH(10, 10, 80, 80));
+ builder_stroked.DrawRect(SkRect::MakeXYWH(10, 10, 80, 80),
+ DlPaint().setDrawStyle(DlDrawStyle::kStroke));
auto display_list_stroked = builder_stroked.Build();
auto calculators = AccumulatorCalculators();
@@ -129,7 +130,7 @@
TEST(DisplayListComplexity, SaveLayers) {
DisplayListBuilder builder;
- builder.saveLayer(nullptr, true);
+ builder.SaveLayer(nullptr, nullptr);
auto display_list = builder.Build();
auto calculators = AccumulatorCalculators();
@@ -144,7 +145,7 @@
line_path.moveTo(SkPoint::Make(0, 0));
line_path.lineTo(SkPoint::Make(10, 10));
line_path.close();
- builder_line.drawPath(line_path);
+ builder_line.DrawPath(line_path, DlPaint());
auto display_list_line = builder_line.Build();
DisplayListBuilder builder_quad;
@@ -152,7 +153,7 @@
quad_path.moveTo(SkPoint::Make(0, 0));
quad_path.quadTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20));
quad_path.close();
- builder_quad.drawPath(quad_path);
+ builder_quad.DrawPath(quad_path, DlPaint());
auto display_list_quad = builder_quad.Build();
DisplayListBuilder builder_conic;
@@ -160,7 +161,7 @@
conic_path.moveTo(SkPoint::Make(0, 0));
conic_path.conicTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20), 1.5f);
conic_path.close();
- builder_conic.drawPath(conic_path);
+ builder_conic.DrawPath(conic_path, DlPaint());
auto display_list_conic = builder_conic.Build();
DisplayListBuilder builder_cubic;
@@ -168,7 +169,7 @@
cubic_path.moveTo(SkPoint::Make(0, 0));
cubic_path.cubicTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20),
SkPoint::Make(20, 20));
- builder_cubic.drawPath(cubic_path);
+ builder_cubic.DrawPath(cubic_path, DlPaint());
auto display_list_cubic = builder_cubic.Build();
auto calculators = AccumulatorCalculators();
@@ -186,7 +187,7 @@
line_path.moveTo(SkPoint::Make(0, 0));
line_path.lineTo(SkPoint::Make(10, 10));
line_path.close();
- builder_line.drawShadow(line_path, SK_ColorRED, 10.0f, false, 1.0f);
+ builder_line.DrawShadow(line_path, SK_ColorRED, 10.0f, false, 1.0f);
auto display_list_line = builder_line.Build();
DisplayListBuilder builder_quad;
@@ -194,7 +195,7 @@
quad_path.moveTo(SkPoint::Make(0, 0));
quad_path.quadTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20));
quad_path.close();
- builder_quad.drawShadow(quad_path, SK_ColorRED, 10.0f, false, 1.0f);
+ builder_quad.DrawShadow(quad_path, SK_ColorRED, 10.0f, false, 1.0f);
auto display_list_quad = builder_quad.Build();
DisplayListBuilder builder_conic;
@@ -202,7 +203,7 @@
conic_path.moveTo(SkPoint::Make(0, 0));
conic_path.conicTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20), 1.5f);
conic_path.close();
- builder_conic.drawShadow(conic_path, SK_ColorRED, 10.0f, false, 1.0f);
+ builder_conic.DrawShadow(conic_path, SK_ColorRED, 10.0f, false, 1.0f);
auto display_list_conic = builder_conic.Build();
DisplayListBuilder builder_cubic;
@@ -210,7 +211,7 @@
cubic_path.moveTo(SkPoint::Make(0, 0));
cubic_path.cubicTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20),
SkPoint::Make(20, 20));
- builder_cubic.drawShadow(cubic_path, SK_ColorRED, 10.0f, false, 1.0f);
+ builder_cubic.DrawShadow(cubic_path, SK_ColorRED, 10.0f, false, 1.0f);
auto display_list_cubic = builder_cubic.Build();
auto calculators = AccumulatorCalculators();
@@ -224,7 +225,7 @@
TEST(DisplayListComplexity, DrawOval) {
DisplayListBuilder builder;
- builder.drawOval(SkRect::MakeXYWH(10, 10, 100, 80));
+ builder.DrawOval(SkRect::MakeXYWH(10, 10, 100, 80), DlPaint());
auto display_list = builder.Build();
auto calculators = AccumulatorCalculators();
@@ -235,7 +236,7 @@
TEST(DisplayListComplexity, DrawCircle) {
DisplayListBuilder builder;
- builder.drawCircle(SkPoint::Make(50, 50), 10.0f);
+ builder.DrawCircle(SkPoint::Make(50, 50), 10.0f, DlPaint());
auto display_list = builder.Build();
auto calculators = AccumulatorCalculators();
@@ -246,8 +247,9 @@
TEST(DisplayListComplexity, DrawRRect) {
DisplayListBuilder builder;
- builder.drawRRect(
- SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 80), 2.0f, 3.0f));
+ builder.DrawRRect(
+ SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 80), 2.0f, 3.0f),
+ DlPaint());
auto display_list = builder.Build();
auto calculators = AccumulatorCalculators();
@@ -262,7 +264,7 @@
SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 80), 2.0f, 3.0f);
SkRRect inner =
SkRRect::MakeRectXY(SkRect::MakeXYWH(15, 15, 70, 70), 1.5f, 1.5f);
- builder.drawDRRect(outer, inner);
+ builder.DrawDRRect(outer, inner, DlPaint());
auto display_list = builder.Build();
auto calculators = AccumulatorCalculators();
@@ -273,7 +275,8 @@
TEST(DisplayListComplexity, DrawArc) {
DisplayListBuilder builder;
- builder.drawArc(SkRect::MakeXYWH(10, 10, 100, 80), 0.0f, 10.0f, true);
+ builder.DrawArc(SkRect::MakeXYWH(10, 10, 100, 80), 0.0f, 10.0f, true,
+ DlPaint());
auto display_list = builder.Build();
auto calculators = AccumulatorCalculators();
@@ -287,7 +290,7 @@
auto vertices = DlVertices::Make(DlVertexMode::kTriangles, points.size(),
points.data(), nullptr, nullptr);
DisplayListBuilder builder;
- builder.drawVertices(vertices, DlBlendMode::kSrc);
+ builder.DrawVertices(vertices.get(), DlBlendMode::kSrc, DlPaint());
auto display_list = builder.Build();
auto calculators = AccumulatorCalculators();
@@ -301,12 +304,12 @@
"The quick brown fox jumps over the lazy dog.", SkFont());
DisplayListBuilder builder;
- builder.drawTextBlob(text_blob, 0.0f, 0.0f);
+ builder.DrawTextBlob(text_blob, 0.0f, 0.0f, DlPaint());
auto display_list = builder.Build();
DisplayListBuilder builder_multiple;
- builder_multiple.drawTextBlob(text_blob, 0.0f, 0.0f);
- builder_multiple.drawTextBlob(text_blob, 0.0f, 0.0f);
+ builder_multiple.DrawTextBlob(text_blob, 0.0f, 0.0f, DlPaint());
+ builder_multiple.DrawTextBlob(text_blob, 0.0f, 0.0f, DlPaint());
auto display_list_multiple = builder_multiple.Build();
auto calculators = AccumulatorCalculators();
@@ -320,18 +323,18 @@
TEST(DisplayListComplexity, DrawPoints) {
auto points = GetTestPoints();
DisplayListBuilder builder_lines;
- builder_lines.drawPoints(DlCanvas::PointMode::kLines, points.size(),
- points.data());
+ builder_lines.DrawPoints(DlCanvas::PointMode::kLines, points.size(),
+ points.data(), DlPaint());
auto display_list_lines = builder_lines.Build();
DisplayListBuilder builder_points;
- builder_points.drawPoints(DlCanvas::PointMode::kPoints, points.size(),
- points.data());
+ builder_points.DrawPoints(DlCanvas::PointMode::kPoints, points.size(),
+ points.data(), DlPaint());
auto display_list_points = builder_points.Build();
DisplayListBuilder builder_polygon;
- builder_polygon.drawPoints(DlCanvas::PointMode::kPolygon, points.size(),
- points.data());
+ builder_polygon.DrawPoints(DlCanvas::PointMode::kPolygon, points.size(),
+ points.data(), DlPaint());
auto display_list_polygon = builder_polygon.Build();
auto calculators = AccumulatorCalculators();
@@ -351,8 +354,8 @@
auto image = SkImage::MakeFromBitmap(bitmap);
DisplayListBuilder builder;
- builder.drawImage(DlImage::Make(image), SkPoint::Make(0, 0),
- DlImageSampling::kNearestNeighbor, false);
+ builder.DrawImage(DlImage::Make(image), SkPoint::Make(0, 0),
+ DlImageSampling::kNearestNeighbor, nullptr);
auto display_list = builder.Build();
auto calculators = AccumulatorCalculators();
@@ -373,8 +376,8 @@
SkRect dest = SkRect::MakeXYWH(0, 0, 50, 50);
DisplayListBuilder builder;
- builder.drawImageNine(DlImage::Make(image), center, dest,
- DlFilterMode::kNearest, true);
+ builder.DrawImageNine(DlImage::Make(image), center, dest,
+ DlFilterMode::kNearest, nullptr);
auto display_list = builder.Build();
auto calculators = AccumulatorCalculators();
@@ -395,8 +398,8 @@
SkRect dest = SkRect::MakeXYWH(0, 0, 50, 50);
DisplayListBuilder builder;
- builder.drawImageRect(DlImage::Make(image), src, dest,
- DlImageSampling::kNearestNeighbor, true);
+ builder.DrawImageRect(DlImage::Make(image), src, dest,
+ DlImageSampling::kNearestNeighbor, nullptr);
auto display_list = builder.Build();
auto calculators = AccumulatorCalculators();
@@ -421,9 +424,9 @@
}
DisplayListBuilder builder;
- builder.drawAtlas(DlImage::Make(image), xforms.data(), rects.data(), nullptr,
+ builder.DrawAtlas(DlImage::Make(image), xforms.data(), rects.data(), nullptr,
10, DlBlendMode::kSrc, DlImageSampling::kNearestNeighbor,
- nullptr, true);
+ nullptr, nullptr);
auto display_list = builder.Build();
auto calculators = AccumulatorCalculators();
diff --git a/display_list/display_list_enum_unittests.cc b/display_list/display_list_enum_unittests.cc
deleted file mode 100644
index 0da01c0..0000000
--- a/display_list/display_list_enum_unittests.cc
+++ /dev/null
@@ -1,172 +0,0 @@
-// 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_blend_mode.h"
-#include "flutter/display_list/display_list_paint.h"
-#include "flutter/display_list/display_list_sampling_options.h"
-#include "flutter/display_list/display_list_tile_mode.h"
-#include "flutter/display_list/display_list_vertices.h"
-#include "flutter/display_list/types.h"
-#include "gtest/gtest.h"
-#include "include/core/SkSamplingOptions.h"
-
-namespace flutter {
-namespace testing {
-
-TEST(DisplayListEnum, ToDlTileMode) {
- ASSERT_EQ(ToDl(SkTileMode::kClamp), DlTileMode::kClamp);
- ASSERT_EQ(ToDl(SkTileMode::kRepeat), DlTileMode::kRepeat);
- ASSERT_EQ(ToDl(SkTileMode::kMirror), DlTileMode::kMirror);
- ASSERT_EQ(ToDl(SkTileMode::kDecal), DlTileMode::kDecal);
-}
-
-TEST(DisplayListEnum, ToSkTileMode) {
- ASSERT_EQ(ToSk(DlTileMode::kClamp), SkTileMode::kClamp);
- ASSERT_EQ(ToSk(DlTileMode::kRepeat), SkTileMode::kRepeat);
- ASSERT_EQ(ToSk(DlTileMode::kMirror), SkTileMode::kMirror);
- ASSERT_EQ(ToSk(DlTileMode::kDecal), SkTileMode::kDecal);
-}
-
-TEST(DisplayListEnum, ToDlDrawStyle) {
- ASSERT_EQ(ToDl(SkPaint::Style::kFill_Style), DlDrawStyle::kFill);
- ASSERT_EQ(ToDl(SkPaint::Style::kStroke_Style), DlDrawStyle::kStroke);
- ASSERT_EQ(ToDl(SkPaint::Style::kStrokeAndFill_Style),
- DlDrawStyle::kStrokeAndFill);
-}
-
-TEST(DisplayListEnum, ToSkDrawStyle) {
- ASSERT_EQ(ToSk(DlDrawStyle::kFill), SkPaint::Style::kFill_Style);
- ASSERT_EQ(ToSk(DlDrawStyle::kStroke), SkPaint::Style::kStroke_Style);
- ASSERT_EQ(ToSk(DlDrawStyle::kStrokeAndFill),
- SkPaint::Style::kStrokeAndFill_Style);
-}
-
-TEST(DisplayListEnum, ToDlStrokeCap) {
- ASSERT_EQ(ToDl(SkPaint::Cap::kButt_Cap), DlStrokeCap::kButt);
- ASSERT_EQ(ToDl(SkPaint::Cap::kRound_Cap), DlStrokeCap::kRound);
- ASSERT_EQ(ToDl(SkPaint::Cap::kSquare_Cap), DlStrokeCap::kSquare);
-}
-
-TEST(DisplayListEnum, ToSkStrokeCap) {
- ASSERT_EQ(ToSk(DlStrokeCap::kButt), SkPaint::Cap::kButt_Cap);
- ASSERT_EQ(ToSk(DlStrokeCap::kRound), SkPaint::Cap::kRound_Cap);
- ASSERT_EQ(ToSk(DlStrokeCap::kSquare), SkPaint::Cap::kSquare_Cap);
-}
-
-TEST(DisplayListEnum, ToDlStrokeJoin) {
- ASSERT_EQ(ToDl(SkPaint::Join::kMiter_Join), DlStrokeJoin::kMiter);
- ASSERT_EQ(ToDl(SkPaint::Join::kRound_Join), DlStrokeJoin::kRound);
- ASSERT_EQ(ToDl(SkPaint::Join::kBevel_Join), DlStrokeJoin::kBevel);
-}
-
-TEST(DisplayListEnum, ToSkStrokeJoin) {
- ASSERT_EQ(ToSk(DlStrokeJoin::kMiter), SkPaint::Join::kMiter_Join);
- ASSERT_EQ(ToSk(DlStrokeJoin::kRound), SkPaint::Join::kRound_Join);
- ASSERT_EQ(ToSk(DlStrokeJoin::kBevel), SkPaint::Join::kBevel_Join);
-}
-
-TEST(DisplayListEnum, ToDlVertexMode) {
- ASSERT_EQ(ToDl(SkVertices::VertexMode::kTriangles_VertexMode),
- DlVertexMode::kTriangles);
- ASSERT_EQ(ToDl(SkVertices::VertexMode::kTriangleStrip_VertexMode),
- DlVertexMode::kTriangleStrip);
- ASSERT_EQ(ToDl(SkVertices::VertexMode::kTriangleFan_VertexMode),
- DlVertexMode::kTriangleFan);
-}
-
-TEST(DisplayListEnum, ToSkVertexMode) {
- ASSERT_EQ(ToSk(DlVertexMode::kTriangles),
- SkVertices::VertexMode::kTriangles_VertexMode);
- ASSERT_EQ(ToSk(DlVertexMode::kTriangleStrip),
- SkVertices::VertexMode::kTriangleStrip_VertexMode);
- ASSERT_EQ(ToSk(DlVertexMode::kTriangleFan),
- SkVertices::VertexMode::kTriangleFan_VertexMode);
-}
-
-TEST(DisplayListEnum, ToDlFilterMode) {
- ASSERT_EQ(ToDl(SkFilterMode::kLinear), DlFilterMode::kLinear);
- ASSERT_EQ(ToDl(SkFilterMode::kNearest), DlFilterMode::kNearest);
- ASSERT_EQ(ToDl(SkFilterMode::kLast), DlFilterMode::kLast);
-}
-
-TEST(DisplayListEnum, ToSkFilterMode) {
- ASSERT_EQ(ToSk(DlFilterMode::kLinear), SkFilterMode::kLinear);
- ASSERT_EQ(ToSk(DlFilterMode::kNearest), SkFilterMode::kNearest);
- ASSERT_EQ(ToSk(DlFilterMode::kLast), SkFilterMode::kLast);
-}
-
-TEST(DisplayListEnum, ToDlImageSampling) {
- ASSERT_EQ(ToDl(SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone)),
- DlImageSampling::kLinear);
- ASSERT_EQ(
- ToDl(SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear)),
- DlImageSampling::kMipmapLinear);
- ASSERT_EQ(
- ToDl(SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone)),
- DlImageSampling::kNearestNeighbor);
- ASSERT_EQ(ToDl(SkSamplingOptions(SkCubicResampler{1 / 3.0f, 1 / 3.0f})),
- DlImageSampling::kCubic);
-}
-
-TEST(DisplayListEnum, ToSkSamplingOptions) {
- ASSERT_EQ(ToSk(DlImageSampling::kLinear),
- SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone));
- ASSERT_EQ(ToSk(DlImageSampling::kMipmapLinear),
- SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear));
- ASSERT_EQ(ToSk(DlImageSampling::kNearestNeighbor),
- SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone));
- ASSERT_EQ(ToSk(DlImageSampling::kCubic),
- SkSamplingOptions(SkCubicResampler{1 / 3.0f, 1 / 3.0f}));
-}
-
-#define CHECK_TO_DLENUM(V) ASSERT_EQ(ToDl(SkBlendMode::V), DlBlendMode::V);
-#define CHECK_TO_SKENUM(V) ASSERT_EQ(ToSk(DlBlendMode::V), SkBlendMode::V);
-
-#define FOR_EACH_ENUM(FUNC) \
- FUNC(kSrc) \
- FUNC(kClear) \
- FUNC(kSrc) \
- FUNC(kDst) \
- FUNC(kSrcOver) \
- FUNC(kDstOver) \
- FUNC(kSrcIn) \
- FUNC(kDstIn) \
- FUNC(kSrcOut) \
- FUNC(kDstOut) \
- FUNC(kSrcATop) \
- FUNC(kDstATop) \
- FUNC(kXor) \
- FUNC(kPlus) \
- FUNC(kModulate) \
- FUNC(kScreen) \
- FUNC(kOverlay) \
- FUNC(kDarken) \
- FUNC(kLighten) \
- FUNC(kColorDodge) \
- FUNC(kColorBurn) \
- FUNC(kHardLight) \
- FUNC(kSoftLight) \
- FUNC(kDifference) \
- FUNC(kExclusion) \
- FUNC(kMultiply) \
- FUNC(kHue) \
- FUNC(kSaturation) \
- FUNC(kColor) \
- FUNC(kLuminosity) \
- FUNC(kLastCoeffMode) \
- FUNC(kLastSeparableMode) \
- FUNC(kLastMode)
-
-TEST(DisplayListEnum, ToDlBlendMode){FOR_EACH_ENUM(CHECK_TO_DLENUM)}
-
-TEST(DisplayListEnum, ToSkBlendMode) {
- FOR_EACH_ENUM(CHECK_TO_SKENUM)
-}
-
-#undef CHECK_TO_DLENUM
-#undef CHECK_TO_SKENUM
-#undef FOR_EACH_ENUM
-
-} // namespace testing
-} // namespace flutter
diff --git a/display_list/display_list_image_filter.h b/display_list/display_list_image_filter.h
index 5e29bdb..c497d4f 100644
--- a/display_list/display_list_image_filter.h
+++ b/display_list/display_list_image_filter.h
@@ -29,9 +29,9 @@
kDilate,
kErode,
kMatrix,
- kComposeFilter,
+ kCompose,
kColorFilter,
- kLocalMatrixFilter,
+ kLocalMatrix,
};
class DlBlurImageFilter;
@@ -42,8 +42,7 @@
class DlComposeImageFilter;
class DlColorFilterImageFilter;
-class DlImageFilter
- : public DlAttribute<DlImageFilter, SkImageFilter, DlImageFilterType> {
+class DlImageFilter : public DlAttribute<DlImageFilter, DlImageFilterType> {
public:
enum class MatrixCapability {
kTranslate,
@@ -227,6 +226,16 @@
explicit DlBlurImageFilter(const DlBlurImageFilter& filter)
: DlBlurImageFilter(&filter) {}
+ static std::shared_ptr<DlImageFilter> Make(SkScalar sigma_x,
+ SkScalar sigma_y,
+ DlTileMode tile_mode) {
+ if (SkScalarIsFinite(sigma_x) && sigma_x > SK_ScalarNearlyZero &&
+ SkScalarIsFinite(sigma_y) && sigma_y > SK_ScalarNearlyZero) {
+ return std::make_shared<DlBlurImageFilter>(sigma_x, sigma_y, tile_mode);
+ }
+ return nullptr;
+ }
+
std::shared_ptr<DlImageFilter> shared() const override {
return std::make_shared<DlBlurImageFilter>(this);
}
@@ -262,10 +271,6 @@
SkScalar sigma_y() const { return sigma_y_; }
DlTileMode tile_mode() const { return tile_mode_; }
- sk_sp<SkImageFilter> skia_object() const override {
- return SkImageFilters::Blur(sigma_x_, sigma_y_, ToSk(tile_mode_), nullptr);
- }
-
protected:
bool equals_(const DlImageFilter& other) const override {
FML_DCHECK(other.type() == DlImageFilterType::kBlur);
@@ -289,6 +294,15 @@
explicit DlDilateImageFilter(const DlDilateImageFilter& filter)
: DlDilateImageFilter(&filter) {}
+ static std::shared_ptr<DlImageFilter> Make(SkScalar radius_x,
+ SkScalar radius_y) {
+ if (SkScalarIsFinite(radius_x) && radius_x > SK_ScalarNearlyZero &&
+ SkScalarIsFinite(radius_y) && radius_y > SK_ScalarNearlyZero) {
+ return std::make_shared<DlDilateImageFilter>(radius_x, radius_y);
+ }
+ return nullptr;
+ }
+
std::shared_ptr<DlImageFilter> shared() const override {
return std::make_shared<DlDilateImageFilter>(this);
}
@@ -323,10 +337,6 @@
SkScalar radius_x() const { return radius_x_; }
SkScalar radius_y() const { return radius_y_; }
- sk_sp<SkImageFilter> skia_object() const override {
- return SkImageFilters::Dilate(radius_x_, radius_y_, nullptr);
- }
-
protected:
bool equals_(const DlImageFilter& other) const override {
FML_DCHECK(other.type() == DlImageFilterType::kDilate);
@@ -348,6 +358,15 @@
explicit DlErodeImageFilter(const DlErodeImageFilter& filter)
: DlErodeImageFilter(&filter) {}
+ static std::shared_ptr<DlImageFilter> Make(SkScalar radius_x,
+ SkScalar radius_y) {
+ if (SkScalarIsFinite(radius_x) && radius_x > SK_ScalarNearlyZero &&
+ SkScalarIsFinite(radius_y) && radius_y > SK_ScalarNearlyZero) {
+ return std::make_shared<DlErodeImageFilter>(radius_x, radius_y);
+ }
+ return nullptr;
+ }
+
std::shared_ptr<DlImageFilter> shared() const override {
return std::make_shared<DlErodeImageFilter>(this);
}
@@ -382,10 +401,6 @@
SkScalar radius_x() const { return radius_x_; }
SkScalar radius_y() const { return radius_y_; }
- sk_sp<SkImageFilter> skia_object() const override {
- return SkImageFilters::Erode(radius_x_, radius_y_, nullptr);
- }
-
protected:
bool equals_(const DlImageFilter& other) const override {
FML_DCHECK(other.type() == DlImageFilterType::kErode);
@@ -407,6 +422,14 @@
explicit DlMatrixImageFilter(const DlMatrixImageFilter& filter)
: DlMatrixImageFilter(&filter) {}
+ static std::shared_ptr<DlImageFilter> Make(const SkMatrix& matrix,
+ DlImageSampling sampling) {
+ if (matrix.isFinite() && !matrix.isIdentity()) {
+ return std::make_shared<DlMatrixImageFilter>(matrix, sampling);
+ }
+ return nullptr;
+ }
+
std::shared_ptr<DlImageFilter> shared() const override {
return std::make_shared<DlMatrixImageFilter>(this);
}
@@ -460,10 +483,6 @@
return &input_bounds;
}
- sk_sp<SkImageFilter> skia_object() const override {
- return SkImageFilters::MatrixTransform(matrix_, ToSk(sampling_), nullptr);
- }
-
protected:
bool equals_(const DlImageFilter& other) const override {
FML_DCHECK(other.type() == DlImageFilterType::kMatrix);
@@ -478,8 +497,8 @@
class DlComposeImageFilter final : public DlImageFilter {
public:
- DlComposeImageFilter(std::shared_ptr<DlImageFilter> outer,
- std::shared_ptr<DlImageFilter> inner)
+ DlComposeImageFilter(std::shared_ptr<const DlImageFilter> outer,
+ std::shared_ptr<const DlImageFilter> inner)
: outer_(std::move(outer)), inner_(std::move(inner)) {}
DlComposeImageFilter(const DlImageFilter* outer, const DlImageFilter* inner)
: outer_(outer->shared()), inner_(inner->shared()) {}
@@ -490,17 +509,29 @@
explicit DlComposeImageFilter(const DlComposeImageFilter& filter)
: DlComposeImageFilter(&filter) {}
+ static std::shared_ptr<const DlImageFilter> Make(
+ std::shared_ptr<const DlImageFilter> outer,
+ std::shared_ptr<const DlImageFilter> inner) {
+ if (!outer) {
+ return inner;
+ }
+ if (!inner) {
+ return outer;
+ }
+ return std::make_shared<DlComposeImageFilter>(outer, inner);
+ }
+
std::shared_ptr<DlImageFilter> shared() const override {
return std::make_shared<DlComposeImageFilter>(this);
}
DlImageFilterType type() const override {
- return DlImageFilterType::kComposeFilter;
+ return DlImageFilterType::kCompose;
}
size_t size() const override { return sizeof(*this); }
- std::shared_ptr<DlImageFilter> outer() const { return outer_; }
- std::shared_ptr<DlImageFilter> inner() const { return inner_; }
+ std::shared_ptr<const DlImageFilter> outer() const { return outer_; }
+ std::shared_ptr<const DlImageFilter> inner() const { return inner_; }
const DlComposeImageFilter* asCompose() const override { return this; }
@@ -525,30 +556,25 @@
const SkMatrix& ctm,
SkIRect& input_bounds) const override;
- sk_sp<SkImageFilter> skia_object() const override {
- return SkImageFilters::Compose(outer_->skia_object(),
- inner_->skia_object());
- }
-
MatrixCapability matrix_capability() const override {
return std::min(outer_->matrix_capability(), inner_->matrix_capability());
}
protected:
bool equals_(const DlImageFilter& other) const override {
- FML_DCHECK(other.type() == DlImageFilterType::kComposeFilter);
+ FML_DCHECK(other.type() == DlImageFilterType::kCompose);
auto that = static_cast<const DlComposeImageFilter*>(&other);
return (Equals(outer_, that->outer_) && Equals(inner_, that->inner_));
}
private:
- std::shared_ptr<DlImageFilter> outer_;
- std::shared_ptr<DlImageFilter> inner_;
+ std::shared_ptr<const DlImageFilter> outer_;
+ std::shared_ptr<const DlImageFilter> inner_;
};
class DlColorFilterImageFilter final : public DlImageFilter {
public:
- explicit DlColorFilterImageFilter(std::shared_ptr<DlColorFilter> filter)
+ explicit DlColorFilterImageFilter(std::shared_ptr<const DlColorFilter> filter)
: color_filter_(std::move(filter)) {}
explicit DlColorFilterImageFilter(const DlColorFilter* filter)
: color_filter_(filter->shared()) {}
@@ -559,6 +585,14 @@
explicit DlColorFilterImageFilter(const DlColorFilterImageFilter& filter)
: DlColorFilterImageFilter(&filter) {}
+ static std::shared_ptr<DlImageFilter> Make(
+ std::shared_ptr<const DlColorFilter> filter) {
+ if (filter) {
+ return std::make_shared<DlColorFilterImageFilter>(filter);
+ }
+ return nullptr;
+ }
+
std::shared_ptr<DlImageFilter> shared() const override {
return std::make_shared<DlColorFilterImageFilter>(color_filter_);
}
@@ -568,7 +602,7 @@
}
size_t size() const override { return sizeof(*this); }
- const std::shared_ptr<DlColorFilter> color_filter() const {
+ const std::shared_ptr<const DlColorFilter> color_filter() const {
return color_filter_;
}
@@ -602,10 +636,6 @@
return map_device_bounds(output_bounds, ctm, input_bounds);
}
- sk_sp<SkImageFilter> skia_object() const override {
- return SkImageFilters::ColorFilter(color_filter_->skia_object(), nullptr);
- }
-
MatrixCapability matrix_capability() const override {
return MatrixCapability::kComplex;
}
@@ -623,7 +653,7 @@
}
private:
- std::shared_ptr<DlColorFilter> color_filter_;
+ std::shared_ptr<const DlColorFilter> color_filter_;
};
class DlLocalMatrixImageFilter final : public DlImageFilter {
@@ -640,7 +670,7 @@
}
DlImageFilterType type() const override {
- return DlImageFilterType::kLocalMatrixFilter;
+ return DlImageFilterType::kLocalMatrix;
}
size_t size() const override { return sizeof(*this); }
@@ -689,20 +719,9 @@
output_bounds, SkMatrix::Concat(ctm, matrix_), input_bounds);
}
- sk_sp<SkImageFilter> skia_object() const override {
- if (!image_filter_) {
- return nullptr;
- }
- sk_sp<SkImageFilter> skia_object = image_filter_->skia_object();
- if (!skia_object) {
- return nullptr;
- }
- return skia_object->makeWithLocalMatrix(matrix_);
- }
-
protected:
bool equals_(const DlImageFilter& other) const override {
- FML_DCHECK(other.type() == DlImageFilterType::kLocalMatrixFilter);
+ FML_DCHECK(other.type() == DlImageFilterType::kLocalMatrix);
auto that = static_cast<const DlLocalMatrixImageFilter*>(&other);
return (matrix_ == that->matrix_ &&
Equals(image_filter_, that->image_filter_));
diff --git a/display_list/display_list_image_filter_unittests.cc b/display_list/display_list_image_filter_unittests.cc
index 7e125db..1cc0231 100644
--- a/display_list/display_list_image_filter_unittests.cc
+++ b/display_list/display_list_image_filter_unittests.cc
@@ -17,21 +17,6 @@
namespace flutter {
namespace testing {
-TEST(DisplayListImageFilter, BuilderSetGet) {
- DlBlurImageFilter filter(5.0, 5.0, DlTileMode::kDecal);
- DisplayListBuilder builder;
-
- ASSERT_EQ(builder.getImageFilter(), nullptr);
-
- builder.setImageFilter(&filter);
- ASSERT_NE(builder.getImageFilter(), nullptr);
- ASSERT_TRUE(
- Equals(builder.getImageFilter(), static_cast<DlImageFilter*>(&filter)));
-
- builder.setImageFilter(nullptr);
- ASSERT_EQ(builder.getImageFilter(), nullptr);
-}
-
// SkRect::contains treats the rect as a half-open interval which is
// appropriate for so many operations. Unfortunately, we are using
// it here to test containment of the corners of a transformed quad
@@ -708,8 +693,8 @@
SkImageFilters::ColorFilter(
SkColorFilters::Blend(SK_ColorRED, SkBlendMode::kSrcOver), nullptr),
SkImageFilters::Dilate(5.0, 10.0, nullptr),
- SkImageFilters::MatrixTransform(filter_matrix,
- ToSk(DlImageSampling::kLinear), nullptr),
+ SkImageFilters::MatrixTransform(
+ filter_matrix, SkSamplingOptions(SkFilterMode::kLinear), nullptr),
SkImageFilters::Compose(
SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat, nullptr),
SkImageFilters::ColorFilter(
@@ -785,15 +770,5 @@
}
}
-TEST(DisplayListImageFilter, LocalImageSkiaNull) {
- auto blur_filter =
- std::make_shared<DlBlurImageFilter>(0, 0, DlTileMode::kClamp);
- DlLocalMatrixImageFilter dl_local_matrix_filter(SkMatrix::RotateDeg(45),
- blur_filter);
- // With sigmas set to zero on the blur filter, Skia will return a null filter.
- // The local matrix filter should return nullptr instead of crashing.
- ASSERT_EQ(dl_local_matrix_filter.skia_object(), nullptr);
-}
-
} // namespace testing
} // namespace flutter
diff --git a/display_list/display_list_mask_filter.h b/display_list/display_list_mask_filter.h
index 7e8c678..c48dae5 100644
--- a/display_list/display_list_mask_filter.h
+++ b/display_list/display_list_mask_filter.h
@@ -20,8 +20,7 @@
// An enumerated type for the supported MaskFilter operations.
enum class DlMaskFilterType { kBlur };
-class DlMaskFilter
- : public DlAttribute<DlMaskFilter, SkMaskFilter, DlMaskFilterType> {
+class DlMaskFilter : public DlAttribute<DlMaskFilter, DlMaskFilterType> {
public:
// Return a DlBlurMaskFilter pointer to this object iff it is a Blur
// type of MaskFilter, otherwise return nullptr.
@@ -43,6 +42,15 @@
: DlBlurMaskFilter(filter->style_, filter->sigma_, filter->respect_ctm_) {
}
+ static std::shared_ptr<DlMaskFilter> Make(SkBlurStyle style,
+ SkScalar sigma,
+ bool respect_ctm = true) {
+ if (SkScalarIsFinite(sigma) && sigma > 0) {
+ return std::make_shared<DlBlurMaskFilter>(style, sigma, respect_ctm);
+ }
+ return nullptr;
+ }
+
DlMaskFilterType type() const override { return DlMaskFilterType::kBlur; }
size_t size() const override { return sizeof(*this); }
@@ -50,10 +58,6 @@
return std::make_shared<DlBlurMaskFilter>(this);
}
- sk_sp<SkMaskFilter> skia_object() const override {
- return SkMaskFilter::MakeBlur(style_, sigma_, respect_ctm_);
- }
-
const DlBlurMaskFilter* asBlur() const override { return this; }
SkBlurStyle style() const { return style_; }
diff --git a/display_list/display_list_mask_filter_unittests.cc b/display_list/display_list_mask_filter_unittests.cc
index 5ae2261..b794360 100644
--- a/display_list/display_list_mask_filter_unittests.cc
+++ b/display_list/display_list_mask_filter_unittests.cc
@@ -12,18 +12,6 @@
namespace flutter {
namespace testing {
-TEST(DisplayListMaskFilter, BuilderSetGet) {
- DlBlurMaskFilter filter(SkBlurStyle::kNormal_SkBlurStyle, 5.0);
- DisplayListBuilder builder;
- ASSERT_EQ(builder.getMaskFilter(), nullptr);
- builder.setMaskFilter(&filter);
- ASSERT_NE(builder.getMaskFilter(), nullptr);
- ASSERT_TRUE(
- Equals(builder.getMaskFilter(), static_cast<DlMaskFilter*>(&filter)));
- builder.setMaskFilter(nullptr);
- ASSERT_EQ(builder.getMaskFilter(), nullptr);
-}
-
TEST(DisplayListMaskFilter, BlurConstructor) {
DlBlurMaskFilter filter(SkBlurStyle::kNormal_SkBlurStyle, 5.0);
}
diff --git a/display_list/display_list_ops.h b/display_list/display_list_ops.h
index fb949b5..e9c6642 100644
--- a/display_list/display_list_ops.h
+++ b/display_list/display_list_ops.h
@@ -8,8 +8,8 @@
#include "display_list_color_source.h"
#include "flutter/display_list/display_list.h"
#include "flutter/display_list/display_list_blend_mode.h"
-#include "flutter/display_list/display_list_dispatcher.h"
#include "flutter/display_list/display_list_sampling_options.h"
+#include "flutter/display_list/dl_op_receiver.h"
#include "flutter/display_list/types.h"
#include "flutter/fml/macros.h"
@@ -37,7 +37,7 @@
// cheap to deal with a complicated "lifetime" tracking to
// determine if they will be used.
struct DispatchContext {
- Dispatcher& dispatcher;
+ DlOpReceiver& receiver;
int cur_index;
int next_render_index;
@@ -111,7 +111,7 @@
const bool value; \
\
void dispatch(DispatchContext& ctx) const { \
- ctx.dispatcher.set##name(value); \
+ ctx.receiver.set##name(value); \
} \
};
DEFINE_SET_BOOL_OP(AntiAlias)
@@ -129,7 +129,7 @@
const DlStroke##name value; \
\
void dispatch(DispatchContext& ctx) const { \
- ctx.dispatcher.setStroke##name(value); \
+ ctx.receiver.setStroke##name(value); \
} \
};
DEFINE_SET_ENUM_OP(Cap)
@@ -144,7 +144,7 @@
const DlDrawStyle style;
- void dispatch(DispatchContext& ctx) const { ctx.dispatcher.setStyle(style); }
+ void dispatch(DispatchContext& ctx) const { ctx.receiver.setStyle(style); }
};
// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct SetStrokeWidthOp final : DLOp {
@@ -155,7 +155,7 @@
const float width;
void dispatch(DispatchContext& ctx) const {
- ctx.dispatcher.setStrokeWidth(width);
+ ctx.receiver.setStrokeWidth(width);
}
};
// 4 byte header + 4 byte payload packs into minimum 8 bytes
@@ -167,7 +167,7 @@
const float limit;
void dispatch(DispatchContext& ctx) const {
- ctx.dispatcher.setStrokeMiter(limit);
+ ctx.receiver.setStrokeMiter(limit);
}
};
@@ -179,7 +179,7 @@
const DlColor color;
- void dispatch(DispatchContext& ctx) const { ctx.dispatcher.setColor(color); }
+ void dispatch(DispatchContext& ctx) const { ctx.receiver.setColor(color); }
};
// 4 byte header + 4 byte payload packs into minimum 8 bytes
struct SetBlendModeOp final : DLOp {
@@ -189,8 +189,8 @@
const DlBlendMode mode;
- void dispatch(DispatchContext& ctx) const {
- ctx.dispatcher.setBlendMode(mode);
+ void dispatch(DispatchContext& ctx) const { //
+ ctx.receiver.setBlendMode(mode);
}
};
@@ -207,7 +207,7 @@
Clear##name##Op() {} \
\
void dispatch(DispatchContext& ctx) const { \
- ctx.dispatcher.set##name(nullptr); \
+ ctx.receiver.set##name(nullptr); \
} \
}; \
struct SetPod##name##Op final : DLOp { \
@@ -217,7 +217,7 @@
\
void dispatch(DispatchContext& ctx) const { \
const Dl##name* filter = reinterpret_cast<const Dl##name*>(this + 1); \
- ctx.dispatcher.set##name(filter); \
+ ctx.receiver.set##name(filter); \
} \
};
DEFINE_SET_CLEAR_DLATTR_OP(ColorFilter, ColorFilter, filter)
@@ -242,7 +242,7 @@
const DlImageColorSource source;
void dispatch(DispatchContext& ctx) const {
- ctx.dispatcher.setColorSource(&source);
+ ctx.receiver.setColorSource(&source);
}
};
@@ -259,7 +259,7 @@
const DlRuntimeEffectColorSource source;
void dispatch(DispatchContext& ctx) const {
- ctx.dispatcher.setColorSource(&source);
+ ctx.receiver.setColorSource(&source);
}
DisplayListCompare equals(const SetRuntimeEffectColorSourceOp* other) const {
@@ -278,7 +278,7 @@
const DlSceneColorSource source;
void dispatch(DispatchContext& ctx) const {
- ctx.dispatcher.setColorSource(&source);
+ ctx.receiver.setColorSource(&source);
}
DisplayListCompare equals(const SetSceneColorSourceOp* other) const {
@@ -298,7 +298,7 @@
const std::shared_ptr<DlImageFilter> filter;
void dispatch(DispatchContext& ctx) const {
- ctx.dispatcher.setImageFilter(filter.get());
+ ctx.receiver.setImageFilter(filter.get());
}
DisplayListCompare equals(const SetSharedImageFilterOp* other) const {
@@ -336,7 +336,7 @@
void dispatch(DispatchContext& ctx) const {
if (save_needed(ctx)) {
- ctx.dispatcher.save();
+ ctx.receiver.save();
}
}
};
@@ -348,7 +348,7 @@
void dispatch(DispatchContext& ctx) const {
if (save_needed(ctx)) {
- ctx.dispatcher.saveLayer(nullptr, options);
+ ctx.receiver.saveLayer(nullptr, options);
}
}
};
@@ -363,7 +363,7 @@
void dispatch(DispatchContext& ctx) const {
if (save_needed(ctx)) {
- ctx.dispatcher.saveLayer(&rect, options);
+ ctx.receiver.saveLayer(&rect, options);
}
}
};
@@ -379,7 +379,7 @@
void dispatch(DispatchContext& ctx) const {
if (save_needed(ctx)) {
- ctx.dispatcher.saveLayer(nullptr, options, backdrop.get());
+ ctx.receiver.saveLayer(nullptr, options, backdrop.get());
}
}
@@ -403,7 +403,7 @@
void dispatch(DispatchContext& ctx) const {
if (save_needed(ctx)) {
- ctx.dispatcher.saveLayer(&rect, options, backdrop.get());
+ ctx.receiver.saveLayer(&rect, options, backdrop.get());
}
}
@@ -423,7 +423,7 @@
void dispatch(DispatchContext& ctx) const {
DispatchContext::SaveInfo& info = ctx.save_infos.back();
if (info.save_was_needed) {
- ctx.dispatcher.restore();
+ ctx.receiver.restore();
}
ctx.next_restore_index = info.previous_restore_index;
ctx.save_infos.pop_back();
@@ -447,7 +447,7 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.translate(tx, ty);
+ ctx.receiver.translate(tx, ty);
}
}
};
@@ -463,7 +463,7 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.scale(sx, sy);
+ ctx.receiver.scale(sx, sy);
}
}
};
@@ -477,7 +477,7 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.rotate(degrees);
+ ctx.receiver.rotate(degrees);
}
}
};
@@ -493,7 +493,7 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.skew(sx, sy);
+ ctx.receiver.skew(sx, sy);
}
}
};
@@ -513,8 +513,8 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.transform2DAffine(mxx, mxy, mxt, //
- myx, myy, myt);
+ ctx.receiver.transform2DAffine(mxx, mxy, mxt, //
+ myx, myy, myt);
}
}
};
@@ -542,10 +542,10 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.transformFullPerspective(mxx, mxy, mxz, mxt, //
- myx, myy, myz, myt, //
- mzx, mzy, mzz, mzt, //
- mwx, mwy, mwz, mwt);
+ ctx.receiver.transformFullPerspective(mxx, mxy, mxz, mxt, //
+ myx, myy, myz, myt, //
+ mzx, mzy, mzz, mzt, //
+ mwx, mwy, mwz, mwt);
}
}
};
@@ -558,7 +558,7 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.transformReset();
+ ctx.receiver.transformReset();
}
}
};
@@ -585,8 +585,8 @@
\
void dispatch(DispatchContext& ctx) const { \
if (op_needed(ctx)) { \
- ctx.dispatcher.clip##shapetype(shape, DlCanvas::ClipOp::k##clipop, \
- is_aa); \
+ ctx.receiver.clip##shapetype(shape, DlCanvas::ClipOp::k##clipop, \
+ is_aa); \
} \
} \
};
@@ -596,27 +596,27 @@
DEFINE_CLIP_SHAPE_OP(RRect, Difference)
#undef DEFINE_CLIP_SHAPE_OP
-#define DEFINE_CLIP_PATH_OP(clipop) \
- struct Clip##clipop##PathOp final : TransformClipOpBase { \
- static const auto kType = DisplayListOpType::kClip##clipop##Path; \
- \
- Clip##clipop##PathOp(SkPath path, bool is_aa) \
- : is_aa(is_aa), path(path) {} \
- \
- const bool is_aa; \
- const SkPath path; \
- \
- void dispatch(DispatchContext& ctx) const { \
- if (op_needed(ctx)) { \
- ctx.dispatcher.clipPath(path, DlCanvas::ClipOp::k##clipop, is_aa); \
- } \
- } \
- \
- DisplayListCompare equals(const Clip##clipop##PathOp* other) const { \
- return is_aa == other->is_aa && path == other->path \
- ? DisplayListCompare::kEqual \
- : DisplayListCompare::kNotEqual; \
- } \
+#define DEFINE_CLIP_PATH_OP(clipop) \
+ struct Clip##clipop##PathOp final : TransformClipOpBase { \
+ static const auto kType = DisplayListOpType::kClip##clipop##Path; \
+ \
+ Clip##clipop##PathOp(SkPath path, bool is_aa) \
+ : is_aa(is_aa), path(path) {} \
+ \
+ const bool is_aa; \
+ const SkPath path; \
+ \
+ void dispatch(DispatchContext& ctx) const { \
+ if (op_needed(ctx)) { \
+ ctx.receiver.clipPath(path, DlCanvas::ClipOp::k##clipop, is_aa); \
+ } \
+ } \
+ \
+ DisplayListCompare equals(const Clip##clipop##PathOp* other) const { \
+ return is_aa == other->is_aa && path == other->path \
+ ? DisplayListCompare::kEqual \
+ : DisplayListCompare::kNotEqual; \
+ } \
};
DEFINE_CLIP_PATH_OP(Intersect)
DEFINE_CLIP_PATH_OP(Difference)
@@ -636,7 +636,7 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.drawPaint();
+ ctx.receiver.drawPaint();
}
}
};
@@ -652,7 +652,7 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.drawColor(color, mode);
+ ctx.receiver.drawColor(color, mode);
}
}
};
@@ -672,7 +672,7 @@
\
void dispatch(DispatchContext& ctx) const { \
if (op_needed(ctx)) { \
- ctx.dispatcher.draw##op_name(arg_name); \
+ ctx.receiver.draw##op_name(arg_name); \
} \
} \
};
@@ -692,7 +692,7 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.drawPath(path);
+ ctx.receiver.drawPath(path);
}
}
@@ -720,7 +720,7 @@
\
void dispatch(DispatchContext& ctx) const { \
if (op_needed(ctx)) { \
- ctx.dispatcher.draw##op_name(name1, name2); \
+ ctx.receiver.draw##op_name(name1, name2); \
} \
} \
};
@@ -743,7 +743,7 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.drawArc(bounds, start, sweep, center);
+ ctx.receiver.drawArc(bounds, start, sweep, center);
}
}
};
@@ -754,20 +754,20 @@
// so this op will always pack efficiently
// The point type is packed into 3 different OpTypes to avoid expanding
// the fixed payload beyond the 8 bytes
-#define DEFINE_DRAW_POINTS_OP(name, mode) \
- struct Draw##name##Op final : DrawOpBase { \
- static const auto kType = DisplayListOpType::kDraw##name; \
- \
- explicit Draw##name##Op(uint32_t count) : count(count) {} \
- \
- const uint32_t count; \
- \
- void dispatch(DispatchContext& ctx) const { \
- if (op_needed(ctx)) { \
- const SkPoint* pts = reinterpret_cast<const SkPoint*>(this + 1); \
- ctx.dispatcher.drawPoints(DlCanvas::PointMode::mode, count, pts); \
- } \
- } \
+#define DEFINE_DRAW_POINTS_OP(name, mode) \
+ struct Draw##name##Op final : DrawOpBase { \
+ static const auto kType = DisplayListOpType::kDraw##name; \
+ \
+ explicit Draw##name##Op(uint32_t count) : count(count) {} \
+ \
+ const uint32_t count; \
+ \
+ void dispatch(DispatchContext& ctx) const { \
+ if (op_needed(ctx)) { \
+ const SkPoint* pts = reinterpret_cast<const SkPoint*>(this + 1); \
+ ctx.receiver.drawPoints(DlCanvas::PointMode::mode, count, pts); \
+ } \
+ } \
};
DEFINE_DRAW_POINTS_OP(Points, kPoints);
DEFINE_DRAW_POINTS_OP(Lines, kLines);
@@ -792,38 +792,38 @@
if (op_needed(ctx)) {
const DlVertices* vertices =
reinterpret_cast<const DlVertices*>(this + 1);
- ctx.dispatcher.drawVertices(vertices, mode);
+ ctx.receiver.drawVertices(vertices, mode);
}
}
};
// 4 byte header + 40 byte payload uses 44 bytes but is rounded up to 48 bytes
// (4 bytes unused)
-#define DEFINE_DRAW_IMAGE_OP(name, with_attributes) \
- struct name##Op final : DrawOpBase { \
- static const auto kType = DisplayListOpType::k##name; \
- \
- name##Op(const sk_sp<DlImage> image, \
- const SkPoint& point, \
- DlImageSampling sampling) \
- : point(point), sampling(sampling), image(std::move(image)) {} \
- \
- const SkPoint point; \
- const DlImageSampling sampling; \
- const sk_sp<DlImage> image; \
- \
- void dispatch(DispatchContext& ctx) const { \
- if (op_needed(ctx)) { \
- ctx.dispatcher.drawImage(image, point, sampling, with_attributes); \
- } \
- } \
- \
- DisplayListCompare equals(const name##Op* other) const { \
- return (point == other->point && sampling == other->sampling && \
- image->Equals(other->image)) \
- ? DisplayListCompare::kEqual \
- : DisplayListCompare::kNotEqual; \
- } \
+#define DEFINE_DRAW_IMAGE_OP(name, with_attributes) \
+ struct name##Op final : DrawOpBase { \
+ static const auto kType = DisplayListOpType::k##name; \
+ \
+ name##Op(const sk_sp<DlImage> image, \
+ const SkPoint& point, \
+ DlImageSampling sampling) \
+ : point(point), sampling(sampling), image(std::move(image)) {} \
+ \
+ const SkPoint point; \
+ const DlImageSampling sampling; \
+ const sk_sp<DlImage> image; \
+ \
+ void dispatch(DispatchContext& ctx) const { \
+ if (op_needed(ctx)) { \
+ ctx.receiver.drawImage(image, point, sampling, with_attributes); \
+ } \
+ } \
+ \
+ DisplayListCompare equals(const name##Op* other) const { \
+ return (point == other->point && sampling == other->sampling && \
+ image->Equals(other->image)) \
+ ? DisplayListCompare::kEqual \
+ : DisplayListCompare::kNotEqual; \
+ } \
};
DEFINE_DRAW_IMAGE_OP(DrawImage, false)
DEFINE_DRAW_IMAGE_OP(DrawImageWithAttr, true)
@@ -839,7 +839,7 @@
const SkRect& dst,
DlImageSampling sampling,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint)
+ DlCanvas::SrcRectConstraint constraint)
: src(src),
dst(dst),
sampling(sampling),
@@ -851,13 +851,13 @@
const SkRect dst;
const DlImageSampling sampling;
const bool render_with_attributes;
- const SkCanvas::SrcRectConstraint constraint;
+ const DlCanvas::SrcRectConstraint constraint;
const sk_sp<DlImage> image;
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.drawImageRect(image, src, dst, sampling,
- render_with_attributes, constraint);
+ ctx.receiver.drawImageRect(image, src, dst, sampling,
+ render_with_attributes, constraint);
}
}
@@ -889,8 +889,8 @@
\
void dispatch(DispatchContext& ctx) const { \
if (op_needed(ctx)) { \
- ctx.dispatcher.drawImageNine(image, center, dst, mode, \
- render_with_attributes); \
+ ctx.receiver.drawImageNine(image, center, dst, mode, \
+ render_with_attributes); \
} \
} \
\
@@ -976,8 +976,8 @@
const DlColor* colors =
has_colors ? reinterpret_cast<const DlColor*>(tex + count) : nullptr;
const DlBlendMode mode = static_cast<DlBlendMode>(mode_index);
- ctx.dispatcher.drawAtlas(atlas, xform, tex, colors, count, mode, sampling,
- nullptr, render_with_attributes);
+ ctx.receiver.drawAtlas(atlas, xform, tex, colors, count, mode, sampling,
+ nullptr, render_with_attributes);
}
}
@@ -1021,8 +1021,8 @@
const DlColor* colors =
has_colors ? reinterpret_cast<const DlColor*>(tex + count) : nullptr;
const DlBlendMode mode = static_cast<DlBlendMode>(mode_index);
- ctx.dispatcher.drawAtlas(atlas, xform, tex, colors, count, mode, sampling,
- &cull_rect, render_with_attributes);
+ ctx.receiver.drawAtlas(atlas, xform, tex, colors, count, mode, sampling,
+ &cull_rect, render_with_attributes);
}
}
@@ -1041,19 +1041,22 @@
struct DrawDisplayListOp final : DrawOpBase {
static const auto kType = DisplayListOpType::kDrawDisplayList;
- explicit DrawDisplayListOp(const sk_sp<DisplayList> display_list)
- : display_list(std::move(display_list)) {}
+ explicit DrawDisplayListOp(const sk_sp<DisplayList> display_list,
+ SkScalar opacity)
+ : opacity(opacity), display_list(std::move(display_list)) {}
+ SkScalar opacity;
const sk_sp<DisplayList> display_list;
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.drawDisplayList(display_list);
+ ctx.receiver.drawDisplayList(display_list, opacity);
}
}
DisplayListCompare equals(const DrawDisplayListOp* other) const {
- return display_list->Equals(other->display_list)
+ return (opacity == other->opacity &&
+ display_list->Equals(other->display_list))
? DisplayListCompare::kEqual
: DisplayListCompare::kNotEqual;
}
@@ -1073,33 +1076,33 @@
void dispatch(DispatchContext& ctx) const {
if (op_needed(ctx)) {
- ctx.dispatcher.drawTextBlob(blob, x, y);
+ ctx.receiver.drawTextBlob(blob, x, y);
}
}
};
// 4 byte header + 28 byte payload packs evenly into 32 bytes
-#define DEFINE_DRAW_SHADOW_OP(name, transparent_occluder) \
- struct Draw##name##Op final : DrawOpBase { \
- static const auto kType = DisplayListOpType::kDraw##name; \
- \
- Draw##name##Op(const SkPath& path, \
- DlColor color, \
- SkScalar elevation, \
- SkScalar dpr) \
- : color(color), elevation(elevation), dpr(dpr), path(path) {} \
- \
- const DlColor color; \
- const SkScalar elevation; \
- const SkScalar dpr; \
- const SkPath path; \
- \
- void dispatch(DispatchContext& ctx) const { \
- if (op_needed(ctx)) { \
- ctx.dispatcher.drawShadow(path, color, elevation, \
- transparent_occluder, dpr); \
- } \
- } \
+#define DEFINE_DRAW_SHADOW_OP(name, transparent_occluder) \
+ struct Draw##name##Op final : DrawOpBase { \
+ static const auto kType = DisplayListOpType::kDraw##name; \
+ \
+ Draw##name##Op(const SkPath& path, \
+ DlColor color, \
+ SkScalar elevation, \
+ SkScalar dpr) \
+ : color(color), elevation(elevation), dpr(dpr), path(path) {} \
+ \
+ const DlColor color; \
+ const SkScalar elevation; \
+ const SkScalar dpr; \
+ const SkPath path; \
+ \
+ void dispatch(DispatchContext& ctx) const { \
+ if (op_needed(ctx)) { \
+ ctx.receiver.drawShadow(path, color, elevation, transparent_occluder, \
+ dpr); \
+ } \
+ } \
};
DEFINE_DRAW_SHADOW_OP(Shadow, false)
DEFINE_DRAW_SHADOW_OP(ShadowTransparentOccluder, true)
diff --git a/display_list/display_list_paint.h b/display_list/display_list_paint.h
index 871be22..7bfdbfa 100644
--- a/display_list/display_list_paint.h
+++ b/display_list/display_list_paint.h
@@ -25,14 +25,6 @@
kDefaultStyle = kFill,
};
-inline DlDrawStyle ToDl(SkPaint::Style style) {
- return static_cast<DlDrawStyle>(style);
-}
-
-inline SkPaint::Style ToSk(DlDrawStyle style) {
- return static_cast<SkPaint::Style>(style);
-}
-
enum class DlStrokeCap {
kButt, //!< no stroke extension
kRound, //!< adds circle
@@ -42,14 +34,6 @@
kDefaultCap = kButt,
};
-inline DlStrokeCap ToDl(SkPaint::Cap cap) {
- return static_cast<DlStrokeCap>(cap);
-}
-
-inline SkPaint::Cap ToSk(DlStrokeCap cap) {
- return static_cast<SkPaint::Cap>(cap);
-}
-
enum class DlStrokeJoin {
kMiter, //!< extends to miter limit
kRound, //!< adds circle
@@ -59,14 +43,6 @@
kDefaultJoin = kMiter,
};
-inline DlStrokeJoin ToDl(SkPaint::Join join) {
- return static_cast<DlStrokeJoin>(join);
-}
-
-inline SkPaint::Join ToSk(DlStrokeJoin join) {
- return static_cast<SkPaint::Join>(join);
-}
-
class DlPaint {
public:
static constexpr DlColor kDefaultColor = DlColor::kBlack();
@@ -174,7 +150,7 @@
}
const DlColorFilter* getColorFilterPtr() const { return colorFilter_.get(); }
DlPaint& setColorFilter(const std::shared_ptr<const DlColorFilter> filter) {
- colorFilter_ = filter ? filter->shared() : nullptr;
+ colorFilter_ = filter;
return *this;
}
DlPaint& setColorFilter(const DlColorFilter* filter) {
@@ -216,6 +192,10 @@
pathEffect_ = pathEffect;
return *this;
}
+ DlPaint& setPathEffect(const DlPathEffect* effect) {
+ pathEffect_ = effect ? effect->shared() : nullptr;
+ return *this;
+ }
bool isDefault() const { return *this == kDefault; }
diff --git a/display_list/display_list_path_effect.h b/display_list/display_list_path_effect.h
index d03f194..f8bd030 100644
--- a/display_list/display_list_path_effect.h
+++ b/display_list/display_list_path_effect.h
@@ -25,8 +25,7 @@
kDash,
};
-class DlPathEffect
- : public DlAttribute<DlPathEffect, SkPathEffect, DlPathEffectType> {
+class DlPathEffect : public DlAttribute<DlPathEffect, DlPathEffectType> {
public:
virtual const DlDashPathEffect* asDash() const { return nullptr; }
@@ -77,13 +76,11 @@
const DlDashPathEffect* asDash() const override { return this; }
- sk_sp<SkPathEffect> skia_object() const override {
- return SkDashPathEffect::Make(intervals(), count_, phase_);
- }
-
const SkScalar* intervals() const {
return reinterpret_cast<const SkScalar*>(this + 1);
}
+ int count() const { return count_; }
+ SkScalar phase() const { return phase_; }
std::optional<SkRect> effect_bounds(SkRect& rect) const override;
diff --git a/display_list/display_list_path_effect_unittests.cc b/display_list/display_list_path_effect_unittests.cc
index 0067c37..e111108 100644
--- a/display_list/display_list_path_effect_unittests.cc
+++ b/display_list/display_list_path_effect_unittests.cc
@@ -13,19 +13,6 @@
namespace flutter {
namespace testing {
-TEST(DisplayListPathEffect, BuilderSetGet) {
- const SkScalar test_dashes[] = {4.0, 2.0};
- auto dash_path_effect = DlDashPathEffect::Make(test_dashes, 2, 0.0);
- DisplayListBuilder builder;
- ASSERT_EQ(builder.getPathEffect(), nullptr);
- builder.setPathEffect(dash_path_effect.get());
- ASSERT_NE(builder.getPathEffect(), nullptr);
- ASSERT_TRUE(Equals(builder.getPathEffect(),
- static_cast<DlPathEffect*>(dash_path_effect.get())));
- builder.setPathEffect(nullptr);
- ASSERT_EQ(builder.getPathEffect(), nullptr);
-}
-
TEST(DisplayListPathEffect, EffectShared) {
const SkScalar TestDashes2[] = {1.0, 1.5};
auto effect = DlDashPathEffect::Make(TestDashes2, 2, 0.0);
diff --git a/display_list/display_list_sampling_options.h b/display_list/display_list_sampling_options.h
index b3f1afa..c3896bf 100644
--- a/display_list/display_list_sampling_options.h
+++ b/display_list/display_list_sampling_options.h
@@ -16,14 +16,6 @@
kLast = kLinear,
};
-inline DlFilterMode ToDl(const SkFilterMode filter_mode) {
- return static_cast<DlFilterMode>(filter_mode);
-}
-
-inline SkFilterMode ToSk(const DlFilterMode filter_mode) {
- return static_cast<SkFilterMode>(filter_mode);
-}
-
enum class DlImageSampling {
kNearestNeighbor,
kLinear,
@@ -31,34 +23,6 @@
kCubic,
};
-inline DlImageSampling ToDl(const SkSamplingOptions& so) {
- if (so.useCubic) {
- return DlImageSampling::kCubic;
- }
- if (so.filter == SkFilterMode::kLinear) {
- if (so.mipmap == SkMipmapMode::kNone) {
- return DlImageSampling::kLinear;
- }
- if (so.mipmap == SkMipmapMode::kLinear) {
- return DlImageSampling::kMipmapLinear;
- }
- }
- return DlImageSampling::kNearestNeighbor;
-}
-
-inline SkSamplingOptions ToSk(DlImageSampling sampling) {
- switch (sampling) {
- case DlImageSampling::kCubic:
- return SkSamplingOptions(SkCubicResampler{1 / 3.0f, 1 / 3.0f});
- case DlImageSampling::kLinear:
- return SkSamplingOptions(SkFilterMode::kLinear);
- case DlImageSampling::kMipmapLinear:
- return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
- case DlImageSampling::kNearestNeighbor:
- return SkSamplingOptions(SkFilterMode::kNearest);
- }
-}
-
} // namespace flutter
#endif // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_SAMPLING_OPTIONS_H_
diff --git a/display_list/display_list_tile_mode.h b/display_list/display_list_tile_mode.h
index 0be9b54..15c04cf 100644
--- a/display_list/display_list_tile_mode.h
+++ b/display_list/display_list_tile_mode.h
@@ -30,14 +30,6 @@
kDecal,
};
-inline DlTileMode ToDl(SkTileMode sk_mode) {
- return static_cast<DlTileMode>(sk_mode);
-}
-
-inline SkTileMode ToSk(DlTileMode dl_mode) {
- return static_cast<SkTileMode>(dl_mode);
-}
-
} // namespace flutter
#endif // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_TILE_MODE_H_
diff --git a/display_list/display_list_unittests.cc b/display_list/display_list_unittests.cc
index b2ac33e..03c05c0 100644
--- a/display_list/display_list_unittests.cc
+++ b/display_list/display_list_unittests.cc
@@ -14,6 +14,7 @@
#include "flutter/display_list/display_list_paint.h"
#include "flutter/display_list/display_list_rtree.h"
#include "flutter/display_list/display_list_utils.h"
+#include "flutter/display_list/skia/dl_sk_dispatcher.h"
#include "flutter/display_list/testing/dl_test_snippets.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/math.h"
@@ -24,6 +25,11 @@
#include "third_party/skia/include/core/SkSurface.h"
namespace flutter {
+
+DlOpReceiver& DisplayListBuilderTestingAccessor(DisplayListBuilder& builder) {
+ return builder.asReceiver();
+}
+
namespace testing {
static std::vector<testing::DisplayListInvocationGroup> allGroups =
@@ -32,7 +38,61 @@
using ClipOp = DlCanvas::ClipOp;
using PointMode = DlCanvas::PointMode;
-TEST(DisplayList, BuilderCanBeReused) {
+template <typename BaseT>
+class DisplayListTestBase : public BaseT {
+ public:
+ DisplayListTestBase() = default;
+
+ static DlOpReceiver& ToReceiver(DisplayListBuilder& builder) {
+ return DisplayListBuilderTestingAccessor(builder);
+ }
+
+ static sk_sp<DisplayList> Build(DisplayListInvocation& invocation) {
+ DisplayListBuilder builder;
+ invocation.Invoke(ToReceiver(builder));
+ return builder.Build();
+ }
+
+ static sk_sp<DisplayList> Build(size_t g_index, size_t v_index) {
+ DisplayListBuilder builder;
+ DlOpReceiver& receiver =
+ DisplayListTestBase<::testing::Test>::ToReceiver(builder);
+ unsigned int op_count = 0;
+ size_t byte_count = 0;
+ for (size_t i = 0; i < allGroups.size(); i++) {
+ DisplayListInvocationGroup& group = allGroups[i];
+ size_t j = (i == g_index ? v_index : 0);
+ if (j >= group.variants.size()) {
+ continue;
+ }
+ DisplayListInvocation& invocation = group.variants[j];
+ op_count += invocation.op_count();
+ byte_count += invocation.raw_byte_count();
+ invocation.invoker(receiver);
+ }
+ sk_sp<DisplayList> dl = builder.Build();
+ std::string name;
+ if (g_index >= allGroups.size()) {
+ name = "Default";
+ } else {
+ name = allGroups[g_index].op_name;
+ if (v_index >= allGroups[g_index].variants.size()) {
+ name += " skipped";
+ } else {
+ name += " variant " + std::to_string(v_index + 1);
+ }
+ }
+ EXPECT_EQ(dl->op_count(false), op_count) << name;
+ EXPECT_EQ(dl->bytes(false), byte_count + sizeof(DisplayList)) << name;
+ return dl;
+ }
+
+ private:
+ FML_DISALLOW_COPY_AND_ASSIGN(DisplayListTestBase);
+};
+using DisplayListTest = DisplayListTestBase<::testing::Test>;
+
+TEST_F(DisplayListTest, BuilderCanBeReused) {
DisplayListBuilder builder(kTestBounds);
builder.DrawRect(kTestBounds, DlPaint());
auto dl = builder.Build();
@@ -41,7 +101,7 @@
ASSERT_TRUE(dl->Equals(dl2));
}
-TEST(DisplayList, BuilderBoundsTransformComparedToSkia) {
+TEST_F(DisplayListTest, BuilderBoundsTransformComparedToSkia) {
const SkRect frame_rect = SkRect::MakeLTRB(10, 10, 100, 100);
DisplayListBuilder builder(frame_rect);
SkPictureRecorder recorder;
@@ -53,60 +113,60 @@
ASSERT_EQ(builder.GetTransform(), canvas->getTotalMatrix());
}
-TEST(DisplayList, BuilderInitialClipBounds) {
+TEST_F(DisplayListTest, BuilderInitialClipBounds) {
SkRect cull_rect = SkRect::MakeWH(100, 100);
SkRect clip_bounds = SkRect::MakeWH(100, 100);
DisplayListBuilder builder(cull_rect);
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds);
}
-TEST(DisplayList, BuilderInitialClipBoundsNaN) {
+TEST_F(DisplayListTest, BuilderInitialClipBoundsNaN) {
SkRect cull_rect = SkRect::MakeWH(SK_ScalarNaN, SK_ScalarNaN);
SkRect clip_bounds = SkRect::MakeEmpty();
DisplayListBuilder builder(cull_rect);
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds);
}
-TEST(DisplayList, BuilderClipBoundsAfterClipRect) {
+TEST_F(DisplayListTest, BuilderClipBoundsAfterClipRect) {
SkRect cull_rect = SkRect::MakeWH(100, 100);
SkRect clip_rect = SkRect::MakeLTRB(10, 10, 20, 20);
SkRect clip_bounds = SkRect::MakeLTRB(10, 10, 20, 20);
DisplayListBuilder builder(cull_rect);
- builder.clipRect(clip_rect, ClipOp::kIntersect, false);
+ builder.ClipRect(clip_rect, ClipOp::kIntersect, false);
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds);
}
-TEST(DisplayList, BuilderClipBoundsAfterClipRRect) {
+TEST_F(DisplayListTest, BuilderClipBoundsAfterClipRRect) {
SkRect cull_rect = SkRect::MakeWH(100, 100);
SkRect clip_rect = SkRect::MakeLTRB(10, 10, 20, 20);
SkRRect clip_rrect = SkRRect::MakeRectXY(clip_rect, 2, 2);
SkRect clip_bounds = SkRect::MakeLTRB(10, 10, 20, 20);
DisplayListBuilder builder(cull_rect);
- builder.clipRRect(clip_rrect, ClipOp::kIntersect, false);
+ builder.ClipRRect(clip_rrect, ClipOp::kIntersect, false);
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds);
}
-TEST(DisplayList, BuilderClipBoundsAfterClipPath) {
+TEST_F(DisplayListTest, BuilderClipBoundsAfterClipPath) {
SkRect cull_rect = SkRect::MakeWH(100, 100);
SkPath clip_path = SkPath().addRect(10, 10, 15, 15).addRect(15, 15, 20, 20);
SkRect clip_bounds = SkRect::MakeLTRB(10, 10, 20, 20);
DisplayListBuilder builder(cull_rect);
- builder.clipPath(clip_path, ClipOp::kIntersect, false);
+ builder.ClipPath(clip_path, ClipOp::kIntersect, false);
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds);
}
-TEST(DisplayList, BuilderInitialClipBoundsNonZero) {
+TEST_F(DisplayListTest, BuilderInitialClipBoundsNonZero) {
SkRect cull_rect = SkRect::MakeLTRB(10, 10, 100, 100);
SkRect clip_bounds = SkRect::MakeLTRB(10, 10, 100, 100);
DisplayListBuilder builder(cull_rect);
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds);
}
-TEST(DisplayList, SingleOpSizes) {
+TEST_F(DisplayListTest, SingleOpSizes) {
for (auto& group : allGroups) {
for (size_t i = 0; i < group.variants.size(); i++) {
auto& invocation = group.variants[i];
- sk_sp<DisplayList> dl = invocation.Build();
+ sk_sp<DisplayList> dl = Build(invocation);
auto desc = group.op_name + "(variant " + std::to_string(i + 1) + ")";
ASSERT_EQ(dl->op_count(false), invocation.op_count()) << desc;
ASSERT_EQ(dl->bytes(false), invocation.byte_count()) << desc;
@@ -114,11 +174,11 @@
}
}
-TEST(DisplayList, SingleOpDisplayListsNotEqualEmpty) {
+TEST_F(DisplayListTest, SingleOpDisplayListsNotEqualEmpty) {
sk_sp<DisplayList> empty = DisplayListBuilder().Build();
for (auto& group : allGroups) {
for (size_t i = 0; i < group.variants.size(); i++) {
- sk_sp<DisplayList> dl = group.variants[i].Build();
+ sk_sp<DisplayList> dl = Build(group.variants[i]);
auto desc =
group.op_name + "(variant " + std::to_string(i + 1) + " != empty)";
if (group.variants[i].is_empty()) {
@@ -132,15 +192,16 @@
}
}
-TEST(DisplayList, SingleOpDisplayListsRecapturedAreEqual) {
+TEST_F(DisplayListTest, SingleOpDisplayListsRecapturedAreEqual) {
for (auto& group : allGroups) {
for (size_t i = 0; i < group.variants.size(); i++) {
- sk_sp<DisplayList> dl = group.variants[i].Build();
+ sk_sp<DisplayList> dl = Build(group.variants[i]);
// Verify recapturing the replay of the display list is Equals()
// when dispatching directly from the DL to another builder
- DisplayListBuilder builder;
- dl->Dispatch(builder.asDispatcher());
- sk_sp<DisplayList> copy = builder.Build();
+ DisplayListBuilder copy_builder;
+ DlOpReceiver& r = ToReceiver(copy_builder);
+ dl->Dispatch(r);
+ sk_sp<DisplayList> copy = copy_builder.Build();
auto desc =
group.op_name + "(variant " + std::to_string(i + 1) + " == copy)";
ASSERT_EQ(copy->op_count(false), dl->op_count(false)) << desc;
@@ -154,13 +215,13 @@
}
}
-TEST(DisplayList, SingleOpDisplayListsCompareToEachOther) {
+TEST_F(DisplayListTest, SingleOpDisplayListsCompareToEachOther) {
for (auto& group : allGroups) {
std::vector<sk_sp<DisplayList>> lists_a;
std::vector<sk_sp<DisplayList>> lists_b;
for (size_t i = 0; i < group.variants.size(); i++) {
- lists_a.push_back(group.variants[i].Build());
- lists_b.push_back(group.variants[i].Build());
+ lists_a.push_back(Build(group.variants[i]));
+ lists_b.push_back(Build(group.variants[i]));
}
for (size_t i = 0; i < lists_a.size(); i++) {
@@ -190,13 +251,13 @@
}
}
-TEST(DisplayList, SingleOpDisplayListsAreEqualWhetherOrNotToPrepareRtree) {
+TEST_F(DisplayListTest, SingleOpDisplayListsAreEqualWithOrWithoutRtree) {
for (auto& group : allGroups) {
for (size_t i = 0; i < group.variants.size(); i++) {
DisplayListBuilder builder1(/*prepare_rtree=*/false);
DisplayListBuilder builder2(/*prepare_rtree=*/true);
- group.variants[i].invoker(builder1);
- group.variants[i].invoker(builder2);
+ group.variants[i].invoker(ToReceiver(builder1));
+ group.variants[i].invoker(ToReceiver(builder2));
sk_sp<DisplayList> dl1 = builder1.Build();
sk_sp<DisplayList> dl2 = builder2.Build();
@@ -214,13 +275,14 @@
}
}
-TEST(DisplayList, FullRotationsAreNop) {
+TEST_F(DisplayListTest, FullRotationsAreNop) {
DisplayListBuilder builder;
- builder.rotate(0);
- builder.rotate(360);
- builder.rotate(720);
- builder.rotate(1080);
- builder.rotate(1440);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.rotate(0);
+ receiver.rotate(360);
+ receiver.rotate(720);
+ receiver.rotate(1080);
+ receiver.rotate(1440);
sk_sp<DisplayList> dl = builder.Build();
ASSERT_EQ(dl->bytes(false), sizeof(DisplayList));
ASSERT_EQ(dl->bytes(true), sizeof(DisplayList));
@@ -228,9 +290,10 @@
ASSERT_EQ(dl->op_count(true), 0u);
}
-TEST(DisplayList, AllBlendModeNops) {
+TEST_F(DisplayListTest, AllBlendModeNops) {
DisplayListBuilder builder;
- builder.setBlendMode(DlBlendMode::kSrcOver);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setBlendMode(DlBlendMode::kSrcOver);
sk_sp<DisplayList> dl = builder.Build();
ASSERT_EQ(dl->bytes(false), sizeof(DisplayList));
ASSERT_EQ(dl->bytes(true), sizeof(DisplayList));
@@ -238,39 +301,7 @@
ASSERT_EQ(dl->op_count(true), 0u);
}
-static sk_sp<DisplayList> Build(size_t g_index, size_t v_index) {
- DisplayListBuilder builder;
- unsigned int op_count = 0;
- size_t byte_count = 0;
- for (size_t i = 0; i < allGroups.size(); i++) {
- DisplayListInvocationGroup& group = allGroups[i];
- size_t j = (i == g_index ? v_index : 0);
- if (j >= group.variants.size()) {
- continue;
- }
- DisplayListInvocation& invocation = group.variants[j];
- op_count += invocation.op_count();
- byte_count += invocation.raw_byte_count();
- invocation.invoker(builder);
- }
- sk_sp<DisplayList> dl = builder.Build();
- std::string name;
- if (g_index >= allGroups.size()) {
- name = "Default";
- } else {
- name = allGroups[g_index].op_name;
- if (v_index >= allGroups[g_index].variants.size()) {
- name += " skipped";
- } else {
- name += " variant " + std::to_string(v_index + 1);
- }
- }
- EXPECT_EQ(dl->op_count(false), op_count) << name;
- EXPECT_EQ(dl->bytes(false), byte_count + sizeof(DisplayList)) << name;
- return dl;
-}
-
-TEST(DisplayList, DisplayListsWithVaryingOpComparisons) {
+TEST_F(DisplayListTest, DisplayListsWithVaryingOpComparisons) {
sk_sp<DisplayList> default_dl = Build(allGroups.size(), 0);
ASSERT_TRUE(default_dl->Equals(*default_dl)) << "Default == itself";
for (size_t gi = 0; gi < allGroups.size(); gi++) {
@@ -303,7 +334,7 @@
}
}
-TEST(DisplayList, DisplayListSaveLayerBoundsWithAlphaFilter) {
+TEST_F(DisplayListTest, DisplayListSaveLayerBoundsWithAlphaFilter) {
SkRect build_bounds = SkRect::MakeLTRB(-100, -100, 200, 200);
SkRect save_bounds = SkRect::MakeWH(100, 100);
SkRect rect = SkRect::MakeLTRB(30, 30, 70, 70);
@@ -325,13 +356,16 @@
};
// clang-format on
DlMatrixColorFilter alpha_color_filter(alpha_matrix);
+ sk_sp<SkColorFilter> sk_alpha_color_filter =
+ SkColorFilters::Matrix(alpha_matrix);
{
// No tricky stuff, just verifying drawing a rect produces rect bounds
DisplayListBuilder builder(build_bounds);
- builder.saveLayer(&save_bounds, true);
- builder.drawRect(rect);
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.saveLayer(&save_bounds, SaveLayerOptions::kWithAttributes);
+ receiver.drawRect(rect);
+ receiver.restore();
sk_sp<DisplayList> display_list = builder.Build();
ASSERT_EQ(display_list->bounds(), rect);
}
@@ -339,11 +373,12 @@
{
// Now checking that a normal color filter still produces rect bounds
DisplayListBuilder builder(build_bounds);
- builder.setColorFilter(&base_color_filter);
- builder.saveLayer(&save_bounds, true);
- builder.setColorFilter(nullptr);
- builder.drawRect(rect);
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColorFilter(&base_color_filter);
+ receiver.saveLayer(&save_bounds, SaveLayerOptions::kWithAttributes);
+ receiver.setColorFilter(nullptr);
+ receiver.drawRect(rect);
+ receiver.restore();
sk_sp<DisplayList> display_list = builder.Build();
ASSERT_EQ(display_list->bounds(), rect);
}
@@ -356,7 +391,7 @@
SkRTreeFactory rtree_factory;
SkCanvas* canvas = recorder.beginRecording(build_bounds, &rtree_factory);
SkPaint p1;
- p1.setColorFilter(alpha_color_filter.skia_object());
+ p1.setColorFilter(sk_alpha_color_filter);
canvas->saveLayer(save_bounds, &p1);
SkPaint p2;
canvas->drawRect(rect, p2);
@@ -371,11 +406,12 @@
// cull rect of the DisplayListBuilder when it encounters a
// save layer that modifies an unbounded region
DisplayListBuilder builder(build_bounds);
- builder.setColorFilter(&alpha_color_filter);
- builder.saveLayer(&save_bounds, true);
- builder.setColorFilter(nullptr);
- builder.drawRect(rect);
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColorFilter(&alpha_color_filter);
+ receiver.saveLayer(&save_bounds, SaveLayerOptions::kWithAttributes);
+ receiver.setColorFilter(nullptr);
+ receiver.drawRect(rect);
+ receiver.restore();
sk_sp<DisplayList> display_list = builder.Build();
ASSERT_EQ(display_list->bounds(), build_bounds);
}
@@ -384,11 +420,12 @@
// Verifying that the save layer bounds are not relevant
// to the behavior in the previous example
DisplayListBuilder builder(build_bounds);
- builder.setColorFilter(&alpha_color_filter);
- builder.saveLayer(nullptr, true);
- builder.setColorFilter(nullptr);
- builder.drawRect(rect);
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColorFilter(&alpha_color_filter);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.setColorFilter(nullptr);
+ receiver.drawRect(rect);
+ receiver.restore();
sk_sp<DisplayList> display_list = builder.Build();
ASSERT_EQ(display_list->bounds(), build_bounds);
}
@@ -397,12 +434,13 @@
// Making sure hiding a ColorFilter as an ImageFilter will
// generate the same behavior as setting it as a ColorFilter
DisplayListBuilder builder(build_bounds);
+ DlOpReceiver& receiver = ToReceiver(builder);
DlColorFilterImageFilter color_filter_image_filter(base_color_filter);
- builder.setImageFilter(&color_filter_image_filter);
- builder.saveLayer(&save_bounds, true);
- builder.setImageFilter(nullptr);
- builder.drawRect(rect);
- builder.restore();
+ receiver.setImageFilter(&color_filter_image_filter);
+ receiver.saveLayer(&save_bounds, SaveLayerOptions::kWithAttributes);
+ receiver.setImageFilter(nullptr);
+ receiver.drawRect(rect);
+ receiver.restore();
sk_sp<DisplayList> display_list = builder.Build();
ASSERT_EQ(display_list->bounds(), rect);
}
@@ -411,12 +449,13 @@
// Making sure hiding a problematic ColorFilter as an ImageFilter
// will generate the same behavior as setting it as a ColorFilter
DisplayListBuilder builder(build_bounds);
+ DlOpReceiver& receiver = ToReceiver(builder);
DlColorFilterImageFilter color_filter_image_filter(alpha_color_filter);
- builder.setImageFilter(&color_filter_image_filter);
- builder.saveLayer(&save_bounds, true);
- builder.setImageFilter(nullptr);
- builder.drawRect(rect);
- builder.restore();
+ receiver.setImageFilter(&color_filter_image_filter);
+ receiver.saveLayer(&save_bounds, SaveLayerOptions::kWithAttributes);
+ receiver.setImageFilter(nullptr);
+ receiver.drawRect(rect);
+ receiver.restore();
sk_sp<DisplayList> display_list = builder.Build();
ASSERT_EQ(display_list->bounds(), build_bounds);
}
@@ -424,12 +463,13 @@
{
// Same as above (ImageFilter hiding ColorFilter) with no save bounds
DisplayListBuilder builder(build_bounds);
+ DlOpReceiver& receiver = ToReceiver(builder);
DlColorFilterImageFilter color_filter_image_filter(alpha_color_filter);
- builder.setImageFilter(&color_filter_image_filter);
- builder.saveLayer(nullptr, true);
- builder.setImageFilter(nullptr);
- builder.drawRect(rect);
- builder.restore();
+ receiver.setImageFilter(&color_filter_image_filter);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.setImageFilter(nullptr);
+ receiver.drawRect(rect);
+ receiver.restore();
sk_sp<DisplayList> display_list = builder.Build();
ASSERT_EQ(display_list->bounds(), build_bounds);
}
@@ -437,11 +477,12 @@
{
// Testing behavior with an unboundable blend mode
DisplayListBuilder builder(build_bounds);
- builder.setBlendMode(DlBlendMode::kClear);
- builder.saveLayer(&save_bounds, true);
- builder.setBlendMode(DlBlendMode::kSrcOver);
- builder.drawRect(rect);
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setBlendMode(DlBlendMode::kClear);
+ receiver.saveLayer(&save_bounds, SaveLayerOptions::kWithAttributes);
+ receiver.setBlendMode(DlBlendMode::kSrcOver);
+ receiver.drawRect(rect);
+ receiver.restore();
sk_sp<DisplayList> display_list = builder.Build();
ASSERT_EQ(display_list->bounds(), build_bounds);
}
@@ -449,17 +490,18 @@
{
// Same as previous with no save bounds
DisplayListBuilder builder(build_bounds);
- builder.setBlendMode(DlBlendMode::kClear);
- builder.saveLayer(nullptr, true);
- builder.setBlendMode(DlBlendMode::kSrcOver);
- builder.drawRect(rect);
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setBlendMode(DlBlendMode::kClear);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.setBlendMode(DlBlendMode::kSrcOver);
+ receiver.drawRect(rect);
+ receiver.restore();
sk_sp<DisplayList> display_list = builder.Build();
ASSERT_EQ(display_list->bounds(), build_bounds);
}
}
-TEST(DisplayList, NestedOpCountMetricsSameAsSkPicture) {
+TEST_F(DisplayListTest, NestedOpCountMetricsSameAsSkPicture) {
SkPictureRecorder recorder;
recorder.beginRecording(SkRect::MakeWH(150, 100));
SkCanvas* canvas = recorder.getRecordingCanvas();
@@ -480,14 +522,16 @@
ASSERT_EQ(picture->approximateOpCount(true), 36);
DisplayListBuilder builder(SkRect::MakeWH(150, 100));
+ DlOpReceiver& receiver = ToReceiver(builder);
for (int y = 10; y <= 60; y += 10) {
for (int x = 10; x <= 60; x += 10) {
- builder.setColor(((x + y) % 20) == 10 ? SK_ColorRED : SK_ColorBLUE);
- builder.drawRect(SkRect::MakeXYWH(x, y, 80, 80));
+ receiver.setColor(((x + y) % 20) == 10 ? SK_ColorRED : SK_ColorBLUE);
+ receiver.drawRect(SkRect::MakeXYWH(x, y, 80, 80));
}
}
DisplayListBuilder outer_builder(SkRect::MakeWH(150, 100));
- outer_builder.drawDisplayList(builder.Build());
+ DlOpReceiver& outer_receiver = ToReceiver(outer_builder);
+ outer_receiver.drawDisplayList(builder.Build());
auto display_list = outer_builder.Build();
ASSERT_EQ(display_list->op_count(), 1u);
@@ -499,7 +543,7 @@
static_cast<int>(display_list->op_count(true)));
}
-TEST(DisplayList, DisplayListFullPerspectiveTransformHandling) {
+TEST_F(DisplayListTest, DisplayListFullPerspectiveTransformHandling) {
// SkM44 constructor takes row-major order
SkM44 sk_matrix = SkM44(
// clang-format off
@@ -512,8 +556,9 @@
{ // First test ==
DisplayListBuilder builder;
- // builder.transformFullPerspective takes row-major order
- builder.transformFullPerspective(
+ DlOpReceiver& receiver = ToReceiver(builder);
+ // receiver.transformFullPerspective takes row-major order
+ receiver.transformFullPerspective(
// clang-format off
1, 2, 3, 4,
5, 6, 7, 8,
@@ -524,14 +569,18 @@
sk_sp<DisplayList> display_list = builder.Build();
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(10, 10);
SkCanvas* canvas = surface->getCanvas();
- display_list->RenderTo(canvas);
+ // We can't use DlSkCanvas.DrawDisplayList as that method protects
+ // the canvas against mutations from the display list being drawn.
+ auto dispatcher = DlSkCanvasDispatcher(surface->getCanvas());
+ display_list->Dispatch(dispatcher);
SkM44 dl_matrix = canvas->getLocalToDevice();
ASSERT_EQ(sk_matrix, dl_matrix);
}
{ // Next test !=
DisplayListBuilder builder;
- // builder.transformFullPerspective takes row-major order
- builder.transformFullPerspective(
+ DlOpReceiver& receiver = ToReceiver(builder);
+ // receiver.transformFullPerspective takes row-major order
+ receiver.transformFullPerspective(
// clang-format off
1, 5, 9, 13,
2, 6, 7, 11,
@@ -542,33 +591,41 @@
sk_sp<DisplayList> display_list = builder.Build();
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(10, 10);
SkCanvas* canvas = surface->getCanvas();
- display_list->RenderTo(canvas);
+ // We can't use DlSkCanvas.DrawDisplayList as that method protects
+ // the canvas against mutations from the display list being drawn.
+ auto dispatcher = DlSkCanvasDispatcher(surface->getCanvas());
+ display_list->Dispatch(dispatcher);
SkM44 dl_matrix = canvas->getLocalToDevice();
ASSERT_NE(sk_matrix, dl_matrix);
}
}
-TEST(DisplayList, DisplayListTransformResetHandling) {
+TEST_F(DisplayListTest, DisplayListTransformResetHandling) {
DisplayListBuilder builder;
- builder.scale(20.0, 20.0);
- builder.transformReset();
- auto list = builder.Build();
- ASSERT_NE(list, nullptr);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.scale(20.0, 20.0);
+ receiver.transformReset();
+ auto display_list = builder.Build();
+ ASSERT_NE(display_list, nullptr);
sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(10, 10);
SkCanvas* canvas = surface->getCanvas();
- list->RenderTo(canvas);
+ // We can't use DlSkCanvas.DrawDisplayList as that method protects
+ // the canvas against mutations from the display list being drawn.
+ auto dispatcher = DlSkCanvasDispatcher(surface->getCanvas());
+ display_list->Dispatch(dispatcher);
ASSERT_TRUE(canvas->getTotalMatrix().isIdentity());
}
-TEST(DisplayList, SingleOpsMightSupportGroupOpacityWithOrWithoutBlendMode) {
+TEST_F(DisplayListTest, SingleOpsMightSupportGroupOpacityBlendMode) {
auto run_tests = [](const std::string& name,
- void build(DisplayListBuilder & builder),
- bool expect_for_op, bool expect_with_kSrc) {
+ void build(DlOpReceiver & receiver), bool expect_for_op,
+ bool expect_with_kSrc) {
{
// First test is the draw op, by itself
// (usually supports group opacity)
DisplayListBuilder builder;
- build(builder);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ build(receiver);
auto display_list = builder.Build();
EXPECT_EQ(display_list->can_apply_group_opacity(), expect_for_op)
<< "{" << std::endl
@@ -579,12 +636,13 @@
// Second test i the draw op with kSrc,
// (usually fails group opacity)
DisplayListBuilder builder;
- builder.setBlendMode(DlBlendMode::kSrc);
- build(builder);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setBlendMode(DlBlendMode::kSrc);
+ build(receiver);
auto display_list = builder.Build();
EXPECT_EQ(display_list->can_apply_group_opacity(), expect_with_kSrc)
<< "{" << std::endl
- << " builder.setBlendMode(kSrc);" << std::endl
+ << " receiver.setBlendMode(kSrc);" << std::endl
<< " " << name << std::endl
<< "}";
}
@@ -592,150 +650,163 @@
#define RUN_TESTS(body) \
run_tests( \
- #body, [](DisplayListBuilder& builder) { body }, true, false)
+ #body, [](DlOpReceiver& receiver) { body }, true, false)
#define RUN_TESTS2(body, expect) \
run_tests( \
- #body, [](DisplayListBuilder& builder) { body }, expect, expect)
+ #body, [](DlOpReceiver& receiver) { body }, expect, expect)
- RUN_TESTS(builder.drawPaint(););
- RUN_TESTS2(builder.drawColor(SK_ColorRED, DlBlendMode::kSrcOver);, true);
- RUN_TESTS2(builder.drawColor(SK_ColorRED, DlBlendMode::kSrc);, false);
- RUN_TESTS(builder.drawLine({0, 0}, {10, 10}););
- RUN_TESTS(builder.drawRect({0, 0, 10, 10}););
- RUN_TESTS(builder.drawOval({0, 0, 10, 10}););
- RUN_TESTS(builder.drawCircle({10, 10}, 5););
- RUN_TESTS(builder.drawRRect(SkRRect::MakeRectXY({0, 0, 10, 10}, 2, 2)););
- RUN_TESTS(builder.drawDRRect(SkRRect::MakeRectXY({0, 0, 10, 10}, 2, 2),
- SkRRect::MakeRectXY({2, 2, 8, 8}, 2, 2)););
- RUN_TESTS(builder.drawPath(
+ RUN_TESTS(receiver.drawPaint(););
+ RUN_TESTS2(receiver.drawColor(SK_ColorRED, DlBlendMode::kSrcOver);, true);
+ RUN_TESTS2(receiver.drawColor(SK_ColorRED, DlBlendMode::kSrc);, false);
+ RUN_TESTS(receiver.drawLine({0, 0}, {10, 10}););
+ RUN_TESTS(receiver.drawRect({0, 0, 10, 10}););
+ RUN_TESTS(receiver.drawOval({0, 0, 10, 10}););
+ RUN_TESTS(receiver.drawCircle({10, 10}, 5););
+ RUN_TESTS(receiver.drawRRect(SkRRect::MakeRectXY({0, 0, 10, 10}, 2, 2)););
+ RUN_TESTS(receiver.drawDRRect(SkRRect::MakeRectXY({0, 0, 10, 10}, 2, 2),
+ SkRRect::MakeRectXY({2, 2, 8, 8}, 2, 2)););
+ RUN_TESTS(receiver.drawPath(
SkPath().addOval({0, 0, 10, 10}).addOval({5, 5, 15, 15})););
- RUN_TESTS(builder.drawArc({0, 0, 10, 10}, 0, math::kPi, true););
- RUN_TESTS2(builder.drawPoints(PointMode::kPoints, TestPointCount, TestPoints);
+ RUN_TESTS(receiver.drawArc({0, 0, 10, 10}, 0, math::kPi, true););
+ RUN_TESTS2(
+ receiver.drawPoints(PointMode::kPoints, TestPointCount, TestPoints);
+ , false);
+ RUN_TESTS2(receiver.drawVertices(TestVertices1.get(), DlBlendMode::kSrc);
, false);
- RUN_TESTS2(builder.drawVertices(TestVertices1, DlBlendMode::kSrc);, false);
- RUN_TESTS(builder.drawImage(TestImage1, {0, 0}, kLinearSampling, true););
- RUN_TESTS2(builder.drawImage(TestImage1, {0, 0}, kLinearSampling, false);
+ RUN_TESTS(receiver.drawImage(TestImage1, {0, 0}, kLinearSampling, true););
+ RUN_TESTS2(receiver.drawImage(TestImage1, {0, 0}, kLinearSampling, false);
, true);
- RUN_TESTS(builder.drawImageRect(TestImage1, {10, 10, 20, 20}, {0, 0, 10, 10},
- kNearestSampling, true););
- RUN_TESTS2(builder.drawImageRect(TestImage1, {10, 10, 20, 20}, {0, 0, 10, 10},
- kNearestSampling, false);
+ RUN_TESTS(receiver.drawImageRect(TestImage1, {10, 10, 20, 20}, {0, 0, 10, 10},
+ kNearestSampling, true,
+ DlCanvas::SrcRectConstraint::kFast););
+ RUN_TESTS2(receiver.drawImageRect(TestImage1, {10, 10, 20, 20},
+ {0, 0, 10, 10}, kNearestSampling, false,
+ DlCanvas::SrcRectConstraint::kFast);
, true);
- RUN_TESTS(builder.drawImageNine(TestImage2, {20, 20, 30, 30}, {0, 0, 20, 20},
- DlFilterMode::kLinear, true););
- RUN_TESTS2(builder.drawImageNine(TestImage2, {20, 20, 30, 30}, {0, 0, 20, 20},
- DlFilterMode::kLinear, false);
- , true);
+ RUN_TESTS(receiver.drawImageNine(TestImage2, {20, 20, 30, 30}, {0, 0, 20, 20},
+ DlFilterMode::kLinear, true););
+ RUN_TESTS2(
+ receiver.drawImageNine(TestImage2, {20, 20, 30, 30}, {0, 0, 20, 20},
+ DlFilterMode::kLinear, false);
+ , true);
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
RUN_TESTS2(
- builder.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
- DlBlendMode::kSrcIn, kNearestSampling, nullptr, true);
+ receiver.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
+ DlBlendMode::kSrcIn, kNearestSampling, nullptr, true);
, false);
RUN_TESTS2(
- builder.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
- DlBlendMode::kSrcIn, kNearestSampling, nullptr, false);
+ receiver.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
+ DlBlendMode::kSrcIn, kNearestSampling, nullptr, false);
, false);
EXPECT_TRUE(TestDisplayList1->can_apply_group_opacity());
- RUN_TESTS2(builder.drawDisplayList(TestDisplayList1);, true);
+ RUN_TESTS2(receiver.drawDisplayList(TestDisplayList1);, true);
{
static DisplayListBuilder builder;
- builder.drawRect({0, 0, 10, 10});
- builder.drawRect({5, 5, 15, 15});
+ builder.DrawRect({0, 0, 10, 10}, DlPaint());
+ builder.DrawRect({5, 5, 15, 15}, DlPaint());
static auto display_list = builder.Build();
- RUN_TESTS2(builder.drawDisplayList(display_list);, false);
+ RUN_TESTS2(receiver.drawDisplayList(display_list);, false);
}
- RUN_TESTS2(builder.drawTextBlob(TestBlob1, 0, 0);, false);
- RUN_TESTS2(builder.drawShadow(kTestPath1, SK_ColorBLACK, 1.0, false, 1.0);
+ RUN_TESTS2(receiver.drawTextBlob(TestBlob1, 0, 0);, false);
+ RUN_TESTS2(receiver.drawShadow(kTestPath1, SK_ColorBLACK, 1.0, false, 1.0);
, false);
#undef RUN_TESTS2
#undef RUN_TESTS
}
-TEST(DisplayList, OverlappingOpsDoNotSupportGroupOpacity) {
+TEST_F(DisplayListTest, OverlappingOpsDoNotSupportGroupOpacity) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
for (int i = 0; i < 10; i++) {
- builder.drawRect(SkRect::MakeXYWH(i * 10, 0, 30, 30));
+ receiver.drawRect(SkRect::MakeXYWH(i * 10, 0, 30, 30));
}
auto display_list = builder.Build();
EXPECT_FALSE(display_list->can_apply_group_opacity());
}
-TEST(DisplayList, SaveLayerFalseSupportsGroupOpacityWithOverlappingChidren) {
+TEST_F(DisplayListTest, SaveLayerFalseSupportsGroupOpacityOverlappingChidren) {
DisplayListBuilder builder;
- builder.saveLayer(nullptr, false);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kNoAttributes);
for (int i = 0; i < 10; i++) {
- builder.drawRect(SkRect::MakeXYWH(i * 10, 0, 30, 30));
+ receiver.drawRect(SkRect::MakeXYWH(i * 10, 0, 30, 30));
}
- builder.restore();
+ receiver.restore();
auto display_list = builder.Build();
EXPECT_TRUE(display_list->can_apply_group_opacity());
}
-TEST(DisplayList, SaveLayerTrueSupportsGroupOpacityWithOverlappingChidren) {
+TEST_F(DisplayListTest, SaveLayerTrueSupportsGroupOpacityOverlappingChidren) {
DisplayListBuilder builder;
- builder.saveLayer(nullptr, true);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
for (int i = 0; i < 10; i++) {
- builder.drawRect(SkRect::MakeXYWH(i * 10, 0, 30, 30));
+ receiver.drawRect(SkRect::MakeXYWH(i * 10, 0, 30, 30));
}
- builder.restore();
+ receiver.restore();
auto display_list = builder.Build();
EXPECT_TRUE(display_list->can_apply_group_opacity());
}
-TEST(DisplayList, SaveLayerFalseWithSrcBlendSupportsGroupOpacity) {
+TEST_F(DisplayListTest, SaveLayerFalseWithSrcBlendSupportsGroupOpacity) {
DisplayListBuilder builder;
- builder.setBlendMode(DlBlendMode::kSrc);
- builder.saveLayer(nullptr, false);
- builder.drawRect({0, 0, 10, 10});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setBlendMode(DlBlendMode::kSrc);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kNoAttributes);
+ receiver.drawRect({0, 0, 10, 10});
+ receiver.restore();
auto display_list = builder.Build();
EXPECT_TRUE(display_list->can_apply_group_opacity());
}
-TEST(DisplayList, SaveLayerTrueWithSrcBlendDoesNotSupportGroupOpacity) {
+TEST_F(DisplayListTest, SaveLayerTrueWithSrcBlendDoesNotSupportGroupOpacity) {
DisplayListBuilder builder;
- builder.setBlendMode(DlBlendMode::kSrc);
- builder.saveLayer(nullptr, true);
- builder.drawRect({0, 0, 10, 10});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setBlendMode(DlBlendMode::kSrc);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.drawRect({0, 0, 10, 10});
+ receiver.restore();
auto display_list = builder.Build();
EXPECT_FALSE(display_list->can_apply_group_opacity());
}
-TEST(DisplayList, SaveLayerFalseSupportsGroupOpacityWithChildSrcBlend) {
+TEST_F(DisplayListTest, SaveLayerFalseSupportsGroupOpacityWithChildSrcBlend) {
DisplayListBuilder builder;
- builder.saveLayer(nullptr, false);
- builder.setBlendMode(DlBlendMode::kSrc);
- builder.drawRect({0, 0, 10, 10});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kNoAttributes);
+ receiver.setBlendMode(DlBlendMode::kSrc);
+ receiver.drawRect({0, 0, 10, 10});
+ receiver.restore();
auto display_list = builder.Build();
EXPECT_TRUE(display_list->can_apply_group_opacity());
}
-TEST(DisplayList, SaveLayerTrueSupportsGroupOpacityWithChildSrcBlend) {
+TEST_F(DisplayListTest, SaveLayerTrueSupportsGroupOpacityWithChildSrcBlend) {
DisplayListBuilder builder;
- builder.saveLayer(nullptr, true);
- builder.setBlendMode(DlBlendMode::kSrc);
- builder.drawRect({0, 0, 10, 10});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.setBlendMode(DlBlendMode::kSrc);
+ receiver.drawRect({0, 0, 10, 10});
+ receiver.restore();
auto display_list = builder.Build();
EXPECT_TRUE(display_list->can_apply_group_opacity());
}
-TEST(DisplayList, SaveLayerBoundsSnapshotsImageFilter) {
+TEST_F(DisplayListTest, SaveLayerBoundsSnapshotsImageFilter) {
DisplayListBuilder builder;
- builder.saveLayer(nullptr, true);
- builder.drawRect({50, 50, 100, 100});
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.drawRect({50, 50, 100, 100});
// This image filter should be ignored since it was not set before saveLayer
- builder.setImageFilter(&kTestBlurImageFilter1);
- builder.restore();
+ receiver.setImageFilter(&kTestBlurImageFilter1);
+ receiver.restore();
SkRect bounds = builder.Build()->bounds();
EXPECT_EQ(bounds, SkRect::MakeLTRB(50, 50, 100, 100));
}
-class SaveLayerOptionsExpector : public virtual Dispatcher,
+class SaveLayerOptionsExpector : public virtual DlOpReceiver,
public IgnoreAttributeDispatchHelper,
public IgnoreClipDispatchHelper,
public IgnoreTransformDispatchHelper,
@@ -762,51 +833,54 @@
int save_layer_count_ = 0;
};
-TEST(DisplayList, SaveLayerOneSimpleOpSupportsOpacityOptimization) {
+TEST_F(DisplayListTest, SaveLayerOneSimpleOpInheritsOpacity) {
SaveLayerOptions expected =
SaveLayerOptions::kWithAttributes.with_can_distribute_opacity();
SaveLayerOptionsExpector expector(expected);
DisplayListBuilder builder;
- builder.setColor(SkColorSetARGB(127, 255, 255, 255));
- builder.saveLayer(nullptr, true);
- builder.drawRect({10, 10, 20, 20});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColor(SkColorSetARGB(127, 255, 255, 255));
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.restore();
builder.Build()->Dispatch(expector);
EXPECT_EQ(expector.save_layer_count(), 1);
}
-TEST(DisplayList, SaveLayerNoAttributesSupportsOpacityOptimization) {
+TEST_F(DisplayListTest, SaveLayerNoAttributesInheritsOpacity) {
SaveLayerOptions expected =
SaveLayerOptions::kNoAttributes.with_can_distribute_opacity();
SaveLayerOptionsExpector expector(expected);
DisplayListBuilder builder;
- builder.saveLayer(nullptr, false);
- builder.drawRect({10, 10, 20, 20});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kNoAttributes);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.restore();
builder.Build()->Dispatch(expector);
EXPECT_EQ(expector.save_layer_count(), 1);
}
-TEST(DisplayList, SaveLayerTwoOverlappingOpsPreventsOpacityOptimization) {
+TEST_F(DisplayListTest, SaveLayerTwoOverlappingOpsDoesNotInheritOpacity) {
SaveLayerOptions expected = SaveLayerOptions::kWithAttributes;
SaveLayerOptionsExpector expector(expected);
DisplayListBuilder builder;
- builder.setColor(SkColorSetARGB(127, 255, 255, 255));
- builder.saveLayer(nullptr, true);
- builder.drawRect({10, 10, 20, 20});
- builder.drawRect({15, 15, 25, 25});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColor(SkColorSetARGB(127, 255, 255, 255));
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.drawRect({15, 15, 25, 25});
+ receiver.restore();
builder.Build()->Dispatch(expector);
EXPECT_EQ(expector.save_layer_count(), 1);
}
-TEST(DisplayList, NestedSaveLayersMightSupportOpacityOptimization) {
+TEST_F(DisplayListTest, NestedSaveLayersMightInheritOpacity) {
SaveLayerOptions expected1 =
SaveLayerOptions::kWithAttributes.with_can_distribute_opacity();
SaveLayerOptions expected2 = SaveLayerOptions::kWithAttributes;
@@ -815,21 +889,22 @@
SaveLayerOptionsExpector expector({expected1, expected2, expected3});
DisplayListBuilder builder;
- builder.setColor(SkColorSetARGB(127, 255, 255, 255));
- builder.saveLayer(nullptr, true);
- builder.saveLayer(nullptr, true);
- builder.drawRect({10, 10, 20, 20});
- builder.saveLayer(nullptr, true);
- builder.drawRect({15, 15, 25, 25});
- builder.restore();
- builder.restore();
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColor(SkColorSetARGB(127, 255, 255, 255));
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.drawRect({15, 15, 25, 25});
+ receiver.restore();
+ receiver.restore();
+ receiver.restore();
builder.Build()->Dispatch(expector);
EXPECT_EQ(expector.save_layer_count(), 3);
}
-TEST(DisplayList, NestedSaveLayersCanBothSupportOpacityOptimization) {
+TEST_F(DisplayListTest, NestedSaveLayersCanBothSupportOpacityOptimization) {
SaveLayerOptions expected1 =
SaveLayerOptions::kWithAttributes.with_can_distribute_opacity();
SaveLayerOptions expected2 =
@@ -837,112 +912,119 @@
SaveLayerOptionsExpector expector({expected1, expected2});
DisplayListBuilder builder;
- builder.setColor(SkColorSetARGB(127, 255, 255, 255));
- builder.saveLayer(nullptr, true);
- builder.saveLayer(nullptr, false);
- builder.drawRect({10, 10, 20, 20});
- builder.restore();
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColor(SkColorSetARGB(127, 255, 255, 255));
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kNoAttributes);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.restore();
+ receiver.restore();
builder.Build()->Dispatch(expector);
EXPECT_EQ(expector.save_layer_count(), 2);
}
-TEST(DisplayList, SaveLayerImageFilterPreventsOpacityOptimization) {
+TEST_F(DisplayListTest, SaveLayerImageFilterDoesNotInheritOpacity) {
SaveLayerOptions expected = SaveLayerOptions::kWithAttributes;
SaveLayerOptionsExpector expector(expected);
DisplayListBuilder builder;
- builder.setColor(SkColorSetARGB(127, 255, 255, 255));
- builder.setImageFilter(&kTestBlurImageFilter1);
- builder.saveLayer(nullptr, true);
- builder.setImageFilter(nullptr);
- builder.drawRect({10, 10, 20, 20});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColor(SkColorSetARGB(127, 255, 255, 255));
+ receiver.setImageFilter(&kTestBlurImageFilter1);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.setImageFilter(nullptr);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.restore();
builder.Build()->Dispatch(expector);
EXPECT_EQ(expector.save_layer_count(), 1);
}
-TEST(DisplayList, SaveLayerColorFilterPreventsOpacityOptimization) {
+TEST_F(DisplayListTest, SaveLayerColorFilterDoesNotInheritOpacity) {
SaveLayerOptions expected = SaveLayerOptions::kWithAttributes;
SaveLayerOptionsExpector expector(expected);
DisplayListBuilder builder;
- builder.setColor(SkColorSetARGB(127, 255, 255, 255));
- builder.setColorFilter(&kTestMatrixColorFilter1);
- builder.saveLayer(nullptr, true);
- builder.setColorFilter(nullptr);
- builder.drawRect({10, 10, 20, 20});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColor(SkColorSetARGB(127, 255, 255, 255));
+ receiver.setColorFilter(&kTestMatrixColorFilter1);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.setColorFilter(nullptr);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.restore();
builder.Build()->Dispatch(expector);
EXPECT_EQ(expector.save_layer_count(), 1);
}
-TEST(DisplayList, SaveLayerSrcBlendPreventsOpacityOptimization) {
+TEST_F(DisplayListTest, SaveLayerSrcBlendDoesNotInheritOpacity) {
SaveLayerOptions expected = SaveLayerOptions::kWithAttributes;
SaveLayerOptionsExpector expector(expected);
DisplayListBuilder builder;
- builder.setColor(SkColorSetARGB(127, 255, 255, 255));
- builder.setBlendMode(DlBlendMode::kSrc);
- builder.saveLayer(nullptr, true);
- builder.setBlendMode(DlBlendMode::kSrcOver);
- builder.drawRect({10, 10, 20, 20});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColor(SkColorSetARGB(127, 255, 255, 255));
+ receiver.setBlendMode(DlBlendMode::kSrc);
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.setBlendMode(DlBlendMode::kSrcOver);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.restore();
builder.Build()->Dispatch(expector);
EXPECT_EQ(expector.save_layer_count(), 1);
}
-TEST(DisplayList, SaveLayerImageFilterOnChildSupportsOpacityOptimization) {
+TEST_F(DisplayListTest, SaveLayerImageFilterOnChildInheritsOpacity) {
SaveLayerOptions expected =
SaveLayerOptions::kWithAttributes.with_can_distribute_opacity();
SaveLayerOptionsExpector expector(expected);
DisplayListBuilder builder;
- builder.setColor(SkColorSetARGB(127, 255, 255, 255));
- builder.saveLayer(nullptr, true);
- builder.setImageFilter(&kTestBlurImageFilter1);
- builder.drawRect({10, 10, 20, 20});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColor(SkColorSetARGB(127, 255, 255, 255));
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.setImageFilter(&kTestBlurImageFilter1);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.restore();
builder.Build()->Dispatch(expector);
EXPECT_EQ(expector.save_layer_count(), 1);
}
-TEST(DisplayList, SaveLayerColorFilterOnChildPreventsOpacityOptimization) {
+TEST_F(DisplayListTest, SaveLayerColorFilterOnChildDoesNotInheritOpacity) {
SaveLayerOptions expected = SaveLayerOptions::kWithAttributes;
SaveLayerOptionsExpector expector(expected);
DisplayListBuilder builder;
- builder.setColor(SkColorSetARGB(127, 255, 255, 255));
- builder.saveLayer(nullptr, true);
- builder.setColorFilter(&kTestMatrixColorFilter1);
- builder.drawRect({10, 10, 20, 20});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColor(SkColorSetARGB(127, 255, 255, 255));
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.setColorFilter(&kTestMatrixColorFilter1);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.restore();
builder.Build()->Dispatch(expector);
EXPECT_EQ(expector.save_layer_count(), 1);
}
-TEST(DisplayList, SaveLayerSrcBlendOnChildPreventsOpacityOptimization) {
+TEST_F(DisplayListTest, SaveLayerSrcBlendOnChildDoesNotInheritOpacity) {
SaveLayerOptions expected = SaveLayerOptions::kWithAttributes;
SaveLayerOptionsExpector expector(expected);
DisplayListBuilder builder;
- builder.setColor(SkColorSetARGB(127, 255, 255, 255));
- builder.saveLayer(nullptr, true);
- builder.setBlendMode(DlBlendMode::kSrc);
- builder.drawRect({10, 10, 20, 20});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setColor(SkColorSetARGB(127, 255, 255, 255));
+ receiver.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ receiver.setBlendMode(DlBlendMode::kSrc);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.restore();
builder.Build()->Dispatch(expector);
EXPECT_EQ(expector.save_layer_count(), 1);
}
-TEST(DisplayList, FlutterSvgIssue661BoundsWereEmpty) {
+TEST_F(DisplayListTest, FlutterSvgIssue661BoundsWereEmpty) {
// See https://github.com/dnfield/flutter_svg/issues/661
SkPath path1;
@@ -1013,42 +1095,40 @@
path2.close();
DisplayListBuilder builder;
+ DlPaint paint = DlPaint(DlColor::kWhite()).setAntiAlias(true);
{
- builder.save();
- builder.clipRect({0, 0, 100, 100}, ClipOp::kIntersect, true);
+ builder.Save();
+ builder.ClipRect({0, 0, 100, 100}, ClipOp::kIntersect, true);
{
- builder.save();
- builder.transform2DAffine(2.17391, 0, -2547.83, //
+ builder.Save();
+ builder.Transform2DAffine(2.17391, 0, -2547.83, //
0, 2.04082, -500);
{
- builder.save();
- builder.clipRect({1172, 245, 1218, 294}, ClipOp::kIntersect, true);
+ builder.Save();
+ builder.ClipRect({1172, 245, 1218, 294}, ClipOp::kIntersect, true);
{
- builder.saveLayer(nullptr, SaveLayerOptions::kWithAttributes,
- nullptr);
+ builder.SaveLayer(nullptr, nullptr, nullptr);
{
- builder.save();
- builder.transform2DAffine(1.4375, 0, 1164.09, //
+ builder.Save();
+ builder.Transform2DAffine(1.4375, 0, 1164.09, //
0, 1.53125, 236.548);
- builder.setAntiAlias(1);
- builder.setColor(0xffffffff);
- builder.drawPath(path1);
- builder.restore();
+ builder.DrawPath(path1, paint);
+ builder.Restore();
}
{
- builder.save();
- builder.transform2DAffine(1.4375, 0, 1164.09, //
+ builder.Save();
+ builder.Transform2DAffine(1.4375, 0, 1164.09, //
0, 1.53125, 236.548);
- builder.drawPath(path2);
- builder.restore();
+ builder.DrawPath(path2, paint);
+ builder.Restore();
}
- builder.restore();
+ builder.Restore();
}
- builder.restore();
+ builder.Restore();
}
- builder.restore();
+ builder.Restore();
}
- builder.restore();
+ builder.Restore();
}
sk_sp<DisplayList> display_list = builder.Build();
// Prior to the fix, the bounds were empty.
@@ -1070,16 +1150,17 @@
EXPECT_EQ(display_list->bytes(), sizeof(DisplayList) + 352u);
}
-TEST(DisplayList, TranslateAffectsCurrentTransform) {
+TEST_F(DisplayListTest, TranslateAffectsCurrentTransform) {
DisplayListBuilder builder;
- builder.translate(12.3, 14.5);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.translate(12.3, 14.5);
SkMatrix matrix = SkMatrix::Translate(12.3, 14.5);
SkM44 m44 = SkM44(matrix);
SkM44 cur_m44 = builder.GetTransformFullPerspective();
SkMatrix cur_matrix = builder.GetTransform();
ASSERT_EQ(cur_m44, m44);
ASSERT_EQ(cur_matrix, matrix);
- builder.translate(10, 10);
+ receiver.translate(10, 10);
// CurrentTransform has changed
ASSERT_NE(builder.GetTransformFullPerspective(), m44);
ASSERT_NE(builder.GetTransform(), cur_matrix);
@@ -1088,16 +1169,17 @@
ASSERT_EQ(cur_matrix, matrix);
}
-TEST(DisplayList, ScaleAffectsCurrentTransform) {
+TEST_F(DisplayListTest, ScaleAffectsCurrentTransform) {
DisplayListBuilder builder;
- builder.scale(12.3, 14.5);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.scale(12.3, 14.5);
SkMatrix matrix = SkMatrix::Scale(12.3, 14.5);
SkM44 m44 = SkM44(matrix);
SkM44 cur_m44 = builder.GetTransformFullPerspective();
SkMatrix cur_matrix = builder.GetTransform();
ASSERT_EQ(cur_m44, m44);
ASSERT_EQ(cur_matrix, matrix);
- builder.translate(10, 10);
+ receiver.translate(10, 10);
// CurrentTransform has changed
ASSERT_NE(builder.GetTransformFullPerspective(), m44);
ASSERT_NE(builder.GetTransform(), cur_matrix);
@@ -1106,16 +1188,17 @@
ASSERT_EQ(cur_matrix, matrix);
}
-TEST(DisplayList, RotateAffectsCurrentTransform) {
+TEST_F(DisplayListTest, RotateAffectsCurrentTransform) {
DisplayListBuilder builder;
- builder.rotate(12.3);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.rotate(12.3);
SkMatrix matrix = SkMatrix::RotateDeg(12.3);
SkM44 m44 = SkM44(matrix);
SkM44 cur_m44 = builder.GetTransformFullPerspective();
SkMatrix cur_matrix = builder.GetTransform();
ASSERT_EQ(cur_m44, m44);
ASSERT_EQ(cur_matrix, matrix);
- builder.translate(10, 10);
+ receiver.translate(10, 10);
// CurrentTransform has changed
ASSERT_NE(builder.GetTransformFullPerspective(), m44);
ASSERT_NE(builder.GetTransform(), cur_matrix);
@@ -1124,16 +1207,17 @@
ASSERT_EQ(cur_matrix, matrix);
}
-TEST(DisplayList, SkewAffectsCurrentTransform) {
+TEST_F(DisplayListTest, SkewAffectsCurrentTransform) {
DisplayListBuilder builder;
- builder.skew(12.3, 14.5);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.skew(12.3, 14.5);
SkMatrix matrix = SkMatrix::Skew(12.3, 14.5);
SkM44 m44 = SkM44(matrix);
SkM44 cur_m44 = builder.GetTransformFullPerspective();
SkMatrix cur_matrix = builder.GetTransform();
ASSERT_EQ(cur_m44, m44);
ASSERT_EQ(cur_matrix, matrix);
- builder.translate(10, 10);
+ receiver.translate(10, 10);
// CurrentTransform has changed
ASSERT_NE(builder.GetTransformFullPerspective(), m44);
ASSERT_NE(builder.GetTransform(), cur_matrix);
@@ -1142,10 +1226,11 @@
ASSERT_EQ(cur_matrix, matrix);
}
-TEST(DisplayList, TransformAffectsCurrentTransform) {
+TEST_F(DisplayListTest, TransformAffectsCurrentTransform) {
DisplayListBuilder builder;
- builder.transform2DAffine(3, 0, 12.3, //
- 1, 5, 14.5);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.transform2DAffine(3, 0, 12.3, //
+ 1, 5, 14.5);
SkMatrix matrix = SkMatrix::MakeAll(3, 0, 12.3, //
1, 5, 14.5, //
0, 0, 1);
@@ -1154,7 +1239,7 @@
SkMatrix cur_matrix = builder.GetTransform();
ASSERT_EQ(cur_m44, m44);
ASSERT_EQ(cur_matrix, matrix);
- builder.translate(10, 10);
+ receiver.translate(10, 10);
// CurrentTransform has changed
ASSERT_NE(builder.GetTransformFullPerspective(), m44);
ASSERT_NE(builder.GetTransform(), cur_matrix);
@@ -1163,12 +1248,13 @@
ASSERT_EQ(cur_matrix, matrix);
}
-TEST(DisplayList, FullTransformAffectsCurrentTransform) {
+TEST_F(DisplayListTest, FullTransformAffectsCurrentTransform) {
DisplayListBuilder builder;
- builder.transformFullPerspective(3, 0, 4, 12.3, //
- 1, 5, 3, 14.5, //
- 0, 0, 7, 16.2, //
- 0, 0, 0, 1);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.transformFullPerspective(3, 0, 4, 12.3, //
+ 1, 5, 3, 14.5, //
+ 0, 0, 7, 16.2, //
+ 0, 0, 0, 1);
SkMatrix matrix = SkMatrix::MakeAll(3, 0, 12.3, //
1, 5, 14.5, //
0, 0, 1);
@@ -1180,7 +1266,7 @@
SkMatrix cur_matrix = builder.GetTransform();
ASSERT_EQ(cur_m44, m44);
ASSERT_EQ(cur_matrix, matrix);
- builder.translate(10, 10);
+ receiver.translate(10, 10);
// CurrentTransform has changed
ASSERT_NE(builder.GetTransformFullPerspective(), m44);
ASSERT_NE(builder.GetTransform(), cur_matrix);
@@ -1189,10 +1275,11 @@
ASSERT_EQ(cur_matrix, matrix);
}
-TEST(DisplayList, ClipRectAffectsClipBounds) {
+TEST_F(DisplayListTest, ClipRectAffectsClipBounds) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkRect clip_bounds = SkRect::MakeLTRB(10.2, 11.3, 20.4, 25.7);
- builder.clipRect(clip_bounds, ClipOp::kIntersect, false);
+ receiver.clipRect(clip_bounds, ClipOp::kIntersect, false);
// Save initial return values for testing restored values
SkRect initial_local_bounds = builder.GetLocalClipBounds();
@@ -1200,38 +1287,39 @@
ASSERT_EQ(initial_local_bounds, clip_bounds);
ASSERT_EQ(initial_destination_bounds, clip_bounds);
- builder.save();
- builder.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, false);
+ receiver.save();
+ receiver.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, false);
// Both clip bounds have changed
ASSERT_NE(builder.GetLocalClipBounds(), clip_bounds);
ASSERT_NE(builder.GetDestinationClipBounds(), clip_bounds);
// Previous return values have not changed
ASSERT_EQ(initial_local_bounds, clip_bounds);
ASSERT_EQ(initial_destination_bounds, clip_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
- builder.save();
- builder.scale(2, 2);
+ receiver.save();
+ receiver.scale(2, 2);
SkRect scaled_clip_bounds = SkRect::MakeLTRB(5.1, 5.65, 10.2, 12.85);
ASSERT_EQ(builder.GetLocalClipBounds(), scaled_clip_bounds);
// Destination bounds are unaffected by transform
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
}
-TEST(DisplayList, ClipRectDoAAAffectsClipBounds) {
+TEST_F(DisplayListTest, ClipRectDoAAAffectsClipBounds) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkRect clip_bounds = SkRect::MakeLTRB(10.2, 11.3, 20.4, 25.7);
SkRect clip_expanded_bounds = SkRect::MakeLTRB(10, 11, 21, 26);
- builder.clipRect(clip_bounds, ClipOp::kIntersect, true);
+ receiver.clipRect(clip_bounds, ClipOp::kIntersect, true);
// Save initial return values for testing restored values
SkRect initial_local_bounds = builder.GetLocalClipBounds();
@@ -1239,57 +1327,59 @@
ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
- builder.save();
- builder.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, true);
+ receiver.save();
+ receiver.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, true);
// Both clip bounds have changed
ASSERT_NE(builder.GetLocalClipBounds(), clip_expanded_bounds);
ASSERT_NE(builder.GetDestinationClipBounds(), clip_expanded_bounds);
// Previous return values have not changed
ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
- builder.save();
- builder.scale(2, 2);
+ receiver.save();
+ receiver.scale(2, 2);
SkRect scaled_expanded_bounds = SkRect::MakeLTRB(5, 5.5, 10.5, 13);
ASSERT_EQ(builder.GetLocalClipBounds(), scaled_expanded_bounds);
// Destination bounds are unaffected by transform
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_expanded_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
}
-TEST(DisplayList, ClipRectAffectsClipBoundsWithMatrix) {
+TEST_F(DisplayListTest, ClipRectAffectsClipBoundsWithMatrix) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkRect clip_bounds_1 = SkRect::MakeLTRB(0, 0, 10, 10);
SkRect clip_bounds_2 = SkRect::MakeLTRB(10, 10, 20, 20);
- builder.save();
- builder.clipRect(clip_bounds_1, ClipOp::kIntersect, false);
- builder.translate(10, 0);
- builder.clipRect(clip_bounds_1, ClipOp::kIntersect, false);
+ receiver.save();
+ receiver.clipRect(clip_bounds_1, ClipOp::kIntersect, false);
+ receiver.translate(10, 0);
+ receiver.clipRect(clip_bounds_1, ClipOp::kIntersect, false);
ASSERT_TRUE(builder.GetDestinationClipBounds().isEmpty());
- builder.restore();
+ receiver.restore();
- builder.save();
- builder.clipRect(clip_bounds_1, ClipOp::kIntersect, false);
- builder.translate(-10, -10);
- builder.clipRect(clip_bounds_2, ClipOp::kIntersect, false);
+ receiver.save();
+ receiver.clipRect(clip_bounds_1, ClipOp::kIntersect, false);
+ receiver.translate(-10, -10);
+ receiver.clipRect(clip_bounds_2, ClipOp::kIntersect, false);
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds_1);
- builder.restore();
+ receiver.restore();
}
-TEST(DisplayList, ClipRRectAffectsClipBounds) {
+TEST_F(DisplayListTest, ClipRRectAffectsClipBounds) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkRect clip_bounds = SkRect::MakeLTRB(10.2, 11.3, 20.4, 25.7);
SkRRect clip = SkRRect::MakeRectXY(clip_bounds, 3, 2);
- builder.clipRRect(clip, ClipOp::kIntersect, false);
+ receiver.clipRRect(clip, ClipOp::kIntersect, false);
// Save initial return values for testing restored values
SkRect initial_local_bounds = builder.GetLocalClipBounds();
@@ -1297,39 +1387,40 @@
ASSERT_EQ(initial_local_bounds, clip_bounds);
ASSERT_EQ(initial_destination_bounds, clip_bounds);
- builder.save();
- builder.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, false);
+ receiver.save();
+ receiver.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, false);
// Both clip bounds have changed
ASSERT_NE(builder.GetLocalClipBounds(), clip_bounds);
ASSERT_NE(builder.GetDestinationClipBounds(), clip_bounds);
// Previous return values have not changed
ASSERT_EQ(initial_local_bounds, clip_bounds);
ASSERT_EQ(initial_destination_bounds, clip_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
- builder.save();
- builder.scale(2, 2);
+ receiver.save();
+ receiver.scale(2, 2);
SkRect scaled_clip_bounds = SkRect::MakeLTRB(5.1, 5.65, 10.2, 12.85);
ASSERT_EQ(builder.GetLocalClipBounds(), scaled_clip_bounds);
// Destination bounds are unaffected by transform
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
}
-TEST(DisplayList, ClipRRectDoAAAffectsClipBounds) {
+TEST_F(DisplayListTest, ClipRRectDoAAAffectsClipBounds) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkRect clip_bounds = SkRect::MakeLTRB(10.2, 11.3, 20.4, 25.7);
SkRect clip_expanded_bounds = SkRect::MakeLTRB(10, 11, 21, 26);
SkRRect clip = SkRRect::MakeRectXY(clip_bounds, 3, 2);
- builder.clipRRect(clip, ClipOp::kIntersect, true);
+ receiver.clipRRect(clip, ClipOp::kIntersect, true);
// Save initial return values for testing restored values
SkRect initial_local_bounds = builder.GetLocalClipBounds();
@@ -1337,60 +1428,62 @@
ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
- builder.save();
- builder.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, true);
+ receiver.save();
+ receiver.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, true);
// Both clip bounds have changed
ASSERT_NE(builder.GetLocalClipBounds(), clip_expanded_bounds);
ASSERT_NE(builder.GetDestinationClipBounds(), clip_expanded_bounds);
// Previous return values have not changed
ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
- builder.save();
- builder.scale(2, 2);
+ receiver.save();
+ receiver.scale(2, 2);
SkRect scaled_expanded_bounds = SkRect::MakeLTRB(5, 5.5, 10.5, 13);
ASSERT_EQ(builder.GetLocalClipBounds(), scaled_expanded_bounds);
// Destination bounds are unaffected by transform
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_expanded_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
}
-TEST(DisplayList, ClipRRectAffectsClipBoundsWithMatrix) {
+TEST_F(DisplayListTest, ClipRRectAffectsClipBoundsWithMatrix) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkRect clip_bounds_1 = SkRect::MakeLTRB(0, 0, 10, 10);
SkRect clip_bounds_2 = SkRect::MakeLTRB(10, 10, 20, 20);
SkRRect clip1 = SkRRect::MakeRectXY(clip_bounds_1, 3, 2);
SkRRect clip2 = SkRRect::MakeRectXY(clip_bounds_2, 3, 2);
- builder.save();
- builder.clipRRect(clip1, ClipOp::kIntersect, false);
- builder.translate(10, 0);
- builder.clipRRect(clip1, ClipOp::kIntersect, false);
+ receiver.save();
+ receiver.clipRRect(clip1, ClipOp::kIntersect, false);
+ receiver.translate(10, 0);
+ receiver.clipRRect(clip1, ClipOp::kIntersect, false);
ASSERT_TRUE(builder.GetDestinationClipBounds().isEmpty());
- builder.restore();
+ receiver.restore();
- builder.save();
- builder.clipRRect(clip1, ClipOp::kIntersect, false);
- builder.translate(-10, -10);
- builder.clipRRect(clip2, ClipOp::kIntersect, false);
+ receiver.save();
+ receiver.clipRRect(clip1, ClipOp::kIntersect, false);
+ receiver.translate(-10, -10);
+ receiver.clipRRect(clip2, ClipOp::kIntersect, false);
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds_1);
- builder.restore();
+ receiver.restore();
}
-TEST(DisplayList, ClipPathAffectsClipBounds) {
+TEST_F(DisplayListTest, ClipPathAffectsClipBounds) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkPath clip = SkPath().addCircle(10.2, 11.3, 2).addCircle(20.4, 25.7, 2);
SkRect clip_bounds = SkRect::MakeLTRB(8.2, 9.3, 22.4, 27.7);
- builder.clipPath(clip, ClipOp::kIntersect, false);
+ receiver.clipPath(clip, ClipOp::kIntersect, false);
// Save initial return values for testing restored values
SkRect initial_local_bounds = builder.GetLocalClipBounds();
@@ -1398,38 +1491,39 @@
ASSERT_EQ(initial_local_bounds, clip_bounds);
ASSERT_EQ(initial_destination_bounds, clip_bounds);
- builder.save();
- builder.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, false);
+ receiver.save();
+ receiver.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, false);
// Both clip bounds have changed
ASSERT_NE(builder.GetLocalClipBounds(), clip_bounds);
ASSERT_NE(builder.GetDestinationClipBounds(), clip_bounds);
// Previous return values have not changed
ASSERT_EQ(initial_local_bounds, clip_bounds);
ASSERT_EQ(initial_destination_bounds, clip_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
- builder.save();
- builder.scale(2, 2);
+ receiver.save();
+ receiver.scale(2, 2);
SkRect scaled_clip_bounds = SkRect::MakeLTRB(4.1, 4.65, 11.2, 13.85);
ASSERT_EQ(builder.GetLocalClipBounds(), scaled_clip_bounds);
// Destination bounds are unaffected by transform
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
}
-TEST(DisplayList, ClipPathDoAAAffectsClipBounds) {
+TEST_F(DisplayListTest, ClipPathDoAAAffectsClipBounds) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkPath clip = SkPath().addCircle(10.2, 11.3, 2).addCircle(20.4, 25.7, 2);
SkRect clip_expanded_bounds = SkRect::MakeLTRB(8, 9, 23, 28);
- builder.clipPath(clip, ClipOp::kIntersect, true);
+ receiver.clipPath(clip, ClipOp::kIntersect, true);
// Save initial return values for testing restored values
SkRect initial_local_bounds = builder.GetLocalClipBounds();
@@ -1437,59 +1531,61 @@
ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
- builder.save();
- builder.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, true);
+ receiver.save();
+ receiver.clipRect({0, 0, 15, 15}, ClipOp::kIntersect, true);
// Both clip bounds have changed
ASSERT_NE(builder.GetLocalClipBounds(), clip_expanded_bounds);
ASSERT_NE(builder.GetDestinationClipBounds(), clip_expanded_bounds);
// Previous return values have not changed
ASSERT_EQ(initial_local_bounds, clip_expanded_bounds);
ASSERT_EQ(initial_destination_bounds, clip_expanded_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
- builder.save();
- builder.scale(2, 2);
+ receiver.save();
+ receiver.scale(2, 2);
SkRect scaled_expanded_bounds = SkRect::MakeLTRB(4, 4.5, 11.5, 14);
ASSERT_EQ(builder.GetLocalClipBounds(), scaled_expanded_bounds);
// Destination bounds are unaffected by transform
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_expanded_bounds);
- builder.restore();
+ receiver.restore();
// save/restore returned the values to their original values
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
}
-TEST(DisplayList, ClipPathAffectsClipBoundsWithMatrix) {
+TEST_F(DisplayListTest, ClipPathAffectsClipBoundsWithMatrix) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkRect clip_bounds = SkRect::MakeLTRB(0, 0, 10, 10);
SkPath clip1 = SkPath().addCircle(2.5, 2.5, 2.5).addCircle(7.5, 7.5, 2.5);
SkPath clip2 = SkPath().addCircle(12.5, 12.5, 2.5).addCircle(17.5, 17.5, 2.5);
- builder.save();
- builder.clipPath(clip1, ClipOp::kIntersect, false);
- builder.translate(10, 0);
- builder.clipPath(clip1, ClipOp::kIntersect, false);
+ receiver.save();
+ receiver.clipPath(clip1, ClipOp::kIntersect, false);
+ receiver.translate(10, 0);
+ receiver.clipPath(clip1, ClipOp::kIntersect, false);
ASSERT_TRUE(builder.GetDestinationClipBounds().isEmpty());
- builder.restore();
+ receiver.restore();
- builder.save();
- builder.clipPath(clip1, ClipOp::kIntersect, false);
- builder.translate(-10, -10);
- builder.clipPath(clip2, ClipOp::kIntersect, false);
+ receiver.save();
+ receiver.clipPath(clip1, ClipOp::kIntersect, false);
+ receiver.translate(-10, -10);
+ receiver.clipPath(clip2, ClipOp::kIntersect, false);
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds);
- builder.restore();
+ receiver.restore();
}
-TEST(DisplayList, DiffClipRectDoesNotAffectClipBounds) {
+TEST_F(DisplayListTest, DiffClipRectDoesNotAffectClipBounds) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkRect diff_clip = SkRect::MakeLTRB(0, 0, 15, 15);
SkRect clip_bounds = SkRect::MakeLTRB(10.2, 11.3, 20.4, 25.7);
- builder.clipRect(clip_bounds, ClipOp::kIntersect, false);
+ receiver.clipRect(clip_bounds, ClipOp::kIntersect, false);
// Save initial return values for testing after kDifference clip
SkRect initial_local_bounds = builder.GetLocalClipBounds();
@@ -1497,17 +1593,18 @@
ASSERT_EQ(initial_local_bounds, clip_bounds);
ASSERT_EQ(initial_destination_bounds, clip_bounds);
- builder.clipRect(diff_clip, ClipOp::kDifference, false);
+ receiver.clipRect(diff_clip, ClipOp::kDifference, false);
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
}
-TEST(DisplayList, DiffClipRRectDoesNotAffectClipBounds) {
+TEST_F(DisplayListTest, DiffClipRRectDoesNotAffectClipBounds) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkRRect diff_clip = SkRRect::MakeRectXY({0, 0, 15, 15}, 1, 1);
SkRect clip_bounds = SkRect::MakeLTRB(10.2, 11.3, 20.4, 25.7);
SkRRect clip = SkRRect::MakeRectXY({10.2, 11.3, 20.4, 25.7}, 3, 2);
- builder.clipRRect(clip, ClipOp::kIntersect, false);
+ receiver.clipRRect(clip, ClipOp::kIntersect, false);
// Save initial return values for testing after kDifference clip
SkRect initial_local_bounds = builder.GetLocalClipBounds();
@@ -1515,17 +1612,18 @@
ASSERT_EQ(initial_local_bounds, clip_bounds);
ASSERT_EQ(initial_destination_bounds, clip_bounds);
- builder.clipRRect(diff_clip, ClipOp::kDifference, false);
+ receiver.clipRRect(diff_clip, ClipOp::kDifference, false);
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
}
-TEST(DisplayList, DiffClipPathDoesNotAffectClipBounds) {
+TEST_F(DisplayListTest, DiffClipPathDoesNotAffectClipBounds) {
DisplayListBuilder builder;
+ DlOpReceiver& receiver = ToReceiver(builder);
SkPath diff_clip = SkPath().addRect({0, 0, 15, 15});
SkPath clip = SkPath().addCircle(10.2, 11.3, 2).addCircle(20.4, 25.7, 2);
SkRect clip_bounds = SkRect::MakeLTRB(8.2, 9.3, 22.4, 27.7);
- builder.clipPath(clip, ClipOp::kIntersect, false);
+ receiver.clipPath(clip, ClipOp::kIntersect, false);
// Save initial return values for testing after kDifference clip
SkRect initial_local_bounds = builder.GetLocalClipBounds();
@@ -1533,40 +1631,43 @@
ASSERT_EQ(initial_local_bounds, clip_bounds);
ASSERT_EQ(initial_destination_bounds, clip_bounds);
- builder.clipPath(diff_clip, ClipOp::kDifference, false);
+ receiver.clipPath(diff_clip, ClipOp::kDifference, false);
ASSERT_EQ(builder.GetLocalClipBounds(), initial_local_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), initial_destination_bounds);
}
-TEST(DisplayList, ClipPathWithInvertFillTypeDoesNotAffectClipBounds) {
+TEST_F(DisplayListTest, ClipPathWithInvertFillTypeDoesNotAffectClipBounds) {
SkRect cull_rect = SkRect::MakeLTRB(0, 0, 100.0, 100.0);
DisplayListBuilder builder(cull_rect);
+ DlOpReceiver& receiver = ToReceiver(builder);
SkPath clip = SkPath().addCircle(10.2, 11.3, 2).addCircle(20.4, 25.7, 2);
clip.setFillType(SkPathFillType::kInverseWinding);
- builder.clipPath(clip, ClipOp::kIntersect, false);
+ receiver.clipPath(clip, ClipOp::kIntersect, false);
ASSERT_EQ(builder.GetLocalClipBounds(), cull_rect);
ASSERT_EQ(builder.GetDestinationClipBounds(), cull_rect);
}
-TEST(DisplayList, DiffClipPathWithInvertFillTypeAffectsClipBounds) {
+TEST_F(DisplayListTest, DiffClipPathWithInvertFillTypeAffectsClipBounds) {
SkRect cull_rect = SkRect::MakeLTRB(0, 0, 100.0, 100.0);
DisplayListBuilder builder(cull_rect);
+ DlOpReceiver& receiver = ToReceiver(builder);
SkPath clip = SkPath().addCircle(10.2, 11.3, 2).addCircle(20.4, 25.7, 2);
clip.setFillType(SkPathFillType::kInverseWinding);
SkRect clip_bounds = SkRect::MakeLTRB(8.2, 9.3, 22.4, 27.7);
- builder.clipPath(clip, ClipOp::kDifference, false);
+ receiver.clipPath(clip, ClipOp::kDifference, false);
ASSERT_EQ(builder.GetLocalClipBounds(), clip_bounds);
ASSERT_EQ(builder.GetDestinationClipBounds(), clip_bounds);
}
-TEST(DisplayList, FlatDrawPointsProducesBounds) {
+TEST_F(DisplayListTest, FlatDrawPointsProducesBounds) {
SkPoint horizontal_points[2] = {{10, 10}, {20, 10}};
SkPoint vertical_points[2] = {{10, 10}, {10, 20}};
{
DisplayListBuilder builder;
- builder.drawPoints(PointMode::kPolygon, 2, horizontal_points);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.drawPoints(PointMode::kPolygon, 2, horizontal_points);
SkRect bounds = builder.Build()->bounds();
EXPECT_TRUE(bounds.contains(10, 10));
EXPECT_TRUE(bounds.contains(20, 10));
@@ -1574,7 +1675,8 @@
}
{
DisplayListBuilder builder;
- builder.drawPoints(PointMode::kPolygon, 2, vertical_points);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.drawPoints(PointMode::kPolygon, 2, vertical_points);
SkRect bounds = builder.Build()->bounds();
EXPECT_TRUE(bounds.contains(10, 10));
EXPECT_TRUE(bounds.contains(10, 20));
@@ -1582,14 +1684,16 @@
}
{
DisplayListBuilder builder;
- builder.drawPoints(PointMode::kPoints, 1, horizontal_points);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.drawPoints(PointMode::kPoints, 1, horizontal_points);
SkRect bounds = builder.Build()->bounds();
EXPECT_TRUE(bounds.contains(10, 10));
}
{
DisplayListBuilder builder;
- builder.setStrokeWidth(2);
- builder.drawPoints(PointMode::kPolygon, 2, horizontal_points);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setStrokeWidth(2);
+ receiver.drawPoints(PointMode::kPolygon, 2, horizontal_points);
SkRect bounds = builder.Build()->bounds();
EXPECT_TRUE(bounds.contains(10, 10));
EXPECT_TRUE(bounds.contains(20, 10));
@@ -1597,8 +1701,9 @@
}
{
DisplayListBuilder builder;
- builder.setStrokeWidth(2);
- builder.drawPoints(PointMode::kPolygon, 2, vertical_points);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setStrokeWidth(2);
+ receiver.drawPoints(PointMode::kPolygon, 2, vertical_points);
SkRect bounds = builder.Build()->bounds();
EXPECT_TRUE(bounds.contains(10, 10));
EXPECT_TRUE(bounds.contains(10, 20));
@@ -1606,8 +1711,9 @@
}
{
DisplayListBuilder builder;
- builder.setStrokeWidth(2);
- builder.drawPoints(PointMode::kPoints, 1, horizontal_points);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.setStrokeWidth(2);
+ receiver.drawPoints(PointMode::kPoints, 1, horizontal_points);
SkRect bounds = builder.Build()->bounds();
EXPECT_TRUE(bounds.contains(10, 10));
EXPECT_EQ(bounds, SkRect::MakeLTRB(9, 9, 11, 11));
@@ -1631,10 +1737,11 @@
}
}
-TEST(DisplayList, RTreeOfSimpleScene) {
+TEST_F(DisplayListTest, RTreeOfSimpleScene) {
DisplayListBuilder builder(/*prepare_rtree=*/true);
- builder.drawRect({10, 10, 20, 20});
- builder.drawRect({50, 50, 60, 60});
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.drawRect({50, 50, 60, 60});
auto display_list = builder.Build();
auto rtree = display_list->rtree();
std::vector<SkRect> rects = {
@@ -1658,12 +1765,13 @@
test_rtree(rtree, {19, 19, 51, 51}, rects, {0, 1});
}
-TEST(DisplayList, RTreeOfSaveRestoreScene) {
+TEST_F(DisplayListTest, RTreeOfSaveRestoreScene) {
DisplayListBuilder builder(/*prepare_rtree=*/true);
- builder.drawRect({10, 10, 20, 20});
- builder.save();
- builder.drawRect({50, 50, 60, 60});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.save();
+ receiver.drawRect({50, 50, 60, 60});
+ receiver.restore();
auto display_list = builder.Build();
auto rtree = display_list->rtree();
std::vector<SkRect> rects = {
@@ -1687,7 +1795,7 @@
test_rtree(rtree, {19, 19, 51, 51}, rects, {0, 1});
}
-TEST(DisplayList, RTreeOfSaveLayerFilterScene) {
+TEST_F(DisplayListTest, RTreeOfSaveLayerFilterScene) {
DisplayListBuilder builder(/*prepare_rtree=*/true);
// blur filter with sigma=1 expands by 3 on all sides
auto filter = DlBlurImageFilter(1.0, 1.0, DlTileMode::kClamp);
@@ -1722,14 +1830,16 @@
test_rtree(rtree, {19, 19, 51, 51}, rects, {0, 1});
}
-TEST(DisplayList, NestedDisplayListRTreesAreSparse) {
+TEST_F(DisplayListTest, NestedDisplayListRTreesAreSparse) {
DisplayListBuilder nested_dl_builder(/**prepare_rtree=*/true);
- nested_dl_builder.drawRect({10, 10, 20, 20});
- nested_dl_builder.drawRect({50, 50, 60, 60});
+ DlOpReceiver& nested_dl_receiver = ToReceiver(nested_dl_builder);
+ nested_dl_receiver.drawRect({10, 10, 20, 20});
+ nested_dl_receiver.drawRect({50, 50, 60, 60});
auto nested_display_list = nested_dl_builder.Build();
DisplayListBuilder builder(/**prepare_rtree=*/true);
- builder.drawDisplayList(nested_display_list);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.drawDisplayList(nested_display_list);
auto display_list = builder.Build();
auto rtree = display_list->rtree();
@@ -1742,98 +1852,106 @@
test_rtree(rtree, {19, 19, 51, 51}, rects, {0, 1});
}
-TEST(DisplayList, RemoveUnnecessarySaveRestorePairs) {
+TEST_F(DisplayListTest, RemoveUnnecessarySaveRestorePairs) {
{
DisplayListBuilder builder;
- builder.drawRect({10, 10, 20, 20});
- builder.save(); // This save op is unnecessary
- builder.drawRect({50, 50, 60, 60});
- builder.restore();
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.save(); // This save op is unnecessary
+ receiver.drawRect({50, 50, 60, 60});
+ receiver.restore();
DisplayListBuilder builder2;
- builder2.drawRect({10, 10, 20, 20});
- builder2.drawRect({50, 50, 60, 60});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.drawRect({10, 10, 20, 20});
+ receiver2.drawRect({50, 50, 60, 60});
ASSERT_TRUE(DisplayListsEQ_Verbose(builder.Build(), builder2.Build()));
}
{
DisplayListBuilder builder;
- builder.drawRect({10, 10, 20, 20});
- builder.save();
- builder.translate(1.0, 1.0);
+ DlOpReceiver& receiver = ToReceiver(builder);
+ receiver.drawRect({10, 10, 20, 20});
+ receiver.save();
+ receiver.translate(1.0, 1.0);
{
- builder.save(); // unnecessary
- builder.drawRect({50, 50, 60, 60});
- builder.restore();
+ receiver.save(); // unnecessary
+ receiver.drawRect({50, 50, 60, 60});
+ receiver.restore();
}
- builder.restore();
+ receiver.restore();
DisplayListBuilder builder2;
- builder2.drawRect({10, 10, 20, 20});
- builder2.save();
- builder2.translate(1.0, 1.0);
- { builder2.drawRect({50, 50, 60, 60}); }
- builder2.restore();
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.drawRect({10, 10, 20, 20});
+ receiver2.save();
+ receiver2.translate(1.0, 1.0);
+ { receiver2.drawRect({50, 50, 60, 60}); }
+ receiver2.restore();
ASSERT_TRUE(DisplayListsEQ_Verbose(builder.Build(), builder2.Build()));
}
}
-TEST(DisplayList, CollapseMultipleNestedSaveRestore) {
+TEST_F(DisplayListTest, CollapseMultipleNestedSaveRestore) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.save();
- builder1.translate(10, 10);
- builder1.scale(2, 2);
- builder1.clipRect({10, 10, 20, 20}, ClipOp::kIntersect, false);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.restore();
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.save();
+ receiver1.translate(10, 10);
+ receiver1.scale(2, 2);
+ receiver1.clipRect({10, 10, 20, 20}, ClipOp::kIntersect, false);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.restore();
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.translate(10, 10);
- builder2.scale(2, 2);
- builder2.clipRect({10, 10, 20, 20}, ClipOp::kIntersect, false);
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.translate(10, 10);
+ receiver2.scale(2, 2);
+ receiver2.clipRect({10, 10, 20, 20}, ClipOp::kIntersect, false);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, CollapseNestedSaveAndSaveLayerRestore) {
+TEST_F(DisplayListTest, CollapseNestedSaveAndSaveLayerRestore) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.saveLayer(nullptr, false);
- builder1.drawRect({0, 0, 100, 100});
- builder1.scale(2, 2);
- builder1.restore();
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.saveLayer(nullptr, SaveLayerOptions::kNoAttributes);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.scale(2, 2);
+ receiver1.restore();
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.saveLayer(nullptr, false);
- builder2.drawRect({0, 0, 100, 100});
- builder2.scale(2, 2);
- builder2.restore();
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.saveLayer(nullptr, SaveLayerOptions::kNoAttributes);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.scale(2, 2);
+ receiver2.restore();
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, RemoveUnnecessarySaveRestorePairsInSetPaint) {
+TEST_F(DisplayListTest, RemoveUnnecessarySaveRestorePairsInSetPaint) {
SkRect build_bounds = SkRect::MakeLTRB(-100, -100, 200, 200);
SkRect rect = SkRect::MakeLTRB(30, 30, 70, 70);
// clang-format off
const float alpha_matrix[] = {
- 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0,
- 0, 0, 1, 0, 0,
- 0, 0, 0, 0, 1,
+ 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 0, 1,
};
// clang-format on
DlMatrixColorFilter alpha_color_filter(alpha_matrix);
@@ -1880,359 +1998,437 @@
}
}
-TEST(DisplayList, TransformTriggersDeferredSave) {
+TEST_F(DisplayListTest, TransformTriggersDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.transform(SkM44::Translate(10, 100));
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.transform(SkM44::Translate(10, 100));
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.transformFullPerspective(1, 0, 0, 10, //
+ 0, 1, 0, 100, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.transformFullPerspective(1, 0, 0, 10, //
+ 0, 1, 0, 100, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.transform(SkM44::Translate(10, 100));
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
- builder2.save();
- builder2.transform(SkM44::Translate(10, 100));
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.transformFullPerspective(1, 0, 0, 10, //
+ 0, 1, 0, 100, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
+ receiver2.save();
+ receiver2.transformFullPerspective(1, 0, 0, 10, //
+ 0, 1, 0, 100, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, Transform2DTriggersDeferredSave) {
+TEST_F(DisplayListTest, Transform2DTriggersDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.transform2DAffine(0, 1, 12, 1, 0, 33);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.transform2DAffine(0, 1, 12, 1, 0, 33);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.transform2DAffine(0, 1, 12, 1, 0, 33);
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.transform2DAffine(0, 1, 12, 1, 0, 33);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, TransformPerspectiveTriggersDeferredSave) {
+TEST_F(DisplayListTest, TransformPerspectiveTriggersDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.transformFullPerspective(0, 1, 0, 12, 1, 0, 0, 33, 3, 2, 5, 29, 0, 0,
- 0, 12);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.transformFullPerspective(0, 1, 0, 12, //
+ 1, 0, 0, 33, //
+ 3, 2, 5, 29, //
+ 0, 0, 0, 12);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.transformFullPerspective(0, 1, 0, 12, 1, 0, 0, 33, 3, 2, 5, 29, 0, 0,
- 0, 12);
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.transformFullPerspective(0, 1, 0, 12, //
+ 1, 0, 0, 33, //
+ 3, 2, 5, 29, //
+ 0, 0, 0, 12);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, ResetTransformTriggersDeferredSave) {
+TEST_F(DisplayListTest, ResetTransformTriggersDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.transformReset();
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.transformReset();
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.transformReset();
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.transformReset();
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, SkewTriggersDeferredSave) {
+TEST_F(DisplayListTest, SkewTriggersDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.skew(10, 10);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.skew(10, 10);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.skew(10, 10);
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.skew(10, 10);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, TranslateTriggersDeferredSave) {
+TEST_F(DisplayListTest, TranslateTriggersDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.translate(10, 10);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.translate(10, 10);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.translate(10, 10);
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.translate(10, 10);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, ScaleTriggersDeferredSave) {
+TEST_F(DisplayListTest, ScaleTriggersDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.scale(0.5, 0.5);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.scale(0.5, 0.5);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.scale(0.5, 0.5);
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.scale(0.5, 0.5);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, ClipRectTriggersDeferredSave) {
+TEST_F(DisplayListTest, ClipRectTriggersDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.clipRect(SkRect::MakeLTRB(0, 0, 100, 100), ClipOp::kIntersect, true);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.transform(SkM44());
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.clipRect(SkRect::MakeLTRB(0, 0, 100, 100), ClipOp::kIntersect,
+ true);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.transformFullPerspective(1, 0, 0, 0, //
+ 0, 1, 0, 0, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.clipRect(SkRect::MakeLTRB(0, 0, 100, 100), ClipOp::kIntersect, true);
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
- builder2.transform(SkM44());
- builder2.drawRect({0, 0, 100, 100});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.clipRect(SkRect::MakeLTRB(0, 0, 100, 100), ClipOp::kIntersect,
+ true);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
+ receiver2.transformFullPerspective(1, 0, 0, 0, //
+ 0, 1, 0, 0, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, ClipRRectTriggersDeferredSave) {
+TEST_F(DisplayListTest, ClipRRectTriggersDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.clipRRect(kTestRRect, ClipOp::kIntersect, true);
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.clipRRect(kTestRRect, ClipOp::kIntersect, true);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.transform(SkM44());
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.transformFullPerspective(1, 0, 0, 0, //
+ 0, 1, 0, 0, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.clipRRect(kTestRRect, ClipOp::kIntersect, true);
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.clipRRect(kTestRRect, ClipOp::kIntersect, true);
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
- builder2.transform(SkM44());
- builder2.drawRect({0, 0, 100, 100});
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
+ receiver2.transformFullPerspective(1, 0, 0, 0, //
+ 0, 1, 0, 0, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, ClipPathTriggersDeferredSave) {
+TEST_F(DisplayListTest, ClipPathTriggersDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.clipPath(kTestPath1, ClipOp::kIntersect, true);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.transform(SkM44());
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.clipPath(kTestPath1, ClipOp::kIntersect, true);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.transformFullPerspective(1, 0, 0, 0, //
+ 0, 1, 0, 0, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.clipPath(kTestPath1, ClipOp::kIntersect, true);
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
- builder2.transform(SkM44());
- builder2.drawRect({0, 0, 100, 100});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.clipPath(kTestPath1, ClipOp::kIntersect, true);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
+ receiver2.transformFullPerspective(1, 0, 0, 0, //
+ 0, 1, 0, 0, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, NOPTranslateDoesNotTriggerDeferredSave) {
+TEST_F(DisplayListTest, NOPTranslateDoesNotTriggerDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.translate(0, 0);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.translate(0, 0);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.drawRect({0, 0, 100, 100});
- builder2.drawRect({0, 0, 100, 100});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, NOPScaleDoesNotTriggerDeferredSave) {
+TEST_F(DisplayListTest, NOPScaleDoesNotTriggerDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.scale(1.0, 1.0);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.scale(1.0, 1.0);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.drawRect({0, 0, 100, 100});
- builder2.drawRect({0, 0, 100, 100});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, NOPRotationDoesNotTriggerDeferredSave) {
+TEST_F(DisplayListTest, NOPRotationDoesNotTriggerDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.rotate(360);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.rotate(360);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.drawRect({0, 0, 100, 100});
- builder2.drawRect({0, 0, 100, 100});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, NOPSkewDoesNotTriggerDeferredSave) {
+TEST_F(DisplayListTest, NOPSkewDoesNotTriggerDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.skew(0, 0);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.skew(0, 0);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.drawRect({0, 0, 100, 100});
- builder2.drawRect({0, 0, 100, 100});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, NOPTransformDoesNotTriggerDeferredSave) {
+TEST_F(DisplayListTest, NOPTransformDoesNotTriggerDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.transform(SkM44());
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.transform(SkM44());
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.transformFullPerspective(1, 0, 0, 0, //
+ 0, 1, 0, 0, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.transformFullPerspective(1, 0, 0, 0, //
+ 0, 1, 0, 0, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.drawRect({0, 0, 100, 100});
- builder2.drawRect({0, 0, 100, 100});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, NOPTransform2DDoesNotTriggerDeferredSave) {
+TEST_F(DisplayListTest, NOPTransform2DDoesNotTriggerDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.transform2DAffine(1, 0, 0, 0, 1, 0);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.transform2DAffine(1, 0, 0, 0, 1, 0);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.drawRect({0, 0, 100, 100});
- builder2.drawRect({0, 0, 100, 100});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, NOPTransformFullPerspectiveDoesNotTriggerDeferredSave) {
+TEST_F(DisplayListTest, NOPTransformFullPerspectiveDoesNotTriggerDeferredSave) {
{
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.transformFullPerspective(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 1);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.transformFullPerspective(1, 0, 0, 0, //
+ 0, 1, 0, 0, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.drawRect({0, 0, 100, 100});
- builder2.drawRect({0, 0, 100, 100});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
@@ -2240,23 +2436,27 @@
{
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.transformFullPerspective(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
- 0, 1);
- builder1.transformReset();
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.transformFullPerspective(1, 0, 0, 0, //
+ 0, 1, 0, 0, //
+ 0, 0, 1, 0, //
+ 0, 0, 0, 1);
+ receiver1.transformReset();
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.save();
- builder2.transformReset();
- builder2.drawRect({0, 0, 100, 100});
- builder2.restore();
- builder2.drawRect({0, 0, 100, 100});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.save();
+ receiver2.transformReset();
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.restore();
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
@@ -2264,40 +2464,42 @@
}
}
-TEST(DisplayList, NOPClipDoesNotTriggerDeferredSave) {
+TEST_F(DisplayListTest, NOPClipDoesNotTriggerDeferredSave) {
DisplayListBuilder builder1;
- builder1.save();
- builder1.save();
- builder1.clipRect(SkRect::MakeLTRB(0, SK_ScalarNaN, SK_ScalarNaN, 0),
- ClipOp::kIntersect, true);
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
- builder1.drawRect({0, 0, 100, 100});
- builder1.restore();
+ DlOpReceiver& receiver1 = ToReceiver(builder1);
+ receiver1.save();
+ receiver1.save();
+ receiver1.clipRect(SkRect::MakeLTRB(0, SK_ScalarNaN, SK_ScalarNaN, 0),
+ ClipOp::kIntersect, true);
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
+ receiver1.drawRect({0, 0, 100, 100});
+ receiver1.restore();
auto display_list1 = builder1.Build();
DisplayListBuilder builder2;
- builder2.drawRect({0, 0, 100, 100});
- builder2.drawRect({0, 0, 100, 100});
+ DlOpReceiver& receiver2 = ToReceiver(builder2);
+ receiver2.drawRect({0, 0, 100, 100});
+ receiver2.drawRect({0, 0, 100, 100});
auto display_list2 = builder2.Build();
ASSERT_TRUE(DisplayListsEQ_Verbose(display_list1, display_list2));
}
-TEST(DisplayList, RTreeOfClippedSaveLayerFilterScene) {
+TEST_F(DisplayListTest, RTreeOfClippedSaveLayerFilterScene) {
DisplayListBuilder builder(/*prepare_rtree=*/true);
// blur filter with sigma=1 expands by 30 on all sides
auto filter = DlBlurImageFilter(10.0, 10.0, DlTileMode::kClamp);
DlPaint default_paint = DlPaint();
DlPaint filter_paint = DlPaint().setImageFilter(&filter);
builder.DrawRect({10, 10, 20, 20}, default_paint);
- builder.clipRect({50, 50, 60, 60}, ClipOp::kIntersect, false);
+ builder.ClipRect({50, 50, 60, 60}, ClipOp::kIntersect, false);
builder.SaveLayer(nullptr, &filter_paint);
// the following rectangle will be expanded to 23,23,87,87
// by the saveLayer filter during the restore operation
// but it will then be clipped to 50,50,60,60
builder.DrawRect({53, 53, 57, 57}, default_paint);
- builder.restore();
+ builder.Restore();
auto display_list = builder.Build();
auto rtree = display_list->rtree();
std::vector<SkRect> rects = {
@@ -2321,12 +2523,13 @@
test_rtree(rtree, {19, 19, 51, 51}, rects, {0, 1});
}
-TEST(DisplayList, RTreeRenderCulling) {
+TEST_F(DisplayListTest, RTreeRenderCulling) {
DisplayListBuilder main_builder(true);
- main_builder.drawRect({0, 0, 10, 10});
- main_builder.drawRect({20, 0, 30, 10});
- main_builder.drawRect({0, 20, 10, 30});
- main_builder.drawRect({20, 20, 30, 30});
+ DlOpReceiver& main_receiver = ToReceiver(main_builder);
+ main_receiver.drawRect({0, 0, 10, 10});
+ main_receiver.drawRect({20, 0, 30, 10});
+ main_receiver.drawRect({0, 20, 10, 30});
+ main_receiver.drawRect({20, 20, 30, 30});
auto main = main_builder.Build();
{ // No rects
@@ -2336,7 +2539,7 @@
auto expected = expected_builder.Build();
DisplayListBuilder culling_builder(cull_rect);
- main->RenderTo(&culling_builder);
+ main->Dispatch(ToReceiver(culling_builder), cull_rect);
EXPECT_TRUE(DisplayListsEQ_Verbose(culling_builder.Build(), expected));
}
@@ -2345,11 +2548,12 @@
SkRect cull_rect = {9, 9, 19, 19};
DisplayListBuilder expected_builder;
- expected_builder.drawRect({0, 0, 10, 10});
+ DlOpReceiver& expected_receiver = ToReceiver(expected_builder);
+ expected_receiver.drawRect({0, 0, 10, 10});
auto expected = expected_builder.Build();
DisplayListBuilder culling_builder(cull_rect);
- main->RenderTo(&culling_builder);
+ main->Dispatch(ToReceiver(culling_builder), cull_rect);
EXPECT_TRUE(DisplayListsEQ_Verbose(culling_builder.Build(), expected));
}
@@ -2358,11 +2562,12 @@
SkRect cull_rect = {11, 9, 21, 19};
DisplayListBuilder expected_builder;
- expected_builder.drawRect({20, 0, 30, 10});
+ DlOpReceiver& expected_receiver = ToReceiver(expected_builder);
+ expected_receiver.drawRect({20, 0, 30, 10});
auto expected = expected_builder.Build();
DisplayListBuilder culling_builder(cull_rect);
- main->RenderTo(&culling_builder);
+ main->Dispatch(ToReceiver(culling_builder), cull_rect);
EXPECT_TRUE(DisplayListsEQ_Verbose(culling_builder.Build(), expected));
}
@@ -2371,11 +2576,12 @@
SkRect cull_rect = {9, 11, 19, 21};
DisplayListBuilder expected_builder;
- expected_builder.drawRect({0, 20, 10, 30});
+ DlOpReceiver& expected_receiver = ToReceiver(expected_builder);
+ expected_receiver.drawRect({0, 20, 10, 30});
auto expected = expected_builder.Build();
DisplayListBuilder culling_builder(cull_rect);
- main->RenderTo(&culling_builder);
+ main->Dispatch(ToReceiver(culling_builder), cull_rect);
EXPECT_TRUE(DisplayListsEQ_Verbose(culling_builder.Build(), expected));
}
@@ -2384,11 +2590,12 @@
SkRect cull_rect = {11, 11, 21, 21};
DisplayListBuilder expected_builder;
- expected_builder.drawRect({20, 20, 30, 30});
+ DlOpReceiver& expected_receiver = ToReceiver(expected_builder);
+ expected_receiver.drawRect({20, 20, 30, 30});
auto expected = expected_builder.Build();
DisplayListBuilder culling_builder(cull_rect);
- main->RenderTo(&culling_builder);
+ main->Dispatch(ToReceiver(culling_builder), cull_rect);
EXPECT_TRUE(DisplayListsEQ_Verbose(culling_builder.Build(), expected));
}
@@ -2397,13 +2604,13 @@
SkRect cull_rect = {9, 9, 21, 21};
DisplayListBuilder culling_builder(cull_rect);
- main->RenderTo(&culling_builder);
+ main->Dispatch(ToReceiver(culling_builder), cull_rect);
EXPECT_TRUE(DisplayListsEQ_Verbose(culling_builder.Build(), main));
}
}
-TEST(DisplayListTest, DrawSaveDrawCannotInheritOpacity) {
+TEST_F(DisplayListTest, DrawSaveDrawCannotInheritOpacity) {
DisplayListBuilder builder;
builder.DrawCircle({10, 10}, 5, DlPaint());
builder.Save();
diff --git a/display_list/display_list_utils.cc b/display_list/display_list_utils.cc
index 2ffed31..e6c21d5 100644
--- a/display_list/display_list_utils.cc
+++ b/display_list/display_list_utils.cc
@@ -4,106 +4,8 @@
#include "flutter/display_list/display_list_utils.h"
-#include <math.h>
-#include <optional>
-#include <type_traits>
-
-#include "flutter/display_list/display_list_blend_mode.h"
-#include "flutter/display_list/display_list_canvas_dispatcher.h"
-#include "flutter/fml/logging.h"
-#include "third_party/skia/include/core/SkMaskFilter.h"
-#include "third_party/skia/include/core/SkPath.h"
-#include "third_party/skia/include/core/SkRSXform.h"
-#include "third_party/skia/include/core/SkTextBlob.h"
-#include "third_party/skia/include/utils/SkShadowUtils.h"
-
namespace flutter {
-// clang-format off
-constexpr float kInvertColorMatrix[20] = {
- -1.0, 0, 0, 1.0, 0,
- 0, -1.0, 0, 1.0, 0,
- 0, 0, -1.0, 1.0, 0,
- 1.0, 1.0, 1.0, 1.0, 0
-};
-// clang-format on
-
-void SkPaintDispatchHelper::save_opacity(SkScalar child_opacity) {
- save_stack_.emplace_back(opacity_);
- set_opacity(child_opacity);
-}
-void SkPaintDispatchHelper::restore_opacity() {
- if (save_stack_.empty()) {
- return;
- }
- set_opacity(save_stack_.back().opacity);
- save_stack_.pop_back();
-}
-
-void SkPaintDispatchHelper::setAntiAlias(bool aa) {
- paint_.setAntiAlias(aa);
-}
-void SkPaintDispatchHelper::setDither(bool dither) {
- paint_.setDither(dither);
-}
-void SkPaintDispatchHelper::setInvertColors(bool invert) {
- invert_colors_ = invert;
- paint_.setColorFilter(makeColorFilter());
-}
-void SkPaintDispatchHelper::setStrokeCap(DlStrokeCap cap) {
- paint_.setStrokeCap(ToSk(cap));
-}
-void SkPaintDispatchHelper::setStrokeJoin(DlStrokeJoin join) {
- paint_.setStrokeJoin(ToSk(join));
-}
-void SkPaintDispatchHelper::setStyle(DlDrawStyle style) {
- paint_.setStyle(ToSk(style));
-}
-void SkPaintDispatchHelper::setStrokeWidth(SkScalar width) {
- paint_.setStrokeWidth(width);
-}
-void SkPaintDispatchHelper::setStrokeMiter(SkScalar limit) {
- paint_.setStrokeMiter(limit);
-}
-void SkPaintDispatchHelper::setColor(DlColor color) {
- current_color_ = color;
- paint_.setColor(color);
- if (has_opacity()) {
- paint_.setAlphaf(paint_.getAlphaf() * opacity());
- }
-}
-void SkPaintDispatchHelper::setBlendMode(DlBlendMode mode) {
- paint_.setBlendMode(ToSk(mode));
-}
-void SkPaintDispatchHelper::setColorSource(const DlColorSource* source) {
- paint_.setShader(source ? source->skia_object() : nullptr);
-}
-void SkPaintDispatchHelper::setImageFilter(const DlImageFilter* filter) {
- paint_.setImageFilter(filter ? filter->skia_object() : nullptr);
-}
-void SkPaintDispatchHelper::setColorFilter(const DlColorFilter* filter) {
- color_filter_ = filter ? filter->shared() : nullptr;
- paint_.setColorFilter(makeColorFilter());
-}
-void SkPaintDispatchHelper::setPathEffect(const DlPathEffect* effect) {
- paint_.setPathEffect(effect ? effect->skia_object() : nullptr);
-}
-void SkPaintDispatchHelper::setMaskFilter(const DlMaskFilter* filter) {
- paint_.setMaskFilter(filter ? filter->skia_object() : nullptr);
-}
-
-sk_sp<SkColorFilter> SkPaintDispatchHelper::makeColorFilter() const {
- if (!invert_colors_) {
- return color_filter_ ? color_filter_->skia_object() : nullptr;
- }
- sk_sp<SkColorFilter> invert_filter =
- SkColorFilters::Matrix(kInvertColorMatrix);
- if (color_filter_) {
- invert_filter = invert_filter->makeComposed(color_filter_->skia_object());
- }
- return invert_filter;
-}
-
void RectBoundsAccumulator::accumulate(const SkRect& r, int index) {
if (r.fLeft < r.fRight && r.fTop < r.fBottom) {
rect_.accumulate(r.fLeft, r.fTop);
diff --git a/display_list/display_list_utils.h b/display_list/display_list_utils.h
index c2bed14..152ae10 100644
--- a/display_list/display_list_utils.h
+++ b/display_list/display_list_utils.h
@@ -7,33 +7,24 @@
#include <optional>
-#include "flutter/display_list/display_list.h"
-#include "flutter/display_list/display_list_blend_mode.h"
-#include "flutter/display_list/display_list_dispatcher.h"
-#include "flutter/display_list/display_list_flags.h"
#include "flutter/display_list/display_list_rtree.h"
+#include "flutter/display_list/dl_op_receiver.h"
#include "flutter/fml/logging.h"
-#include "flutter/fml/macros.h"
-#include "third_party/skia/include/core/SkMaskFilter.h"
// This file contains various utility classes to ease implementing
-// a Flutter DisplayList Dispatcher, including:
+// a Flutter DisplayList DlOpReceiver, including:
//
// IgnoreAttributeDispatchHelper:
// IgnoreClipDispatchHelper:
// IgnoreTransformDispatchHelper
-// Empty overrides of all of the associated methods of Dispatcher
-// for dispatchers that only track some of the rendering operations
-//
-// SkPaintAttributeDispatchHelper:
-// Tracks the attribute methods and maintains their state in an
-// SkPaint object.
+// Empty overrides of all of the associated methods of DlOpReceiver
+// for receivers that only track some of the rendering operations
namespace flutter {
-// A utility class that will ignore all Dispatcher methods relating
+// A utility class that will ignore all DlOpReceiver methods relating
// to the setting of attributes.
-class IgnoreAttributeDispatchHelper : public virtual Dispatcher {
+class IgnoreAttributeDispatchHelper : public virtual DlOpReceiver {
public:
void setAntiAlias(bool aa) override {}
void setDither(bool dither) override {}
@@ -52,9 +43,9 @@
void setMaskFilter(const DlMaskFilter* filter) override {}
};
-// A utility class that will ignore all Dispatcher methods relating
+// A utility class that will ignore all DlOpReceiver methods relating
// to setting a clip.
-class IgnoreClipDispatchHelper : public virtual Dispatcher {
+class IgnoreClipDispatchHelper : public virtual DlOpReceiver {
void clipRect(const SkRect& rect,
DlCanvas::ClipOp clip_op,
bool is_aa) override {}
@@ -66,9 +57,9 @@
bool is_aa) override {}
};
-// A utility class that will ignore all Dispatcher methods relating
+// A utility class that will ignore all DlOpReceiver methods relating
// to modifying the transform.
-class IgnoreTransformDispatchHelper : public virtual Dispatcher {
+class IgnoreTransformDispatchHelper : public virtual DlOpReceiver {
public:
void translate(SkScalar tx, SkScalar ty) override {}
void scale(SkScalar sx, SkScalar sy) override {}
@@ -88,7 +79,7 @@
void transformReset() override {}
};
-class IgnoreDrawDispatchHelper : public virtual Dispatcher {
+class IgnoreDrawDispatchHelper : public virtual DlOpReceiver {
public:
void save() override {}
void saveLayer(const SkRect* bounds,
@@ -121,7 +112,7 @@
const SkRect& dst,
DlImageSampling sampling,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) override {}
+ SrcRectConstraint constraint) override {}
void drawImageNine(const sk_sp<DlImage> image,
const SkIRect& center,
const SkRect& dst,
@@ -136,7 +127,8 @@
DlImageSampling sampling,
const SkRect* cull_rect,
bool render_with_attributes) override {}
- void drawDisplayList(const sk_sp<DisplayList> display_list) override {}
+ void drawDisplayList(const sk_sp<DisplayList> display_list,
+ SkScalar opacity) override {}
void drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y) override {}
@@ -147,77 +139,6 @@
SkScalar dpr) override {}
};
-// A utility class that will monitor the Dispatcher methods relating
-// to the rendering attributes and accumulate them into an SkPaint
-// which can be accessed at any time via paint().
-class SkPaintDispatchHelper : public virtual Dispatcher {
- public:
- SkPaintDispatchHelper(SkScalar opacity = SK_Scalar1)
- : current_color_(SK_ColorBLACK), opacity_(opacity) {
- if (opacity < SK_Scalar1) {
- paint_.setAlphaf(opacity);
- }
- }
-
- void setAntiAlias(bool aa) override;
- void setDither(bool dither) override;
- void setStyle(DlDrawStyle style) override;
- void setColor(DlColor color) override;
- void setStrokeWidth(SkScalar width) override;
- void setStrokeMiter(SkScalar limit) override;
- void setStrokeCap(DlStrokeCap cap) override;
- void setStrokeJoin(DlStrokeJoin join) override;
- void setColorSource(const DlColorSource* source) override;
- void setColorFilter(const DlColorFilter* filter) override;
- void setInvertColors(bool invert) override;
- void setBlendMode(DlBlendMode mode) override;
- void setPathEffect(const DlPathEffect* effect) override;
- void setMaskFilter(const DlMaskFilter* filter) override;
- void setImageFilter(const DlImageFilter* filter) override;
-
- const SkPaint& paint() { return paint_; }
-
- /// Returns the current opacity attribute which is used to reduce
- /// the alpha of all setColor calls encountered in the streeam
- SkScalar opacity() { return opacity_; }
- /// Returns the combined opacity that includes both the current
- /// opacity attribute and the alpha of the most recent color.
- /// The most recently set color will have combined the two and
- /// stored the combined value in the alpha of the paint.
- SkScalar combined_opacity() { return paint_.getAlphaf(); }
- /// Returns true iff the current opacity attribute is not opaque,
- /// irrespective of the alpha of the current color
- bool has_opacity() { return opacity_ < SK_Scalar1; }
-
- protected:
- void save_opacity(SkScalar opacity_for_children);
- void restore_opacity();
-
- private:
- SkPaint paint_;
- bool invert_colors_ = false;
- std::shared_ptr<const DlColorFilter> color_filter_;
-
- sk_sp<SkColorFilter> makeColorFilter() const;
-
- struct SaveInfo {
- SaveInfo(SkScalar opacity) : opacity(opacity) {}
-
- SkScalar opacity;
- };
- std::vector<SaveInfo> save_stack_;
-
- void set_opacity(SkScalar opacity) {
- if (opacity_ != opacity) {
- opacity_ = opacity;
- setColor(current_color_);
- }
- }
-
- SkColor current_color_;
- SkScalar opacity_;
-};
-
enum class BoundsAccumulatorType {
kRect,
kRTree,
diff --git a/display_list/display_list_vertices.cc b/display_list/display_list_vertices.cc
index 6c20c3a..e6a9b72 100644
--- a/display_list/display_list_vertices.cc
+++ b/display_list/display_list_vertices.cc
@@ -176,13 +176,6 @@
FML_DCHECK((index_count_ != 0) == (indices() != nullptr));
}
-sk_sp<SkVertices> DlVertices::skia_object() const {
- const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors());
- return SkVertices::MakeCopy(ToSk(mode_), vertex_count_, vertices(),
- texture_coordinates(), sk_colors, index_count_,
- indices());
-}
-
bool DlVertices::operator==(DlVertices const& other) const {
auto lists_equal = [](auto* a, auto* b, int count) {
if (a == nullptr || b == nullptr) {
diff --git a/display_list/display_list_vertices.h b/display_list/display_list_vertices.h
index 885ef6c..04044ba 100644
--- a/display_list/display_list_vertices.h
+++ b/display_list/display_list_vertices.h
@@ -30,14 +30,6 @@
kTriangleFan,
};
-inline SkVertices::VertexMode ToSk(DlVertexMode dl_mode) {
- return static_cast<SkVertices::VertexMode>(dl_mode);
-}
-
-inline DlVertexMode ToDl(SkVertices::VertexMode sk_mode) {
- return static_cast<DlVertexMode>(sk_mode);
-}
-
//------------------------------------------------------------------------------
/// @brief Holds all of the data (both required and optional) for a
/// DisplayList drawVertices call.
@@ -233,9 +225,6 @@
return static_cast<const uint16_t*>(pod(indices_offset_));
}
- // Returns an equivalent sk_sp<SkVertices> analog to this object.
- sk_sp<SkVertices> skia_object() const;
-
bool operator==(DlVertices const& other) const;
bool operator!=(DlVertices const& other) const { return !(*this == other); }
diff --git a/display_list/display_list_vertices_unittests.cc b/display_list/display_list_vertices_unittests.cc
index 0323b62..5a11dc2e 100644
--- a/display_list/display_list_vertices_unittests.cc
+++ b/display_list/display_list_vertices_unittests.cc
@@ -22,7 +22,6 @@
EXPECT_EQ(vertices1->colors(), nullptr);
EXPECT_EQ(vertices1->index_count(), 0);
EXPECT_EQ(vertices1->indices(), nullptr);
- EXPECT_NE(vertices1->skia_object(), nullptr);
std::shared_ptr<const DlVertices> vertices2 = DlVertices::Make(
DlVertexMode::kTriangles, -1, nullptr, nullptr, nullptr, -1, nullptr);
@@ -33,7 +32,6 @@
EXPECT_EQ(vertices2->colors(), nullptr);
EXPECT_EQ(vertices2->index_count(), 0);
EXPECT_EQ(vertices2->indices(), nullptr);
- EXPECT_NE(vertices2->skia_object(), nullptr);
TestEquals(*vertices1, *vertices2);
}
@@ -425,7 +423,6 @@
EXPECT_EQ(vertices1->colors(), nullptr);
EXPECT_EQ(vertices1->index_count(), 0);
EXPECT_EQ(vertices1->indices(), nullptr);
- EXPECT_NE(vertices1->skia_object(), nullptr);
Builder builder2(DlVertexMode::kTriangles, -1, Builder::kNone, -1);
EXPECT_TRUE(builder2.is_valid());
@@ -437,7 +434,6 @@
EXPECT_EQ(vertices2->colors(), nullptr);
EXPECT_EQ(vertices2->index_count(), 0);
EXPECT_EQ(vertices2->indices(), nullptr);
- EXPECT_NE(vertices2->skia_object(), nullptr);
TestEquals(*vertices1, *vertices2);
}
diff --git a/display_list/dl_canvas.cc b/display_list/dl_canvas.cc
new file mode 100644
index 0000000..7f9e3fc
--- /dev/null
+++ b/display_list/dl_canvas.cc
@@ -0,0 +1,23 @@
+// 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/dl_canvas.h"
+
+#include "third_party/skia/include/utils/SkShadowUtils.h"
+
+namespace flutter {
+
+SkRect DlCanvas::ComputeShadowBounds(const SkPath& path,
+ float elevation,
+ SkScalar dpr,
+ const SkMatrix& ctm) {
+ SkRect shadow_bounds(path.getBounds());
+ SkShadowUtils::GetLocalBounds(
+ ctm, path, SkPoint3::Make(0, 0, dpr * elevation),
+ SkPoint3::Make(0, -1, 1), kShadowLightRadius / kShadowLightHeight,
+ SkShadowFlags::kDirectionalLight_ShadowFlag, &shadow_bounds);
+ return shadow_bounds;
+}
+
+} // namespace flutter
diff --git a/display_list/dl_canvas.h b/display_list/dl_canvas.h
index 5d8d97e..7d94352c 100644
--- a/display_list/dl_canvas.h
+++ b/display_list/dl_canvas.h
@@ -35,6 +35,11 @@
kPolygon, //!< draw each pair of overlapping points as a line segment
};
+ enum class SrcRectConstraint {
+ kStrict,
+ kFast,
+ };
+
virtual ~DlCanvas() = default;
virtual SkISize GetBaseLayerSize() const = 0;
@@ -146,28 +151,29 @@
const SkPoint point,
DlImageSampling sampling,
const DlPaint* paint = nullptr) = 0;
- virtual void DrawImageRect(const sk_sp<DlImage>& image,
- const SkRect& src,
- const SkRect& dst,
- DlImageSampling sampling,
- const DlPaint* paint = nullptr,
- bool enforce_src_edges = false) = 0;
- virtual void DrawImageRect(const sk_sp<DlImage>& image,
- const SkIRect& src,
- const SkRect& dst,
- DlImageSampling sampling,
- const DlPaint* paint = nullptr,
- bool enforce_src_edges = false) {
- DrawImageRect(image, SkRect::Make(src), dst, sampling, paint,
- enforce_src_edges);
+ virtual void DrawImageRect(
+ const sk_sp<DlImage>& image,
+ const SkRect& src,
+ const SkRect& dst,
+ DlImageSampling sampling,
+ const DlPaint* paint = nullptr,
+ SrcRectConstraint constraint = SrcRectConstraint::kFast) = 0;
+ virtual void DrawImageRect(
+ const sk_sp<DlImage>& image,
+ const SkIRect& src,
+ const SkRect& dst,
+ DlImageSampling sampling,
+ const DlPaint* paint = nullptr,
+ SrcRectConstraint constraint = SrcRectConstraint::kFast) {
+ DrawImageRect(image, SkRect::Make(src), dst, sampling, paint, constraint);
}
- virtual void DrawImageRect(const sk_sp<DlImage>& image,
- const SkRect& dst,
- DlImageSampling sampling,
- const DlPaint* paint = nullptr,
- bool enforce_src_edges = false) {
- DrawImageRect(image, image->bounds(), dst, sampling, paint,
- enforce_src_edges);
+ virtual void DrawImageRect(
+ const sk_sp<DlImage>& image,
+ const SkRect& dst,
+ DlImageSampling sampling,
+ const DlPaint* paint = nullptr,
+ SrcRectConstraint constraint = SrcRectConstraint::kFast) {
+ DrawImageRect(image, image->bounds(), dst, sampling, paint, constraint);
}
virtual void DrawImageNine(const sk_sp<DlImage>& image,
const SkIRect& center,
@@ -196,6 +202,14 @@
SkScalar dpr) = 0;
virtual void Flush() = 0;
+
+ static constexpr SkScalar kShadowLightHeight = 600;
+ static constexpr SkScalar kShadowLightRadius = 800;
+
+ static SkRect ComputeShadowBounds(const SkPath& path,
+ float elevation,
+ SkScalar dpr,
+ const SkMatrix& ctm);
};
class DlAutoCanvasRestore {
diff --git a/display_list/display_list_dispatcher.cc b/display_list/dl_op_receiver.cc
similarity index 64%
rename from display_list/display_list_dispatcher.cc
rename to display_list/dl_op_receiver.cc
index e321f02..b1b6c01 100644
--- a/display_list/display_list_dispatcher.cc
+++ b/display_list/dl_op_receiver.cc
@@ -2,10 +2,10 @@
// 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_dispatcher.h"
+#include "flutter/display_list/dl_op_receiver.h"
namespace flutter {
-//
+// Just exists to ensure that the header can be cleanly imported.
} // namespace flutter
diff --git a/display_list/display_list_dispatcher.h b/display_list/dl_op_receiver.h
similarity index 96%
rename from display_list/display_list_dispatcher.h
rename to display_list/dl_op_receiver.h
index 00dc966..0f406f9 100644
--- a/display_list/display_list_dispatcher.h
+++ b/display_list/dl_op_receiver.h
@@ -28,10 +28,11 @@
/// through the DisplayListBuilder and also the methods that will be
/// invoked through the DisplayList::dispatch() method.
///
-class Dispatcher {
+class DlOpReceiver {
protected:
using ClipOp = DlCanvas::ClipOp;
using PointMode = DlCanvas::PointMode;
+ using SrcRectConstraint = DlCanvas::SrcRectConstraint;
public:
// MaxDrawPointsCount * sizeof(SkPoint) must be less than 1 << 32
@@ -219,12 +220,13 @@
const SkPoint point,
DlImageSampling sampling,
bool render_with_attributes) = 0;
- virtual void drawImageRect(const sk_sp<DlImage> image,
- const SkRect& src,
- const SkRect& dst,
- DlImageSampling sampling,
- bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) = 0;
+ virtual void drawImageRect(
+ const sk_sp<DlImage> image,
+ const SkRect& src,
+ const SkRect& dst,
+ DlImageSampling sampling,
+ bool render_with_attributes,
+ SrcRectConstraint constraint = SrcRectConstraint::kFast) = 0;
virtual void drawImageNine(const sk_sp<DlImage> image,
const SkIRect& center,
const SkRect& dst,
@@ -239,7 +241,8 @@
DlImageSampling sampling,
const SkRect* cull_rect,
bool render_with_attributes) = 0;
- virtual void drawDisplayList(const sk_sp<DisplayList> display_list) = 0;
+ virtual void drawDisplayList(const sk_sp<DisplayList> display_list,
+ SkScalar opacity = SK_Scalar1) = 0;
virtual void drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y) = 0;
diff --git a/display_list/display_list_canvas_unittests.cc b/display_list/dl_rendering_unittests.cc
similarity index 85%
rename from display_list/display_list_canvas_unittests.cc
rename to display_list/dl_rendering_unittests.cc
index a6aed32..4f40d1f 100644
--- a/display_list/display_list_canvas_unittests.cc
+++ b/display_list/dl_rendering_unittests.cc
@@ -6,15 +6,16 @@
#include "flutter/display_list/display_list.h"
#include "flutter/display_list/display_list_builder.h"
-#include "flutter/display_list/display_list_canvas_dispatcher.h"
#include "flutter/display_list/display_list_comparable.h"
#include "flutter/display_list/display_list_flags.h"
#include "flutter/display_list/display_list_sampling_options.h"
#include "flutter/display_list/skia/dl_sk_canvas.h"
+#include "flutter/display_list/skia/dl_sk_dispatcher.h"
#include "flutter/display_list/testing/dl_test_surface_provider.h"
#include "flutter/fml/math.h"
#include "flutter/testing/display_list_testing.h"
#include "flutter/testing/testing.h"
+#include "third_party/skia/include/core/SkColorFilter.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkSurface.h"
@@ -135,6 +136,18 @@
(sizeof(kHorizontalMiterDiamondPoints) /
sizeof(kHorizontalMiterDiamondPoints[0]));
+class SkImageSampling {
+ public:
+ static constexpr SkSamplingOptions kNearestNeighbor =
+ SkSamplingOptions(SkFilterMode::kNearest);
+ static constexpr SkSamplingOptions kLinear =
+ SkSamplingOptions(SkFilterMode::kLinear);
+ static constexpr SkSamplingOptions kMipmapLinear =
+ SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
+ static constexpr SkSamplingOptions kCubic =
+ SkSamplingOptions(SkCubicResampler{1 / 3.0f, 1 / 3.0f});
+};
+
// A class to specify how much tolerance to allow in bounds estimates.
// For some attributes, the machinery must make some conservative
// assumptions as to the extent of the bounds, but some of our test
@@ -409,7 +422,7 @@
: display_list_(std::move(display_list)) {}
void Render(SkCanvas* canvas, const RenderJobInfo& info) {
- display_list_->RenderTo(canvas, info.opacity);
+ DlSkCanvasAdapter(canvas).DrawDisplayList(display_list_, info.opacity);
}
private:
@@ -998,12 +1011,12 @@
RenderEnvironment::MakeN32(env.provider());
SkSetup sk_backdrop_setup = [=](SkCanvas* cv, SkPaint& p) {
SkPaint setup_p;
- setup_p.setShader(kTestImageColorSource.skia_object());
+ setup_p.setShader(kTestSkImageColorSource);
cv->drawPaint(setup_p);
};
DlSetup dl_backdrop_setup = [=](DlCanvas* cv, DlPaint& p) {
DlPaint setup_p;
- setup_p.setColorSource(&kTestImageColorSource);
+ setup_p.setColorSource(&kTestDlImageColorSource);
cv->DrawPaint(setup_p);
};
SkSetup sk_content_setup = [=](SkCanvas* cv, SkPaint& p) {
@@ -1016,38 +1029,39 @@
dl_backdrop_setup, testP.dl_renderer());
quickCompareToReference(backdrop_env, "backdrop");
- DlBlurImageFilter backdrop(5, 5, DlTileMode::kDecal);
+ DlBlurImageFilter dl_backdrop(5, 5, DlTileMode::kDecal);
+ auto sk_backdrop =
+ SkImageFilters::Blur(5, 5, SkTileMode::kDecal, nullptr);
RenderWith(testP, backdrop_env, tolerance,
CaseParameters(
"saveLayer with backdrop",
[=](SkCanvas* cv, SkPaint& p) {
sk_backdrop_setup(cv, p);
cv->saveLayer(SkCanvas::SaveLayerRec(
- nullptr, nullptr, backdrop.skia_object().get(), 0));
+ nullptr, nullptr, sk_backdrop.get(), 0));
sk_content_setup(cv, p);
},
[=](DlCanvas* cv, DlPaint& p) {
dl_backdrop_setup(cv, p);
- cv->SaveLayer(nullptr, nullptr, &backdrop);
+ cv->SaveLayer(nullptr, nullptr, &dl_backdrop);
dl_content_setup(cv, p);
})
.with_restore(sk_safe_restore, dl_safe_restore, true));
- RenderWith(
- testP, backdrop_env, tolerance,
- CaseParameters(
- "saveLayer with bounds and backdrop",
- [=](SkCanvas* cv, SkPaint& p) {
- sk_backdrop_setup(cv, p);
- cv->saveLayer(SkCanvas::SaveLayerRec(
- &layer_bounds, nullptr, backdrop.skia_object().get(), 0));
- sk_content_setup(cv, p);
- },
- [=](DlCanvas* cv, DlPaint& p) {
- dl_backdrop_setup(cv, p);
- cv->SaveLayer(&layer_bounds, nullptr, &backdrop);
- dl_content_setup(cv, p);
- })
- .with_restore(sk_safe_restore, dl_safe_restore, true));
+ RenderWith(testP, backdrop_env, tolerance,
+ CaseParameters(
+ "saveLayer with bounds and backdrop",
+ [=](SkCanvas* cv, SkPaint& p) {
+ sk_backdrop_setup(cv, p);
+ cv->saveLayer(SkCanvas::SaveLayerRec(
+ &layer_bounds, nullptr, sk_backdrop.get(), 0));
+ sk_content_setup(cv, p);
+ },
+ [=](DlCanvas* cv, DlPaint& p) {
+ dl_backdrop_setup(cv, p);
+ cv->SaveLayer(&layer_bounds, nullptr, &dl_backdrop);
+ dl_content_setup(cv, p);
+ })
+ .with_restore(sk_safe_restore, dl_safe_restore, true));
RenderWith(testP, backdrop_env, tolerance,
CaseParameters(
"clipped saveLayer with backdrop",
@@ -1055,13 +1069,13 @@
sk_backdrop_setup(cv, p);
cv->clipRect(layer_bounds);
cv->saveLayer(SkCanvas::SaveLayerRec(
- nullptr, nullptr, backdrop.skia_object().get(), 0));
+ nullptr, nullptr, sk_backdrop.get(), 0));
sk_content_setup(cv, p);
},
[=](DlCanvas* cv, DlPaint& p) {
dl_backdrop_setup(cv, p);
cv->ClipRect(layer_bounds);
- cv->SaveLayer(nullptr, nullptr, &backdrop);
+ cv->SaveLayer(nullptr, nullptr, &dl_backdrop);
dl_content_setup(cv, p);
})
.with_restore(sk_safe_restore, dl_safe_restore, true));
@@ -1076,20 +1090,22 @@
0, 0, 0, 0.5, 0,
};
// clang-format on
- DlMatrixColorFilter filter(rotate_alpha_color_matrix);
+ DlMatrixColorFilter dl_alpha_rotate_filter(rotate_alpha_color_matrix);
+ auto sk_alpha_rotate_filter =
+ SkColorFilters::Matrix(rotate_alpha_color_matrix);
{
RenderWith(testP, env, tolerance,
CaseParameters(
"saveLayer ColorFilter, no bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
- save_p.setColorFilter(filter.skia_object());
+ save_p.setColorFilter(sk_alpha_rotate_filter);
cv->saveLayer(nullptr, &save_p);
p.setStrokeWidth(5.0);
},
[=](DlCanvas* cv, DlPaint& p) {
DlPaint save_p;
- save_p.setColorFilter(&filter);
+ save_p.setColorFilter(&dl_alpha_rotate_filter);
cv->SaveLayer(nullptr, &save_p);
p.setStrokeWidth(5.0);
})
@@ -1101,13 +1117,13 @@
"saveLayer ColorFilter and bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
- save_p.setColorFilter(filter.skia_object());
+ save_p.setColorFilter(sk_alpha_rotate_filter);
cv->saveLayer(kRenderBounds, &save_p);
p.setStrokeWidth(5.0);
},
[=](DlCanvas* cv, DlPaint& p) {
DlPaint save_p;
- save_p.setColorFilter(&filter);
+ save_p.setColorFilter(&dl_alpha_rotate_filter);
cv->SaveLayer(&kRenderBounds, &save_p);
p.setStrokeWidth(5.0);
})
@@ -1124,21 +1140,23 @@
0, 0, 0, 1, 0,
};
// clang-format on
- DlMatrixColorFilter color_filter(color_matrix);
- DlColorFilterImageFilter filter(color_filter);
+ DlMatrixColorFilter dl_color_filter(color_matrix);
+ DlColorFilterImageFilter dl_cf_image_filter(dl_color_filter);
+ auto sk_cf_image_filter = SkImageFilters::ColorFilter(
+ SkColorFilters::Matrix(color_matrix), nullptr);
{
RenderWith(testP, env, tolerance,
CaseParameters(
"saveLayer ImageFilter, no bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
- save_p.setImageFilter(filter.skia_object());
+ save_p.setImageFilter(sk_cf_image_filter);
cv->saveLayer(nullptr, &save_p);
p.setStrokeWidth(5.0);
},
[=](DlCanvas* cv, DlPaint& p) {
DlPaint save_p;
- save_p.setImageFilter(&filter);
+ save_p.setImageFilter(&dl_cf_image_filter);
cv->SaveLayer(nullptr, &save_p);
p.setStrokeWidth(5.0);
})
@@ -1150,13 +1168,13 @@
"saveLayer ImageFilter and bounds",
[=](SkCanvas* cv, SkPaint& p) {
SkPaint save_p;
- save_p.setImageFilter(filter.skia_object());
+ save_p.setImageFilter(sk_cf_image_filter);
cv->saveLayer(kRenderBounds, &save_p);
p.setStrokeWidth(5.0);
},
[=](DlCanvas* cv, DlPaint& p) {
DlPaint save_p;
- save_p.setImageFilter(&filter);
+ save_p.setImageFilter(&dl_cf_image_filter);
cv->SaveLayer(&kRenderBounds, &save_p);
p.setStrokeWidth(5.0);
})
@@ -1225,12 +1243,12 @@
} else {
DlColor dither_bg = DlColor::kBlack();
SkSetup sk_dither_setup = [=](SkCanvas*, SkPaint& p) {
- p.setShader(kTestImageColorSource.skia_object());
+ p.setShader(kTestSkImageColorSource);
p.setAlpha(0xf0);
p.setStrokeWidth(5.0);
};
DlSetup dl_dither_setup = [=](DlCanvas*, DlPaint& p) {
- p.setColorSource(&kTestImageColorSource);
+ p.setColorSource(&kTestDlImageColorSource);
p.setAlpha(0xf0);
p.setStrokeWidth(5.0);
};
@@ -1316,17 +1334,19 @@
// (for drawPaint) so we create a new environment for these tests.
RenderEnvironment blur_env = RenderEnvironment::MakeN32(env.provider());
SkSetup sk_blur_setup = [=](SkCanvas*, SkPaint& p) {
- p.setShader(kTestImageColorSource.skia_object());
+ p.setShader(kTestSkImageColorSource);
p.setStrokeWidth(5.0);
};
DlSetup dl_blur_setup = [=](DlCanvas*, DlPaint& p) {
- p.setColorSource(&kTestImageColorSource);
+ p.setColorSource(&kTestDlImageColorSource);
p.setStrokeWidth(5.0);
};
blur_env.init_ref(sk_blur_setup, testP.sk_renderer(), //
dl_blur_setup, testP.dl_renderer());
quickCompareToReference(blur_env, "blur");
- DlBlurImageFilter filter_decal_5(5.0, 5.0, DlTileMode::kDecal);
+ DlBlurImageFilter dl_filter_decal_5(5.0, 5.0, DlTileMode::kDecal);
+ auto sk_filter_decal_5 =
+ SkImageFilters::Blur(5.0, 5.0, SkTileMode::kDecal, nullptr);
BoundsTolerance blur_5_tolerance = tolerance.addBoundsPadding(4, 4);
{
RenderWith(testP, blur_env, blur_5_tolerance,
@@ -1334,25 +1354,27 @@
"ImageFilter == Decal Blur 5",
[=](SkCanvas* cv, SkPaint& p) {
sk_blur_setup(cv, p);
- p.setImageFilter(filter_decal_5.skia_object());
+ p.setImageFilter(sk_filter_decal_5);
},
[=](DlCanvas* cv, DlPaint& p) {
dl_blur_setup(cv, p);
- p.setImageFilter(&filter_decal_5);
+ p.setImageFilter(&dl_filter_decal_5);
}));
}
- DlBlurImageFilter filter_clamp_5(5.0, 5.0, DlTileMode::kClamp);
+ DlBlurImageFilter dl_filter_clamp_5(5.0, 5.0, DlTileMode::kClamp);
+ auto sk_filter_clamp_5 =
+ SkImageFilters::Blur(5.0, 5.0, SkTileMode::kClamp, nullptr);
{
RenderWith(testP, blur_env, blur_5_tolerance,
CaseParameters(
"ImageFilter == Clamp Blur 5",
[=](SkCanvas* cv, SkPaint& p) {
sk_blur_setup(cv, p);
- p.setImageFilter(filter_clamp_5.skia_object());
+ p.setImageFilter(sk_filter_clamp_5);
},
[=](DlCanvas* cv, DlPaint& p) {
dl_blur_setup(cv, p);
- p.setImageFilter(&filter_clamp_5);
+ p.setImageFilter(&dl_filter_clamp_5);
}));
}
}
@@ -1363,27 +1385,28 @@
// (for drawPaint) so we create a new environment for these tests.
RenderEnvironment dilate_env = RenderEnvironment::MakeN32(env.provider());
SkSetup sk_dilate_setup = [=](SkCanvas*, SkPaint& p) {
- p.setShader(kTestImageColorSource.skia_object());
+ p.setShader(kTestSkImageColorSource);
p.setStrokeWidth(5.0);
};
DlSetup dl_dilate_setup = [=](DlCanvas*, DlPaint& p) {
- p.setColorSource(&kTestImageColorSource);
+ p.setColorSource(&kTestDlImageColorSource);
p.setStrokeWidth(5.0);
};
dilate_env.init_ref(sk_dilate_setup, testP.sk_renderer(), //
dl_dilate_setup, testP.dl_renderer());
quickCompareToReference(dilate_env, "dilate");
- DlDilateImageFilter filter_5(5.0, 5.0);
+ DlDilateImageFilter dl_dilate_filter_5(5.0, 5.0);
+ auto sk_dilate_filter_5 = SkImageFilters::Dilate(5.0, 5.0, nullptr);
RenderWith(testP, dilate_env, tolerance,
CaseParameters(
"ImageFilter == Dilate 5",
[=](SkCanvas* cv, SkPaint& p) {
sk_dilate_setup(cv, p);
- p.setImageFilter(filter_5.skia_object());
+ p.setImageFilter(sk_dilate_filter_5);
},
[=](DlCanvas* cv, DlPaint& p) {
dl_dilate_setup(cv, p);
- p.setImageFilter(&filter_5);
+ p.setImageFilter(&dl_dilate_filter_5);
}));
}
@@ -1393,11 +1416,11 @@
// (for drawPaint) so we create a new environment for these tests.
RenderEnvironment erode_env = RenderEnvironment::MakeN32(env.provider());
SkSetup sk_erode_setup = [=](SkCanvas*, SkPaint& p) {
- p.setShader(kTestImageColorSource.skia_object());
+ p.setShader(kTestSkImageColorSource);
p.setStrokeWidth(6.0);
};
DlSetup dl_erode_setup = [=](DlCanvas*, DlPaint& p) {
- p.setColorSource(&kTestImageColorSource);
+ p.setColorSource(&kTestDlImageColorSource);
p.setStrokeWidth(6.0);
};
erode_env.init_ref(sk_erode_setup, testP.sk_renderer(), //
@@ -1405,17 +1428,18 @@
quickCompareToReference(erode_env, "erode");
// do not erode too much, because some tests assert there are enough
// pixels that are changed.
- DlErodeImageFilter filter_1(1.0, 1.0);
+ DlErodeImageFilter dl_erode_filter_1(1.0, 1.0);
+ auto sk_erode_filter_1 = SkImageFilters::Erode(1.0, 1.0, nullptr);
RenderWith(testP, erode_env, tolerance,
CaseParameters(
"ImageFilter == Erode 1",
[=](SkCanvas* cv, SkPaint& p) {
sk_erode_setup(cv, p);
- p.setImageFilter(filter_1.skia_object());
+ p.setImageFilter(sk_erode_filter_1);
},
[=](DlCanvas* cv, DlPaint& p) {
dl_erode_setup(cv, p);
- p.setImageFilter(&filter_1);
+ p.setImageFilter(&dl_erode_filter_1);
}));
}
@@ -1434,7 +1458,8 @@
1.0, 1.0, 1.0, 1.0, 0,
};
// clang-format on
- DlMatrixColorFilter filter(rotate_color_matrix);
+ DlMatrixColorFilter dl_color_filter(rotate_color_matrix);
+ auto sk_color_filter = SkColorFilters::Matrix(rotate_color_matrix);
{
DlColor bg = DlColor::kWhite();
RenderWith(testP, env, tolerance,
@@ -1442,34 +1467,35 @@
"ColorFilter == RotateRGB",
[=](SkCanvas*, SkPaint& p) {
p.setColor(DlColor::kYellow());
- p.setColorFilter(filter.skia_object());
+ p.setColorFilter(sk_color_filter);
},
[=](DlCanvas*, DlPaint& p) {
p.setColor(DlColor::kYellow());
- p.setColorFilter(&filter);
+ p.setColorFilter(&dl_color_filter);
})
.with_bg(bg));
}
- filter = DlMatrixColorFilter(invert_color_matrix);
{
DlColor bg = DlColor::kWhite();
- RenderWith(testP, env, tolerance,
- CaseParameters(
- "ColorFilter == Invert",
- [=](SkCanvas*, SkPaint& p) {
- p.setColor(DlColor::kYellow());
- p.setColorFilter(filter.skia_object());
- },
- [=](DlCanvas*, DlPaint& p) {
- p.setColor(DlColor::kYellow());
- p.setInvertColors(true);
- })
- .with_bg(bg));
+ RenderWith(
+ testP, env, tolerance,
+ CaseParameters(
+ "ColorFilter == Invert",
+ [=](SkCanvas*, SkPaint& p) {
+ p.setColor(DlColor::kYellow());
+ p.setColorFilter(SkColorFilters::Matrix(invert_color_matrix));
+ },
+ [=](DlCanvas*, DlPaint& p) {
+ p.setColor(DlColor::kYellow());
+ p.setInvertColors(true);
+ })
+ .with_bg(bg));
}
}
{
- const DlBlurMaskFilter filter(kNormal_SkBlurStyle, 5.0);
+ const DlBlurMaskFilter dl_mask_filter(kNormal_SkBlurStyle, 5.0);
+ auto sk_mask_filter = SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 5.0);
BoundsTolerance blur_5_tolerance = tolerance.addBoundsPadding(4, 4);
{
// Stroked primitives need some non-trivial stroke size to be blurred
@@ -1478,11 +1504,11 @@
"MaskFilter == Blur 5",
[=](SkCanvas*, SkPaint& p) {
p.setStrokeWidth(5.0);
- p.setMaskFilter(filter.skia_object());
+ p.setMaskFilter(sk_mask_filter);
},
[=](DlCanvas*, DlPaint& p) {
p.setStrokeWidth(5.0);
- p.setMaskFilter(&filter);
+ p.setMaskFilter(&dl_mask_filter);
}));
}
}
@@ -1492,27 +1518,33 @@
SkPoint::Make(kRenderBounds.fLeft, kRenderBounds.fTop),
SkPoint::Make(kRenderBounds.fRight, kRenderBounds.fBottom),
};
- DlColor colors[] = {
+ DlColor dl_colors[] = {
DlColor::kGreen(),
DlColor::kYellow().withAlpha(0x7f),
DlColor::kBlue(),
};
+ SkColor sk_colors[] = {
+ SK_ColorGREEN,
+ SkColorSetA(SK_ColorYELLOW, 0x7f),
+ SK_ColorBLUE,
+ };
float stops[] = {
0.0,
0.5,
1.0,
};
- std::shared_ptr<DlColorSource> source = DlColorSource::MakeLinear(
- end_points[0], end_points[1], 3, colors, stops, DlTileMode::kMirror);
+ auto dl_gradient =
+ DlColorSource::MakeLinear(end_points[0], end_points[1], 3, dl_colors,
+ stops, DlTileMode::kMirror);
+ auto sk_gradient = SkGradientShader::MakeLinear(
+ end_points, sk_colors, stops, 3, SkTileMode::kMirror, 0, nullptr);
{
RenderWith(
testP, env, tolerance,
CaseParameters(
"LinearGradient GYB",
- [=](SkCanvas*, SkPaint& p) {
- p.setShader(source->skia_object());
- },
- [=](DlCanvas*, DlPaint& p) { p.setColorSource(source); }));
+ [=](SkCanvas*, SkPaint& p) { p.setShader(sk_gradient); },
+ [=](DlCanvas*, DlPaint& p) { p.setColorSource(dl_gradient); }));
}
}
}
@@ -1697,7 +1729,8 @@
{
const SkScalar test_dashes_1[] = {29.0, 2.0};
const SkScalar test_dashes_2[] = {17.0, 1.5};
- auto effect = DlDashPathEffect::Make(test_dashes_1, 2, 0.0f);
+ auto dl_dash_effect = DlDashPathEffect::Make(test_dashes_1, 2, 0.0f);
+ auto sk_dash_effect = SkDashPathEffect::Make(test_dashes_1, 2, 0.0f);
{
RenderWith(testP, stroke_base_env, tolerance,
CaseParameters(
@@ -1705,12 +1738,12 @@
[=](SkCanvas*, SkPaint& p) {
// Provide some non-trivial stroke size to get dashed
p.setStrokeWidth(5.0);
- p.setPathEffect(effect->skia_object());
+ p.setPathEffect(sk_dash_effect);
},
[=](DlCanvas*, DlPaint& p) {
// Provide some non-trivial stroke size to get dashed
p.setStrokeWidth(5.0);
- p.setPathEffect(effect);
+ p.setPathEffect(dl_dash_effect);
}));
}
{
@@ -1722,17 +1755,18 @@
p.setStyle(SkPaint::kStroke_Style);
// Provide some non-trivial stroke size to get dashed
p.setStrokeWidth(5.0);
- p.setPathEffect(effect->skia_object());
+ p.setPathEffect(sk_dash_effect);
},
[=](DlCanvas*, DlPaint& p) {
// Need stroke style to see dashing properly
p.setDrawStyle(DlDrawStyle::kStroke);
// Provide some non-trivial stroke size to get dashed
p.setStrokeWidth(5.0);
- p.setPathEffect(effect);
+ p.setPathEffect(dl_dash_effect);
}));
}
- effect = DlDashPathEffect::Make(test_dashes_2, 2, 0.0f);
+ dl_dash_effect = DlDashPathEffect::Make(test_dashes_2, 2, 0.0f);
+ sk_dash_effect = SkDashPathEffect::Make(test_dashes_2, 2, 0.0f);
{
RenderWith(testP, stroke_base_env, tolerance,
CaseParameters(
@@ -1742,14 +1776,14 @@
p.setStyle(SkPaint::kStroke_Style);
// Provide some non-trivial stroke size to get dashed
p.setStrokeWidth(5.0);
- p.setPathEffect(effect->skia_object());
+ p.setPathEffect(sk_dash_effect);
},
[=](DlCanvas*, DlPaint& p) {
// Need stroke style to see dashing properly
p.setDrawStyle(DlDrawStyle::kStroke);
// Provide some non-trivial stroke size to get dashed
p.setStrokeWidth(5.0);
- p.setPathEffect(effect);
+ p.setPathEffect(dl_dash_effect);
}));
}
}
@@ -2178,6 +2212,23 @@
ASSERT_GT(pixels_touched, 0) << info;
}
+ static int countModifiedTransparentPixels(const RenderResult* ref_result,
+ const RenderResult* test_result) {
+ int count = 0;
+ for (int y = 0; y < kTestHeight; y++) {
+ const uint32_t* ref_row = ref_result->addr32(0, y);
+ const uint32_t* test_row = test_result->addr32(0, y);
+ for (int x = 0; x < kTestWidth; x++) {
+ if (ref_row[x] != test_row[x]) {
+ if (ref_row[x] == 0) {
+ count++;
+ }
+ }
+ }
+ }
+ return count;
+ }
+
static void quickCompareToReference(const RenderEnvironment& env,
const std::string& info) {
quickCompareToReference(env.ref_sk_result(), env.ref_dl_result(), true,
@@ -2198,7 +2249,7 @@
const uint32_t* test_row = test_result->addr32(0, y);
for (int x = 0; x < w; x++) {
if (ref_row[x] != test_row[x]) {
- if (should_match) {
+ if (should_match && pixels_different < 5) {
FML_LOG(ERROR) << std::hex << ref_row[x] << " != " << test_row[x];
}
pixels_different++;
@@ -2258,7 +2309,7 @@
bool match = fuzzyCompares ? fuzzyCompare(test_row[x], ref_row[x], 1)
: test_row[x] == ref_row[x];
if (!match) {
- if (printMismatches) {
+ if (printMismatches && pixels_different < 5) {
FML_LOG(ERROR) << "pix[" << x << ", " << y
<< "] mismatch: " << std::hex << test_row[x]
<< "(test) != (ref)" << ref_row[x] << std::dec;
@@ -2347,7 +2398,8 @@
return surface->makeImageSnapshot();
}
- static const DlImageColorSource kTestImageColorSource;
+ static const DlImageColorSource kTestDlImageColorSource;
+ static const sk_sp<SkShader> kTestSkImageColorSource;
static sk_sp<SkTextBlob> MakeTextBlob(const std::string& string,
SkScalar font_height) {
@@ -2365,11 +2417,15 @@
BoundsTolerance().addAbsolutePadding(1, 1);
const sk_sp<SkImage> CanvasCompareTester::kTestImage = makeTestImage();
-const DlImageColorSource CanvasCompareTester::kTestImageColorSource(
+const DlImageColorSource CanvasCompareTester::kTestDlImageColorSource(
DlImage::Make(kTestImage),
DlTileMode::kRepeat,
DlTileMode::kRepeat,
DlImageSampling::kLinear);
+const sk_sp<SkShader> CanvasCompareTester::kTestSkImageColorSource =
+ kTestImage->makeShader(SkTileMode::kRepeat,
+ SkTileMode::kRepeat,
+ SkImageSampling::kLinear);
// Eventually this bare bones testing::Test fixture will subsume the
// CanvasCompareTester and the TestParameters could then become just
@@ -2870,21 +2926,27 @@
SkPoint::Make(kRenderLeft, kRenderCenterY),
SkPoint::Make(kRenderRight, kRenderBottom),
};
- const DlColor colors[6] = {
+ const DlColor dl_colors[6] = {
+ DlColor::kRed(), DlColor::kBlue(), DlColor::kGreen(),
+ DlColor::kCyan(), DlColor::kYellow(), DlColor::kMagenta(),
+ };
+ const SkColor sk_colors[6] = {
SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN,
SK_ColorCYAN, SK_ColorYELLOW, SK_ColorMAGENTA,
};
- const std::shared_ptr<DlVertices> vertices =
- DlVertices::Make(DlVertexMode::kTriangles, 6, pts, nullptr, colors);
+ const std::shared_ptr<DlVertices> dl_vertices =
+ DlVertices::Make(DlVertexMode::kTriangles, 6, pts, nullptr, dl_colors);
+ const auto sk_vertices =
+ SkVertices::MakeCopy(SkVertices::VertexMode::kTriangles_VertexMode, 6,
+ pts, nullptr, sk_colors);
CanvasCompareTester::RenderAll( //
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) { //
- canvas->drawVertices(vertices->skia_object(), SkBlendMode::kSrcOver,
- paint);
+ canvas->drawVertices(sk_vertices, SkBlendMode::kSrcOver, paint);
},
[=](DlCanvas* canvas, const DlPaint& paint) { //
- canvas->DrawVertices(vertices, DlBlendMode::kSrcOver, paint);
+ canvas->DrawVertices(dl_vertices, DlBlendMode::kSrcOver, paint);
},
kDrawVerticesFlags));
}
@@ -2917,27 +2979,27 @@
SkPoint::Make(0, 0),
SkPoint::Make(kRenderWidth, 0),
};
- const std::shared_ptr<DlVertices> vertices =
+ const std::shared_ptr<DlVertices> dl_vertices =
DlVertices::Make(DlVertexMode::kTriangles, 6, pts, tex, nullptr);
+ const auto sk_vertices = SkVertices::MakeCopy(
+ SkVertices::VertexMode::kTriangles_VertexMode, 6, pts, tex, nullptr);
CanvasCompareTester::RenderAll( //
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) { //
SkPaint v_paint = paint;
if (v_paint.getShader() == nullptr) {
- v_paint.setShader(
- CanvasCompareTester::kTestImageColorSource.skia_object());
+ v_paint.setShader(CanvasCompareTester::kTestSkImageColorSource);
}
- canvas->drawVertices(vertices->skia_object(), SkBlendMode::kSrcOver,
- v_paint);
+ canvas->drawVertices(sk_vertices, SkBlendMode::kSrcOver, v_paint);
},
[=](DlCanvas* canvas, const DlPaint& paint) { //
DlPaint v_paint = paint;
if (v_paint.getColorSource() == nullptr) {
v_paint.setColorSource(
- &CanvasCompareTester::kTestImageColorSource);
+ &CanvasCompareTester::kTestDlImageColorSource);
}
- canvas->DrawVertices(vertices, DlBlendMode::kSrcOver, v_paint);
+ canvas->DrawVertices(dl_vertices, DlBlendMode::kSrcOver, v_paint);
},
kDrawVerticesFlags));
}
@@ -2948,7 +3010,7 @@
[=](SkCanvas* canvas, const SkPaint& paint) { //
canvas->drawImage(CanvasCompareTester::kTestImage, //
kRenderLeft, kRenderTop,
- ToSk(DlImageSampling::kNearestNeighbor), &paint);
+ SkImageSampling::kNearestNeighbor, &paint);
},
[=](DlCanvas* canvas, const DlPaint& paint) {
canvas->DrawImage(DlImage::Make(CanvasCompareTester::kTestImage),
@@ -2964,7 +3026,7 @@
[=](SkCanvas* canvas, const SkPaint& paint) { //
canvas->drawImage(CanvasCompareTester::kTestImage, //
kRenderLeft, kRenderTop,
- ToSk(DlImageSampling::kNearestNeighbor), nullptr);
+ SkImageSampling::kNearestNeighbor, nullptr);
},
[=](DlCanvas* canvas, const DlPaint& paint) {
canvas->DrawImage(DlImage::Make(CanvasCompareTester::kTestImage),
@@ -2979,8 +3041,8 @@
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) { //
canvas->drawImage(CanvasCompareTester::kTestImage, //
- kRenderLeft, kRenderTop,
- ToSk(DlImageSampling::kLinear), &paint);
+ kRenderLeft, kRenderTop, SkImageSampling::kLinear,
+ &paint);
},
[=](DlCanvas* canvas, const DlPaint& paint) {
canvas->DrawImage(DlImage::Make(CanvasCompareTester::kTestImage),
@@ -2997,13 +3059,14 @@
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) { //
canvas->drawImageRect(CanvasCompareTester::kTestImage, src, dst,
- ToSk(DlImageSampling::kNearestNeighbor),
- &paint, SkCanvas::kFast_SrcRectConstraint);
+ SkImageSampling::kNearestNeighbor, &paint,
+ SkCanvas::kFast_SrcRectConstraint);
},
[=](DlCanvas* canvas, const DlPaint& paint) { //
canvas->DrawImageRect(
DlImage::Make(CanvasCompareTester::kTestImage), src, dst,
- DlImageSampling::kNearestNeighbor, &paint, false);
+ DlImageSampling::kNearestNeighbor, &paint,
+ DlCanvas::SrcRectConstraint::kFast);
},
kDrawImageRectWithPaintFlags));
}
@@ -3015,13 +3078,14 @@
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) { //
canvas->drawImageRect(CanvasCompareTester::kTestImage, src, dst,
- ToSk(DlImageSampling::kNearestNeighbor),
- nullptr, SkCanvas::kFast_SrcRectConstraint);
+ SkImageSampling::kNearestNeighbor, nullptr,
+ SkCanvas::kFast_SrcRectConstraint);
},
[=](DlCanvas* canvas, const DlPaint& paint) { //
canvas->DrawImageRect(
DlImage::Make(CanvasCompareTester::kTestImage), src, dst,
- DlImageSampling::kNearestNeighbor, nullptr, false);
+ DlImageSampling::kNearestNeighbor, nullptr,
+ DlCanvas::SrcRectConstraint::kFast);
},
kDrawImageRectFlags));
}
@@ -3033,13 +3097,14 @@
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) { //
canvas->drawImageRect(CanvasCompareTester::kTestImage, src, dst,
- ToSk(DlImageSampling::kLinear), &paint,
+ SkImageSampling::kLinear, &paint,
SkCanvas::kFast_SrcRectConstraint);
},
[=](DlCanvas* canvas, const DlPaint& paint) { //
canvas->DrawImageRect(
DlImage::Make(CanvasCompareTester::kTestImage), src, dst,
- DlImageSampling::kLinear, &paint, false);
+ DlImageSampling::kLinear, &paint,
+ DlCanvas::SrcRectConstraint::kFast);
},
kDrawImageRectWithPaintFlags));
}
@@ -3125,17 +3190,19 @@
DlColor::kMagenta(),
};
const sk_sp<SkImage> image = CanvasCompareTester::kTestImage;
- const DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
+ const DlImageSampling dl_sampling = DlImageSampling::kNearestNeighbor;
+ const SkSamplingOptions sk_sampling = SkImageSampling::kNearestNeighbor;
CanvasCompareTester::RenderAll( //
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) {
canvas->drawAtlas(image.get(), xform, tex, sk_colors, 4,
- SkBlendMode::kSrcOver, ToSk(sampling), nullptr,
+ SkBlendMode::kSrcOver, sk_sampling, nullptr,
&paint);
},
[=](DlCanvas* canvas, const DlPaint& paint) {
canvas->DrawAtlas(DlImage::Make(image), xform, tex, dl_colors, 4,
- DlBlendMode::kSrcOver, sampling, nullptr, &paint);
+ DlBlendMode::kSrcOver, dl_sampling, nullptr,
+ &paint);
},
kDrawAtlasWithPaintFlags));
}
@@ -3170,17 +3237,18 @@
DlColor::kMagenta(),
};
const sk_sp<SkImage> image = CanvasCompareTester::kTestImage;
- const DlImageSampling sampling = DlImageSampling::kNearestNeighbor;
+ const DlImageSampling dl_sampling = DlImageSampling::kNearestNeighbor;
+ const SkSamplingOptions sk_sampling = SkImageSampling::kNearestNeighbor;
CanvasCompareTester::RenderAll( //
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) {
canvas->drawAtlas(image.get(), xform, tex, sk_colors, 4,
- SkBlendMode::kSrcOver, ToSk(sampling), //
+ SkBlendMode::kSrcOver, sk_sampling, //
nullptr, nullptr);
},
[=](DlCanvas* canvas, const DlPaint& paint) {
canvas->DrawAtlas(DlImage::Make(image), xform, tex, dl_colors, 4,
- DlBlendMode::kSrcOver, sampling, nullptr,
+ DlBlendMode::kSrcOver, dl_sampling, nullptr,
nullptr);
},
kDrawAtlasFlags));
@@ -3216,34 +3284,39 @@
DlColor::kMagenta(),
};
const sk_sp<SkImage> image = CanvasCompareTester::kTestImage;
- const DlImageSampling sampling = DlImageSampling::kLinear;
+ const DlImageSampling dl_sampling = DlImageSampling::kLinear;
+ const SkSamplingOptions sk_sampling = SkImageSampling::kLinear;
CanvasCompareTester::RenderAll( //
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) {
canvas->drawAtlas(image.get(), xform, tex, sk_colors, 2, //
- SkBlendMode::kSrcOver, ToSk(sampling), nullptr,
+ SkBlendMode::kSrcOver, sk_sampling, nullptr,
&paint);
},
[=](DlCanvas* canvas, const DlPaint& paint) {
canvas->DrawAtlas(DlImage::Make(image), xform, tex, dl_colors, 2,
- DlBlendMode::kSrcOver, sampling, nullptr, &paint);
+ DlBlendMode::kSrcOver, dl_sampling, nullptr,
+ &paint);
},
kDrawAtlasWithPaintFlags));
}
sk_sp<DisplayList> makeTestDisplayList() {
DisplayListBuilder builder;
- builder.setStyle(DlDrawStyle::kFill);
- builder.setColor(SK_ColorRED);
- builder.drawRect({kRenderLeft, kRenderTop, kRenderCenterX, kRenderCenterY});
- builder.setColor(SK_ColorBLUE);
- builder.drawRect({kRenderCenterX, kRenderTop, kRenderRight, kRenderCenterY});
- builder.setColor(SK_ColorGREEN);
- builder.drawRect(
- {kRenderLeft, kRenderCenterY, kRenderCenterX, kRenderBottom});
- builder.setColor(SK_ColorYELLOW);
- builder.drawRect(
- {kRenderCenterX, kRenderCenterY, kRenderRight, kRenderBottom});
+ DlPaint paint;
+ paint.setDrawStyle(DlDrawStyle::kFill);
+ paint.setColor(SK_ColorRED);
+ builder.DrawRect({kRenderLeft, kRenderTop, kRenderCenterX, kRenderCenterY},
+ paint);
+ paint.setColor(SK_ColorBLUE);
+ builder.DrawRect({kRenderCenterX, kRenderTop, kRenderRight, kRenderCenterY},
+ paint);
+ paint.setColor(SK_ColorGREEN);
+ builder.DrawRect({kRenderLeft, kRenderCenterY, kRenderCenterX, kRenderBottom},
+ paint);
+ paint.setColor(SK_ColorYELLOW);
+ builder.DrawRect(
+ {kRenderCenterX, kRenderCenterY, kRenderRight, kRenderBottom}, paint);
return builder.Build();
}
@@ -3252,7 +3325,7 @@
CanvasCompareTester::RenderAll( //
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) { //
- display_list->RenderTo(canvas);
+ DlSkCanvasAdapter(canvas).DrawDisplayList(display_list);
},
[=](DlCanvas* canvas, const DlPaint& paint) { //
canvas->DrawDisplayList(display_list);
@@ -3310,8 +3383,8 @@
CanvasCompareTester::RenderAll( //
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) { //
- DisplayListCanvasDispatcher::DrawShadow(canvas, path, color,
- elevation, false, 1.0);
+ DlSkCanvasDispatcher::DrawShadow(canvas, path, color, elevation,
+ false, 1.0);
},
[=](DlCanvas* canvas, const DlPaint& paint) { //
canvas->DrawShadow(path, color, elevation, false, 1.0);
@@ -3336,8 +3409,8 @@
CanvasCompareTester::RenderAll( //
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) { //
- DisplayListCanvasDispatcher::DrawShadow(canvas, path, color,
- elevation, true, 1.0);
+ DlSkCanvasDispatcher::DrawShadow(canvas, path, color, elevation,
+ true, 1.0);
},
[=](DlCanvas* canvas, const DlPaint& paint) { //
canvas->DrawShadow(path, color, elevation, true, 1.0);
@@ -3362,8 +3435,8 @@
CanvasCompareTester::RenderAll( //
TestParameters(
[=](SkCanvas* canvas, const SkPaint& paint) { //
- DisplayListCanvasDispatcher::DrawShadow(canvas, path, color,
- elevation, false, 1.5);
+ DlSkCanvasDispatcher::DrawShadow(canvas, path, color, elevation,
+ false, 1.5);
},
[=](DlCanvas* canvas, const DlPaint& paint) { //
canvas->DrawShadow(path, color, elevation, false, 1.5);
@@ -3555,5 +3628,317 @@
}
}
+TEST_F(DisplayListCanvas, MatrixColorFilterModifyTransparencyCheck) {
+ std::vector<std::unique_ptr<RenderEnvironment>> environments;
+ for (auto& provider : CanvasCompareTester::kTestProviders) {
+ auto env = std::make_unique<RenderEnvironment>(
+ provider.get(), PixelFormat::kN32Premul_PixelFormat);
+ environments.push_back(std::move(env));
+ }
+
+ auto test_matrix = [&environments](int element, SkScalar value) {
+ // clang-format off
+ float matrix[] = {
+ 1, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0,
+ };
+ // clang-format on
+ std::string desc =
+ "matrix[" + std::to_string(element) + "] = " + std::to_string(value);
+ float original_value = matrix[element];
+ matrix[element] = value;
+ DlMatrixColorFilter filter(matrix);
+ auto dl_filter = DlMatrixColorFilter::Make(matrix);
+ bool is_identity = (dl_filter == nullptr || original_value == value);
+
+ DlPaint paint(0x7f7f7f7f);
+ DlPaint filter_save_paint = DlPaint().setColorFilter(&filter);
+
+ DisplayListBuilder builder1;
+ builder1.Translate(kTestCenter.fX, kTestCenter.fY);
+ builder1.Rotate(45);
+ builder1.Translate(-kTestCenter.fX, -kTestCenter.fY);
+ builder1.DrawRect(kRenderBounds, paint);
+ auto display_list1 = builder1.Build();
+
+ DisplayListBuilder builder2;
+ builder2.Translate(kTestCenter.fX, kTestCenter.fY);
+ builder2.Rotate(45);
+ builder2.Translate(-kTestCenter.fX, -kTestCenter.fY);
+ builder2.SaveLayer(&kTestBounds, &filter_save_paint);
+ builder2.DrawRect(kRenderBounds, paint);
+ builder2.Restore();
+ auto display_list2 = builder2.Build();
+
+ for (auto& env : environments) {
+ auto results1 = env->getResult(display_list1);
+ auto results2 = env->getResult(display_list2);
+ CanvasCompareTester::quickCompareToReference(
+ results1.get(), results2.get(), is_identity,
+ desc + " filter affects rendering");
+ int modified_transparent_pixels =
+ CanvasCompareTester::countModifiedTransparentPixels(results1.get(),
+ results2.get());
+ EXPECT_EQ(filter.modifies_transparent_black(),
+ modified_transparent_pixels != 0)
+ << desc;
+ }
+ };
+
+ // Tests identity (matrix[0] already == 1 in an identity filter)
+ test_matrix(0, 1);
+ // test_matrix(19, 1);
+ for (int i = 0; i < 20; i++) {
+ test_matrix(i, -0.25);
+ test_matrix(i, 0);
+ test_matrix(i, 0.25);
+ test_matrix(i, 1);
+ test_matrix(i, 1.25);
+ test_matrix(i, SK_ScalarNaN);
+ test_matrix(i, SK_ScalarInfinity);
+ test_matrix(i, -SK_ScalarInfinity);
+ }
+}
+
+TEST_F(DisplayListCanvas, MatrixColorFilterOpacityCommuteCheck) {
+ std::vector<std::unique_ptr<RenderEnvironment>> environments;
+ for (auto& provider : CanvasCompareTester::kTestProviders) {
+ auto env = std::make_unique<RenderEnvironment>(
+ provider.get(), PixelFormat::kN32Premul_PixelFormat);
+ environments.push_back(std::move(env));
+ }
+
+ auto test_matrix = [&environments](int element, SkScalar value) {
+ // clang-format off
+ float matrix[] = {
+ 1, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0,
+ };
+ // clang-format on
+ std::string desc =
+ "matrix[" + std::to_string(element) + "] = " + std::to_string(value);
+ matrix[element] = value;
+ auto filter = DlMatrixColorFilter::Make(matrix);
+ EXPECT_EQ(SkScalarIsFinite(value), filter != nullptr);
+
+ DlPaint paint(0x80808080);
+ DlPaint opacity_save_paint = DlPaint().setOpacity(0.5);
+ DlPaint filter_save_paint = DlPaint().setColorFilter(filter);
+
+ DisplayListBuilder builder1;
+ builder1.SaveLayer(&kTestBounds, &opacity_save_paint);
+ builder1.SaveLayer(&kTestBounds, &filter_save_paint);
+ // builder1.DrawRect(kRenderBounds.makeOffset(20, 20), DlPaint());
+ builder1.DrawRect(kRenderBounds, paint);
+ builder1.Restore();
+ builder1.Restore();
+ auto display_list1 = builder1.Build();
+
+ DisplayListBuilder builder2;
+ builder2.SaveLayer(&kTestBounds, &filter_save_paint);
+ builder2.SaveLayer(&kTestBounds, &opacity_save_paint);
+ // builder1.DrawRect(kRenderBounds.makeOffset(20, 20), DlPaint());
+ builder2.DrawRect(kRenderBounds, paint);
+ builder2.Restore();
+ builder2.Restore();
+ auto display_list2 = builder2.Build();
+
+ for (auto& env : environments) {
+ auto results1 = env->getResult(display_list1);
+ auto results2 = env->getResult(display_list2);
+ if (!filter || filter->can_commute_with_opacity()) {
+ CanvasCompareTester::compareToReference(
+ results2.get(), results1.get(), desc, nullptr, nullptr,
+ DlColor::kTransparent(), true, kTestWidth, kTestHeight, true);
+ } else {
+ CanvasCompareTester::quickCompareToReference(
+ results1.get(), results2.get(), false, desc);
+ }
+ }
+ };
+
+ // Tests identity (matrix[0] already == 1 in an identity filter)
+ test_matrix(0, 1);
+ // test_matrix(19, 1);
+ for (int i = 0; i < 20; i++) {
+ test_matrix(i, -0.25);
+ test_matrix(i, 0);
+ test_matrix(i, 0.25);
+ test_matrix(i, 1);
+ test_matrix(i, 1.1);
+ test_matrix(i, SK_ScalarNaN);
+ test_matrix(i, SK_ScalarInfinity);
+ test_matrix(i, -SK_ScalarInfinity);
+ }
+}
+
+#define FOR_EACH_BLEND_MODE_ENUM(FUNC) \
+ FUNC(kSrc) \
+ FUNC(kClear) \
+ FUNC(kSrc) \
+ FUNC(kDst) \
+ FUNC(kSrcOver) \
+ FUNC(kDstOver) \
+ FUNC(kSrcIn) \
+ FUNC(kDstIn) \
+ FUNC(kSrcOut) \
+ FUNC(kDstOut) \
+ FUNC(kSrcATop) \
+ FUNC(kDstATop) \
+ FUNC(kXor) \
+ FUNC(kPlus) \
+ FUNC(kModulate) \
+ FUNC(kScreen) \
+ FUNC(kOverlay) \
+ FUNC(kDarken) \
+ FUNC(kLighten) \
+ FUNC(kColorDodge) \
+ FUNC(kColorBurn) \
+ FUNC(kHardLight) \
+ FUNC(kSoftLight) \
+ FUNC(kDifference) \
+ FUNC(kExclusion) \
+ FUNC(kMultiply) \
+ FUNC(kHue) \
+ FUNC(kSaturation) \
+ FUNC(kColor) \
+ FUNC(kLuminosity)
+
+TEST_F(DisplayListCanvas, BlendColorFilterModifyTransparencyCheck) {
+ std::vector<std::unique_ptr<RenderEnvironment>> environments;
+ for (auto& provider : CanvasCompareTester::kTestProviders) {
+ auto env = std::make_unique<RenderEnvironment>(
+ provider.get(), PixelFormat::kN32Premul_PixelFormat);
+ environments.push_back(std::move(env));
+ }
+
+ auto test_mode_color = [&environments](DlBlendMode mode, DlColor color) {
+ std::stringstream desc_str;
+ desc_str << "blend[" << mode << ", " << color << "]";
+ std::string desc = desc_str.str();
+ DlBlendColorFilter filter(color, mode);
+ if (filter.modifies_transparent_black()) {
+ ASSERT_NE(DlBlendColorFilter::Make(color, mode), nullptr) << desc;
+ }
+
+ DlPaint paint(0x7f7f7f7f);
+ DlPaint filter_save_paint = DlPaint().setColorFilter(&filter);
+
+ DisplayListBuilder builder1;
+ builder1.Translate(kTestCenter.fX, kTestCenter.fY);
+ builder1.Rotate(45);
+ builder1.Translate(-kTestCenter.fX, -kTestCenter.fY);
+ builder1.DrawRect(kRenderBounds, paint);
+ auto display_list1 = builder1.Build();
+
+ DisplayListBuilder builder2;
+ builder2.Translate(kTestCenter.fX, kTestCenter.fY);
+ builder2.Rotate(45);
+ builder2.Translate(-kTestCenter.fX, -kTestCenter.fY);
+ builder2.SaveLayer(&kTestBounds, &filter_save_paint);
+ builder2.DrawRect(kRenderBounds, paint);
+ builder2.Restore();
+ auto display_list2 = builder2.Build();
+
+ for (auto& env : environments) {
+ auto results1 = env->getResult(display_list1);
+ auto results2 = env->getResult(display_list2);
+ int modified_transparent_pixels =
+ CanvasCompareTester::countModifiedTransparentPixels(results1.get(),
+ results2.get());
+ EXPECT_EQ(filter.modifies_transparent_black(),
+ modified_transparent_pixels != 0)
+ << desc;
+ }
+ };
+
+ auto test_mode = [&test_mode_color](DlBlendMode mode) {
+ test_mode_color(mode, DlColor::kTransparent());
+ test_mode_color(mode, DlColor::kWhite());
+ test_mode_color(mode, DlColor::kWhite().modulateOpacity(0.5));
+ test_mode_color(mode, DlColor::kBlack());
+ test_mode_color(mode, DlColor::kBlack().modulateOpacity(0.5));
+ };
+
+#define TEST_MODE(V) test_mode(DlBlendMode::V);
+ FOR_EACH_BLEND_MODE_ENUM(TEST_MODE)
+#undef TEST_MODE
+}
+
+TEST_F(DisplayListCanvas, BlendColorFilterOpacityCommuteCheck) {
+ std::vector<std::unique_ptr<RenderEnvironment>> environments;
+ for (auto& provider : CanvasCompareTester::kTestProviders) {
+ auto env = std::make_unique<RenderEnvironment>(
+ provider.get(), PixelFormat::kN32Premul_PixelFormat);
+ environments.push_back(std::move(env));
+ }
+
+ auto test_mode_color = [&environments](DlBlendMode mode, DlColor color) {
+ std::stringstream desc_str;
+ desc_str << "blend[" << mode << ", " << color << "]";
+ std::string desc = desc_str.str();
+ DlBlendColorFilter filter(color, mode);
+ if (filter.can_commute_with_opacity()) {
+ // If it can commute with opacity, then it might also be a NOP,
+ // so we won't necessarily get a non-null return from |::Make()|
+ } else {
+ ASSERT_NE(DlBlendColorFilter::Make(color, mode), nullptr) << desc;
+ }
+
+ DlPaint paint(0x80808080);
+ DlPaint opacity_save_paint = DlPaint().setOpacity(0.5);
+ DlPaint filter_save_paint = DlPaint().setColorFilter(&filter);
+
+ DisplayListBuilder builder1;
+ builder1.SaveLayer(&kTestBounds, &opacity_save_paint);
+ builder1.SaveLayer(&kTestBounds, &filter_save_paint);
+ // builder1.DrawRect(kRenderBounds.makeOffset(20, 20), DlPaint());
+ builder1.DrawRect(kRenderBounds, paint);
+ builder1.Restore();
+ builder1.Restore();
+ auto display_list1 = builder1.Build();
+
+ DisplayListBuilder builder2;
+ builder2.SaveLayer(&kTestBounds, &filter_save_paint);
+ builder2.SaveLayer(&kTestBounds, &opacity_save_paint);
+ // builder1.DrawRect(kRenderBounds.makeOffset(20, 20), DlPaint());
+ builder2.DrawRect(kRenderBounds, paint);
+ builder2.Restore();
+ builder2.Restore();
+ auto display_list2 = builder2.Build();
+
+ for (auto& env : environments) {
+ auto results1 = env->getResult(display_list1);
+ auto results2 = env->getResult(display_list2);
+ if (filter.can_commute_with_opacity()) {
+ CanvasCompareTester::compareToReference(
+ results2.get(), results1.get(), desc, nullptr, nullptr,
+ DlColor::kTransparent(), true, kTestWidth, kTestHeight, true);
+ } else {
+ CanvasCompareTester::quickCompareToReference(
+ results1.get(), results2.get(), false, desc);
+ }
+ }
+ };
+
+ auto test_mode = [&test_mode_color](DlBlendMode mode) {
+ test_mode_color(mode, DlColor::kTransparent());
+ test_mode_color(mode, DlColor::kWhite());
+ test_mode_color(mode, DlColor::kWhite().modulateOpacity(0.5));
+ test_mode_color(mode, DlColor::kBlack());
+ test_mode_color(mode, DlColor::kBlack().modulateOpacity(0.5));
+ };
+
+#define TEST_MODE(V) test_mode(DlBlendMode::V);
+ FOR_EACH_BLEND_MODE_ENUM(TEST_MODE)
+#undef TEST_MODE
+}
+
+#undef FOR_EACH_ENUM
+
} // namespace testing
} // namespace flutter
diff --git a/display_list/skia/dl_sk_canvas.cc b/display_list/skia/dl_sk_canvas.cc
index f7a0de8..7f73e05 100644
--- a/display_list/skia/dl_sk_canvas.cc
+++ b/display_list/skia/dl_sk_canvas.cc
@@ -4,43 +4,12 @@
#include "flutter/display_list/skia/dl_sk_canvas.h"
-#include "flutter/display_list/display_list_canvas_dispatcher.h"
+#include "flutter/display_list/skia/dl_sk_conversions.h"
+#include "flutter/display_list/skia/dl_sk_dispatcher.h"
+#include "flutter/fml/trace_event.h"
namespace flutter {
-static sk_sp<SkShader> ToSk(const DlColorSource* source) {
- return source ? source->skia_object() : nullptr;
-}
-
-static sk_sp<SkImageFilter> ToSk(const DlImageFilter* filter) {
- return filter ? filter->skia_object() : nullptr;
-}
-
-static sk_sp<SkColorFilter> ToSk(const DlColorFilter* filter) {
- return filter ? filter->skia_object() : nullptr;
-}
-
-static sk_sp<SkMaskFilter> ToSk(const DlMaskFilter* filter) {
- return filter ? filter->skia_object() : nullptr;
-}
-
-static sk_sp<SkPathEffect> ToSk(const DlPathEffect* effect) {
- return effect ? effect->skia_object() : nullptr;
-}
-
-static SkCanvas::SrcRectConstraint ToSkConstraint(bool enforce_edges) {
- return enforce_edges ? SkCanvas::kStrict_SrcRectConstraint
- : SkCanvas::kFast_SrcRectConstraint;
-}
-
-static SkClipOp ToSk(DlCanvas::ClipOp op) {
- return static_cast<SkClipOp>(op);
-}
-
-static SkCanvas::PointMode ToSk(DlCanvas::PointMode mode) {
- return static_cast<SkCanvas::PointMode>(mode);
-}
-
// clang-format off
constexpr float kInvertColorMatrix[20] = {
-1.0, 0, 0, 1.0, 0,
@@ -119,10 +88,11 @@
void DlSkCanvasAdapter::SaveLayer(const SkRect* bounds,
const DlPaint* paint,
const DlImageFilter* backdrop) {
- sk_sp<SkImageFilter> sk_filter = backdrop ? backdrop->skia_object() : nullptr;
+ sk_sp<SkImageFilter> sk_backdrop = ToSk(backdrop);
SkOptionalPaint sk_paint(paint);
+ TRACE_EVENT0("flutter", "Canvas::saveLayer");
delegate_->saveLayer(
- SkCanvas::SaveLayerRec{bounds, sk_paint(), sk_filter.get(), 0});
+ SkCanvas::SaveLayerRec{bounds, sk_paint(), sk_backdrop.get(), 0});
}
void DlSkCanvasAdapter::Restore() {
@@ -309,7 +279,7 @@
void DlSkCanvasAdapter::DrawVertices(const DlVertices* vertices,
DlBlendMode mode,
const DlPaint& paint) {
- delegate_->drawVertices(vertices->skia_object(), ToSk(mode), ToSk(paint));
+ delegate_->drawVertices(ToSk(vertices), ToSk(mode), ToSk(paint));
}
void DlSkCanvasAdapter::DrawImage(const sk_sp<DlImage>& image,
@@ -327,11 +297,11 @@
const SkRect& dst,
DlImageSampling sampling,
const DlPaint* paint,
- bool enforce_src_edges) {
+ SrcRectConstraint constraint) {
SkOptionalPaint sk_paint(paint);
sk_sp<SkImage> sk_image = image->skia_image();
delegate_->drawImageRect(sk_image.get(), src, dst, ToSk(sampling), sk_paint(),
- ToSkConstraint(enforce_src_edges));
+ ToSk(constraint));
}
void DlSkCanvasAdapter::DrawImageNine(const sk_sp<DlImage>& image,
@@ -363,7 +333,26 @@
void DlSkCanvasAdapter::DrawDisplayList(const sk_sp<DisplayList> display_list,
SkScalar opacity) {
- display_list->RenderTo(delegate_, opacity);
+ const int restore_count = delegate_->getSaveCount();
+
+ // Figure out whether we can apply the opacity during dispatch or
+ // if we need a saveLayer.
+ if (opacity < SK_Scalar1 && !display_list->can_apply_group_opacity()) {
+ TRACE_EVENT0("flutter", "Canvas::saveLayer");
+ delegate_->saveLayerAlphaf(&display_list->bounds(), opacity);
+ opacity = SK_Scalar1;
+ } else {
+ delegate_->save();
+ }
+
+ DlSkCanvasDispatcher dispatcher(delegate_, opacity);
+ if (display_list->has_rtree()) {
+ display_list->Dispatch(dispatcher, delegate_->getLocalClipBounds());
+ } else {
+ display_list->Dispatch(dispatcher);
+ }
+
+ delegate_->restoreToCount(restore_count);
}
void DlSkCanvasAdapter::DrawTextBlob(const sk_sp<SkTextBlob>& blob,
@@ -378,8 +367,8 @@
const SkScalar elevation,
bool transparent_occluder,
SkScalar dpr) {
- DisplayListCanvasDispatcher::DrawShadow(delegate_, path, color, elevation,
- transparent_occluder, dpr);
+ DlSkCanvasDispatcher::DrawShadow(delegate_, path, color, elevation,
+ transparent_occluder, dpr);
}
void DlSkCanvasAdapter::Flush() {
diff --git a/display_list/skia/dl_sk_canvas.h b/display_list/skia/dl_sk_canvas.h
index 249e518..fc66bcc 100644
--- a/display_list/skia/dl_sk_canvas.h
+++ b/display_list/skia/dl_sk_canvas.h
@@ -114,12 +114,13 @@
const SkPoint point,
DlImageSampling sampling,
const DlPaint* paint = nullptr) override;
- void DrawImageRect(const sk_sp<DlImage>& image,
- const SkRect& src,
- const SkRect& dst,
- DlImageSampling sampling,
- const DlPaint* paint = nullptr,
- bool enforce_src_edges = false) override;
+ void DrawImageRect(
+ const sk_sp<DlImage>& image,
+ const SkRect& src,
+ const SkRect& dst,
+ DlImageSampling sampling,
+ const DlPaint* paint = nullptr,
+ SrcRectConstraint constraint = SrcRectConstraint::kFast) override;
void DrawImageNine(const sk_sp<DlImage>& image,
const SkIRect& center,
const SkRect& dst,
@@ -135,7 +136,7 @@
const SkRect* cullRect,
const DlPaint* paint = nullptr) override;
void DrawDisplayList(const sk_sp<DisplayList> display_list,
- SkScalar opacity) override;
+ SkScalar opacity = SK_Scalar1) override;
void DrawTextBlob(const sk_sp<SkTextBlob>& blob,
SkScalar x,
SkScalar y,
diff --git a/display_list/skia/dl_sk_conversions.cc b/display_list/skia/dl_sk_conversions.cc
new file mode 100644
index 0000000..e8dd4cf
--- /dev/null
+++ b/display_list/skia/dl_sk_conversions.cc
@@ -0,0 +1,240 @@
+// 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/skia/dl_sk_conversions.h"
+
+namespace flutter {
+
+sk_sp<SkShader> ToSk(const DlColorSource* source) {
+ if (!source) {
+ return nullptr;
+ }
+ static auto ToSkColors = [](const DlGradientColorSourceBase* gradient) {
+ return reinterpret_cast<const SkColor*>(gradient->colors());
+ };
+ switch (source->type()) {
+ case DlColorSourceType::kColor: {
+ const DlColorColorSource* color_source = source->asColor();
+ FML_DCHECK(color_source != nullptr);
+ return SkShaders::Color(color_source->color());
+ }
+ case DlColorSourceType::kImage: {
+ const DlImageColorSource* image_source = source->asImage();
+ FML_DCHECK(image_source != nullptr);
+ auto image = image_source->image();
+ if (!image || !image->skia_image()) {
+ return nullptr;
+ }
+ return image->skia_image()->makeShader(
+ ToSk(image_source->horizontal_tile_mode()),
+ ToSk(image_source->vertical_tile_mode()),
+ ToSk(image_source->sampling()), image_source->matrix_ptr());
+ }
+ case DlColorSourceType::kLinearGradient: {
+ const DlLinearGradientColorSource* linear_source =
+ source->asLinearGradient();
+ FML_DCHECK(linear_source != nullptr);
+ SkPoint pts[] = {linear_source->start_point(),
+ linear_source->end_point()};
+ return SkGradientShader::MakeLinear(
+ pts, ToSkColors(linear_source), linear_source->stops(),
+ linear_source->stop_count(), ToSk(linear_source->tile_mode()), 0,
+ linear_source->matrix_ptr());
+ }
+ case DlColorSourceType::kRadialGradient: {
+ const DlRadialGradientColorSource* radial_source =
+ source->asRadialGradient();
+ FML_DCHECK(radial_source != nullptr);
+ return SkGradientShader::MakeRadial(
+ radial_source->center(), radial_source->radius(),
+ ToSkColors(radial_source), radial_source->stops(),
+ radial_source->stop_count(), ToSk(radial_source->tile_mode()), 0,
+ radial_source->matrix_ptr());
+ }
+ case DlColorSourceType::kConicalGradient: {
+ const DlConicalGradientColorSource* conical_source =
+ source->asConicalGradient();
+ FML_DCHECK(conical_source != nullptr);
+ return SkGradientShader::MakeTwoPointConical(
+ conical_source->start_center(), conical_source->start_radius(),
+ conical_source->end_center(), conical_source->end_radius(),
+ ToSkColors(conical_source), conical_source->stops(),
+ conical_source->stop_count(), ToSk(conical_source->tile_mode()), 0,
+ conical_source->matrix_ptr());
+ }
+ case DlColorSourceType::kSweepGradient: {
+ const DlSweepGradientColorSource* sweep_source =
+ source->asSweepGradient();
+ FML_DCHECK(sweep_source != nullptr);
+ return SkGradientShader::MakeSweep(
+ sweep_source->center().x(), sweep_source->center().y(),
+ ToSkColors(sweep_source), sweep_source->stops(),
+ sweep_source->stop_count(), ToSk(sweep_source->tile_mode()),
+ sweep_source->start(), sweep_source->end(), 0,
+ sweep_source->matrix_ptr());
+ }
+ case DlColorSourceType::kRuntimeEffect: {
+ const DlRuntimeEffectColorSource* runtime_source =
+ source->asRuntimeEffect();
+ FML_DCHECK(runtime_source != nullptr);
+ auto runtime_effect = runtime_source->runtime_effect();
+ if (!runtime_effect || !runtime_effect->skia_runtime_effect()) {
+ return nullptr;
+ }
+
+ auto samplers = runtime_source->samplers();
+ std::vector<sk_sp<SkShader>> sk_samplers(samplers.size());
+ for (size_t i = 0; i < samplers.size(); i++) {
+ auto sampler = samplers[i];
+ if (sampler == nullptr) {
+ return nullptr;
+ }
+ sk_samplers[i] = ToSk(sampler);
+ }
+
+ auto uniform_data = runtime_source->uniform_data();
+ auto ref = new std::shared_ptr<std::vector<uint8_t>>(uniform_data);
+ auto sk_uniform_data = SkData::MakeWithProc(
+ uniform_data->data(), uniform_data->size(),
+ [](const void* ptr, void* context) {
+ delete reinterpret_cast<std::shared_ptr<std::vector<uint8_t>>*>(
+ context);
+ },
+ ref);
+
+ return runtime_effect->skia_runtime_effect()->makeShader(
+ sk_uniform_data, sk_samplers.data(), sk_samplers.size());
+ }
+#ifdef IMPELLER_ENABLE_3D
+ case DlColorSourceType::kScene: {
+ return nullptr;
+ }
+#endif // IMPELLER_ENABLE_3D
+ }
+}
+
+sk_sp<SkImageFilter> ToSk(const DlImageFilter* filter) {
+ if (!filter) {
+ return nullptr;
+ }
+ switch (filter->type()) {
+ case DlImageFilterType::kBlur: {
+ const DlBlurImageFilter* blur_filter = filter->asBlur();
+ FML_DCHECK(blur_filter != nullptr);
+ return SkImageFilters::Blur(blur_filter->sigma_x(),
+ blur_filter->sigma_y(),
+ ToSk(blur_filter->tile_mode()), nullptr);
+ }
+ case DlImageFilterType::kDilate: {
+ const DlDilateImageFilter* dilate_filter = filter->asDilate();
+ FML_DCHECK(dilate_filter != nullptr);
+ return SkImageFilters::Dilate(dilate_filter->radius_x(),
+ dilate_filter->radius_y(), nullptr);
+ }
+ case DlImageFilterType::kErode: {
+ const DlErodeImageFilter* erode_filter = filter->asErode();
+ FML_DCHECK(erode_filter != nullptr);
+ return SkImageFilters::Erode(erode_filter->radius_x(),
+ erode_filter->radius_y(), nullptr);
+ }
+ case DlImageFilterType::kMatrix: {
+ const DlMatrixImageFilter* matrix_filter = filter->asMatrix();
+ FML_DCHECK(matrix_filter != nullptr);
+ return SkImageFilters::MatrixTransform(
+ matrix_filter->matrix(), ToSk(matrix_filter->sampling()), nullptr);
+ }
+ case DlImageFilterType::kCompose: {
+ const DlComposeImageFilter* compose_filter = filter->asCompose();
+ FML_DCHECK(compose_filter != nullptr);
+ return SkImageFilters::Compose(ToSk(compose_filter->outer()),
+ ToSk(compose_filter->inner()));
+ }
+ case DlImageFilterType::kColorFilter: {
+ const DlColorFilterImageFilter* cf_filter = filter->asColorFilter();
+ FML_DCHECK(cf_filter != nullptr);
+ return SkImageFilters::ColorFilter(ToSk(cf_filter->color_filter()),
+ nullptr);
+ }
+ case DlImageFilterType::kLocalMatrix: {
+ const DlLocalMatrixImageFilter* lm_filter = filter->asLocalMatrix();
+ FML_DCHECK(lm_filter != nullptr);
+ sk_sp<SkImageFilter> skia_filter = ToSk(lm_filter->image_filter());
+ // The image_filter property itself might have been null, or the
+ // construction of the SkImageFilter might be optimized to null
+ // for any number of reasons. In any case, if the filter is null
+ // or optimizaed away, let's then optimize away this local matrix
+ // case by returning null.
+ if (!skia_filter) {
+ return nullptr;
+ }
+ return skia_filter->makeWithLocalMatrix(lm_filter->matrix());
+ }
+ }
+}
+
+sk_sp<SkColorFilter> ToSk(const DlColorFilter* filter) {
+ if (!filter) {
+ return nullptr;
+ }
+ switch (filter->type()) {
+ case DlColorFilterType::kBlend: {
+ const DlBlendColorFilter* blend_filter = filter->asBlend();
+ FML_DCHECK(blend_filter != nullptr);
+ return SkColorFilters::Blend(blend_filter->color(),
+ ToSk(blend_filter->mode()));
+ }
+ case DlColorFilterType::kMatrix: {
+ const DlMatrixColorFilter* matrix_filter = filter->asMatrix();
+ FML_DCHECK(matrix_filter != nullptr);
+ float matrix[20];
+ matrix_filter->get_matrix(matrix);
+ return SkColorFilters::Matrix(matrix);
+ }
+ case DlColorFilterType::kSrgbToLinearGamma: {
+ return SkColorFilters::SRGBToLinearGamma();
+ }
+ case DlColorFilterType::kLinearToSrgbGamma: {
+ return SkColorFilters::LinearToSRGBGamma();
+ }
+ }
+}
+
+sk_sp<SkMaskFilter> ToSk(const DlMaskFilter* filter) {
+ if (!filter) {
+ return nullptr;
+ }
+ switch (filter->type()) {
+ case DlMaskFilterType::kBlur: {
+ const DlBlurMaskFilter* blur_filter = filter->asBlur();
+ FML_DCHECK(blur_filter != nullptr);
+ return SkMaskFilter::MakeBlur(blur_filter->style(), blur_filter->sigma(),
+ blur_filter->respectCTM());
+ }
+ }
+}
+
+sk_sp<SkPathEffect> ToSk(const DlPathEffect* effect) {
+ if (!effect) {
+ return nullptr;
+ }
+ switch (effect->type()) {
+ case DlPathEffectType::kDash: {
+ const DlDashPathEffect* dash_effect = effect->asDash();
+ FML_DCHECK(dash_effect != nullptr);
+ return SkDashPathEffect::Make(dash_effect->intervals(),
+ dash_effect->count(), dash_effect->phase());
+ }
+ }
+}
+
+sk_sp<SkVertices> ToSk(const DlVertices* vertices) {
+ const SkColor* sk_colors =
+ reinterpret_cast<const SkColor*>(vertices->colors());
+ return SkVertices::MakeCopy(ToSk(vertices->mode()), vertices->vertex_count(),
+ vertices->vertices(),
+ vertices->texture_coordinates(), sk_colors,
+ vertices->index_count(), vertices->indices());
+}
+
+} // namespace flutter
diff --git a/display_list/skia/dl_sk_conversions.h b/display_list/skia/dl_sk_conversions.h
new file mode 100644
index 0000000..54056c4
--- /dev/null
+++ b/display_list/skia/dl_sk_conversions.h
@@ -0,0 +1,116 @@
+// 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_SKIA_DL_SK_CONVERSIONS_H_
+#define FLUTTER_DISPLAY_LIST_SKIA_DL_SK_CONVERSIONS_H_
+
+#include "flutter/display_list/dl_op_receiver.h"
+
+namespace flutter {
+
+inline SkBlendMode ToSk(DlBlendMode mode) {
+ return static_cast<SkBlendMode>(mode);
+}
+
+inline SkPaint::Style ToSk(DlDrawStyle style) {
+ return static_cast<SkPaint::Style>(style);
+}
+
+inline SkPaint::Cap ToSk(DlStrokeCap cap) {
+ return static_cast<SkPaint::Cap>(cap);
+}
+
+inline SkPaint::Join ToSk(DlStrokeJoin join) {
+ return static_cast<SkPaint::Join>(join);
+}
+
+inline SkTileMode ToSk(DlTileMode dl_mode) {
+ return static_cast<SkTileMode>(dl_mode);
+}
+
+inline SkFilterMode ToSk(const DlFilterMode filter_mode) {
+ return static_cast<SkFilterMode>(filter_mode);
+}
+
+inline SkVertices::VertexMode ToSk(DlVertexMode dl_mode) {
+ return static_cast<SkVertices::VertexMode>(dl_mode);
+}
+
+inline SkSamplingOptions ToSk(DlImageSampling sampling) {
+ switch (sampling) {
+ case DlImageSampling::kCubic:
+ return SkSamplingOptions(SkCubicResampler{1 / 3.0f, 1 / 3.0f});
+ case DlImageSampling::kLinear:
+ return SkSamplingOptions(SkFilterMode::kLinear);
+ case DlImageSampling::kMipmapLinear:
+ return SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear);
+ case DlImageSampling::kNearestNeighbor:
+ return SkSamplingOptions(SkFilterMode::kNearest);
+ }
+}
+
+inline SkCanvas::SrcRectConstraint ToSk(
+ DlCanvas::SrcRectConstraint constraint) {
+ return static_cast<SkCanvas::SrcRectConstraint>(constraint);
+}
+
+inline SkClipOp ToSk(DlCanvas::ClipOp op) {
+ return static_cast<SkClipOp>(op);
+}
+
+inline SkCanvas::PointMode ToSk(DlCanvas::PointMode mode) {
+ return static_cast<SkCanvas::PointMode>(mode);
+}
+
+extern sk_sp<SkShader> ToSk(const DlColorSource* source);
+inline sk_sp<SkShader> ToSk(std::shared_ptr<const DlColorSource> source) {
+ return ToSk(source.get());
+}
+inline sk_sp<SkShader> ToSk(const DlColorSource& source) {
+ return ToSk(&source);
+}
+
+extern sk_sp<SkImageFilter> ToSk(const DlImageFilter* filter);
+inline sk_sp<SkImageFilter> ToSk(std::shared_ptr<const DlImageFilter> filter) {
+ return ToSk(filter.get());
+}
+inline sk_sp<SkImageFilter> ToSk(const DlImageFilter& filter) {
+ return ToSk(&filter);
+}
+
+extern sk_sp<SkColorFilter> ToSk(const DlColorFilter* filter);
+inline sk_sp<SkColorFilter> ToSk(std::shared_ptr<const DlColorFilter> filter) {
+ return ToSk(filter.get());
+}
+inline sk_sp<SkColorFilter> ToSk(const DlColorFilter& filter) {
+ return ToSk(&filter);
+}
+
+extern sk_sp<SkMaskFilter> ToSk(const DlMaskFilter* filter);
+inline sk_sp<SkMaskFilter> ToSk(std::shared_ptr<const DlMaskFilter> filter) {
+ return ToSk(filter.get());
+}
+inline sk_sp<SkMaskFilter> ToSk(const DlMaskFilter& filter) {
+ return ToSk(&filter);
+}
+
+extern sk_sp<SkPathEffect> ToSk(const DlPathEffect* effect);
+inline sk_sp<SkPathEffect> ToSk(std::shared_ptr<const DlPathEffect> effect) {
+ return ToSk(effect.get());
+}
+inline sk_sp<SkPathEffect> ToSk(const DlPathEffect& effect) {
+ return ToSk(&effect);
+}
+
+extern sk_sp<SkVertices> ToSk(const DlVertices* vertices);
+inline sk_sp<SkVertices> ToSk(std::shared_ptr<const DlVertices> vertices) {
+ return ToSk(vertices.get());
+}
+inline sk_sp<SkVertices> ToSk(const DlVertices& vertices) {
+ return ToSk(&vertices);
+}
+
+} // namespace flutter
+
+#endif // FLUTTER_DISPLAY_LIST_SKIA_DL_SK_CONVERSIONS_H_
diff --git a/display_list/skia/dl_sk_conversions_unittests.cc b/display_list/skia/dl_sk_conversions_unittests.cc
new file mode 100644
index 0000000..c35a3c2
--- /dev/null
+++ b/display_list/skia/dl_sk_conversions_unittests.cc
@@ -0,0 +1,267 @@
+// 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/skia/dl_sk_conversions.h"
+
+#include "flutter/display_list/display_list_blend_mode.h"
+#include "flutter/display_list/display_list_paint.h"
+#include "flutter/display_list/display_list_sampling_options.h"
+#include "flutter/display_list/display_list_tile_mode.h"
+#include "flutter/display_list/display_list_vertices.h"
+#include "flutter/display_list/types.h"
+#include "gtest/gtest.h"
+#include "include/core/SkSamplingOptions.h"
+
+namespace flutter {
+namespace testing {
+
+TEST(DisplayListImageFilter, LocalImageSkiaNull) {
+ auto blur_filter =
+ std::make_shared<DlBlurImageFilter>(0, 0, DlTileMode::kClamp);
+ DlLocalMatrixImageFilter dl_local_matrix_filter(SkMatrix::RotateDeg(45),
+ blur_filter);
+ // With sigmas set to zero on the blur filter, Skia will return a null filter.
+ // The local matrix filter should return nullptr instead of crashing.
+ ASSERT_EQ(ToSk(dl_local_matrix_filter), nullptr);
+}
+
+TEST(DisplayListSkConversions, ToSkTileMode) {
+ ASSERT_EQ(ToSk(DlTileMode::kClamp), SkTileMode::kClamp);
+ ASSERT_EQ(ToSk(DlTileMode::kRepeat), SkTileMode::kRepeat);
+ ASSERT_EQ(ToSk(DlTileMode::kMirror), SkTileMode::kMirror);
+ ASSERT_EQ(ToSk(DlTileMode::kDecal), SkTileMode::kDecal);
+}
+
+TEST(DisplayListSkConversions, ToSkDrawStyle) {
+ ASSERT_EQ(ToSk(DlDrawStyle::kFill), SkPaint::Style::kFill_Style);
+ ASSERT_EQ(ToSk(DlDrawStyle::kStroke), SkPaint::Style::kStroke_Style);
+ ASSERT_EQ(ToSk(DlDrawStyle::kStrokeAndFill),
+ SkPaint::Style::kStrokeAndFill_Style);
+}
+
+TEST(DisplayListSkConversions, ToSkStrokeCap) {
+ ASSERT_EQ(ToSk(DlStrokeCap::kButt), SkPaint::Cap::kButt_Cap);
+ ASSERT_EQ(ToSk(DlStrokeCap::kRound), SkPaint::Cap::kRound_Cap);
+ ASSERT_EQ(ToSk(DlStrokeCap::kSquare), SkPaint::Cap::kSquare_Cap);
+}
+
+TEST(DisplayListSkConversions, ToSkStrokeJoin) {
+ ASSERT_EQ(ToSk(DlStrokeJoin::kMiter), SkPaint::Join::kMiter_Join);
+ ASSERT_EQ(ToSk(DlStrokeJoin::kRound), SkPaint::Join::kRound_Join);
+ ASSERT_EQ(ToSk(DlStrokeJoin::kBevel), SkPaint::Join::kBevel_Join);
+}
+
+TEST(DisplayListSkConversions, ToSkVertexMode) {
+ ASSERT_EQ(ToSk(DlVertexMode::kTriangles),
+ SkVertices::VertexMode::kTriangles_VertexMode);
+ ASSERT_EQ(ToSk(DlVertexMode::kTriangleStrip),
+ SkVertices::VertexMode::kTriangleStrip_VertexMode);
+ ASSERT_EQ(ToSk(DlVertexMode::kTriangleFan),
+ SkVertices::VertexMode::kTriangleFan_VertexMode);
+}
+
+TEST(DisplayListSkConversions, ToSkFilterMode) {
+ ASSERT_EQ(ToSk(DlFilterMode::kLinear), SkFilterMode::kLinear);
+ ASSERT_EQ(ToSk(DlFilterMode::kNearest), SkFilterMode::kNearest);
+ ASSERT_EQ(ToSk(DlFilterMode::kLast), SkFilterMode::kLast);
+}
+
+TEST(DisplayListSkConversions, ToSkSrcRectConstraint) {
+ ASSERT_EQ(ToSk(DlCanvas::SrcRectConstraint::kFast),
+ SkCanvas::SrcRectConstraint::kFast_SrcRectConstraint);
+ ASSERT_EQ(ToSk(DlCanvas::SrcRectConstraint::kStrict),
+ SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint);
+}
+
+TEST(DisplayListSkConversions, ToSkSamplingOptions) {
+ ASSERT_EQ(ToSk(DlImageSampling::kLinear),
+ SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone));
+ ASSERT_EQ(ToSk(DlImageSampling::kMipmapLinear),
+ SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear));
+ ASSERT_EQ(ToSk(DlImageSampling::kNearestNeighbor),
+ SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone));
+ ASSERT_EQ(ToSk(DlImageSampling::kCubic),
+ SkSamplingOptions(SkCubicResampler{1 / 3.0f, 1 / 3.0f}));
+}
+
+#define FOR_EACH_BLEND_MODE_ENUM(FUNC) \
+ FUNC(kSrc) \
+ FUNC(kClear) \
+ FUNC(kSrc) \
+ FUNC(kDst) \
+ FUNC(kSrcOver) \
+ FUNC(kDstOver) \
+ FUNC(kSrcIn) \
+ FUNC(kDstIn) \
+ FUNC(kSrcOut) \
+ FUNC(kDstOut) \
+ FUNC(kSrcATop) \
+ FUNC(kDstATop) \
+ FUNC(kXor) \
+ FUNC(kPlus) \
+ FUNC(kModulate) \
+ FUNC(kScreen) \
+ FUNC(kOverlay) \
+ FUNC(kDarken) \
+ FUNC(kLighten) \
+ FUNC(kColorDodge) \
+ FUNC(kColorBurn) \
+ FUNC(kHardLight) \
+ FUNC(kSoftLight) \
+ FUNC(kDifference) \
+ FUNC(kExclusion) \
+ FUNC(kMultiply) \
+ FUNC(kHue) \
+ FUNC(kSaturation) \
+ FUNC(kColor) \
+ FUNC(kLuminosity) \
+ FUNC(kLastCoeffMode) \
+ FUNC(kLastSeparableMode) \
+ FUNC(kLastMode)
+
+TEST(DisplayListSkConversions, ToSkBlendMode) {
+#define CHECK_TO_SKENUM(V) ASSERT_EQ(ToSk(DlBlendMode::V), SkBlendMode::V);
+ FOR_EACH_BLEND_MODE_ENUM(CHECK_TO_SKENUM)
+#undef CHECK_TO_SKENUM
+}
+
+TEST(DisplayListSkConversions, BlendColorFilterModifiesTransparency) {
+ auto test_mode_color = [](DlBlendMode mode, DlColor color) {
+ std::stringstream desc_str;
+ desc_str << "blend[" << static_cast<int>(mode) << ", " << color << "]";
+ std::string desc = desc_str.str();
+ DlBlendColorFilter filter(color, mode);
+ if (filter.modifies_transparent_black()) {
+ auto dl_filter = DlBlendColorFilter::Make(color, mode);
+ auto sk_filter = ToSk(filter);
+ ASSERT_NE(dl_filter, nullptr) << desc;
+ ASSERT_NE(sk_filter, nullptr) << desc;
+ ASSERT_TRUE(sk_filter->filterColor(0) != 0) << desc;
+ } else {
+ auto dl_filter = DlBlendColorFilter::Make(color, mode);
+ auto sk_filter = ToSk(filter);
+ EXPECT_EQ(dl_filter == nullptr, sk_filter == nullptr) << desc;
+ ASSERT_TRUE(sk_filter == nullptr || sk_filter->filterColor(0) == 0)
+ << desc;
+ }
+ };
+
+ auto test_mode = [&test_mode_color](DlBlendMode mode) {
+ test_mode_color(mode, DlColor::kTransparent());
+ test_mode_color(mode, DlColor::kWhite());
+ test_mode_color(mode, DlColor::kWhite().modulateOpacity(0.5));
+ test_mode_color(mode, DlColor::kBlack());
+ test_mode_color(mode, DlColor::kBlack().modulateOpacity(0.5));
+ };
+
+#define TEST_MODE(V) test_mode(DlBlendMode::V);
+ FOR_EACH_BLEND_MODE_ENUM(TEST_MODE)
+#undef TEST_MODE
+}
+
+#undef FOR_EACH_BLEND_MODE_ENUM
+
+TEST(DisplayListSkConversions, ConvertWithZeroAndNegativeVerticesAndIndices) {
+ std::shared_ptr<const DlVertices> vertices1 = DlVertices::Make(
+ DlVertexMode::kTriangles, 0, nullptr, nullptr, nullptr, 0, nullptr);
+ EXPECT_NE(vertices1, nullptr);
+ EXPECT_NE(ToSk(vertices1), nullptr);
+
+ std::shared_ptr<const DlVertices> vertices2 = DlVertices::Make(
+ DlVertexMode::kTriangles, -1, nullptr, nullptr, nullptr, -1, nullptr);
+ EXPECT_NE(vertices2, nullptr);
+ EXPECT_NE(ToSk(vertices2), nullptr);
+}
+
+TEST(DisplayListVertices, ConvertWithZeroAndNegativeVerticesAndIndices) {
+ DlVertices::Builder builder1(DlVertexMode::kTriangles, 0,
+ DlVertices::Builder::kNone, 0);
+ EXPECT_TRUE(builder1.is_valid());
+ std::shared_ptr<DlVertices> vertices1 = builder1.build();
+ EXPECT_NE(vertices1, nullptr);
+ EXPECT_NE(ToSk(vertices1), nullptr);
+
+ DlVertices::Builder builder2(DlVertexMode::kTriangles, -1,
+ DlVertices::Builder::kNone, -1);
+ EXPECT_TRUE(builder2.is_valid());
+ std::shared_ptr<DlVertices> vertices2 = builder2.build();
+ EXPECT_NE(vertices2, nullptr);
+ EXPECT_NE(ToSk(vertices2), nullptr);
+}
+
+TEST(DisplayListColorSource, ConvertRuntimeEffect) {
+ const sk_sp<DlRuntimeEffect> kTestRuntimeEffect1 = DlRuntimeEffect::MakeSkia(
+ SkRuntimeEffect::MakeForShader(
+ SkString("vec4 main(vec2 p) { return vec4(0); }"))
+ .effect);
+ const sk_sp<DlRuntimeEffect> kTestRuntimeEffect2 = DlRuntimeEffect::MakeSkia(
+ SkRuntimeEffect::MakeForShader(
+ SkString("vec4 main(vec2 p) { return vec4(1); }"))
+ .effect);
+ std::shared_ptr<DlRuntimeEffectColorSource> source1 =
+ DlColorSource::MakeRuntimeEffect(
+ kTestRuntimeEffect1, {}, std::make_shared<std::vector<uint8_t>>());
+ std::shared_ptr<DlRuntimeEffectColorSource> source2 =
+ DlColorSource::MakeRuntimeEffect(
+ kTestRuntimeEffect2, {}, std::make_shared<std::vector<uint8_t>>());
+ std::shared_ptr<DlRuntimeEffectColorSource> source3 =
+ DlColorSource::MakeRuntimeEffect(
+ nullptr, {}, std::make_shared<std::vector<uint8_t>>());
+
+ ASSERT_NE(ToSk(source1), nullptr);
+ ASSERT_NE(ToSk(source2), nullptr);
+ ASSERT_EQ(ToSk(source3), nullptr);
+}
+
+TEST(DisplayListColorSource, ConvertRuntimeEffectWithNullSampler) {
+ const sk_sp<DlRuntimeEffect> kTestRuntimeEffect1 = DlRuntimeEffect::MakeSkia(
+ SkRuntimeEffect::MakeForShader(
+ SkString("vec4 main(vec2 p) { return vec4(0); }"))
+ .effect);
+ std::shared_ptr<DlRuntimeEffectColorSource> source1 =
+ DlColorSource::MakeRuntimeEffect(
+ kTestRuntimeEffect1, {nullptr},
+ std::make_shared<std::vector<uint8_t>>());
+
+ ASSERT_EQ(ToSk(source1), nullptr);
+}
+
+TEST(DisplayListSkConversions, MatrixColorFilterModifiesTransparency) {
+ auto test_matrix = [](int element, SkScalar value) {
+ // clang-format off
+ float matrix[] = {
+ 1, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0,
+ 0, 0, 1, 0, 0,
+ 0, 0, 0, 1, 0,
+ };
+ // clang-format on
+ std::string desc =
+ "matrix[" + std::to_string(element) + "] = " + std::to_string(value);
+ matrix[element] = value;
+ DlMatrixColorFilter filter(matrix);
+ auto dl_filter = DlMatrixColorFilter::Make(matrix);
+ auto sk_filter = ToSk(filter);
+ EXPECT_EQ(dl_filter == nullptr, sk_filter == nullptr);
+ EXPECT_EQ(filter.modifies_transparent_black(),
+ sk_filter && sk_filter->filterColor(0) != 0);
+ };
+
+ // Tests identity (matrix[0] already == 1 in an identity filter)
+ test_matrix(0, 1);
+ // test_matrix(19, 1);
+ for (int i = 0; i < 20; i++) {
+ test_matrix(i, -0.25);
+ test_matrix(i, 0);
+ test_matrix(i, 0.25);
+ test_matrix(i, 1);
+ test_matrix(i, 1.25);
+ test_matrix(i, SK_ScalarNaN);
+ test_matrix(i, SK_ScalarInfinity);
+ test_matrix(i, -SK_ScalarInfinity);
+ }
+}
+
+} // namespace testing
+} // namespace flutter
diff --git a/display_list/skia/dl_sk_dispatcher.cc b/display_list/skia/dl_sk_dispatcher.cc
new file mode 100644
index 0000000..a808464
--- /dev/null
+++ b/display_list/skia/dl_sk_dispatcher.cc
@@ -0,0 +1,304 @@
+// 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/skia/dl_sk_dispatcher.h"
+
+#include "flutter/display_list/display_list_blend_mode.h"
+#include "flutter/display_list/skia/dl_sk_conversions.h"
+#include "flutter/fml/trace_event.h"
+#include "third_party/skia/include/utils/SkShadowUtils.h"
+
+namespace flutter {
+
+const SkPaint* DlSkCanvasDispatcher::safe_paint(bool use_attributes) {
+ if (use_attributes) {
+ // The accumulated SkPaint object will already have incorporated
+ // any attribute overrides.
+ return &paint();
+ } else if (has_opacity()) {
+ temp_paint_.setAlphaf(opacity());
+ return &temp_paint_;
+ } else {
+ return nullptr;
+ }
+}
+
+void DlSkCanvasDispatcher::save() {
+ canvas_->save();
+ // save has no impact on attributes, but it needs to register a record
+ // on the restore stack so that the eventual call to restore() will
+ // know what to do at that time. We could annotate the restore record
+ // with a flag that the record came from a save call, but it is simpler
+ // to just pass in the current opacity value as the value to be used by
+ // the children and let the utility calls notice that it didn't change.
+ save_opacity(opacity());
+}
+void DlSkCanvasDispatcher::restore() {
+ canvas_->restore();
+ restore_opacity();
+}
+void DlSkCanvasDispatcher::saveLayer(const SkRect* bounds,
+ const SaveLayerOptions options,
+ const DlImageFilter* backdrop) {
+ if (bounds == nullptr && options.can_distribute_opacity() &&
+ backdrop == nullptr) {
+ // We know that:
+ // - no bounds is needed for clipping here
+ // - no backdrop filter is used to initialize the layer
+ // - the current attributes only have an alpha
+ // - the children are compatible with individually rendering with
+ // an inherited opacity
+ // Therefore we can just use a save instead of a saveLayer and pass the
+ // intended opacity to the children.
+ canvas_->save();
+ // If the saveLayer does not use attributes, the children should continue
+ // to render with the inherited opacity unmodified. If attributes are to
+ // be applied, the children should render with the combination of the
+ // inherited opacity combined with the alpha from the current color.
+ save_opacity(options.renders_with_attributes() ? combined_opacity()
+ : opacity());
+ } else {
+ TRACE_EVENT0("flutter", "Canvas::saveLayer");
+ const SkPaint* paint = safe_paint(options.renders_with_attributes());
+ const sk_sp<SkImageFilter> sk_backdrop = ToSk(backdrop);
+ canvas_->saveLayer(
+ SkCanvas::SaveLayerRec(bounds, paint, sk_backdrop.get(), 0));
+ // saveLayer will apply the current opacity on behalf of the children
+ // so they will inherit an opaque opacity.
+ save_opacity(SK_Scalar1);
+ }
+}
+
+void DlSkCanvasDispatcher::translate(SkScalar tx, SkScalar ty) {
+ canvas_->translate(tx, ty);
+}
+void DlSkCanvasDispatcher::scale(SkScalar sx, SkScalar sy) {
+ canvas_->scale(sx, sy);
+}
+void DlSkCanvasDispatcher::rotate(SkScalar degrees) {
+ canvas_->rotate(degrees);
+}
+void DlSkCanvasDispatcher::skew(SkScalar sx, SkScalar sy) {
+ canvas_->skew(sx, sy);
+}
+// clang-format off
+// 2x3 2D affine subset of a 4x4 transform in row major order
+void DlSkCanvasDispatcher::transform2DAffine(
+ SkScalar mxx, SkScalar mxy, SkScalar mxt,
+ SkScalar myx, SkScalar myy, SkScalar myt) {
+ // Internally concat(SkMatrix) gets redirected to concat(SkM44)
+ // so we just jump directly to the SkM44 version
+ canvas_->concat(SkM44(mxx, mxy, 0, mxt,
+ myx, myy, 0, myt,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1));
+}
+// full 4x4 transform in row major order
+void DlSkCanvasDispatcher::transformFullPerspective(
+ SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt,
+ SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt,
+ SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt,
+ SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) {
+ canvas_->concat(SkM44(mxx, mxy, mxz, mxt,
+ myx, myy, myz, myt,
+ mzx, mzy, mzz, mzt,
+ mwx, mwy, mwz, mwt));
+}
+// clang-format on
+void DlSkCanvasDispatcher::transformReset() {
+ canvas_->setMatrix(original_transform_);
+}
+
+void DlSkCanvasDispatcher::clipRect(const SkRect& rect,
+ ClipOp clip_op,
+ bool is_aa) {
+ canvas_->clipRect(rect, ToSk(clip_op), is_aa);
+}
+void DlSkCanvasDispatcher::clipRRect(const SkRRect& rrect,
+ ClipOp clip_op,
+ bool is_aa) {
+ canvas_->clipRRect(rrect, ToSk(clip_op), is_aa);
+}
+void DlSkCanvasDispatcher::clipPath(const SkPath& path,
+ ClipOp clip_op,
+ bool is_aa) {
+ canvas_->clipPath(path, ToSk(clip_op), is_aa);
+}
+
+void DlSkCanvasDispatcher::drawPaint() {
+ const SkPaint& sk_paint = paint();
+ SkImageFilter* filter = sk_paint.getImageFilter();
+ if (filter && !filter->asColorFilter(nullptr)) {
+ // drawPaint does an implicit saveLayer if an SkImageFilter is
+ // present that cannot be replaced by an SkColorFilter.
+ TRACE_EVENT0("flutter", "Canvas::saveLayer");
+ }
+ canvas_->drawPaint(sk_paint);
+}
+void DlSkCanvasDispatcher::drawColor(DlColor color, DlBlendMode mode) {
+ // SkCanvas::drawColor(SkColor) does the following conversion anyway
+ // We do it here manually to increase precision on applying opacity
+ SkColor4f color4f = SkColor4f::FromColor(color);
+ color4f.fA *= opacity();
+ canvas_->drawColor(color4f, ToSk(mode));
+}
+void DlSkCanvasDispatcher::drawLine(const SkPoint& p0, const SkPoint& p1) {
+ canvas_->drawLine(p0, p1, paint());
+}
+void DlSkCanvasDispatcher::drawRect(const SkRect& rect) {
+ canvas_->drawRect(rect, paint());
+}
+void DlSkCanvasDispatcher::drawOval(const SkRect& bounds) {
+ canvas_->drawOval(bounds, paint());
+}
+void DlSkCanvasDispatcher::drawCircle(const SkPoint& center, SkScalar radius) {
+ canvas_->drawCircle(center, radius, paint());
+}
+void DlSkCanvasDispatcher::drawRRect(const SkRRect& rrect) {
+ canvas_->drawRRect(rrect, paint());
+}
+void DlSkCanvasDispatcher::drawDRRect(const SkRRect& outer,
+ const SkRRect& inner) {
+ canvas_->drawDRRect(outer, inner, paint());
+}
+void DlSkCanvasDispatcher::drawPath(const SkPath& path) {
+ canvas_->drawPath(path, paint());
+}
+void DlSkCanvasDispatcher::drawArc(const SkRect& bounds,
+ SkScalar start,
+ SkScalar sweep,
+ bool useCenter) {
+ canvas_->drawArc(bounds, start, sweep, useCenter, paint());
+}
+void DlSkCanvasDispatcher::drawPoints(PointMode mode,
+ uint32_t count,
+ const SkPoint pts[]) {
+ canvas_->drawPoints(ToSk(mode), count, pts, paint());
+}
+void DlSkCanvasDispatcher::drawVertices(const DlVertices* vertices,
+ DlBlendMode mode) {
+ canvas_->drawVertices(ToSk(vertices), ToSk(mode), paint());
+}
+void DlSkCanvasDispatcher::drawImage(const sk_sp<DlImage> image,
+ const SkPoint point,
+ DlImageSampling sampling,
+ bool render_with_attributes) {
+ canvas_->drawImage(image ? image->skia_image() : nullptr, point.fX, point.fY,
+ ToSk(sampling), safe_paint(render_with_attributes));
+}
+void DlSkCanvasDispatcher::drawImageRect(const sk_sp<DlImage> image,
+ const SkRect& src,
+ const SkRect& dst,
+ DlImageSampling sampling,
+ bool render_with_attributes,
+ SrcRectConstraint constraint) {
+ canvas_->drawImageRect(image ? image->skia_image() : nullptr, src, dst,
+ ToSk(sampling), safe_paint(render_with_attributes),
+ ToSk(constraint));
+}
+void DlSkCanvasDispatcher::drawImageNine(const sk_sp<DlImage> image,
+ const SkIRect& center,
+ const SkRect& dst,
+ DlFilterMode filter,
+ bool render_with_attributes) {
+ if (!image) {
+ return;
+ }
+ auto skia_image = image->skia_image();
+ if (!skia_image) {
+ return;
+ }
+ canvas_->drawImageNine(skia_image.get(), center, dst, ToSk(filter),
+ safe_paint(render_with_attributes));
+}
+void DlSkCanvasDispatcher::drawAtlas(const sk_sp<DlImage> atlas,
+ const SkRSXform xform[],
+ const SkRect tex[],
+ const DlColor colors[],
+ int count,
+ DlBlendMode mode,
+ DlImageSampling sampling,
+ const SkRect* cullRect,
+ bool render_with_attributes) {
+ if (!atlas) {
+ return;
+ }
+ auto skia_atlas = atlas->skia_image();
+ if (!skia_atlas) {
+ return;
+ }
+ const SkColor* sk_colors = reinterpret_cast<const SkColor*>(colors);
+ canvas_->drawAtlas(skia_atlas.get(), xform, tex, sk_colors, count, ToSk(mode),
+ ToSk(sampling), cullRect,
+ safe_paint(render_with_attributes));
+}
+void DlSkCanvasDispatcher::drawDisplayList(
+ const sk_sp<DisplayList> display_list,
+ SkScalar opacity) {
+ const int restore_count = canvas_->getSaveCount();
+
+ // Compute combined opacity and figure out whether we can apply it
+ // during dispatch or if we need a saveLayer.
+ SkScalar combined_opacity = opacity * this->opacity();
+ if (combined_opacity < SK_Scalar1 &&
+ !display_list->can_apply_group_opacity()) {
+ TRACE_EVENT0("flutter", "Canvas::saveLayer");
+ canvas_->saveLayerAlphaf(&display_list->bounds(), combined_opacity);
+ combined_opacity = SK_Scalar1;
+ } else {
+ canvas_->save();
+ }
+
+ // Create a new CanvasDispatcher to isolate the actions of the
+ // display_list from the current environment.
+ DlSkCanvasDispatcher dispatcher(canvas_, combined_opacity);
+ if (display_list->rtree()) {
+ display_list->Dispatch(dispatcher, canvas_->getLocalClipBounds());
+ } else {
+ display_list->Dispatch(dispatcher);
+ }
+
+ // Restore canvas state to what it was before dispatching.
+ canvas_->restoreToCount(restore_count);
+}
+void DlSkCanvasDispatcher::drawTextBlob(const sk_sp<SkTextBlob> blob,
+ SkScalar x,
+ SkScalar y) {
+ canvas_->drawTextBlob(blob, x, y, paint());
+}
+
+void DlSkCanvasDispatcher::DrawShadow(SkCanvas* canvas,
+ const SkPath& path,
+ DlColor color,
+ float elevation,
+ bool transparentOccluder,
+ SkScalar dpr) {
+ const SkScalar kAmbientAlpha = 0.039f;
+ const SkScalar kSpotAlpha = 0.25f;
+
+ uint32_t flags = transparentOccluder
+ ? SkShadowFlags::kTransparentOccluder_ShadowFlag
+ : SkShadowFlags::kNone_ShadowFlag;
+ flags |= SkShadowFlags::kDirectionalLight_ShadowFlag;
+ SkColor in_ambient = SkColorSetA(color, kAmbientAlpha * SkColorGetA(color));
+ SkColor in_spot = SkColorSetA(color, kSpotAlpha * SkColorGetA(color));
+ SkColor ambient_color, spot_color;
+ SkShadowUtils::ComputeTonalColors(in_ambient, in_spot, &ambient_color,
+ &spot_color);
+ SkShadowUtils::DrawShadow(
+ canvas, path, SkPoint3::Make(0, 0, dpr * elevation),
+ SkPoint3::Make(0, -1, 1),
+ DlCanvas::kShadowLightRadius / DlCanvas::kShadowLightHeight,
+ ambient_color, spot_color, flags);
+}
+
+void DlSkCanvasDispatcher::drawShadow(const SkPath& path,
+ const DlColor color,
+ const SkScalar elevation,
+ bool transparent_occluder,
+ SkScalar dpr) {
+ DrawShadow(canvas_, path, color, elevation, transparent_occluder, dpr);
+}
+
+} // namespace flutter
diff --git a/display_list/display_list_canvas_dispatcher.h b/display_list/skia/dl_sk_dispatcher.h
similarity index 85%
rename from display_list/display_list_canvas_dispatcher.h
rename to display_list/skia/dl_sk_dispatcher.h
index 993b5b4..1edf2d4 100644
--- a/display_list/display_list_canvas_dispatcher.h
+++ b/display_list/skia/dl_sk_dispatcher.h
@@ -6,9 +6,8 @@
#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_CANVAS_DISPATCHER_H_
#include "flutter/display_list/display_list.h"
-#include "flutter/display_list/display_list_blend_mode.h"
-#include "flutter/display_list/display_list_dispatcher.h"
-#include "flutter/display_list/display_list_utils.h"
+#include "flutter/display_list/dl_op_receiver.h"
+#include "flutter/display_list/skia/dl_sk_utils.h"
#include "flutter/fml/macros.h"
namespace flutter {
@@ -19,11 +18,10 @@
///
/// Receives all methods on Dispatcher and sends them to an SkCanvas
///
-class DisplayListCanvasDispatcher : public virtual Dispatcher,
- public SkPaintDispatchHelper {
+class DlSkCanvasDispatcher : public virtual DlOpReceiver,
+ public SkPaintDispatchHelper {
public:
- explicit DisplayListCanvasDispatcher(SkCanvas* canvas,
- SkScalar opacity = SK_Scalar1)
+ explicit DlSkCanvasDispatcher(SkCanvas* canvas, SkScalar opacity = SK_Scalar1)
: SkPaintDispatchHelper(opacity),
canvas_(canvas),
original_transform_(canvas->getLocalToDevice()) {}
@@ -81,7 +79,7 @@
const SkRect& dst,
DlImageSampling sampling,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) override;
+ SrcRectConstraint constraint) override;
void drawImageNine(const sk_sp<DlImage> image,
const SkIRect& center,
const SkRect& dst,
@@ -96,7 +94,8 @@
DlImageSampling sampling,
const SkRect* cullRect,
bool render_with_attributes) override;
- void drawDisplayList(const sk_sp<DisplayList> display_list) override;
+ void drawDisplayList(const sk_sp<DisplayList> display_list,
+ SkScalar opacity) override;
void drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y) override;
@@ -106,11 +105,6 @@
bool transparent_occluder,
SkScalar dpr) override;
- static SkRect ComputeShadowBounds(const SkPath& path,
- float elevation,
- SkScalar dpr,
- const SkMatrix& ctm);
-
static void DrawShadow(SkCanvas* canvas,
const SkPath& path,
DlColor color,
diff --git a/display_list/skia/dl_sk_utils.cc b/display_list/skia/dl_sk_utils.cc
new file mode 100644
index 0000000..3476ab3
--- /dev/null
+++ b/display_list/skia/dl_sk_utils.cc
@@ -0,0 +1,102 @@
+// 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/skia/dl_sk_utils.h"
+
+#include <math.h>
+#include <optional>
+#include <type_traits>
+
+#include "flutter/display_list/display_list_blend_mode.h"
+#include "flutter/display_list/skia/dl_sk_conversions.h"
+#include "flutter/fml/logging.h"
+
+namespace flutter {
+
+// clang-format off
+constexpr float kInvertColorMatrix[20] = {
+ -1.0, 0, 0, 1.0, 0,
+ 0, -1.0, 0, 1.0, 0,
+ 0, 0, -1.0, 1.0, 0,
+ 1.0, 1.0, 1.0, 1.0, 0
+};
+// clang-format on
+
+void SkPaintDispatchHelper::save_opacity(SkScalar child_opacity) {
+ save_stack_.emplace_back(opacity_);
+ set_opacity(child_opacity);
+}
+void SkPaintDispatchHelper::restore_opacity() {
+ if (save_stack_.empty()) {
+ return;
+ }
+ set_opacity(save_stack_.back().opacity);
+ save_stack_.pop_back();
+}
+
+void SkPaintDispatchHelper::setAntiAlias(bool aa) {
+ paint_.setAntiAlias(aa);
+}
+void SkPaintDispatchHelper::setDither(bool dither) {
+ paint_.setDither(dither);
+}
+void SkPaintDispatchHelper::setInvertColors(bool invert) {
+ invert_colors_ = invert;
+ paint_.setColorFilter(makeColorFilter());
+}
+void SkPaintDispatchHelper::setStrokeCap(DlStrokeCap cap) {
+ paint_.setStrokeCap(ToSk(cap));
+}
+void SkPaintDispatchHelper::setStrokeJoin(DlStrokeJoin join) {
+ paint_.setStrokeJoin(ToSk(join));
+}
+void SkPaintDispatchHelper::setStyle(DlDrawStyle style) {
+ paint_.setStyle(ToSk(style));
+}
+void SkPaintDispatchHelper::setStrokeWidth(SkScalar width) {
+ paint_.setStrokeWidth(width);
+}
+void SkPaintDispatchHelper::setStrokeMiter(SkScalar limit) {
+ paint_.setStrokeMiter(limit);
+}
+void SkPaintDispatchHelper::setColor(DlColor color) {
+ current_color_ = color;
+ paint_.setColor(color);
+ if (has_opacity()) {
+ paint_.setAlphaf(paint_.getAlphaf() * opacity());
+ }
+}
+void SkPaintDispatchHelper::setBlendMode(DlBlendMode mode) {
+ paint_.setBlendMode(ToSk(mode));
+}
+void SkPaintDispatchHelper::setColorSource(const DlColorSource* source) {
+ paint_.setShader(ToSk(source));
+}
+void SkPaintDispatchHelper::setImageFilter(const DlImageFilter* filter) {
+ paint_.setImageFilter(ToSk(filter));
+}
+void SkPaintDispatchHelper::setColorFilter(const DlColorFilter* filter) {
+ sk_color_filter_ = ToSk(filter);
+ paint_.setColorFilter(makeColorFilter());
+}
+void SkPaintDispatchHelper::setPathEffect(const DlPathEffect* effect) {
+ paint_.setPathEffect(ToSk(effect));
+}
+void SkPaintDispatchHelper::setMaskFilter(const DlMaskFilter* filter) {
+ paint_.setMaskFilter(ToSk(filter));
+}
+
+sk_sp<SkColorFilter> SkPaintDispatchHelper::makeColorFilter() const {
+ if (!invert_colors_) {
+ return sk_color_filter_;
+ }
+ sk_sp<SkColorFilter> invert_filter =
+ SkColorFilters::Matrix(kInvertColorMatrix);
+ if (sk_color_filter_) {
+ invert_filter = invert_filter->makeComposed(sk_color_filter_);
+ }
+ return invert_filter;
+}
+
+} // namespace flutter
diff --git a/display_list/skia/dl_sk_utils.h b/display_list/skia/dl_sk_utils.h
new file mode 100644
index 0000000..e61848d
--- /dev/null
+++ b/display_list/skia/dl_sk_utils.h
@@ -0,0 +1,85 @@
+// 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_SKIA_DL_SK_UTILS_H_
+#define FLUTTER_DISPLAY_LIST_SKIA_DL_SK_UTILS_H_
+
+#include "flutter/display_list/dl_op_receiver.h"
+
+namespace flutter {
+
+// A utility class that will monitor the DlOpReceiver methods relating
+// to the rendering attributes and accumulate them into an SkPaint
+// which can be accessed at any time via paint().
+class SkPaintDispatchHelper : public virtual DlOpReceiver {
+ public:
+ SkPaintDispatchHelper(SkScalar opacity = SK_Scalar1)
+ : current_color_(SK_ColorBLACK), opacity_(opacity) {
+ if (opacity < SK_Scalar1) {
+ paint_.setAlphaf(opacity);
+ }
+ }
+
+ void setAntiAlias(bool aa) override;
+ void setDither(bool dither) override;
+ void setStyle(DlDrawStyle style) override;
+ void setColor(DlColor color) override;
+ void setStrokeWidth(SkScalar width) override;
+ void setStrokeMiter(SkScalar limit) override;
+ void setStrokeCap(DlStrokeCap cap) override;
+ void setStrokeJoin(DlStrokeJoin join) override;
+ void setColorSource(const DlColorSource* source) override;
+ void setColorFilter(const DlColorFilter* filter) override;
+ void setInvertColors(bool invert) override;
+ void setBlendMode(DlBlendMode mode) override;
+ void setPathEffect(const DlPathEffect* effect) override;
+ void setMaskFilter(const DlMaskFilter* filter) override;
+ void setImageFilter(const DlImageFilter* filter) override;
+
+ const SkPaint& paint() { return paint_; }
+
+ /// Returns the current opacity attribute which is used to reduce
+ /// the alpha of all setColor calls encountered in the streeam
+ SkScalar opacity() { return opacity_; }
+ /// Returns the combined opacity that includes both the current
+ /// opacity attribute and the alpha of the most recent color.
+ /// The most recently set color will have combined the two and
+ /// stored the combined value in the alpha of the paint.
+ SkScalar combined_opacity() { return paint_.getAlphaf(); }
+ /// Returns true iff the current opacity attribute is not opaque,
+ /// irrespective of the alpha of the current color
+ bool has_opacity() { return opacity_ < SK_Scalar1; }
+
+ protected:
+ void save_opacity(SkScalar opacity_for_children);
+ void restore_opacity();
+
+ private:
+ SkPaint paint_;
+ bool invert_colors_ = false;
+ sk_sp<SkColorFilter> sk_color_filter_;
+
+ sk_sp<SkColorFilter> makeColorFilter() const;
+
+ struct SaveInfo {
+ SaveInfo(SkScalar opacity) : opacity(opacity) {}
+
+ SkScalar opacity;
+ };
+ std::vector<SaveInfo> save_stack_;
+
+ void set_opacity(SkScalar opacity) {
+ if (opacity_ != opacity) {
+ opacity_ = opacity;
+ setColor(current_color_);
+ }
+ }
+
+ SkColor current_color_;
+ SkScalar opacity_;
+};
+
+} // namespace flutter
+
+#endif // FLUTTER_DISPLAY_LIST_SKIA_DL_SK_UTILS_H_
diff --git a/display_list/display_list_utils_unittests.cc b/display_list/skia/dl_sk_utils_unittests.cc
similarity index 89%
rename from display_list/display_list_utils_unittests.cc
rename to display_list/skia/dl_sk_utils_unittests.cc
index 9f77c94..ccab201 100644
--- a/display_list/display_list_utils_unittests.cc
+++ b/display_list/skia/dl_sk_utils_unittests.cc
@@ -3,12 +3,13 @@
// found in the LICENSE file.
#include "flutter/display_list/display_list_utils.h"
+#include "flutter/display_list/skia/dl_sk_utils.h"
#include "gtest/gtest.h"
namespace flutter {
namespace testing {
-class MockDispatchHelper final : public virtual Dispatcher,
+class MockDispatchHelper final : public virtual DlOpReceiver,
public SkPaintDispatchHelper,
public IgnoreClipDispatchHelper,
public IgnoreTransformDispatchHelper,
diff --git a/display_list/testing/dl_test_snippets.cc b/display_list/testing/dl_test_snippets.cc
index 741b0db..2116cf9 100644
--- a/display_list/testing/dl_test_snippets.cc
+++ b/display_list/testing/dl_test_snippets.cc
@@ -4,34 +4,35 @@
#include "flutter/display_list/testing/dl_test_snippets.h"
#include "flutter/display_list/display_list_builder.h"
+#include "flutter/display_list/dl_op_receiver.h"
namespace flutter {
namespace testing {
sk_sp<DisplayList> GetSampleDisplayList() {
DisplayListBuilder builder(SkRect::MakeWH(150, 100));
- builder.setColor(SK_ColorRED);
- builder.drawRect(SkRect::MakeXYWH(10, 10, 80, 80));
+ builder.DrawRect(SkRect::MakeXYWH(10, 10, 80, 80), DlPaint(DlColor::kRed()));
return builder.Build();
}
sk_sp<DisplayList> GetSampleNestedDisplayList() {
DisplayListBuilder builder(SkRect::MakeWH(150, 100));
+ DlPaint paint;
for (int y = 10; y <= 60; y += 10) {
for (int x = 10; x <= 60; x += 10) {
- builder.setColor(((x + y) % 20) == 10 ? SK_ColorRED : SK_ColorBLUE);
- builder.drawRect(SkRect::MakeXYWH(x, y, 80, 80));
+ paint.setColor(((x + y) % 20) == 10 ? SK_ColorRED : SK_ColorBLUE);
+ builder.DrawRect(SkRect::MakeXYWH(x, y, 80, 80), paint);
}
}
DisplayListBuilder outer_builder(SkRect::MakeWH(150, 100));
- outer_builder.drawDisplayList(builder.Build());
+ outer_builder.DrawDisplayList(builder.Build());
return outer_builder.Build();
}
sk_sp<DisplayList> GetSampleDisplayList(int ops) {
DisplayListBuilder builder(SkRect::MakeWH(150, 100));
for (int i = 0; i < ops; i++) {
- builder.drawColor(SK_ColorRED, DlBlendMode::kSrc);
+ builder.DrawColor(DlColor::kRed(), DlBlendMode::kSrc);
}
return builder.Build();
}
@@ -44,192 +45,148 @@
return {
{"SetAntiAlias",
{
- {0, 8, 0, 0, [](DisplayListBuilder& b) { b.setAntiAlias(true); }},
- {0, 0, 0, 0, [](DisplayListBuilder& b) { b.setAntiAlias(false); }},
+ {0, 8, 0, 0, [](DlOpReceiver& r) { r.setAntiAlias(true); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.setAntiAlias(false); }},
}},
{"SetDither",
{
- {0, 8, 0, 0, [](DisplayListBuilder& b) { b.setDither(true); }},
- {0, 0, 0, 0, [](DisplayListBuilder& b) { b.setDither(false); }},
+ {0, 8, 0, 0, [](DlOpReceiver& r) { r.setDither(true); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.setDither(false); }},
}},
{"SetInvertColors",
{
- {0, 8, 0, 0, [](DisplayListBuilder& b) { b.setInvertColors(true); }},
- {0, 0, 0, 0,
- [](DisplayListBuilder& b) { b.setInvertColors(false); }},
+ {0, 8, 0, 0, [](DlOpReceiver& r) { r.setInvertColors(true); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.setInvertColors(false); }},
}},
{"SetStrokeCap",
{
{0, 8, 0, 0,
- [](DisplayListBuilder& b) { b.setStrokeCap(DlStrokeCap::kRound); }},
+ [](DlOpReceiver& r) { r.setStrokeCap(DlStrokeCap::kRound); }},
{0, 8, 0, 0,
- [](DisplayListBuilder& b) {
- b.setStrokeCap(DlStrokeCap::kSquare);
- }},
+ [](DlOpReceiver& r) { r.setStrokeCap(DlStrokeCap::kSquare); }},
{0, 0, 0, 0,
- [](DisplayListBuilder& b) { b.setStrokeCap(DlStrokeCap::kButt); }},
+ [](DlOpReceiver& r) { r.setStrokeCap(DlStrokeCap::kButt); }},
}},
{"SetStrokeJoin",
{
{0, 8, 0, 0,
- [](DisplayListBuilder& b) {
- b.setStrokeJoin(DlStrokeJoin::kBevel);
- }},
+ [](DlOpReceiver& r) { r.setStrokeJoin(DlStrokeJoin::kBevel); }},
{0, 8, 0, 0,
- [](DisplayListBuilder& b) {
- b.setStrokeJoin(DlStrokeJoin::kRound);
- }},
+ [](DlOpReceiver& r) { r.setStrokeJoin(DlStrokeJoin::kRound); }},
{0, 0, 0, 0,
- [](DisplayListBuilder& b) {
- b.setStrokeJoin(DlStrokeJoin::kMiter);
- }},
+ [](DlOpReceiver& r) { r.setStrokeJoin(DlStrokeJoin::kMiter); }},
}},
{"SetStyle",
{
{0, 8, 0, 0,
- [](DisplayListBuilder& b) { b.setStyle(DlDrawStyle::kStroke); }},
+ [](DlOpReceiver& r) { r.setStyle(DlDrawStyle::kStroke); }},
{0, 8, 0, 0,
- [](DisplayListBuilder& b) {
- b.setStyle(DlDrawStyle::kStrokeAndFill);
- }},
+ [](DlOpReceiver& r) { r.setStyle(DlDrawStyle::kStrokeAndFill); }},
{0, 0, 0, 0,
- [](DisplayListBuilder& b) { b.setStyle(DlDrawStyle::kFill); }},
+ [](DlOpReceiver& r) { r.setStyle(DlDrawStyle::kFill); }},
}},
{"SetStrokeWidth",
{
- {0, 8, 0, 0, [](DisplayListBuilder& b) { b.setStrokeWidth(1.0); }},
- {0, 8, 0, 0, [](DisplayListBuilder& b) { b.setStrokeWidth(5.0); }},
- {0, 0, 0, 0, [](DisplayListBuilder& b) { b.setStrokeWidth(0.0); }},
+ {0, 8, 0, 0, [](DlOpReceiver& r) { r.setStrokeWidth(1.0); }},
+ {0, 8, 0, 0, [](DlOpReceiver& r) { r.setStrokeWidth(5.0); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.setStrokeWidth(0.0); }},
}},
{"SetStrokeMiter",
{
- {0, 8, 0, 0, [](DisplayListBuilder& b) { b.setStrokeMiter(0.0); }},
- {0, 8, 0, 0, [](DisplayListBuilder& b) { b.setStrokeMiter(5.0); }},
- {0, 0, 0, 0, [](DisplayListBuilder& b) { b.setStrokeMiter(4.0); }},
+ {0, 8, 0, 0, [](DlOpReceiver& r) { r.setStrokeMiter(0.0); }},
+ {0, 8, 0, 0, [](DlOpReceiver& r) { r.setStrokeMiter(5.0); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.setStrokeMiter(4.0); }},
}},
{"SetColor",
{
- {0, 8, 0, 0,
- [](DisplayListBuilder& b) { b.setColor(SK_ColorGREEN); }},
- {0, 8, 0, 0,
- [](DisplayListBuilder& b) { b.setColor(SK_ColorBLUE); }},
- {0, 0, 0, 0,
- [](DisplayListBuilder& b) { b.setColor(SK_ColorBLACK); }},
+ {0, 8, 0, 0, [](DlOpReceiver& r) { r.setColor(SK_ColorGREEN); }},
+ {0, 8, 0, 0, [](DlOpReceiver& r) { r.setColor(SK_ColorBLUE); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.setColor(SK_ColorBLACK); }},
}},
{"SetBlendMode",
{
{0, 8, 0, 0,
- [](DisplayListBuilder& b) { b.setBlendMode(DlBlendMode::kSrcIn); }},
+ [](DlOpReceiver& r) { r.setBlendMode(DlBlendMode::kSrcIn); }},
{0, 8, 0, 0,
- [](DisplayListBuilder& b) { b.setBlendMode(DlBlendMode::kDstIn); }},
+ [](DlOpReceiver& r) { r.setBlendMode(DlBlendMode::kDstIn); }},
{0, 0, 0, 0,
- [](DisplayListBuilder& b) {
- b.setBlendMode(DlBlendMode::kSrcOver);
- }},
+ [](DlOpReceiver& r) { r.setBlendMode(DlBlendMode::kSrcOver); }},
}},
{"SetColorSource",
{
{0, 96, 0, 0,
- [](DisplayListBuilder& b) { b.setColorSource(&kTestSource1); }},
+ [](DlOpReceiver& r) { r.setColorSource(&kTestSource1); }},
// stop_count * (sizeof(float) + sizeof(uint32_t)) = 80
{0, 80 + 6 * 4, 0, 0,
- [](DisplayListBuilder& b) {
- b.setColorSource(kTestSource2.get());
- }},
+ [](DlOpReceiver& r) { r.setColorSource(kTestSource2.get()); }},
{0, 80 + 6 * 4, 0, 0,
- [](DisplayListBuilder& b) {
- b.setColorSource(kTestSource3.get());
- }},
+ [](DlOpReceiver& r) { r.setColorSource(kTestSource3.get()); }},
{0, 88 + 6 * 4, 0, 0,
- [](DisplayListBuilder& b) {
- b.setColorSource(kTestSource4.get());
- }},
+ [](DlOpReceiver& r) { r.setColorSource(kTestSource4.get()); }},
{0, 80 + 6 * 4, 0, 0,
- [](DisplayListBuilder& b) {
- b.setColorSource(kTestSource5.get());
- }},
- {0, 0, 0, 0,
- [](DisplayListBuilder& b) { b.setColorSource(nullptr); }},
+ [](DlOpReceiver& r) { r.setColorSource(kTestSource5.get()); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.setColorSource(nullptr); }},
}},
{"SetImageFilter",
{
{0, 32, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestBlurImageFilter1);
- }},
+ [](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter1); }},
{0, 32, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestBlurImageFilter2);
- }},
+ [](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter2); }},
{0, 32, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestBlurImageFilter3);
- }},
+ [](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter3); }},
{0, 32, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestBlurImageFilter4);
+ [](DlOpReceiver& r) { r.setImageFilter(&kTestBlurImageFilter4); }},
+ {0, 24, 0, 0,
+ [](DlOpReceiver& r) {
+ r.setImageFilter(&kTestDilateImageFilter1);
}},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestDilateImageFilter1);
+ [](DlOpReceiver& r) {
+ r.setImageFilter(&kTestDilateImageFilter2);
}},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestDilateImageFilter2);
+ [](DlOpReceiver& r) {
+ r.setImageFilter(&kTestDilateImageFilter3);
}},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestDilateImageFilter3);
- }},
+ [](DlOpReceiver& r) { r.setImageFilter(&kTestErodeImageFilter1); }},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestErodeImageFilter1);
- }},
+ [](DlOpReceiver& r) { r.setImageFilter(&kTestErodeImageFilter2); }},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestErodeImageFilter2);
- }},
- {0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestErodeImageFilter3);
+ [](DlOpReceiver& r) { r.setImageFilter(&kTestErodeImageFilter3); }},
+ {0, 64, 0, 0,
+ [](DlOpReceiver& r) {
+ r.setImageFilter(&kTestMatrixImageFilter1);
}},
{0, 64, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestMatrixImageFilter1);
+ [](DlOpReceiver& r) {
+ r.setImageFilter(&kTestMatrixImageFilter2);
}},
{0, 64, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestMatrixImageFilter2);
- }},
- {0, 64, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestMatrixImageFilter3);
+ [](DlOpReceiver& r) {
+ r.setImageFilter(&kTestMatrixImageFilter3);
}},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestComposeImageFilter1);
+ [](DlOpReceiver& r) {
+ r.setImageFilter(&kTestComposeImageFilter1);
}},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestComposeImageFilter2);
+ [](DlOpReceiver& r) {
+ r.setImageFilter(&kTestComposeImageFilter2);
}},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestComposeImageFilter3);
+ [](DlOpReceiver& r) {
+ r.setImageFilter(&kTestComposeImageFilter3);
}},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestCFImageFilter1);
- }},
+ [](DlOpReceiver& r) { r.setImageFilter(&kTestCFImageFilter1); }},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(&kTestCFImageFilter2);
- }},
- {0, 0, 0, 0,
- [](DisplayListBuilder& b) { b.setImageFilter(nullptr); }},
+ [](DlOpReceiver& r) { r.setImageFilter(&kTestCFImageFilter2); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.setImageFilter(nullptr); }},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setImageFilter(
+ [](DlOpReceiver& r) {
+ r.setImageFilter(
kTestBlurImageFilter1
.makeWithLocalMatrix(SkMatrix::Translate(2, 2))
.get());
@@ -238,64 +195,51 @@
{"SetColorFilter",
{
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setColorFilter(&kTestBlendColorFilter1);
- }},
+ [](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter1); }},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setColorFilter(&kTestBlendColorFilter2);
- }},
+ [](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter2); }},
{0, 24, 0, 0,
- [](DisplayListBuilder& b) {
- b.setColorFilter(&kTestBlendColorFilter3);
+ [](DlOpReceiver& r) { r.setColorFilter(&kTestBlendColorFilter3); }},
+ {0, 96, 0, 0,
+ [](DlOpReceiver& r) {
+ r.setColorFilter(&kTestMatrixColorFilter1);
}},
{0, 96, 0, 0,
- [](DisplayListBuilder& b) {
- b.setColorFilter(&kTestMatrixColorFilter1);
- }},
- {0, 96, 0, 0,
- [](DisplayListBuilder& b) {
- b.setColorFilter(&kTestMatrixColorFilter2);
+ [](DlOpReceiver& r) {
+ r.setColorFilter(&kTestMatrixColorFilter2);
}},
{0, 16, 0, 0,
- [](DisplayListBuilder& b) {
- b.setColorFilter(DlSrgbToLinearGammaColorFilter::instance.get());
+ [](DlOpReceiver& r) {
+ r.setColorFilter(DlSrgbToLinearGammaColorFilter::instance.get());
}},
{0, 16, 0, 0,
- [](DisplayListBuilder& b) {
- b.setColorFilter(DlLinearToSrgbGammaColorFilter::instance.get());
+ [](DlOpReceiver& r) {
+ r.setColorFilter(DlLinearToSrgbGammaColorFilter::instance.get());
}},
- {0, 0, 0, 0,
- [](DisplayListBuilder& b) { b.setColorFilter(nullptr); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.setColorFilter(nullptr); }},
}},
{"SetPathEffect",
{
// sizeof(DlDashPathEffect) + 2 * sizeof(SkScalar)
{0, 32, 0, 0,
- [](DisplayListBuilder& b) {
- b.setPathEffect(kTestPathEffect1.get());
- }},
+ [](DlOpReceiver& r) { r.setPathEffect(kTestPathEffect1.get()); }},
{0, 32, 0, 0,
- [](DisplayListBuilder& b) {
- b.setPathEffect(kTestPathEffect2.get());
- }},
- {0, 0, 0, 0,
- [](DisplayListBuilder& b) { b.setPathEffect(nullptr); }},
+ [](DlOpReceiver& r) { r.setPathEffect(kTestPathEffect2.get()); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.setPathEffect(nullptr); }},
}},
{"SetMaskFilter",
{
{0, 32, 0, 0,
- [](DisplayListBuilder& b) { b.setMaskFilter(&kTestMaskFilter1); }},
+ [](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter1); }},
{0, 32, 0, 0,
- [](DisplayListBuilder& b) { b.setMaskFilter(&kTestMaskFilter2); }},
+ [](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter2); }},
{0, 32, 0, 0,
- [](DisplayListBuilder& b) { b.setMaskFilter(&kTestMaskFilter3); }},
+ [](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter3); }},
{0, 32, 0, 0,
- [](DisplayListBuilder& b) { b.setMaskFilter(&kTestMaskFilter4); }},
+ [](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter4); }},
{0, 32, 0, 0,
- [](DisplayListBuilder& b) { b.setMaskFilter(&kTestMaskFilter5); }},
- {0, 0, 0, 0,
- [](DisplayListBuilder& b) { b.setMaskFilter(nullptr); }},
+ [](DlOpReceiver& r) { r.setMaskFilter(&kTestMaskFilter5); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.setMaskFilter(nullptr); }},
}},
};
}
@@ -305,13 +249,13 @@
{"Save(Layer)+Restore",
{
{5, 112, 5, 112,
- [](DisplayListBuilder& b) {
- b.saveLayer(nullptr, SaveLayerOptions::kNoAttributes,
+ [](DlOpReceiver& r) {
+ r.saveLayer(nullptr, SaveLayerOptions::kNoAttributes,
&kTestCFImageFilter1);
- b.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
- b.drawRect({5, 5, 15, 15});
- b.drawRect({10, 10, 20, 20});
- b.restore();
+ r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
+ r.drawRect({5, 5, 15, 15});
+ r.drawRect({10, 10, 20, 20});
+ r.restore();
}},
// There are many reasons that save and restore can elide content,
// including whether or not there are any draw operations between
@@ -321,80 +265,80 @@
// cases we include at least one clip operation and 2 overlapping
// rendering primitives between each save/restore pair.
{5, 96, 5, 96,
- [](DisplayListBuilder& b) {
- b.save();
- b.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
- b.drawRect({5, 5, 15, 15});
- b.drawRect({10, 10, 20, 20});
- b.restore();
+ [](DlOpReceiver& r) {
+ r.save();
+ r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
+ r.drawRect({5, 5, 15, 15});
+ r.drawRect({10, 10, 20, 20});
+ r.restore();
}},
{5, 96, 5, 96,
- [](DisplayListBuilder& b) {
- b.saveLayer(nullptr, false);
- b.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
- b.drawRect({5, 5, 15, 15});
- b.drawRect({10, 10, 20, 20});
- b.restore();
+ [](DlOpReceiver& r) {
+ r.saveLayer(nullptr, SaveLayerOptions::kNoAttributes);
+ r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
+ r.drawRect({5, 5, 15, 15});
+ r.drawRect({10, 10, 20, 20});
+ r.restore();
}},
{5, 96, 5, 96,
- [](DisplayListBuilder& b) {
- b.saveLayer(nullptr, true);
- b.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
- b.drawRect({5, 5, 15, 15});
- b.drawRect({10, 10, 20, 20});
- b.restore();
+ [](DlOpReceiver& r) {
+ r.saveLayer(nullptr, SaveLayerOptions::kWithAttributes);
+ r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
+ r.drawRect({5, 5, 15, 15});
+ r.drawRect({10, 10, 20, 20});
+ r.restore();
}},
{5, 112, 5, 112,
- [](DisplayListBuilder& b) {
- b.saveLayer(&kTestBounds, false);
- b.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
- b.drawRect({5, 5, 15, 15});
- b.drawRect({10, 10, 20, 20});
- b.restore();
+ [](DlOpReceiver& r) {
+ r.saveLayer(&kTestBounds, SaveLayerOptions::kNoAttributes);
+ r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
+ r.drawRect({5, 5, 15, 15});
+ r.drawRect({10, 10, 20, 20});
+ r.restore();
}},
{5, 112, 5, 112,
- [](DisplayListBuilder& b) {
- b.saveLayer(&kTestBounds, true);
- b.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
- b.drawRect({5, 5, 15, 15});
- b.drawRect({10, 10, 20, 20});
- b.restore();
+ [](DlOpReceiver& r) {
+ r.saveLayer(&kTestBounds, SaveLayerOptions::kWithAttributes);
+ r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
+ r.drawRect({5, 5, 15, 15});
+ r.drawRect({10, 10, 20, 20});
+ r.restore();
}},
// backdrop variants - using the TestCFImageFilter because it can be
// reconstituted in the DL->SkCanvas->DL stream
- // {5, 104, 5, 104, [](DisplayListBuilder& b) {
- // b.saveLayer(nullptr, SaveLayerOptions::kNoAttributes,
- // &kTestCFImageFilter1); b.clipRect({0, 0, 25, 25},
- // SkClipOp::kIntersect, true); b.drawRect({5, 5, 15, 15});
- // b.drawRect({10, 10, 20, 20});
- // b.restore();
+ // {5, 104, 5, 104, [](DlOpReceiver& r) {
+ // r.saveLayer(nullptr, SaveLayerOptions::kNoAttributes,
+ // &kTestCFImageFilter1); r.clipRect({0, 0, 25, 25},
+ // SkClipOp::kIntersect, true); r.drawRect({5, 5, 15, 15});
+ // r.drawRect({10, 10, 20, 20});
+ // r.restore();
// }},
{5, 112, 5, 112,
- [](DisplayListBuilder& b) {
- b.saveLayer(nullptr, SaveLayerOptions::kWithAttributes,
+ [](DlOpReceiver& r) {
+ r.saveLayer(nullptr, SaveLayerOptions::kWithAttributes,
&kTestCFImageFilter1);
- b.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
- b.drawRect({5, 5, 15, 15});
- b.drawRect({10, 10, 20, 20});
- b.restore();
+ r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
+ r.drawRect({5, 5, 15, 15});
+ r.drawRect({10, 10, 20, 20});
+ r.restore();
}},
{5, 128, 5, 128,
- [](DisplayListBuilder& b) {
- b.saveLayer(&kTestBounds, SaveLayerOptions::kNoAttributes,
+ [](DlOpReceiver& r) {
+ r.saveLayer(&kTestBounds, SaveLayerOptions::kNoAttributes,
&kTestCFImageFilter1);
- b.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
- b.drawRect({5, 5, 15, 15});
- b.drawRect({10, 10, 20, 20});
- b.restore();
+ r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
+ r.drawRect({5, 5, 15, 15});
+ r.drawRect({10, 10, 20, 20});
+ r.restore();
}},
{5, 128, 5, 128,
- [](DisplayListBuilder& b) {
- b.saveLayer(&kTestBounds, SaveLayerOptions::kWithAttributes,
+ [](DlOpReceiver& r) {
+ r.saveLayer(&kTestBounds, SaveLayerOptions::kWithAttributes,
&kTestCFImageFilter1);
- b.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
- b.drawRect({5, 5, 15, 15});
- b.drawRect({10, 10, 20, 20});
- b.restore();
+ r.clipRect({0, 0, 25, 25}, DlCanvas::ClipOp::kIntersect, true);
+ r.drawRect({5, 5, 15, 15});
+ r.drawRect({10, 10, 20, 20});
+ r.restore();
}},
}},
};
@@ -405,65 +349,61 @@
{"Translate",
{
// cv.translate(0, 0) is ignored
- {1, 16, 1, 16, [](DisplayListBuilder& b) { b.translate(10, 10); }},
- {1, 16, 1, 16, [](DisplayListBuilder& b) { b.translate(10, 15); }},
- {1, 16, 1, 16, [](DisplayListBuilder& b) { b.translate(15, 10); }},
- {0, 0, 0, 0, [](DisplayListBuilder& b) { b.translate(0, 0); }},
+ {1, 16, 1, 16, [](DlOpReceiver& r) { r.translate(10, 10); }},
+ {1, 16, 1, 16, [](DlOpReceiver& r) { r.translate(10, 15); }},
+ {1, 16, 1, 16, [](DlOpReceiver& r) { r.translate(15, 10); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.translate(0, 0); }},
}},
{"Scale",
{
// cv.scale(1, 1) is ignored
- {1, 16, 1, 16, [](DisplayListBuilder& b) { b.scale(2, 2); }},
- {1, 16, 1, 16, [](DisplayListBuilder& b) { b.scale(2, 3); }},
- {1, 16, 1, 16, [](DisplayListBuilder& b) { b.scale(3, 2); }},
- {0, 0, 0, 0, [](DisplayListBuilder& b) { b.scale(1, 1); }},
+ {1, 16, 1, 16, [](DlOpReceiver& r) { r.scale(2, 2); }},
+ {1, 16, 1, 16, [](DlOpReceiver& r) { r.scale(2, 3); }},
+ {1, 16, 1, 16, [](DlOpReceiver& r) { r.scale(3, 2); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.scale(1, 1); }},
}},
{"Rotate",
{
// cv.rotate(0) is ignored, otherwise expressed as concat(rotmatrix)
- {1, 8, 1, 32, [](DisplayListBuilder& b) { b.rotate(30); }},
- {1, 8, 1, 32, [](DisplayListBuilder& b) { b.rotate(45); }},
- {0, 0, 0, 0, [](DisplayListBuilder& b) { b.rotate(0); }},
- {0, 0, 0, 0, [](DisplayListBuilder& b) { b.rotate(360); }},
+ {1, 8, 1, 32, [](DlOpReceiver& r) { r.rotate(30); }},
+ {1, 8, 1, 32, [](DlOpReceiver& r) { r.rotate(45); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.rotate(0); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.rotate(360); }},
}},
{"Skew",
{
// cv.skew(0, 0) is ignored, otherwise expressed as
// concat(skewmatrix)
- {1, 16, 1, 32, [](DisplayListBuilder& b) { b.skew(0.1, 0.1); }},
- {1, 16, 1, 32, [](DisplayListBuilder& b) { b.skew(0.1, 0.2); }},
- {1, 16, 1, 32, [](DisplayListBuilder& b) { b.skew(0.2, 0.1); }},
- {0, 0, 0, 0, [](DisplayListBuilder& b) { b.skew(0, 0); }},
+ {1, 16, 1, 32, [](DlOpReceiver& r) { r.skew(0.1, 0.1); }},
+ {1, 16, 1, 32, [](DlOpReceiver& r) { r.skew(0.1, 0.2); }},
+ {1, 16, 1, 32, [](DlOpReceiver& r) { r.skew(0.2, 0.1); }},
+ {0, 0, 0, 0, [](DlOpReceiver& r) { r.skew(0, 0); }},
}},
{"Transform2DAffine",
{
{1, 32, 1, 32,
- [](DisplayListBuilder& b) {
- b.transform2DAffine(0, 1, 12, 1, 0, 33);
- }},
- // b.transform(identity) is ignored
+ [](DlOpReceiver& r) { r.transform2DAffine(0, 1, 12, 1, 0, 33); }},
+ // r.transform(identity) is ignored
{0, 0, 0, 0,
- [](DisplayListBuilder& b) {
- b.transform2DAffine(1, 0, 0, 0, 1, 0);
- }},
+ [](DlOpReceiver& r) { r.transform2DAffine(1, 0, 0, 0, 1, 0); }},
}},
{"TransformFullPerspective",
{
{1, 72, 1, 72,
- [](DisplayListBuilder& b) {
- b.transformFullPerspective(0, 1, 0, 12, 1, 0, 0, 33, 3, 2, 5, 29,
+ [](DlOpReceiver& r) {
+ r.transformFullPerspective(0, 1, 0, 12, 1, 0, 0, 33, 3, 2, 5, 29,
0, 0, 0, 12);
}},
- // b.transform(2D affine) is reduced to 2x3
+ // r.transform(2D affine) is reduced to 2x3
{1, 32, 1, 32,
- [](DisplayListBuilder& b) {
- b.transformFullPerspective(2, 1, 0, 4, 1, 3, 0, 5, 0, 0, 1, 0, 0,
+ [](DlOpReceiver& r) {
+ r.transformFullPerspective(2, 1, 0, 4, 1, 3, 0, 5, 0, 0, 1, 0, 0,
0, 0, 1);
}},
- // b.transform(identity) is ignored
+ // r.transform(identity) is ignored
{0, 0, 0, 0,
- [](DisplayListBuilder& b) {
- b.transformFullPerspective(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
+ [](DlOpReceiver& r) {
+ r.transformFullPerspective(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0,
0, 0, 1);
}},
}},
@@ -475,86 +415,86 @@
{"ClipRect",
{
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipRect(kTestBounds, DlCanvas::ClipOp::kIntersect, true);
+ [](DlOpReceiver& r) {
+ r.clipRect(kTestBounds, DlCanvas::ClipOp::kIntersect, true);
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipRect(kTestBounds.makeOffset(1, 1),
+ [](DlOpReceiver& r) {
+ r.clipRect(kTestBounds.makeOffset(1, 1),
DlCanvas::ClipOp::kIntersect, true);
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipRect(kTestBounds, DlCanvas::ClipOp::kIntersect, false);
+ [](DlOpReceiver& r) {
+ r.clipRect(kTestBounds, DlCanvas::ClipOp::kIntersect, false);
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipRect(kTestBounds, DlCanvas::ClipOp::kDifference, true);
+ [](DlOpReceiver& r) {
+ r.clipRect(kTestBounds, DlCanvas::ClipOp::kDifference, true);
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipRect(kTestBounds, DlCanvas::ClipOp::kDifference, false);
+ [](DlOpReceiver& r) {
+ r.clipRect(kTestBounds, DlCanvas::ClipOp::kDifference, false);
}},
}},
{"ClipRRect",
{
{1, 64, 1, 64,
- [](DisplayListBuilder& b) {
- b.clipRRect(kTestRRect, DlCanvas::ClipOp::kIntersect, true);
+ [](DlOpReceiver& r) {
+ r.clipRRect(kTestRRect, DlCanvas::ClipOp::kIntersect, true);
}},
{1, 64, 1, 64,
- [](DisplayListBuilder& b) {
- b.clipRRect(kTestRRect.makeOffset(1, 1),
+ [](DlOpReceiver& r) {
+ r.clipRRect(kTestRRect.makeOffset(1, 1),
DlCanvas::ClipOp::kIntersect, true);
}},
{1, 64, 1, 64,
- [](DisplayListBuilder& b) {
- b.clipRRect(kTestRRect, DlCanvas::ClipOp::kIntersect, false);
+ [](DlOpReceiver& r) {
+ r.clipRRect(kTestRRect, DlCanvas::ClipOp::kIntersect, false);
}},
{1, 64, 1, 64,
- [](DisplayListBuilder& b) {
- b.clipRRect(kTestRRect, DlCanvas::ClipOp::kDifference, true);
+ [](DlOpReceiver& r) {
+ r.clipRRect(kTestRRect, DlCanvas::ClipOp::kDifference, true);
}},
{1, 64, 1, 64,
- [](DisplayListBuilder& b) {
- b.clipRRect(kTestRRect, DlCanvas::ClipOp::kDifference, false);
+ [](DlOpReceiver& r) {
+ r.clipRRect(kTestRRect, DlCanvas::ClipOp::kDifference, false);
}},
}},
{"ClipPath",
{
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipPath(kTestPath1, DlCanvas::ClipOp::kIntersect, true);
+ [](DlOpReceiver& r) {
+ r.clipPath(kTestPath1, DlCanvas::ClipOp::kIntersect, true);
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipPath(kTestPath2, DlCanvas::ClipOp::kIntersect, true);
+ [](DlOpReceiver& r) {
+ r.clipPath(kTestPath2, DlCanvas::ClipOp::kIntersect, true);
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipPath(kTestPath3, DlCanvas::ClipOp::kIntersect, true);
+ [](DlOpReceiver& r) {
+ r.clipPath(kTestPath3, DlCanvas::ClipOp::kIntersect, true);
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipPath(kTestPath1, DlCanvas::ClipOp::kIntersect, false);
+ [](DlOpReceiver& r) {
+ r.clipPath(kTestPath1, DlCanvas::ClipOp::kIntersect, false);
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipPath(kTestPath1, DlCanvas::ClipOp::kDifference, true);
+ [](DlOpReceiver& r) {
+ r.clipPath(kTestPath1, DlCanvas::ClipOp::kDifference, true);
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipPath(kTestPath1, DlCanvas::ClipOp::kDifference, false);
+ [](DlOpReceiver& r) {
+ r.clipPath(kTestPath1, DlCanvas::ClipOp::kDifference, false);
}},
// clipPath(rect) becomes clipRect
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.clipPath(kTestPathRect, DlCanvas::ClipOp::kIntersect, true);
+ [](DlOpReceiver& r) {
+ r.clipPath(kTestPathRect, DlCanvas::ClipOp::kIntersect, true);
}},
// clipPath(oval) becomes clipRRect
{1, 64, 1, 64,
- [](DisplayListBuilder& b) {
- b.clipPath(kTestPathOval, DlCanvas::ClipOp::kIntersect, true);
+ [](DlOpReceiver& r) {
+ r.clipPath(kTestPathOval, DlCanvas::ClipOp::kIntersect, true);
}},
}},
};
@@ -564,268 +504,256 @@
return {
{"DrawPaint",
{
- {1, 8, 1, 8, [](DisplayListBuilder& b) { b.drawPaint(); }},
+ {1, 8, 1, 8, [](DlOpReceiver& r) { r.drawPaint(); }},
}},
{"DrawColor",
{
// cv.drawColor becomes cv.drawPaint(paint)
{1, 16, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawColor(SK_ColorBLUE, DlBlendMode::kSrcIn);
+ [](DlOpReceiver& r) {
+ r.drawColor(SK_ColorBLUE, DlBlendMode::kSrcIn);
}},
{1, 16, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawColor(SK_ColorBLUE, DlBlendMode::kDstIn);
+ [](DlOpReceiver& r) {
+ r.drawColor(SK_ColorBLUE, DlBlendMode::kDstIn);
}},
{1, 16, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawColor(SK_ColorCYAN, DlBlendMode::kSrcIn);
+ [](DlOpReceiver& r) {
+ r.drawColor(SK_ColorCYAN, DlBlendMode::kSrcIn);
}},
}},
{"DrawLine",
{
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawLine({0, 0}, {10, 10});
+ [](DlOpReceiver& r) {
+ r.drawLine({0, 0}, {10, 10});
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawLine({0, 1}, {10, 10});
+ [](DlOpReceiver& r) {
+ r.drawLine({0, 1}, {10, 10});
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawLine({0, 0}, {20, 10});
+ [](DlOpReceiver& r) {
+ r.drawLine({0, 0}, {20, 10});
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawLine({0, 0}, {10, 20});
+ [](DlOpReceiver& r) {
+ r.drawLine({0, 0}, {10, 20});
}},
}},
{"DrawRect",
{
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawRect({0, 0, 10, 10});
+ [](DlOpReceiver& r) {
+ r.drawRect({0, 0, 10, 10});
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawRect({0, 1, 10, 10});
+ [](DlOpReceiver& r) {
+ r.drawRect({0, 1, 10, 10});
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawRect({0, 0, 20, 10});
+ [](DlOpReceiver& r) {
+ r.drawRect({0, 0, 20, 10});
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawRect({0, 0, 10, 20});
+ [](DlOpReceiver& r) {
+ r.drawRect({0, 0, 10, 20});
}},
}},
{"DrawOval",
{
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawOval({0, 0, 10, 10});
+ [](DlOpReceiver& r) {
+ r.drawOval({0, 0, 10, 10});
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawOval({0, 1, 10, 10});
+ [](DlOpReceiver& r) {
+ r.drawOval({0, 1, 10, 10});
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawOval({0, 0, 20, 10});
+ [](DlOpReceiver& r) {
+ r.drawOval({0, 0, 20, 10});
}},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawOval({0, 0, 10, 20});
+ [](DlOpReceiver& r) {
+ r.drawOval({0, 0, 10, 20});
}},
}},
{"DrawCircle",
{
// cv.drawCircle becomes cv.drawOval
{1, 16, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawCircle({0, 0}, 10);
+ [](DlOpReceiver& r) {
+ r.drawCircle({0, 0}, 10);
}},
{1, 16, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawCircle({0, 5}, 10);
+ [](DlOpReceiver& r) {
+ r.drawCircle({0, 5}, 10);
}},
{1, 16, 1, 24,
- [](DisplayListBuilder& b) {
- b.drawCircle({0, 0}, 20);
+ [](DlOpReceiver& r) {
+ r.drawCircle({0, 0}, 20);
}},
}},
{"DrawRRect",
{
+ {1, 56, 1, 56, [](DlOpReceiver& r) { r.drawRRect(kTestRRect); }},
{1, 56, 1, 56,
- [](DisplayListBuilder& b) { b.drawRRect(kTestRRect); }},
- {1, 56, 1, 56,
- [](DisplayListBuilder& b) {
- b.drawRRect(kTestRRect.makeOffset(5, 5));
- }},
+ [](DlOpReceiver& r) { r.drawRRect(kTestRRect.makeOffset(5, 5)); }},
}},
{"DrawDRRect",
{
{1, 112, 1, 112,
- [](DisplayListBuilder& b) {
- b.drawDRRect(kTestRRect, kTestInnerRRect);
- }},
+ [](DlOpReceiver& r) { r.drawDRRect(kTestRRect, kTestInnerRRect); }},
{1, 112, 1, 112,
- [](DisplayListBuilder& b) {
- b.drawDRRect(kTestRRect.makeOffset(5, 5),
+ [](DlOpReceiver& r) {
+ r.drawDRRect(kTestRRect.makeOffset(5, 5),
kTestInnerRRect.makeOffset(4, 4));
}},
}},
{"DrawPath",
{
- {1, 24, 1, 24,
- [](DisplayListBuilder& b) { b.drawPath(kTestPath1); }},
- {1, 24, 1, 24,
- [](DisplayListBuilder& b) { b.drawPath(kTestPath2); }},
- {1, 24, 1, 24,
- [](DisplayListBuilder& b) { b.drawPath(kTestPath3); }},
- {1, 24, 1, 24,
- [](DisplayListBuilder& b) { b.drawPath(kTestPathRect); }},
- {1, 24, 1, 24,
- [](DisplayListBuilder& b) { b.drawPath(kTestPathOval); }},
+ {1, 24, 1, 24, [](DlOpReceiver& r) { r.drawPath(kTestPath1); }},
+ {1, 24, 1, 24, [](DlOpReceiver& r) { r.drawPath(kTestPath2); }},
+ {1, 24, 1, 24, [](DlOpReceiver& r) { r.drawPath(kTestPath3); }},
+ {1, 24, 1, 24, [](DlOpReceiver& r) { r.drawPath(kTestPathRect); }},
+ {1, 24, 1, 24, [](DlOpReceiver& r) { r.drawPath(kTestPathOval); }},
}},
{"DrawArc",
{
{1, 32, 1, 32,
- [](DisplayListBuilder& b) {
- b.drawArc(kTestBounds, 45, 270, false);
+ [](DlOpReceiver& r) { r.drawArc(kTestBounds, 45, 270, false); }},
+ {1, 32, 1, 32,
+ [](DlOpReceiver& r) {
+ r.drawArc(kTestBounds.makeOffset(1, 1), 45, 270, false);
}},
{1, 32, 1, 32,
- [](DisplayListBuilder& b) {
- b.drawArc(kTestBounds.makeOffset(1, 1), 45, 270, false);
- }},
+ [](DlOpReceiver& r) { r.drawArc(kTestBounds, 30, 270, false); }},
{1, 32, 1, 32,
- [](DisplayListBuilder& b) {
- b.drawArc(kTestBounds, 30, 270, false);
- }},
+ [](DlOpReceiver& r) { r.drawArc(kTestBounds, 45, 260, false); }},
{1, 32, 1, 32,
- [](DisplayListBuilder& b) {
- b.drawArc(kTestBounds, 45, 260, false);
- }},
- {1, 32, 1, 32,
- [](DisplayListBuilder& b) {
- b.drawArc(kTestBounds, 45, 270, true);
- }},
+ [](DlOpReceiver& r) { r.drawArc(kTestBounds, 45, 270, true); }},
}},
{"DrawPoints",
{
{1, 8 + TestPointCount * 8, 1, 8 + TestPointCount * 8,
- [](DisplayListBuilder& b) {
- b.drawPoints(DlCanvas::PointMode::kPoints, TestPointCount,
+ [](DlOpReceiver& r) {
+ r.drawPoints(DlCanvas::PointMode::kPoints, TestPointCount,
TestPoints);
}},
{1, 8 + (TestPointCount - 1) * 8, 1, 8 + (TestPointCount - 1) * 8,
- [](DisplayListBuilder& b) {
- b.drawPoints(DlCanvas::PointMode::kPoints, TestPointCount - 1,
+ [](DlOpReceiver& r) {
+ r.drawPoints(DlCanvas::PointMode::kPoints, TestPointCount - 1,
TestPoints);
}},
{1, 8 + TestPointCount * 8, 1, 8 + TestPointCount * 8,
- [](DisplayListBuilder& b) {
- b.drawPoints(DlCanvas::PointMode::kLines, TestPointCount,
+ [](DlOpReceiver& r) {
+ r.drawPoints(DlCanvas::PointMode::kLines, TestPointCount,
TestPoints);
}},
{1, 8 + TestPointCount * 8, 1, 8 + TestPointCount * 8,
- [](DisplayListBuilder& b) {
- b.drawPoints(DlCanvas::PointMode::kPolygon, TestPointCount,
+ [](DlOpReceiver& r) {
+ r.drawPoints(DlCanvas::PointMode::kPolygon, TestPointCount,
TestPoints);
}},
}},
{"DrawVertices",
{
{1, 112, 1, 16,
- [](DisplayListBuilder& b) {
- b.drawVertices(TestVertices1, DlBlendMode::kSrcIn);
+ [](DlOpReceiver& r) {
+ r.drawVertices(TestVertices1.get(), DlBlendMode::kSrcIn);
}},
{1, 112, 1, 16,
- [](DisplayListBuilder& b) {
- b.drawVertices(TestVertices1, DlBlendMode::kDstIn);
+ [](DlOpReceiver& r) {
+ r.drawVertices(TestVertices1.get(), DlBlendMode::kDstIn);
}},
{1, 112, 1, 16,
- [](DisplayListBuilder& b) {
- b.drawVertices(TestVertices2, DlBlendMode::kSrcIn);
+ [](DlOpReceiver& r) {
+ r.drawVertices(TestVertices2.get(), DlBlendMode::kSrcIn);
}},
}},
{"DrawImage",
{
{1, 24, -1, 48,
- [](DisplayListBuilder& b) {
- b.drawImage(TestImage1, {10, 10}, kNearestSampling, false);
+ [](DlOpReceiver& r) {
+ r.drawImage(TestImage1, {10, 10}, kNearestSampling, false);
}},
{1, 24, -1, 48,
- [](DisplayListBuilder& b) {
- b.drawImage(TestImage1, {10, 10}, kNearestSampling, true);
+ [](DlOpReceiver& r) {
+ r.drawImage(TestImage1, {10, 10}, kNearestSampling, true);
}},
{1, 24, -1, 48,
- [](DisplayListBuilder& b) {
- b.drawImage(TestImage1, {20, 10}, kNearestSampling, false);
+ [](DlOpReceiver& r) {
+ r.drawImage(TestImage1, {20, 10}, kNearestSampling, false);
}},
{1, 24, -1, 48,
- [](DisplayListBuilder& b) {
- b.drawImage(TestImage1, {10, 20}, kNearestSampling, false);
+ [](DlOpReceiver& r) {
+ r.drawImage(TestImage1, {10, 20}, kNearestSampling, false);
}},
{1, 24, -1, 48,
- [](DisplayListBuilder& b) {
- b.drawImage(TestImage1, {10, 10}, kLinearSampling, false);
+ [](DlOpReceiver& r) {
+ r.drawImage(TestImage1, {10, 10}, kLinearSampling, false);
}},
{1, 24, -1, 48,
- [](DisplayListBuilder& b) {
- b.drawImage(TestImage2, {10, 10}, kNearestSampling, false);
+ [](DlOpReceiver& r) {
+ r.drawImage(TestImage2, {10, 10}, kNearestSampling, false);
}},
{1, 24, -1, 48,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
- b.drawImage(dl_image, {10, 10}, kNearestSampling, false);
+ r.drawImage(dl_image, {10, 10}, kNearestSampling, false);
}},
}},
{"DrawImageRect",
{
{1, 56, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
- kNearestSampling, false);
+ [](DlOpReceiver& r) {
+ r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
+ kNearestSampling, false,
+ DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
- kNearestSampling, true);
+ [](DlOpReceiver& r) {
+ r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
+ kNearestSampling, true,
+ DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageRect(
- TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
- kNearestSampling, false,
- SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint);
+ [](DlOpReceiver& r) {
+ r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
+ kNearestSampling, false,
+ DlCanvas::SrcRectConstraint::kStrict);
}},
{1, 56, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageRect(TestImage1, {10, 10, 25, 20}, {10, 10, 80, 80},
- kNearestSampling, false);
+ [](DlOpReceiver& r) {
+ r.drawImageRect(TestImage1, {10, 10, 25, 20}, {10, 10, 80, 80},
+ kNearestSampling, false,
+ DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 85, 80},
- kNearestSampling, false);
+ [](DlOpReceiver& r) {
+ r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 85, 80},
+ kNearestSampling, false,
+ DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
- kLinearSampling, false);
+ [](DlOpReceiver& r) {
+ r.drawImageRect(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
+ kLinearSampling, false,
+ DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageRect(TestImage2, {10, 10, 15, 15}, {10, 10, 80, 80},
- kNearestSampling, false);
+ [](DlOpReceiver& r) {
+ r.drawImageRect(TestImage2, {10, 10, 15, 15}, {10, 10, 80, 80},
+ kNearestSampling, false,
+ DlCanvas::SrcRectConstraint::kFast);
}},
{1, 56, -1, 80,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
- b.drawImageRect(dl_image, {10, 10, 15, 15}, {10, 10, 80, 80},
- kNearestSampling, false);
+ r.drawImageRect(dl_image, {10, 10, 15, 15}, {10, 10, 80, 80},
+ kNearestSampling, false,
+ DlCanvas::SrcRectConstraint::kFast);
}},
}},
{"DrawImageNine",
@@ -833,124 +761,124 @@
// SkCanvas::drawImageNine is immediately converted to
// drawImageLattice
{1, 48, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
+ [](DlOpReceiver& r) {
+ r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
DlFilterMode::kNearest, false);
}},
{1, 48, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
+ [](DlOpReceiver& r) {
+ r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
DlFilterMode::kNearest, true);
}},
{1, 48, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageNine(TestImage1, {10, 10, 25, 20}, {10, 10, 80, 80},
+ [](DlOpReceiver& r) {
+ r.drawImageNine(TestImage1, {10, 10, 25, 20}, {10, 10, 80, 80},
DlFilterMode::kNearest, false);
}},
{1, 48, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 85, 80},
+ [](DlOpReceiver& r) {
+ r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 85, 80},
DlFilterMode::kNearest, false);
}},
{1, 48, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
+ [](DlOpReceiver& r) {
+ r.drawImageNine(TestImage1, {10, 10, 20, 20}, {10, 10, 80, 80},
DlFilterMode::kLinear, false);
}},
{1, 48, -1, 80,
- [](DisplayListBuilder& b) {
- b.drawImageNine(TestImage2, {10, 10, 15, 15}, {10, 10, 80, 80},
+ [](DlOpReceiver& r) {
+ r.drawImageNine(TestImage2, {10, 10, 15, 15}, {10, 10, 80, 80},
DlFilterMode::kNearest, false);
}},
{1, 48, -1, 80,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
- b.drawImageNine(dl_image, {10, 10, 15, 15}, {10, 10, 80, 80},
+ r.drawImageNine(dl_image, {10, 10, 15, 15}, {10, 10, 80, 80},
DlFilterMode::kNearest, false);
}},
}},
{"DrawAtlas",
{
{1, 48 + 32 + 8, -1, 48 + 32 + 32,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
- b.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
+ r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
{1, 48 + 32 + 8, -1, 48 + 32 + 32,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
- b.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
+ r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr, true);
}},
{1, 48 + 32 + 8, -1, 48 + 32 + 32,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
static SkRSXform xforms[] = {{0, 1, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
- b.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
+ r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
{1, 48 + 32 + 8, -1, 48 + 32 + 32,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 25, 30, 30}};
- b.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
+ r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
{1, 48 + 32 + 8, -1, 48 + 32 + 32,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
- b.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
+ r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kLinearSampling, nullptr, false);
}},
{1, 48 + 32 + 8, -1, 48 + 32 + 32,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
- b.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
+ r.drawAtlas(TestImage1, xforms, texs, nullptr, 2,
DlBlendMode::kDstIn, kNearestSampling, nullptr,
false);
}},
{1, 64 + 32 + 8, -1, 64 + 32 + 32,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
static SkRect cull_rect = {0, 0, 200, 200};
- b.drawAtlas(TestImage2, xforms, texs, nullptr, 2,
+ r.drawAtlas(TestImage2, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, &cull_rect,
false);
}},
{1, 48 + 32 + 8 + 8, -1, 48 + 32 + 32 + 8,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
static DlColor colors[] = {DlColor::kBlue(), DlColor::kGreen()};
- b.drawAtlas(TestImage1, xforms, texs, colors, 2,
+ r.drawAtlas(TestImage1, xforms, texs, colors, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
{1, 64 + 32 + 8 + 8, -1, 64 + 32 + 32 + 8,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
static DlColor colors[] = {DlColor::kBlue(), DlColor::kGreen()};
static SkRect cull_rect = {0, 0, 200, 200};
- b.drawAtlas(TestImage1, xforms, texs, colors, 2,
+ r.drawAtlas(TestImage1, xforms, texs, colors, 2,
DlBlendMode::kSrcIn, kNearestSampling, &cull_rect,
false);
}},
{1, 48 + 32 + 8, -1, 48 + 32 + 32,
- [](DisplayListBuilder& b) {
+ [](DlOpReceiver& r) {
auto dl_image = DlImage::Make(TestSkImage);
static SkRSXform xforms[] = {{1, 0, 0, 0}, {0, 1, 0, 0}};
static SkRect texs[] = {{10, 10, 20, 20}, {20, 20, 30, 30}};
- b.drawAtlas(dl_image, xforms, texs, nullptr, 2,
+ r.drawAtlas(dl_image, xforms, texs, nullptr, 2,
DlBlendMode::kSrcIn, kNearestSampling, nullptr,
false);
}},
@@ -959,24 +887,26 @@
{
// cv.drawDL does not exist
{1, 16, -1, 16,
- [](DisplayListBuilder& b) { b.drawDisplayList(TestDisplayList1); }},
+ [](DlOpReceiver& r) { r.drawDisplayList(TestDisplayList1, 1.0); }},
{1, 16, -1, 16,
- [](DisplayListBuilder& b) { b.drawDisplayList(TestDisplayList2); }},
+ [](DlOpReceiver& r) { r.drawDisplayList(TestDisplayList1, 0.5); }},
{1, 16, -1, 16,
- [](DisplayListBuilder& b) {
- b.drawDisplayList(MakeTestDisplayList(10, 10, SK_ColorRED));
+ [](DlOpReceiver& r) { r.drawDisplayList(TestDisplayList2, 1.0); }},
+ {1, 16, -1, 16,
+ [](DlOpReceiver& r) {
+ r.drawDisplayList(MakeTestDisplayList(10, 10, SK_ColorRED), 1.0);
}},
}},
{"DrawTextBlob",
{
{1, 24, 1, 24,
- [](DisplayListBuilder& b) { b.drawTextBlob(TestBlob1, 10, 10); }},
+ [](DlOpReceiver& r) { r.drawTextBlob(TestBlob1, 10, 10); }},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) { b.drawTextBlob(TestBlob1, 20, 10); }},
+ [](DlOpReceiver& r) { r.drawTextBlob(TestBlob1, 20, 10); }},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) { b.drawTextBlob(TestBlob1, 10, 20); }},
+ [](DlOpReceiver& r) { r.drawTextBlob(TestBlob1, 10, 20); }},
{1, 24, 1, 24,
- [](DisplayListBuilder& b) { b.drawTextBlob(TestBlob2, 10, 10); }},
+ [](DlOpReceiver& r) { r.drawTextBlob(TestBlob2, 10, 10); }},
}},
// The -1 op counts below are to indicate to the framework not to test
// SkCanvas conversion of these ops as it converts the operation into a
@@ -988,28 +918,28 @@
// cv shadows are turned into an opaque ShadowRec which is not
// exposed
{1, 32, -1, 32,
- [](DisplayListBuilder& b) {
- b.drawShadow(kTestPath1, SK_ColorGREEN, 1.0, false, 1.0);
+ [](DlOpReceiver& r) {
+ r.drawShadow(kTestPath1, SK_ColorGREEN, 1.0, false, 1.0);
}},
{1, 32, -1, 32,
- [](DisplayListBuilder& b) {
- b.drawShadow(kTestPath2, SK_ColorGREEN, 1.0, false, 1.0);
+ [](DlOpReceiver& r) {
+ r.drawShadow(kTestPath2, SK_ColorGREEN, 1.0, false, 1.0);
}},
{1, 32, -1, 32,
- [](DisplayListBuilder& b) {
- b.drawShadow(kTestPath1, SK_ColorBLUE, 1.0, false, 1.0);
+ [](DlOpReceiver& r) {
+ r.drawShadow(kTestPath1, SK_ColorBLUE, 1.0, false, 1.0);
}},
{1, 32, -1, 32,
- [](DisplayListBuilder& b) {
- b.drawShadow(kTestPath1, SK_ColorGREEN, 2.0, false, 1.0);
+ [](DlOpReceiver& r) {
+ r.drawShadow(kTestPath1, SK_ColorGREEN, 2.0, false, 1.0);
}},
{1, 32, -1, 32,
- [](DisplayListBuilder& b) {
- b.drawShadow(kTestPath1, SK_ColorGREEN, 1.0, true, 1.0);
+ [](DlOpReceiver& r) {
+ r.drawShadow(kTestPath1, SK_ColorGREEN, 1.0, true, 1.0);
}},
{1, 32, -1, 32,
- [](DisplayListBuilder& b) {
- b.drawShadow(kTestPath1, SK_ColorGREEN, 1.0, false, 2.5);
+ [](DlOpReceiver& r) {
+ r.drawShadow(kTestPath1, SK_ColorGREEN, 1.0, false, 2.5);
}},
}},
};
diff --git a/display_list/testing/dl_test_snippets.h b/display_list/testing/dl_test_snippets.h
index 35278db..69bab82 100644
--- a/display_list/testing/dl_test_snippets.h
+++ b/display_list/testing/dl_test_snippets.h
@@ -20,7 +20,7 @@
sk_sp<DisplayList> GetSampleDisplayList(int ops);
sk_sp<DisplayList> GetSampleNestedDisplayList();
-typedef const std::function<void(DisplayListBuilder&)> DlInvoker;
+typedef const std::function<void(DlOpReceiver&)> DlInvoker;
constexpr SkPoint kEndPoints[] = {
{0, 0},
@@ -214,8 +214,7 @@
static sk_sp<DisplayList> MakeTestDisplayList(int w, int h, SkColor color) {
DisplayListBuilder builder;
- builder.setColor(color);
- builder.drawRect(SkRect::MakeWH(w, h));
+ builder.DrawRect(SkRect::MakeWH(w, h), DlPaint(color));
return builder.Build();
}
static sk_sp<DisplayList> TestDisplayList1 =
@@ -271,13 +270,13 @@
// through an SkCanvas interface, comparable to |DisplayList.byte_count().
size_t sk_byte_count() { return sizeof(DisplayList) + sk_byte_count_; }
- void Invoke(DisplayListBuilder& builder) { invoker(builder); }
+ void Invoke(DlOpReceiver& builder) { invoker(builder); }
- sk_sp<DisplayList> Build() {
- DisplayListBuilder builder;
- invoker(builder);
- return builder.Build();
- }
+ // sk_sp<DisplayList> Build() {
+ // DisplayListBuilder builder;
+ // invoker(builder.asReceiver());
+ // return builder.Build();
+ // }
};
struct DisplayListInvocationGroup {
diff --git a/display_list/types.h b/display_list/types.h
index dbe04aa..b8737f5 100644
--- a/display_list/types.h
+++ b/display_list/types.h
@@ -28,5 +28,4 @@
#include "third_party/skia/include/effects/SkDashPathEffect.h"
#include "third_party/skia/include/effects/SkDiscretePathEffect.h"
#include "third_party/skia/include/gpu/GrTypes.h"
-#include "third_party/skia/include/utils/SkShadowUtils.h"
#endif // FLUTTER_DISPLAY_LIST_TYPES_H_
diff --git a/flow/layers/checkerboard_layertree_unittests.cc b/flow/layers/checkerboard_layertree_unittests.cc
index d54abf9..7917b5e 100644
--- a/flow/layers/checkerboard_layertree_unittests.cc
+++ b/flow/layers/checkerboard_layertree_unittests.cc
@@ -2,7 +2,6 @@
// 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_canvas_dispatcher.h"
#include "flutter/flow/layers/clip_path_layer.h"
#include "flutter/flow/layers/clip_rect_layer.h"
#include "flutter/flow/layers/clip_rrect_layer.h"
@@ -235,8 +234,8 @@
// The Fuchsia system compositor handles all elevated PhysicalShapeLayers and
// their shadows , so we do not do any painting there.
EXPECT_EQ(layer->paint_bounds(),
- DisplayListCanvasDispatcher::ComputeShadowBounds(
- layer_path, initial_elevation, 1.0f, SkMatrix()));
+ DlCanvas::ComputeShadowBounds(layer_path, initial_elevation, 1.0f,
+ SkMatrix()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(layer->elevation(), initial_elevation);
diff --git a/flow/layers/clip_path_layer_unittests.cc b/flow/layers/clip_path_layer_unittests.cc
index 4f07f8c..1012a4c 100644
--- a/flow/layers/clip_path_layer_unittests.cc
+++ b/flow/layers/clip_path_layer_unittests.cc
@@ -424,7 +424,7 @@
{
expected_builder.Translate(offset.fX, offset.fY);
/* ClipRectLayer::Paint() */ {
- expected_builder.save();
+ expected_builder.Save();
expected_builder.ClipPath(layer_clip, ClipOp::kIntersect, true);
/* child layer1 paint */ {
expected_builder.DrawPath(path1, DlPaint().setAlpha(opacity_alpha));
@@ -472,25 +472,24 @@
DisplayListBuilder expected_builder;
/* OpacityLayer::Paint() */ {
- expected_builder.save();
+ expected_builder.Save();
{
- expected_builder.translate(offset.fX, offset.fY);
+ expected_builder.Translate(offset.fX, offset.fY);
/* ClipRectLayer::Paint() */ {
- expected_builder.save();
- expected_builder.clipPath(layer_clip, ClipOp::kIntersect, true);
- expected_builder.setColor(opacity_alpha << 24);
- expected_builder.saveLayer(&children_bounds, true);
+ expected_builder.Save();
+ expected_builder.ClipPath(layer_clip, ClipOp::kIntersect, true);
+ expected_builder.SaveLayer(&children_bounds,
+ &DlPaint().setAlpha(opacity_alpha));
/* child layer1 paint */ {
- expected_builder.setColor(0xFF000000);
- expected_builder.drawPath(path1);
+ expected_builder.DrawPath(path1, DlPaint());
}
/* child layer2 paint */ { //
- expected_builder.drawPath(path2);
+ expected_builder.DrawPath(path2, DlPaint());
}
- expected_builder.restore();
+ expected_builder.Restore();
}
}
- expected_builder.restore();
+ expected_builder.Restore();
}
opacity_layer->Paint(display_list_paint_context());
diff --git a/flow/layers/clip_rect_layer_unittests.cc b/flow/layers/clip_rect_layer_unittests.cc
index 728e487..6ddb907 100644
--- a/flow/layers/clip_rect_layer_unittests.cc
+++ b/flow/layers/clip_rect_layer_unittests.cc
@@ -454,25 +454,24 @@
DisplayListBuilder expected_builder;
/* OpacityLayer::Paint() */ {
- expected_builder.save();
+ expected_builder.Save();
{
- expected_builder.translate(offset.fX, offset.fY);
+ expected_builder.Translate(offset.fX, offset.fY);
/* ClipRectLayer::Paint() */ {
- expected_builder.save();
- expected_builder.clipRect(clip_rect, ClipOp::kIntersect, true);
- expected_builder.setColor(opacity_alpha << 24);
- expected_builder.saveLayer(&children_bounds, true);
+ expected_builder.Save();
+ expected_builder.ClipRect(clip_rect, ClipOp::kIntersect, true);
+ expected_builder.SaveLayer(&children_bounds,
+ &DlPaint().setAlpha(opacity_alpha));
/* child layer1 paint */ {
- expected_builder.setColor(0xFF000000);
- expected_builder.drawPath(path1);
+ expected_builder.DrawPath(path1, DlPaint());
}
/* child layer2 paint */ { //
- expected_builder.drawPath(path2);
+ expected_builder.DrawPath(path2, DlPaint());
}
- expected_builder.restore();
+ expected_builder.Restore();
}
}
- expected_builder.restore();
+ expected_builder.Restore();
}
opacity_layer->Paint(display_list_paint_context());
diff --git a/flow/layers/clip_rrect_layer_unittests.cc b/flow/layers/clip_rrect_layer_unittests.cc
index 9e789ce..75ca41c 100644
--- a/flow/layers/clip_rrect_layer_unittests.cc
+++ b/flow/layers/clip_rrect_layer_unittests.cc
@@ -467,25 +467,24 @@
DisplayListBuilder expected_builder;
/* OpacityLayer::Paint() */ {
- expected_builder.save();
+ expected_builder.Save();
{
- expected_builder.translate(offset.fX, offset.fY);
+ expected_builder.Translate(offset.fX, offset.fY);
/* ClipRectLayer::Paint() */ {
- expected_builder.save();
- expected_builder.clipRRect(clip_rrect, ClipOp::kIntersect, true);
- expected_builder.setColor(opacity_alpha << 24);
- expected_builder.saveLayer(&children_bounds, true);
+ expected_builder.Save();
+ expected_builder.ClipRRect(clip_rrect, ClipOp::kIntersect, true);
+ expected_builder.SaveLayer(&children_bounds,
+ &DlPaint().setAlpha(opacity_alpha));
/* child layer1 paint */ {
- expected_builder.setColor(0xFF000000);
- expected_builder.drawPath(path1);
+ expected_builder.DrawPath(path1, DlPaint());
}
/* child layer2 paint */ { //
- expected_builder.drawPath(path2);
+ expected_builder.DrawPath(path2, DlPaint());
}
- expected_builder.restore();
+ expected_builder.Restore();
}
}
- expected_builder.restore();
+ expected_builder.Restore();
}
opacity_layer->Paint(display_list_paint_context());
diff --git a/flow/layers/display_list_layer_unittests.cc b/flow/layers/display_list_layer_unittests.cc
index 5d4b633..1b2ad31 100644
--- a/flow/layers/display_list_layer_unittests.cc
+++ b/flow/layers/display_list_layer_unittests.cc
@@ -32,7 +32,7 @@
const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
DisplayListBuilder builder;
- builder.drawRect(picture_bounds);
+ builder.DrawRect(picture_bounds, DlPaint());
auto display_list = builder.Build();
auto layer = std::make_shared<DisplayListLayer>(
layer_offset, SkiaGPUObject<DisplayList>(display_list, unref_queue()),
@@ -47,7 +47,7 @@
const SkPoint layer_offset = SkPoint::Make(0.0f, 0.0f);
const SkRect picture_bounds = SkRect::MakeEmpty();
DisplayListBuilder builder;
- builder.drawRect(picture_bounds);
+ builder.DrawRect(picture_bounds, DlPaint());
auto display_list = builder.Build();
auto layer = std::make_shared<DisplayListLayer>(
layer_offset, SkiaGPUObject<DisplayList>(display_list, unref_queue()),
@@ -77,7 +77,7 @@
SkMatrix::Translate(layer_offset.fX, layer_offset.fY);
const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
DisplayListBuilder builder;
- builder.drawRect(picture_bounds);
+ builder.DrawRect(picture_bounds, DlPaint());
auto display_list = builder.Build();
auto layer = std::make_shared<DisplayListLayer>(
layer_offset, SkiaGPUObject(display_list, unref_queue()), false, false);
@@ -102,7 +102,7 @@
TEST_F(DisplayListLayerTest, CachingDoesNotChangeCullRect) {
const SkPoint layer_offset = SkPoint::Make(10, 10);
DisplayListBuilder builder;
- builder.drawRect({10, 10, 20, 20});
+ builder.DrawRect({10, 10, 20, 20}, DlPaint());
auto display_list = builder.Build();
auto layer = std::make_shared<DisplayListLayer>(
layer_offset, SkiaGPUObject(display_list, unref_queue()), true, false);
@@ -118,7 +118,7 @@
const SkPoint layer_offset = SkPoint::Make(1.5f, -0.5f);
const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
DisplayListBuilder builder;
- builder.drawRect(picture_bounds);
+ builder.DrawRect(picture_bounds, DlPaint());
auto display_list = builder.Build();
auto display_list_layer = std::make_shared<DisplayListLayer>(
layer_offset, SkiaGPUObject(display_list, unref_queue()), false, false);
@@ -130,6 +130,7 @@
LayerStateStack::kCallerCanApplyOpacity);
int opacity_alpha = 0x7F;
+ SkScalar opacity = opacity_alpha / 255.0;
SkPoint opacity_offset = SkPoint::Make(10, 10);
auto opacity_layer =
std::make_shared<OpacityLayer>(opacity_alpha, opacity_offset);
@@ -138,30 +139,24 @@
EXPECT_TRUE(opacity_layer->children_can_accept_opacity());
DisplayListBuilder child_builder;
- child_builder.drawRect(picture_bounds);
+ child_builder.DrawRect(picture_bounds, DlPaint());
auto child_display_list = child_builder.Build();
DisplayListBuilder expected_builder;
/* opacity_layer::Paint() */ {
- expected_builder.save();
+ expected_builder.Save();
{
- expected_builder.translate(opacity_offset.fX, opacity_offset.fY);
+ expected_builder.Translate(opacity_offset.fX, opacity_offset.fY);
/* display_list_layer::Paint() */ {
- expected_builder.save();
+ expected_builder.Save();
{
- expected_builder.translate(layer_offset.fX, layer_offset.fY);
- expected_builder.setColor(opacity_alpha << 24);
- expected_builder.saveLayer(&picture_bounds, true);
- /* display_list contents */ { //
- expected_builder.drawDisplayList(child_display_list);
- }
- expected_builder.restore();
- expected_builder.setColor(DlColor::kBlack());
+ expected_builder.Translate(layer_offset.fX, layer_offset.fY);
+ expected_builder.DrawDisplayList(child_display_list, opacity);
}
- expected_builder.restore();
+ expected_builder.Restore();
}
}
- expected_builder.restore();
+ expected_builder.Restore();
}
opacity_layer->Paint(display_list_paint_context());
@@ -174,8 +169,8 @@
const SkRect picture1_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
const SkRect picture2_bounds = SkRect::MakeLTRB(10.0f, 15.0f, 30.0f, 35.0f);
DisplayListBuilder builder;
- builder.drawRect(picture1_bounds);
- builder.drawRect(picture2_bounds);
+ builder.DrawRect(picture1_bounds, DlPaint());
+ builder.DrawRect(picture2_bounds, DlPaint());
auto display_list = builder.Build();
auto display_list_layer = std::make_shared<DisplayListLayer>(
layer_offset, SkiaGPUObject(display_list, unref_queue()), false, false);
@@ -194,8 +189,8 @@
EXPECT_FALSE(opacity_layer->children_can_accept_opacity());
DisplayListBuilder child_builder;
- child_builder.drawRect(picture1_bounds);
- child_builder.drawRect(picture2_bounds);
+ child_builder.DrawRect(picture1_bounds, DlPaint());
+ child_builder.DrawRect(picture2_bounds, DlPaint());
auto child_display_list = child_builder.Build();
auto display_list_bounds = picture1_bounds;
@@ -204,24 +199,24 @@
display_list_bounds.makeOffset(layer_offset.fX, layer_offset.fY);
DisplayListBuilder expected_builder;
/* opacity_layer::Paint() */ {
- expected_builder.save();
+ expected_builder.Save();
{
- expected_builder.translate(opacity_offset.fX, opacity_offset.fY);
- expected_builder.setColor(opacity_alpha << 24);
- expected_builder.saveLayer(&save_layer_bounds, true);
+ expected_builder.Translate(opacity_offset.fX, opacity_offset.fY);
+ expected_builder.SaveLayer(&save_layer_bounds,
+ &DlPaint().setAlpha(opacity_alpha));
{
/* display_list_layer::Paint() */ {
- expected_builder.save();
+ expected_builder.Save();
{
- expected_builder.translate(layer_offset.fX, layer_offset.fY);
- expected_builder.drawDisplayList(child_display_list);
+ expected_builder.Translate(layer_offset.fX, layer_offset.fY);
+ expected_builder.DrawDisplayList(child_display_list);
}
- expected_builder.restore();
+ expected_builder.Restore();
}
}
- expected_builder.restore();
+ expected_builder.Restore();
}
- expected_builder.restore();
+ expected_builder.Restore();
}
opacity_layer->Paint(display_list_paint_context());
@@ -234,8 +229,8 @@
const SkRect picture1_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
const SkRect picture2_bounds = SkRect::MakeLTRB(10.0f, 15.0f, 30.0f, 35.0f);
DisplayListBuilder builder;
- builder.drawRect(picture1_bounds);
- builder.drawRect(picture2_bounds);
+ builder.DrawRect(picture1_bounds, DlPaint());
+ builder.DrawRect(picture2_bounds, DlPaint());
auto display_list = builder.Build();
auto display_list_layer = std::make_shared<DisplayListLayer>(
layer_offset, SkiaGPUObject(display_list, unref_queue()), true, false);
@@ -386,7 +381,7 @@
const SkPoint layer_offset = SkPoint::Make(1.5f, -0.5f);
const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
DisplayListBuilder builder;
- builder.drawRect(picture_bounds);
+ builder.DrawRect(picture_bounds, DlPaint());
auto display_list = builder.Build();
auto layer = std::make_shared<DisplayListLayer>(
layer_offset, SkiaGPUObject(display_list, unref_queue()), false, false);
@@ -405,7 +400,7 @@
const SkPoint layer_offset = SkPoint::Make(1.5f, -0.5f);
const SkRect picture_bounds = SkRect::MakeLTRB(5.0f, 6.0f, 20.5f, 21.5f);
DisplayListBuilder builder;
- builder.drawRect(picture_bounds);
+ builder.DrawRect(picture_bounds, DlPaint());
auto display_list = builder.Build();
auto layer = std::make_shared<DisplayListLayer>(
layer_offset, SkiaGPUObject(display_list, unref_queue()), false, false);
@@ -423,7 +418,7 @@
const SkRect missed_cull_rect = SkRect::MakeLTRB(100, 100, 200, 200);
const SkRect hit_cull_rect = SkRect::MakeLTRB(0, 0, 200, 200);
DisplayListBuilder builder;
- builder.drawRect(picture_bounds);
+ builder.DrawRect(picture_bounds, DlPaint());
auto display_list = builder.Build();
auto layer = std::make_shared<DisplayListLayer>(
layer_offset, SkiaGPUObject(display_list, unref_queue()), true, false);
@@ -524,8 +519,8 @@
std::shared_ptr<DisplayListLayer> layers[layer_count];
for (int i = 0; i < layer_count; i++) {
DisplayListBuilder builder(false);
- builder.drawRect({0, 0, 100, 100});
- builder.drawRect({50, 50, 100, 100});
+ builder.DrawRect({0, 0, 100, 100}, DlPaint());
+ builder.DrawRect({50, 50, 100, 100}, DlPaint());
auto display_list = builder.Build();
ASSERT_FALSE(display_list->can_apply_group_opacity());
SkPoint offset = {i * 200.0f, 0};
diff --git a/flow/layers/image_filter_layer_unittests.cc b/flow/layers/image_filter_layer_unittests.cc
index 77789a9..bb5ced3 100644
--- a/flow/layers/image_filter_layer_unittests.cc
+++ b/flow/layers/image_filter_layer_unittests.cc
@@ -248,7 +248,7 @@
}
}
}
- expected_builder.restore();
+ expected_builder.Restore();
auto expected_display_list = expected_builder.Build();
layer->Paint(display_list_paint_context());
diff --git a/flow/layers/opacity_layer_unittests.cc b/flow/layers/opacity_layer_unittests.cc
index a5e72e0..1be70be 100644
--- a/flow/layers/opacity_layer_unittests.cc
+++ b/flow/layers/opacity_layer_unittests.cc
@@ -606,24 +606,23 @@
DisplayListBuilder expected_builder;
/* opacity_layer_1::Paint */ {
- expected_builder.save();
+ expected_builder.Save();
{
- expected_builder.translate(offset1.fX, offset1.fY);
+ expected_builder.Translate(offset1.fX, offset1.fY);
/* opacity_layer_2::Paint */ {
- expected_builder.save();
+ expected_builder.Save();
{
- expected_builder.translate(offset2.fX, offset2.fY);
- expected_builder.setColor(savelayer_paint.getAlpha() << 24);
- expected_builder.saveLayer(&mock_layer->paint_bounds(), true);
+ expected_builder.Translate(offset2.fX, offset2.fY);
+ expected_builder.SaveLayer(&mock_layer->paint_bounds(),
+ &savelayer_paint);
/* mock_layer::Paint */ {
- expected_builder.setColor(0xFF000000);
- expected_builder.drawPath(mock_path);
+ expected_builder.DrawPath(mock_path, DlPaint());
}
}
- expected_builder.restore();
+ expected_builder.Restore();
}
}
- expected_builder.restore();
+ expected_builder.Restore();
}
opacity_layer_1->Paint(display_list_paint_context());
diff --git a/flow/layers/physical_shape_layer.cc b/flow/layers/physical_shape_layer.cc
index 61b3199..c237114 100644
--- a/flow/layers/physical_shape_layer.cc
+++ b/flow/layers/physical_shape_layer.cc
@@ -4,7 +4,6 @@
#include "flutter/flow/layers/physical_shape_layer.h"
-#include "flutter/display_list/display_list_canvas_dispatcher.h"
#include "flutter/flow/paint_utils.h"
namespace flutter {
@@ -36,9 +35,9 @@
if (elevation_ == 0) {
bounds = path_.getBounds();
} else {
- bounds = DisplayListCanvasDispatcher::ComputeShadowBounds(
- path_, elevation_, context->frame_device_pixel_ratio(),
- context->GetTransform3x3());
+ bounds = DlCanvas::ComputeShadowBounds(path_, elevation_,
+ context->frame_device_pixel_ratio(),
+ context->GetTransform3x3());
}
context->AddLayerBounds(bounds);
@@ -65,7 +64,7 @@
} else {
// We will draw the shadow in Paint(), so add some margin to the paint
// bounds to leave space for the shadow.
- paint_bounds = DisplayListCanvasDispatcher::ComputeShadowBounds(
+ paint_bounds = DlCanvas::ComputeShadowBounds(
path_, elevation_, context->frame_device_pixel_ratio,
context->state_stack.transform_3x3());
}
diff --git a/flow/layers/physical_shape_layer_unittests.cc b/flow/layers/physical_shape_layer_unittests.cc
index daae090..6c97b45 100644
--- a/flow/layers/physical_shape_layer_unittests.cc
+++ b/flow/layers/physical_shape_layer_unittests.cc
@@ -4,7 +4,6 @@
#include "flutter/flow/layers/physical_shape_layer.h"
-#include "flutter/display_list/display_list_canvas_dispatcher.h"
#include "flutter/flow/testing/diff_context_test.h"
#include "flutter/flow/testing/layer_test.h"
#include "flutter/flow/testing/mock_layer.h"
@@ -214,8 +213,8 @@
// The Fuchsia system compositor handles all elevated PhysicalShapeLayers and
// their shadows , so we do not do any painting there.
EXPECT_EQ(layer->paint_bounds(),
- DisplayListCanvasDispatcher::ComputeShadowBounds(
- layer_path, initial_elevation, 1.0f, SkMatrix()));
+ DlCanvas::ComputeShadowBounds(layer_path, initial_elevation, 1.0f,
+ SkMatrix()));
EXPECT_TRUE(layer->needs_painting(paint_context()));
EXPECT_EQ(layer->elevation(), initial_elevation);
@@ -264,7 +263,7 @@
// On Fuchsia, the system compositor handles all elevated
// PhysicalShapeLayers and their shadows , so we do not do any painting
// there.
- SkRect paint_bounds = DisplayListCanvasDispatcher::ComputeShadowBounds(
+ SkRect paint_bounds = DlCanvas::ComputeShadowBounds(
layer_path, initial_elevations[i], 1.0f /* pixel_ratio */, SkMatrix());
// Without clipping the children will be painted as well
@@ -313,15 +312,15 @@
path.addRect(0, 0, 8, 8).close();
for (SkScalar elevation : elevations) {
- SkRect baseline_bounds = DisplayListCanvasDispatcher::ComputeShadowBounds(
- path, elevation, 1.0f, SkMatrix());
+ SkRect baseline_bounds =
+ DlCanvas::ComputeShadowBounds(path, elevation, 1.0f, SkMatrix());
for (SkScalar scale : scales) {
for (SkScalar translate_x : translates) {
for (SkScalar translate_y : translates) {
SkMatrix ctm;
ctm.setScaleTranslate(scale, scale, translate_x, translate_y);
- SkRect bounds = DisplayListCanvasDispatcher::ComputeShadowBounds(
- path, elevation, scale, ctm);
+ SkRect bounds =
+ DlCanvas::ComputeShadowBounds(path, elevation, scale, ctm);
EXPECT_FLOAT_EQ(bounds.fLeft, baseline_bounds.fLeft);
EXPECT_FLOAT_EQ(bounds.fTop, baseline_bounds.fTop);
EXPECT_FLOAT_EQ(bounds.fRight, baseline_bounds.fRight);
@@ -377,14 +376,14 @@
[=](SkCanvas* canvas) {
SkPath path;
path.addRect(test_case[0]).close();
- DisplayListCanvasDispatcher::DrawShadow(
- canvas, path, DlColor::kBlack(), 1.0f, false, 1.0f);
+ DlSkCanvasAdapter(canvas).DrawShadow(
+ path, DlColor::kBlack(), 1.0f, false, 1.0f);
},
[=](SkCanvas* canvas) {
SkPath path;
path.addRect(test_case[1]).close();
- DisplayListCanvasDispatcher::DrawShadow(
- canvas, path, DlColor::kBlack(), 1.0f, false, 1.0f);
+ DlSkCanvasAdapter(canvas).DrawShadow(
+ path, DlColor::kBlack(), 1.0f, false, 1.0f);
},
SkSize::Make(100, 100)),
0);
diff --git a/flow/layers/shader_mask_layer_unittests.cc b/flow/layers/shader_mask_layer_unittests.cc
index 886f0d0..b08d73c 100644
--- a/flow/layers/shader_mask_layer_unittests.cc
+++ b/flow/layers/shader_mask_layer_unittests.cc
@@ -383,7 +383,7 @@
/* child layer paint */ {
expected_builder.DrawPath(child_path, DlPaint());
}
- expected_builder.translate(mask_rect.fLeft, mask_rect.fTop);
+ expected_builder.Translate(mask_rect.fLeft, mask_rect.fTop);
expected_builder.DrawRect(
SkRect::MakeWH(mask_rect.width(), mask_rect.height()),
DlPaint().setBlendMode(DlBlendMode::kSrc));
diff --git a/flow/raster_cache_unittests.cc b/flow/raster_cache_unittests.cc
index 7fc8a5c..7f1c518 100644
--- a/flow/raster_cache_unittests.cc
+++ b/flow/raster_cache_unittests.cc
@@ -449,8 +449,7 @@
SkRect logical_rect = SkRect::MakeLTRB(28, 0, 354.56731, 310.288);
DisplayListBuilder builder(logical_rect);
- builder.setColor(SK_ColorRED);
- builder.drawRect(logical_rect);
+ builder.DrawRect(logical_rect, DlPaint(DlColor::kRed()));
sk_sp<DisplayList> display_list = builder.Build();
SkMatrix ctm = SkMatrix::MakeAll(1.3312, 0, 233, 0, 1.3312, 206, 0, 0, 1);
diff --git a/flow/testing/diff_context_test.cc b/flow/testing/diff_context_test.cc
index 888923a..61629eb 100644
--- a/flow/testing/diff_context_test.cc
+++ b/flow/testing/diff_context_test.cc
@@ -35,8 +35,7 @@
sk_sp<DisplayList> DiffContextTest::CreateDisplayList(const SkRect& bounds,
SkColor color) {
DisplayListBuilder builder;
- builder.setColor(color);
- builder.drawRect(bounds);
+ builder.DrawRect(bounds, DlPaint().setColor(color));
return builder.Build();
}
diff --git a/impeller/display_list/display_list_dispatcher.cc b/impeller/display_list/display_list_dispatcher.cc
index b1f8fb1..06ee1ee 100644
--- a/impeller/display_list/display_list_dispatcher.cc
+++ b/impeller/display_list/display_list_dispatcher.cc
@@ -181,12 +181,12 @@
};
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setAntiAlias(bool aa) {
// Nothing to do because AA is implicit.
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setDither(bool dither) {}
static Paint::Style ToStyle(flutter::DlDrawStyle style) {
@@ -202,12 +202,12 @@
return Paint::Style::kFill;
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setStyle(flutter::DlDrawStyle style) {
paint_.style = ToStyle(style);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setColor(flutter::DlColor color) {
paint_.color = {
color.getRedF(),
@@ -217,17 +217,17 @@
};
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setStrokeWidth(SkScalar width) {
paint_.stroke_width = width;
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setStrokeMiter(SkScalar limit) {
paint_.stroke_miter = limit;
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setStrokeCap(flutter::DlStrokeCap cap) {
switch (cap) {
case flutter::DlStrokeCap::kButt:
@@ -242,7 +242,7 @@
}
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setStrokeJoin(flutter::DlStrokeJoin join) {
switch (join) {
case flutter::DlStrokeJoin::kMiter:
@@ -346,7 +346,7 @@
}
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setColorSource(
const flutter::DlColorSource* source) {
if (!source) {
@@ -618,24 +618,24 @@
return std::nullopt;
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setColorFilter(
const flutter::DlColorFilter* filter) {
// Needs https://github.com/flutter/flutter/issues/95434
paint_.color_filter = ToColorFilterProc(filter);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setInvertColors(bool invert) {
paint_.invert_colors = invert;
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setBlendMode(flutter::DlBlendMode dl_mode) {
paint_.blend_mode = ToBlendMode(dl_mode);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setPathEffect(const flutter::DlPathEffect* effect) {
// Needs https://github.com/flutter/flutter/issues/95434
UNIMPLEMENTED;
@@ -654,7 +654,7 @@
}
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setMaskFilter(const flutter::DlMaskFilter* filter) {
// Needs https://github.com/flutter/flutter/issues/95434
if (filter == nullptr) {
@@ -743,7 +743,7 @@
};
break;
}
- case flutter::DlImageFilterType::kComposeFilter: {
+ case flutter::DlImageFilterType::kCompose: {
auto compose = filter->asCompose();
FML_DCHECK(compose);
auto outer = compose->outer();
@@ -782,7 +782,7 @@
bool is_subpass) { return color_filter(std::move(input)); };
break;
}
- case flutter::DlImageFilterType::kLocalMatrixFilter: {
+ case flutter::DlImageFilterType::kLocalMatrix: {
auto local_matrix_filter = filter->asLocalMatrix();
FML_DCHECK(local_matrix_filter);
auto internal_filter = local_matrix_filter->image_filter();
@@ -808,13 +808,13 @@
}
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::setImageFilter(
const flutter::DlImageFilter* filter) {
paint_.image_filter = ToImageFilterProc(filter);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::save() {
canvas_.Save();
}
@@ -834,7 +834,7 @@
return result;
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::saveLayer(const SkRect* bounds,
const flutter::SaveLayerOptions options,
const flutter::DlImageFilter* backdrop) {
@@ -842,32 +842,32 @@
canvas_.SaveLayer(paint, ToRect(bounds), ToImageFilterProc(backdrop));
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::restore() {
canvas_.Restore();
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::translate(SkScalar tx, SkScalar ty) {
canvas_.Translate({tx, ty, 0.0});
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::scale(SkScalar sx, SkScalar sy) {
canvas_.Scale({sx, sy, 1.0});
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::rotate(SkScalar degrees) {
canvas_.Rotate(Degrees{degrees});
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::skew(SkScalar sx, SkScalar sy) {
canvas_.Skew(sx, sy);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::transform2DAffine(SkScalar mxx,
SkScalar mxy,
SkScalar mxt,
@@ -884,7 +884,7 @@
// clang-format on
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::transformFullPerspective(SkScalar mxx,
SkScalar mxy,
SkScalar mxz,
@@ -914,7 +914,7 @@
canvas_.Transform(xformation);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::transformReset() {
canvas_.ResetTransform();
canvas_.Transform(initial_matrix_);
@@ -934,7 +934,7 @@
}
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::clipRect(const SkRect& rect,
ClipOp clip_op,
bool is_aa) {
@@ -1020,7 +1020,7 @@
case SkPathFillType::kInverseWinding:
case SkPathFillType::kInverseEvenOdd:
// Flutter doesn't expose these path fill types. These are only visible
- // via the dispatcher interface. We should never get here.
+ // via the receiver interface. We should never get here.
fill_type = FillType::kNonZero;
break;
}
@@ -1033,7 +1033,7 @@
.TakePath();
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::clipRRect(const SkRRect& rrect,
ClipOp clip_op,
bool is_aa) {
@@ -1045,14 +1045,14 @@
}
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::clipPath(const SkPath& path,
ClipOp clip_op,
bool is_aa) {
canvas_.ClipPath(ToPath(path), ToClipOperation(clip_op));
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawColor(flutter::DlColor color,
flutter::DlBlendMode dl_mode) {
Paint paint;
@@ -1061,12 +1061,12 @@
canvas_.DrawPaint(paint);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawPaint() {
canvas_.DrawPaint(paint_);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawLine(const SkPoint& p0, const SkPoint& p1) {
auto path = PathBuilder{}.AddLine(ToPoint(p0), ToPoint(p1)).TakePath();
Paint paint = paint_;
@@ -1074,12 +1074,12 @@
canvas_.DrawPath(path, paint);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawRect(const SkRect& rect) {
canvas_.DrawRect(ToRect(rect), paint_);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawOval(const SkRect& bounds) {
if (bounds.width() == bounds.height()) {
canvas_.DrawCircle(ToPoint(bounds.center()), bounds.width() * 0.5, paint_);
@@ -1089,12 +1089,12 @@
}
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawCircle(const SkPoint& center, SkScalar radius) {
canvas_.DrawCircle(ToPoint(center), radius, paint_);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawRRect(const SkRRect& rrect) {
if (rrect.isSimple()) {
canvas_.DrawRRect(ToRect(rrect.rect()), rrect.getSimpleRadii().fX, paint_);
@@ -1103,7 +1103,7 @@
}
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawDRRect(const SkRRect& outer,
const SkRRect& inner) {
PathBuilder builder;
@@ -1112,12 +1112,12 @@
canvas_.DrawPath(builder.TakePath(FillType::kOdd), paint_);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawPath(const SkPath& path) {
canvas_.DrawPath(ToPath(path), paint_);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawArc(const SkRect& oval_bounds,
SkScalar start_degrees,
SkScalar sweep_degrees,
@@ -1128,7 +1128,7 @@
canvas_.DrawPath(builder.TakePath(), paint_);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawPoints(PointMode mode,
uint32_t count,
const SkPoint points[]) {
@@ -1167,14 +1167,14 @@
}
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawVertices(const flutter::DlVertices* vertices,
flutter::DlBlendMode dl_mode) {
canvas_.DrawVertices(DLVerticesGeometry::MakeVertices(vertices),
ToBlendMode(dl_mode), paint_);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawImage(const sk_sp<flutter::DlImage> image,
const SkPoint point,
flutter::DlImageSampling sampling,
@@ -1193,24 +1193,23 @@
const auto dest =
SkRect::MakeXYWH(point.fX, point.fY, size.width, size.height);
- drawImageRect(
- image, // image
- src, // source rect
- dest, // destination rect
- sampling, // sampling options
- render_with_attributes, // render with attributes
- SkCanvas::SrcRectConstraint::kStrict_SrcRectConstraint // constraint
+ drawImageRect(image, // image
+ src, // source rect
+ dest, // destination rect
+ sampling, // sampling options
+ render_with_attributes, // render with attributes
+ SrcRectConstraint::kStrict // constraint
);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawImageRect(
const sk_sp<flutter::DlImage> image,
const SkRect& src,
const SkRect& dst,
flutter::DlImageSampling sampling,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) {
+ SrcRectConstraint constraint = SrcRectConstraint::kFast) {
canvas_.DrawImageRect(
std::make_shared<Image>(image->impeller_texture()), // image
ToRect(src), // source rect
@@ -1220,7 +1219,7 @@
);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawImageNine(const sk_sp<flutter::DlImage> image,
const SkIRect& center,
const SkRect& dst,
@@ -1233,7 +1232,7 @@
ToRect(dst), ToSamplerDescriptor(filter), &canvas_, &paint_);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawAtlas(const sk_sp<flutter::DlImage> atlas,
const SkRSXform xform[],
const SkRect tex[],
@@ -1249,21 +1248,43 @@
ToSamplerDescriptor(sampling), ToRect(cull_rect), paint_);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawDisplayList(
- const sk_sp<flutter::DisplayList> display_list) {
- int saveCount = canvas_.GetSaveCount();
- Paint savePaint = paint_;
- Matrix saveMatrix = initial_matrix_;
- paint_ = Paint();
+ const sk_sp<flutter::DisplayList> display_list,
+ SkScalar opacity) {
+ // Save all values that must remain untouched after the operation.
+ Paint saved_paint = paint_;
+ Matrix saved_initial_matrix = initial_matrix_;
+ int restore_count = canvas_.GetSaveCount();
+
+ // Establish a new baseline for interpreting the new DL.
+ // Matrix and clip are left untouched, the current
+ // transform is saved as the new base matrix, and paint
+ // values are reset to defaults.
initial_matrix_ = canvas_.GetCurrentTransformation();
+ paint_ = Paint();
+
+ // Handle passed opacity in the most brute-force way by using
+ // a SaveLayer. If the display_list is able to inherit the
+ // opacity, this could also be handled by modulating all of its
+ // attribute settings (for example, color), by the indicated
+ // opacity.
+ if (opacity < SK_Scalar1) {
+ Paint save_paint;
+ save_paint.color = Color(0, 0, 0, opacity);
+ canvas_.SaveLayer(save_paint);
+ }
+
display_list->Dispatch(*this);
- paint_ = savePaint;
- initial_matrix_ = saveMatrix;
- canvas_.RestoreToCount(saveCount);
+
+ // Restore all saved state back to what it was before we interpreted
+ // the display_list
+ canvas_.RestoreToCount(restore_count);
+ initial_matrix_ = saved_initial_matrix;
+ paint_ = saved_paint;
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y) {
@@ -1274,7 +1295,7 @@
);
}
-// |flutter::Dispatcher|
+// |flutter::DlOpReceiver|
void DisplayListDispatcher::drawShadow(const SkPath& path,
const flutter::DlColor color,
const SkScalar elevation,
diff --git a/impeller/display_list/display_list_dispatcher.h b/impeller/display_list/display_list_dispatcher.h
index 2f462f9..76cf251 100644
--- a/impeller/display_list/display_list_dispatcher.h
+++ b/impeller/display_list/display_list_dispatcher.h
@@ -7,14 +7,14 @@
#include "display_list/display_list_path_effect.h"
#include "flutter/display_list/display_list.h"
#include "flutter/display_list/display_list_blend_mode.h"
-#include "flutter/display_list/display_list_dispatcher.h"
+#include "flutter/display_list/dl_op_receiver.h"
#include "flutter/fml/macros.h"
#include "impeller/aiks/canvas.h"
#include "impeller/aiks/paint.h"
namespace impeller {
-class DisplayListDispatcher final : public flutter::Dispatcher {
+class DisplayListDispatcher final : public flutter::DlOpReceiver {
public:
DisplayListDispatcher();
@@ -22,75 +22,75 @@
Picture EndRecordingAsPicture();
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setAntiAlias(bool aa) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setDither(bool dither) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setStyle(flutter::DlDrawStyle style) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setColor(flutter::DlColor color) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setStrokeWidth(SkScalar width) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setStrokeMiter(SkScalar limit) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setStrokeCap(flutter::DlStrokeCap cap) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setStrokeJoin(flutter::DlStrokeJoin join) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setColorSource(const flutter::DlColorSource* source) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setColorFilter(const flutter::DlColorFilter* filter) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setInvertColors(bool invert) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setBlendMode(flutter::DlBlendMode mode) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setPathEffect(const flutter::DlPathEffect* effect) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setMaskFilter(const flutter::DlMaskFilter* filter) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void setImageFilter(const flutter::DlImageFilter* filter) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void save() override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void saveLayer(const SkRect* bounds,
const flutter::SaveLayerOptions options,
const flutter::DlImageFilter* backdrop) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void restore() override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void translate(SkScalar tx, SkScalar ty) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void scale(SkScalar sx, SkScalar sy) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void rotate(SkScalar degrees) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void skew(SkScalar sx, SkScalar sy) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void transform2DAffine(SkScalar mxx,
SkScalar mxy,
SkScalar mxt,
@@ -98,7 +98,7 @@
SkScalar myy,
SkScalar myt) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void transformFullPerspective(SkScalar mxx,
SkScalar mxy,
SkScalar mxz,
@@ -116,82 +116,82 @@
SkScalar mwz,
SkScalar mwt) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void transformReset() override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void clipPath(const SkPath& path, ClipOp clip_op, bool is_aa) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawColor(flutter::DlColor color, flutter::DlBlendMode mode) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawPaint() override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawLine(const SkPoint& p0, const SkPoint& p1) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawRect(const SkRect& rect) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawOval(const SkRect& bounds) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawCircle(const SkPoint& center, SkScalar radius) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawRRect(const SkRRect& rrect) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawDRRect(const SkRRect& outer, const SkRRect& inner) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawPath(const SkPath& path) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawArc(const SkRect& oval_bounds,
SkScalar start_degrees,
SkScalar sweep_degrees,
bool use_center) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawPoints(PointMode mode,
uint32_t count,
const SkPoint points[]) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawVertices(const flutter::DlVertices* vertices,
flutter::DlBlendMode dl_mode) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawImage(const sk_sp<flutter::DlImage> image,
const SkPoint point,
flutter::DlImageSampling sampling,
bool render_with_attributes) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawImageRect(const sk_sp<flutter::DlImage> image,
const SkRect& src,
const SkRect& dst,
flutter::DlImageSampling sampling,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) override;
+ SrcRectConstraint constraint) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawImageNine(const sk_sp<flutter::DlImage> image,
const SkIRect& center,
const SkRect& dst,
flutter::DlFilterMode filter,
bool render_with_attributes) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawAtlas(const sk_sp<flutter::DlImage> atlas,
const SkRSXform xform[],
const SkRect tex[],
@@ -202,15 +202,16 @@
const SkRect* cull_rect,
bool render_with_attributes) override;
- // |flutter::Dispatcher|
- void drawDisplayList(const sk_sp<flutter::DisplayList> display_list) override;
+ // |flutter::DlOpReceiver|
+ void drawDisplayList(const sk_sp<flutter::DisplayList> display_list,
+ SkScalar opacity) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y) override;
- // |flutter::Dispatcher|
+ // |flutter::DlOpReceiver|
void drawShadow(const SkPath& path,
const flutter::DlColor color,
const SkScalar elevation,
diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc
index 848f84f..7694196 100644
--- a/impeller/display_list/display_list_unittests.cc
+++ b/impeller/display_list/display_list_unittests.cc
@@ -44,16 +44,15 @@
TEST_P(DisplayListTest, CanDrawRect) {
flutter::DisplayListBuilder builder;
- builder.setColor(SK_ColorBLUE);
- builder.drawRect(SkRect::MakeXYWH(10, 10, 100, 100));
+ builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100),
+ flutter::DlPaint(flutter::DlColor::kBlue()));
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
TEST_P(DisplayListTest, CanDrawTextBlob) {
flutter::DisplayListBuilder builder;
- builder.setColor(SK_ColorBLUE);
- builder.drawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
- 100, 100);
+ builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
+ 100, 100, flutter::DlPaint(flutter::DlColor::kBlue()));
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
@@ -78,70 +77,69 @@
TEST_P(DisplayListTest, CanDrawTextWithSaveLayer) {
flutter::DisplayListBuilder builder;
- builder.setColor(SK_ColorRED);
- builder.drawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
- 100, 100);
+ builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello", CreateTestFont()),
+ 100, 100, flutter::DlPaint(flutter::DlColor::kRed()));
flutter::DlPaint save_paint;
float alpha = 0.5;
save_paint.setAlpha(static_cast<uint8_t>(255 * alpha));
builder.SaveLayer(nullptr, &save_paint);
- builder.setColor(SK_ColorRED);
- builder.drawTextBlob(SkTextBlob::MakeFromString("Hello with half alpha",
+ builder.DrawTextBlob(SkTextBlob::MakeFromString("Hello with half alpha",
CreateTestFontOfSize(100)),
- 100, 300);
- builder.restore();
+ 100, 300, flutter::DlPaint(flutter::DlColor::kRed()));
+ builder.Restore();
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
TEST_P(DisplayListTest, CanDrawImage) {
auto texture = CreateTextureForFixture("embarcadero.jpg");
flutter::DisplayListBuilder builder;
- builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
- flutter::DlImageSampling::kNearestNeighbor, true);
+ builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
+ flutter::DlImageSampling::kNearestNeighbor, nullptr);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
TEST_P(DisplayListTest, CanDrawCapsAndJoins) {
flutter::DisplayListBuilder builder;
+ flutter::DlPaint paint;
- builder.setStyle(flutter::DlDrawStyle::kStroke);
- builder.setStrokeWidth(30);
- builder.setColor(SK_ColorRED);
+ paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
+ paint.setStrokeWidth(30);
+ paint.setColor(SK_ColorRED);
auto path =
SkPathBuilder{}.moveTo(-50, 0).lineTo(0, -50).lineTo(50, 0).snapshot();
- builder.translate(100, 100);
+ builder.Translate(100, 100);
{
- builder.setStrokeCap(flutter::DlStrokeCap::kButt);
- builder.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
- builder.setStrokeMiter(4);
- builder.drawPath(path);
+ paint.setStrokeCap(flutter::DlStrokeCap::kButt);
+ paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
+ paint.setStrokeMiter(4);
+ builder.DrawPath(path, paint);
}
{
- builder.save();
- builder.translate(0, 100);
+ builder.Save();
+ builder.Translate(0, 100);
// The joint in the path is 45 degrees. A miter length of 1 convert to a
// bevel in this case.
- builder.setStrokeMiter(1);
- builder.drawPath(path);
- builder.restore();
+ paint.setStrokeMiter(1);
+ builder.DrawPath(path, paint);
+ builder.Restore();
}
- builder.translate(150, 0);
+ builder.Translate(150, 0);
{
- builder.setStrokeCap(flutter::DlStrokeCap::kSquare);
- builder.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
- builder.drawPath(path);
+ paint.setStrokeCap(flutter::DlStrokeCap::kSquare);
+ paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
+ builder.DrawPath(path, paint);
}
- builder.translate(150, 0);
+ builder.Translate(150, 0);
{
- builder.setStrokeCap(flutter::DlStrokeCap::kRound);
- builder.setStrokeJoin(flutter::DlStrokeJoin::kRound);
- builder.drawPath(path);
+ paint.setStrokeCap(flutter::DlStrokeCap::kRound);
+ paint.setStrokeJoin(flutter::DlStrokeJoin::kRound);
+ builder.DrawPath(path, paint);
}
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
@@ -186,20 +184,21 @@
Point(200, 200), Point(400, 400), 20, Color::White(), Color::White());
flutter::DisplayListBuilder builder;
+ flutter::DlPaint paint;
Vector2 scale = GetContentScale();
- builder.scale(scale.x, scale.y);
- builder.setStyle(flutter::DlDrawStyle::kStroke);
- builder.setStrokeCap(cap);
- builder.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
- builder.setStrokeMiter(10);
+ builder.Scale(scale.x, scale.y);
+ paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
+ paint.setStrokeCap(cap);
+ paint.setStrokeJoin(flutter::DlStrokeJoin::kMiter);
+ paint.setStrokeMiter(10);
auto rect = SkRect::MakeLTRB(p1.x, p1.y, p2.x, p2.y);
- builder.setColor(SK_ColorGREEN);
- builder.setStrokeWidth(2);
- builder.drawRect(rect);
- builder.setColor(SK_ColorRED);
- builder.setStrokeWidth(stroke_width);
- builder.drawArc(rect, start_angle, sweep_angle, use_center);
+ paint.setColor(SK_ColorGREEN);
+ paint.setStrokeWidth(2);
+ builder.DrawRect(rect, paint);
+ paint.setColor(SK_ColorRED);
+ paint.setStrokeWidth(stroke_width);
+ builder.DrawArc(rect, start_angle, sweep_angle, use_center, paint);
return builder.Build();
};
@@ -209,8 +208,10 @@
TEST_P(DisplayListTest, StrokedPathsDrawCorrectly) {
auto callback = [&]() {
flutter::DisplayListBuilder builder;
- builder.setColor(SK_ColorRED);
- builder.setStyle(flutter::DlDrawStyle::kStroke);
+ flutter::DlPaint paint;
+
+ paint.setColor(SK_ColorRED);
+ paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
static float stroke_width = 10.0f;
static int selected_stroke_type = 0;
@@ -256,45 +257,46 @@
join = flutter::DlStrokeJoin::kMiter;
break;
}
- builder.setStrokeCap(cap);
- builder.setStrokeJoin(join);
- builder.setStrokeWidth(stroke_width);
+ paint.setStrokeCap(cap);
+ paint.setStrokeJoin(join);
+ paint.setStrokeWidth(stroke_width);
// Make rendering better to watch.
- builder.scale(1.5f, 1.5f);
+ builder.Scale(1.5f, 1.5f);
// Rectangle
- builder.translate(100, 100);
- builder.drawRect(SkRect::MakeSize({100, 100}));
+ builder.Translate(100, 100);
+ builder.DrawRect(SkRect::MakeSize({100, 100}), paint);
// Rounded rectangle
- builder.translate(150, 0);
- builder.drawRRect(SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10));
+ builder.Translate(150, 0);
+ builder.DrawRRect(SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
+ paint);
// Double rounded rectangle
- builder.translate(150, 0);
- builder.drawDRRect(
+ builder.Translate(150, 0);
+ builder.DrawDRRect(
SkRRect::MakeRectXY(SkRect::MakeSize({100, 50}), 10, 10),
- SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 30), 10, 10));
+ SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 30), 10, 10), paint);
// Contour with duplicate join points
{
- builder.translate(150, 0);
+ builder.Translate(150, 0);
SkPath path;
path.moveTo(0, 0);
path.lineTo(0, 0);
path.lineTo({100, 0});
path.lineTo({100, 0});
path.lineTo({100, 100});
- builder.drawPath(path);
+ builder.DrawPath(path, paint);
}
// Contour with duplicate start and end points
// Line.
- builder.translate(200, 0);
+ builder.Translate(200, 0);
{
- builder.save();
+ builder.Save();
SkPath line_path;
line_path.moveTo(0, 0);
@@ -305,71 +307,71 @@
line_path.lineTo({50, 50});
line_path.lineTo({100, 0});
line_path.lineTo({100, 0});
- builder.drawPath(line_path);
+ builder.DrawPath(line_path, paint);
- builder.translate(0, 100);
- builder.drawPath(line_path);
+ builder.Translate(0, 100);
+ builder.DrawPath(line_path, paint);
- builder.translate(0, 100);
+ builder.Translate(0, 100);
SkPath line_path2;
line_path2.moveTo(0, 0);
line_path2.lineTo(0, 0);
line_path2.lineTo(0, 0);
- builder.drawPath(line_path2);
+ builder.DrawPath(line_path2, paint);
- builder.restore();
+ builder.Restore();
}
// Cubic.
- builder.translate(150, 0);
+ builder.Translate(150, 0);
{
- builder.save();
+ builder.Save();
SkPath cubic_path;
cubic_path.moveTo({0, 0});
cubic_path.cubicTo(0, 0, 140.0, 100.0, 140, 20);
- builder.drawPath(cubic_path);
+ builder.DrawPath(cubic_path, paint);
- builder.translate(0, 100);
+ builder.Translate(0, 100);
SkPath cubic_path2;
cubic_path2.moveTo({0, 0});
cubic_path2.cubicTo(0, 0, 0, 0, 150, 150);
- builder.drawPath(cubic_path2);
+ builder.DrawPath(cubic_path2, paint);
- builder.translate(0, 100);
+ builder.Translate(0, 100);
SkPath cubic_path3;
cubic_path3.moveTo({0, 0});
cubic_path3.cubicTo(0, 0, 0, 0, 0, 0);
- builder.drawPath(cubic_path3);
+ builder.DrawPath(cubic_path3, paint);
- builder.restore();
+ builder.Restore();
}
// Quad.
- builder.translate(200, 0);
+ builder.Translate(200, 0);
{
- builder.save();
+ builder.Save();
SkPath quad_path;
quad_path.moveTo(0, 0);
quad_path.moveTo(0, 0);
quad_path.quadTo({100, 40}, {50, 80});
- builder.drawPath(quad_path);
+ builder.DrawPath(quad_path, paint);
- builder.translate(0, 150);
+ builder.Translate(0, 150);
SkPath quad_path2;
quad_path2.moveTo(0, 0);
quad_path2.moveTo(0, 0);
quad_path2.quadTo({0, 0}, {100, 100});
- builder.drawPath(quad_path2);
+ builder.DrawPath(quad_path2, paint);
- builder.translate(0, 100);
+ builder.Translate(0, 100);
SkPath quad_path3;
quad_path3.moveTo(0, 0);
quad_path3.quadTo({0, 0}, {0, 0});
- builder.drawPath(quad_path3);
+ builder.DrawPath(quad_path3, paint);
- builder.restore();
+ builder.Restore();
}
return builder.Build();
};
@@ -378,15 +380,17 @@
TEST_P(DisplayListTest, CanDrawWithOddPathWinding) {
flutter::DisplayListBuilder builder;
- builder.setColor(SK_ColorRED);
- builder.setStyle(flutter::DlDrawStyle::kFill);
+ flutter::DlPaint paint;
- builder.translate(300, 300);
+ paint.setColor(SK_ColorRED);
+ paint.setDrawStyle(flutter::DlDrawStyle::kFill);
+
+ builder.Translate(300, 300);
SkPath path;
path.setFillType(SkPathFillType::kEvenOdd);
path.addCircle(0, 0, 100);
path.addCircle(0, 0, 50);
- builder.drawPath(path);
+ builder.DrawPath(path, paint);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
@@ -394,29 +398,31 @@
TEST_P(DisplayListTest, CanDrawWithMaskBlur) {
auto texture = CreateTextureForFixture("embarcadero.jpg");
flutter::DisplayListBuilder builder;
+ flutter::DlPaint paint;
// Mask blurred image.
{
auto filter = flutter::DlBlurMaskFilter(kNormal_SkBlurStyle, 10.0f);
- builder.setMaskFilter(&filter);
- builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
- flutter::DlImageSampling::kNearestNeighbor, true);
+ paint.setMaskFilter(&filter);
+ builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
+ flutter::DlImageSampling::kNearestNeighbor, &paint);
}
// Mask blurred filled path.
{
- builder.setColor(SK_ColorYELLOW);
+ paint.setColor(SK_ColorYELLOW);
auto filter = flutter::DlBlurMaskFilter(kOuter_SkBlurStyle, 10.0f);
- builder.setMaskFilter(&filter);
- builder.drawArc(SkRect::MakeXYWH(410, 110, 100, 100), 45, 270, true);
+ paint.setMaskFilter(&filter);
+ builder.DrawArc(SkRect::MakeXYWH(410, 110, 100, 100), 45, 270, true, paint);
}
// Mask blurred text.
{
auto filter = flutter::DlBlurMaskFilter(kSolid_SkBlurStyle, 10.0f);
- builder.setMaskFilter(&filter);
- builder.drawTextBlob(
- SkTextBlob::MakeFromString("Testing", CreateTestFont()), 220, 170);
+ paint.setMaskFilter(&filter);
+ builder.DrawTextBlob(
+ SkTextBlob::MakeFromString("Testing", CreateTestFont()), 220, 170,
+ paint);
}
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
@@ -438,23 +444,24 @@
TEST_P(DisplayListTest, CanDrawWithBlendColorFilter) {
auto texture = CreateTextureForFixture("embarcadero.jpg");
flutter::DisplayListBuilder builder;
+ flutter::DlPaint paint;
// Pipeline blended image.
{
auto filter = flutter::DlBlendColorFilter(SK_ColorYELLOW,
flutter::DlBlendMode::kModulate);
- builder.setColorFilter(&filter);
- builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
- flutter::DlImageSampling::kNearestNeighbor, true);
+ paint.setColorFilter(&filter);
+ builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
+ flutter::DlImageSampling::kNearestNeighbor, &paint);
}
// Advanced blended image.
{
auto filter =
flutter::DlBlendColorFilter(SK_ColorRED, flutter::DlBlendMode::kScreen);
- builder.setColorFilter(&filter);
- builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(250, 250),
- flutter::DlImageSampling::kNearestNeighbor, true);
+ paint.setColorFilter(&filter);
+ builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(250, 250),
+ flutter::DlImageSampling::kNearestNeighbor, &paint);
}
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
@@ -469,18 +476,21 @@
};
auto texture = CreateTextureForFixture("boston.jpg");
flutter::DisplayListBuilder builder;
+ flutter::DlPaint paint;
+
auto color_filter =
std::make_shared<flutter::DlMatrixColorFilter>(invert_color_matrix);
auto image_filter =
std::make_shared<flutter::DlColorFilterImageFilter>(color_filter);
- builder.setImageFilter(image_filter.get());
- builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
- flutter::DlImageSampling::kNearestNeighbor, true);
- builder.translate(0, 700);
- builder.setColorFilter(color_filter.get());
- builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
- flutter::DlImageSampling::kNearestNeighbor, true);
+ paint.setImageFilter(image_filter.get());
+ builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
+ flutter::DlImageSampling::kNearestNeighbor, &paint);
+
+ builder.Translate(0, 700);
+ paint.setColorFilter(color_filter.get());
+ builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
+ flutter::DlImageSampling::kNearestNeighbor, &paint);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
@@ -495,12 +505,13 @@
ImGui::End();
flutter::DisplayListBuilder builder;
+ flutter::DlPaint paint;
auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
flutter::DlTileMode::kClamp);
- builder.setImageFilter(&filter);
- builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
- flutter::DlImageSampling::kNearestNeighbor, true);
+ paint.setImageFilter(&filter);
+ builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
+ flutter::DlImageSampling::kNearestNeighbor, &paint);
return builder.Build();
};
@@ -511,17 +522,20 @@
TEST_P(DisplayListTest, CanDrawWithComposeImageFilter) {
auto texture = CreateTextureForFixture("boston.jpg");
flutter::DisplayListBuilder builder;
+ flutter::DlPaint paint;
+
auto dilate = std::make_shared<flutter::DlDilateImageFilter>(10.0, 10.0);
auto erode = std::make_shared<flutter::DlErodeImageFilter>(10.0, 10.0);
auto open = std::make_shared<flutter::DlComposeImageFilter>(dilate, erode);
auto close = std::make_shared<flutter::DlComposeImageFilter>(erode, dilate);
- builder.setImageFilter(open.get());
- builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
- flutter::DlImageSampling::kNearestNeighbor, true);
- builder.translate(0, 700);
- builder.setImageFilter(close.get());
- builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
- flutter::DlImageSampling::kNearestNeighbor, true);
+
+ paint.setImageFilter(open.get());
+ builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
+ flutter::DlImageSampling::kNearestNeighbor, &paint);
+ builder.Translate(0, 700);
+ paint.setImageFilter(close.get());
+ builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
+ flutter::DlImageSampling::kNearestNeighbor, &paint);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
@@ -550,9 +564,10 @@
auto compose = std::make_shared<flutter::DlComposeImageFilter>(outer, inner);
flutter::DisplayListBuilder builder;
- builder.setImageFilter(compose.get());
- builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
- flutter::DlImageSampling::kNearestNeighbor, true);
+ flutter::DlPaint paint;
+ paint.setImageFilter(compose.get());
+ builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(100, 100),
+ flutter::DlImageSampling::kNearestNeighbor, &paint);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
@@ -686,7 +701,7 @@
flutter::DisplayListBuilder builder;
Vector2 scale = ctm_scale * GetContentScale();
- builder.scale(scale.x, scale.y);
+ builder.Scale(scale.x, scale.y);
auto filter = flutter::DlBlurImageFilter(sigma[0], sigma[1],
flutter::DlTileMode::kClamp);
@@ -701,12 +716,12 @@
// Insert a clip to test that the backdrop filter handles stencil depths > 0
// correctly.
if (add_clip) {
- builder.clipRect(SkRect::MakeLTRB(0, 0, 99999, 99999),
+ builder.ClipRect(SkRect::MakeLTRB(0, 0, 99999, 99999),
flutter::DlCanvas::ClipOp::kIntersect, true);
}
- builder.drawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
- flutter::DlImageSampling::kNearestNeighbor, true);
+ builder.DrawImage(DlImageImpeller::Make(texture), SkPoint::Make(200, 200),
+ flutter::DlImageSampling::kNearestNeighbor, nullptr);
builder.SaveLayer(bounds.has_value() ? &bounds.value() : nullptr, nullptr,
&filter);
@@ -714,12 +729,13 @@
auto circle_center =
IMPELLER_PLAYGROUND_POINT(Point(500, 400), 20, Color::Red());
- builder.setStyle(flutter::DlDrawStyle::kStroke);
- builder.setStrokeCap(flutter::DlStrokeCap::kButt);
- builder.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
- builder.setStrokeWidth(10);
- builder.setColor(flutter::DlColor::kRed().withAlpha(100));
- builder.drawCircle({circle_center.x, circle_center.y}, 100);
+ flutter::DlPaint paint;
+ paint.setDrawStyle(flutter::DlDrawStyle::kStroke);
+ paint.setStrokeCap(flutter::DlStrokeCap::kButt);
+ paint.setStrokeJoin(flutter::DlStrokeJoin::kBevel);
+ paint.setStrokeWidth(10);
+ paint.setColor(flutter::DlColor::kRed().withAlpha(100));
+ builder.DrawCircle({circle_center.x, circle_center.y}, 100, paint);
}
return builder.Build();
@@ -733,12 +749,12 @@
auto texture = CreateTextureForFixture("embarcadero.jpg");
flutter::DisplayListBuilder builder;
auto size = texture->GetSize();
- builder.drawImageNine(
+ builder.DrawImageNine(
DlImageImpeller::Make(texture),
SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
size.height * 3 / 4),
SkRect::MakeLTRB(0, 0, size.width * 2, size.height * 2),
- flutter::DlFilterMode::kNearest, true);
+ flutter::DlFilterMode::kNearest, nullptr);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
@@ -749,12 +765,12 @@
auto texture = CreateTextureForFixture("embarcadero.jpg");
flutter::DisplayListBuilder builder;
auto size = texture->GetSize();
- builder.drawImageNine(
+ builder.DrawImageNine(
DlImageImpeller::Make(texture),
SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
size.height * 3 / 4),
SkRect::MakeLTRB(0, 0, size.width / 2, size.height),
- flutter::DlFilterMode::kNearest, true);
+ flutter::DlFilterMode::kNearest, nullptr);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
@@ -765,12 +781,12 @@
auto texture = CreateTextureForFixture("embarcadero.jpg");
flutter::DisplayListBuilder builder;
auto size = texture->GetSize();
- builder.drawImageNine(
+ builder.DrawImageNine(
DlImageImpeller::Make(texture),
SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
size.height * 3 / 4),
SkRect::MakeLTRB(0, 0, size.width, size.height / 2),
- flutter::DlFilterMode::kNearest, true);
+ flutter::DlFilterMode::kNearest, nullptr);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
@@ -780,12 +796,12 @@
auto texture = CreateTextureForFixture("embarcadero.jpg");
flutter::DisplayListBuilder builder;
auto size = texture->GetSize();
- builder.drawImageNine(
+ builder.DrawImageNine(
DlImageImpeller::Make(texture),
SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
size.height * 3 / 4),
SkRect::MakeLTRB(0, 0, size.width / 2, size.height / 2),
- flutter::DlFilterMode::kNearest, true);
+ flutter::DlFilterMode::kNearest, nullptr);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
@@ -795,12 +811,12 @@
auto texture = CreateTextureForFixture("embarcadero.jpg");
flutter::DisplayListBuilder builder;
auto size = texture->GetSize();
- builder.drawImageNine(
+ builder.DrawImageNine(
DlImageImpeller::Make(texture),
SkIRect::MakeLTRB(size.width / 4, size.height / 4, size.width * 3 / 4,
size.height * 3 / 4),
SkRect::MakeLTRB(0, 0, size.width / 4, size.height / 4),
- flutter::DlFilterMode::kNearest, true);
+ flutter::DlFilterMode::kNearest, nullptr);
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
@@ -865,9 +881,10 @@
TEST_P(DisplayListTest, CanDrawShadow) {
flutter::DisplayListBuilder builder;
+ flutter::DlPaint paint;
auto content_scale = GetContentScale() * 0.8;
- builder.scale(content_scale.x, content_scale.y);
+ builder.Scale(content_scale.x, content_scale.y);
constexpr size_t star_spikes = 5;
constexpr SkScalar half_spike_rotation = kPi / star_spikes;
@@ -892,20 +909,20 @@
SkPath{}.addCircle(100, 50, 50),
SkPath{}.addPoly(star.data(), star.size(), true),
};
- builder.setColor(flutter::DlColor::kWhite());
- builder.drawPaint();
- builder.setColor(flutter::DlColor::kCyan());
- builder.translate(100, 50);
+ paint.setColor(flutter::DlColor::kWhite());
+ builder.DrawPaint(paint);
+ paint.setColor(flutter::DlColor::kCyan());
+ builder.Translate(100, 50);
for (size_t x = 0; x < paths.size(); x++) {
- builder.save();
+ builder.Save();
for (size_t y = 0; y < 6; y++) {
- builder.drawShadow(paths[x], flutter::DlColor::kBlack(), 3 + y * 8, false,
+ builder.DrawShadow(paths[x], flutter::DlColor::kBlack(), 3 + y * 8, false,
1);
- builder.drawPath(paths[x]);
- builder.translate(0, 150);
+ builder.DrawPath(paths[x], paint);
+ builder.Translate(0, 150);
}
- builder.restore();
- builder.translate(250, 0);
+ builder.Restore();
+ builder.Translate(250, 0);
}
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
@@ -1021,20 +1038,21 @@
ImGui::End();
flutter::DisplayListBuilder builder;
- SkPaint paint;
+ flutter::DlPaint paint;
+
if (enable_savelayer) {
builder.SaveLayer(nullptr, nullptr);
}
{
auto content_scale = GetContentScale();
- builder.scale(content_scale.x, content_scale.y);
+ builder.Scale(content_scale.x, content_scale.y);
// Set the current transform
auto ctm_matrix =
SkMatrix::MakeAll(ctm_scale[0], ctm_skew[0], ctm_translation[0], //
ctm_skew[1], ctm_scale[1], ctm_translation[1], //
0, 0, 1);
- builder.transform(ctm_matrix);
+ builder.Transform(ctm_matrix);
// Set the matrix filter
auto filter_matrix =
@@ -1047,7 +1065,7 @@
case 0: {
auto filter = flutter::DlMatrixImageFilter(
filter_matrix, flutter::DlImageSampling::kLinear);
- builder.setImageFilter(&filter);
+ paint.setImageFilter(&filter);
break;
}
case 1: {
@@ -1056,17 +1074,17 @@
.shared();
auto filter = flutter::DlLocalMatrixImageFilter(filter_matrix,
internal_filter);
- builder.setImageFilter(&filter);
+ paint.setImageFilter(&filter);
break;
}
}
}
- builder.drawImage(DlImageImpeller::Make(boston), {},
- flutter::DlImageSampling::kLinear, true);
+ builder.DrawImage(DlImageImpeller::Make(boston), {},
+ flutter::DlImageSampling::kLinear, &paint);
}
if (enable_savelayer) {
- builder.restore();
+ builder.Restore();
}
return builder.Build();
diff --git a/lib/ui/painting/canvas.cc b/lib/ui/painting/canvas.cc
index 92f7043..03d8385 100644
--- a/lib/ui/painting/canvas.cc
+++ b/lib/ui/painting/canvas.cc
@@ -47,7 +47,7 @@
void Canvas::save() {
if (display_list_builder_) {
- builder()->save();
+ builder()->Save();
}
}
@@ -57,11 +57,11 @@
FML_DCHECK(paint.isNotNull());
if (display_list_builder_) {
- bool restore_with_paint =
- paint.sync_to(builder(), kSaveLayerWithPaintFlags);
- FML_DCHECK(restore_with_paint);
+ DlPaint dl_paint;
+ const DlPaint* save_paint = paint.paint(dl_paint, kSaveLayerWithPaintFlags);
+ FML_DCHECK(save_paint);
TRACE_EVENT0("flutter", "ui.Canvas::saveLayer (Recorded)");
- builder()->saveLayer(nullptr, restore_with_paint);
+ builder()->SaveLayer(nullptr, save_paint);
}
}
@@ -76,17 +76,17 @@
FML_DCHECK(paint.isNotNull());
SkRect bounds = SkRect::MakeLTRB(left, top, right, bottom);
if (display_list_builder_) {
- bool restore_with_paint =
- paint.sync_to(builder(), kSaveLayerWithPaintFlags);
- FML_DCHECK(restore_with_paint);
+ DlPaint dl_paint;
+ const DlPaint* save_paint = paint.paint(dl_paint, kSaveLayerWithPaintFlags);
+ FML_DCHECK(save_paint);
TRACE_EVENT0("flutter", "ui.Canvas::saveLayer (Recorded)");
- builder()->saveLayer(&bounds, restore_with_paint);
+ builder()->SaveLayer(&bounds, save_paint);
}
}
void Canvas::restore() {
if (display_list_builder_) {
- builder()->restore();
+ builder()->Restore();
}
}
@@ -100,31 +100,31 @@
void Canvas::restoreToCount(int count) {
if (display_list_builder_ && count < getSaveCount()) {
- builder()->restoreToCount(count);
+ builder()->RestoreToCount(count);
}
}
void Canvas::translate(double dx, double dy) {
if (display_list_builder_) {
- builder()->translate(dx, dy);
+ builder()->Translate(dx, dy);
}
}
void Canvas::scale(double sx, double sy) {
if (display_list_builder_) {
- builder()->scale(sx, sy);
+ builder()->Scale(sx, sy);
}
}
void Canvas::rotate(double radians) {
if (display_list_builder_) {
- builder()->rotate(radians * 180.0 / M_PI);
+ builder()->Rotate(radians * 180.0 / M_PI);
}
}
void Canvas::skew(double sx, double sy) {
if (display_list_builder_) {
- builder()->skew(sx, sy);
+ builder()->Skew(sx, sy);
}
}
@@ -133,7 +133,7 @@
// Both DisplayList and SkM44 constructor take row-major matrix order
if (display_list_builder_) {
// clang-format off
- builder()->transformFullPerspective(
+ builder()->TransformFullPerspective(
matrix4[ 0], matrix4[ 4], matrix4[ 8], matrix4[12],
matrix4[ 1], matrix4[ 5], matrix4[ 9], matrix4[13],
matrix4[ 2], matrix4[ 6], matrix4[10], matrix4[14],
@@ -162,14 +162,14 @@
DlCanvas::ClipOp clipOp,
bool doAntiAlias) {
if (display_list_builder_) {
- builder()->clipRect(SkRect::MakeLTRB(left, top, right, bottom), clipOp,
+ builder()->ClipRect(SkRect::MakeLTRB(left, top, right, bottom), clipOp,
doAntiAlias);
}
}
void Canvas::clipRRect(const RRect& rrect, bool doAntiAlias) {
if (display_list_builder_) {
- builder()->clipRRect(rrect.sk_rrect, DlCanvas::ClipOp::kIntersect,
+ builder()->ClipRRect(rrect.sk_rrect, DlCanvas::ClipOp::kIntersect,
doAntiAlias);
}
}
@@ -181,7 +181,7 @@
return;
}
if (display_list_builder_) {
- builder()->clipPath(path->path(), DlCanvas::ClipOp::kIntersect,
+ builder()->ClipPath(path->path(), DlCanvas::ClipOp::kIntersect,
doAntiAlias);
}
}
@@ -210,7 +210,7 @@
void Canvas::drawColor(SkColor color, DlBlendMode blend_mode) {
if (display_list_builder_) {
- builder()->drawColor(color, blend_mode);
+ builder()->DrawColor(color, blend_mode);
}
}
@@ -224,8 +224,9 @@
FML_DCHECK(paint.isNotNull());
if (display_list_builder_) {
- paint.sync_to(builder(), kDrawLineFlags);
- builder()->drawLine(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2));
+ DlPaint dl_paint;
+ paint.paint(dl_paint, kDrawLineFlags);
+ builder()->DrawLine(SkPoint::Make(x1, y1), SkPoint::Make(x2, y2), dl_paint);
}
}
@@ -234,14 +235,15 @@
FML_DCHECK(paint.isNotNull());
if (display_list_builder_) {
- paint.sync_to(builder(), kDrawPaintFlags);
- std::shared_ptr<const DlImageFilter> filter = builder()->getImageFilter();
+ DlPaint dl_paint;
+ paint.paint(dl_paint, kDrawPaintFlags);
+ std::shared_ptr<const DlImageFilter> filter = dl_paint.getImageFilter();
if (filter && !filter->asColorFilter()) {
// drawPaint does an implicit saveLayer if an SkImageFilter is
// present that cannot be replaced by an SkColorFilter.
TRACE_EVENT0("flutter", "ui.Canvas::saveLayer (Recorded)");
}
- builder()->drawPaint();
+ builder()->DrawPaint(dl_paint);
}
}
@@ -255,8 +257,9 @@
FML_DCHECK(paint.isNotNull());
if (display_list_builder_) {
- paint.sync_to(builder(), kDrawRectFlags);
- builder()->drawRect(SkRect::MakeLTRB(left, top, right, bottom));
+ DlPaint dl_paint;
+ paint.paint(dl_paint, kDrawRectFlags);
+ builder()->DrawRect(SkRect::MakeLTRB(left, top, right, bottom), dl_paint);
}
}
@@ -267,8 +270,9 @@
FML_DCHECK(paint.isNotNull());
if (display_list_builder_) {
- paint.sync_to(builder(), kDrawRRectFlags);
- builder()->drawRRect(rrect.sk_rrect);
+ DlPaint dl_paint;
+ paint.paint(dl_paint, kDrawRRectFlags);
+ builder()->DrawRRect(rrect.sk_rrect, dl_paint);
}
}
@@ -280,8 +284,9 @@
FML_DCHECK(paint.isNotNull());
if (display_list_builder_) {
- paint.sync_to(builder(), kDrawDRRectFlags);
- builder()->drawDRRect(outer.sk_rrect, inner.sk_rrect);
+ DlPaint dl_paint;
+ paint.paint(dl_paint, kDrawDRRectFlags);
+ builder()->DrawDRRect(outer.sk_rrect, inner.sk_rrect, dl_paint);
}
}
@@ -295,8 +300,9 @@
FML_DCHECK(paint.isNotNull());
if (display_list_builder_) {
- paint.sync_to(builder(), kDrawOvalFlags);
- builder()->drawOval(SkRect::MakeLTRB(left, top, right, bottom));
+ DlPaint dl_paint;
+ paint.paint(dl_paint, kDrawOvalFlags);
+ builder()->DrawOval(SkRect::MakeLTRB(left, top, right, bottom), dl_paint);
}
}
@@ -309,8 +315,9 @@
FML_DCHECK(paint.isNotNull());
if (display_list_builder_) {
- paint.sync_to(builder(), kDrawCircleFlags);
- builder()->drawCircle(SkPoint::Make(x, y), radius);
+ DlPaint dl_paint;
+ paint.paint(dl_paint, kDrawCircleFlags);
+ builder()->DrawCircle(SkPoint::Make(x, y), radius, dl_paint);
}
}
@@ -327,13 +334,13 @@
FML_DCHECK(paint.isNotNull());
if (display_list_builder_) {
- paint.sync_to(builder(),
- useCenter //
- ? kDrawArcWithCenterFlags
- : kDrawArcNoCenterFlags);
- builder()->drawArc(SkRect::MakeLTRB(left, top, right, bottom),
+ DlPaint dl_paint;
+ paint.paint(dl_paint, useCenter //
+ ? kDrawArcWithCenterFlags
+ : kDrawArcNoCenterFlags);
+ builder()->DrawArc(SkRect::MakeLTRB(left, top, right, bottom),
startAngle * 180.0 / M_PI, sweepAngle * 180.0 / M_PI,
- useCenter);
+ useCenter, dl_paint);
}
}
@@ -349,8 +356,9 @@
return;
}
if (display_list_builder_) {
- paint.sync_to(builder(), kDrawPathFlags);
- builder()->drawPath(path->path());
+ DlPaint dl_paint;
+ paint.paint(dl_paint, kDrawPathFlags);
+ builder()->DrawPath(path->path(), dl_paint);
}
}
@@ -378,9 +386,9 @@
auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex);
if (display_list_builder_) {
- bool with_attributes = paint.sync_to(builder(), kDrawImageWithPaintFlags);
- builder()->drawImage(dl_image, SkPoint::Make(x, y), sampling,
- with_attributes);
+ DlPaint dl_paint;
+ const DlPaint* opt_paint = paint.paint(dl_paint, kDrawImageWithPaintFlags);
+ builder()->DrawImage(dl_image, SkPoint::Make(x, y), sampling, opt_paint);
}
return Dart_Null();
}
@@ -417,10 +425,11 @@
SkRect dst = SkRect::MakeLTRB(dst_left, dst_top, dst_right, dst_bottom);
auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex);
if (display_list_builder_) {
- bool with_attributes =
- paint.sync_to(builder(), kDrawImageRectWithPaintFlags);
- builder()->drawImageRect(dl_image, src, dst, sampling, with_attributes,
- SkCanvas::kFast_SrcRectConstraint);
+ DlPaint dl_paint;
+ const DlPaint* opt_paint =
+ paint.paint(dl_paint, kDrawImageRectWithPaintFlags);
+ builder()->DrawImageRect(dl_image, src, dst, sampling, opt_paint,
+ DlCanvas::SrcRectConstraint::kFast);
}
return Dart_Null();
}
@@ -459,9 +468,10 @@
SkRect dst = SkRect::MakeLTRB(dst_left, dst_top, dst_right, dst_bottom);
auto filter = ImageFilter::FilterModeFromIndex(bitmapSamplingIndex);
if (display_list_builder_) {
- bool with_attributes =
- paint.sync_to(builder(), kDrawImageNineWithPaintFlags);
- builder()->drawImageNine(dl_image, icenter, dst, filter, with_attributes);
+ DlPaint dl_paint;
+ const DlPaint* opt_paint =
+ paint.paint(dl_paint, kDrawImageNineWithPaintFlags);
+ builder()->DrawImageNine(dl_image, icenter, dst, filter, opt_paint);
}
return Dart_Null();
}
@@ -474,7 +484,7 @@
}
if (picture->display_list()) {
if (display_list_builder_) {
- builder()->drawDisplayList(picture->display_list());
+ builder()->DrawDisplayList(picture->display_list());
}
} else {
FML_DCHECK(false);
@@ -492,20 +502,22 @@
FML_DCHECK(paint.isNotNull());
if (display_list_builder_) {
+ DlPaint dl_paint;
switch (point_mode) {
case DlCanvas::PointMode::kPoints:
- paint.sync_to(builder(), kDrawPointsAsPointsFlags);
+ paint.paint(dl_paint, kDrawPointsAsPointsFlags);
break;
case DlCanvas::PointMode::kLines:
- paint.sync_to(builder(), kDrawPointsAsLinesFlags);
+ paint.paint(dl_paint, kDrawPointsAsLinesFlags);
break;
case DlCanvas::PointMode::kPolygon:
- paint.sync_to(builder(), kDrawPointsAsPolygonFlags);
+ paint.paint(dl_paint, kDrawPointsAsPolygonFlags);
break;
}
- builder()->drawPoints(point_mode,
+ builder()->DrawPoints(point_mode,
points.num_elements() / 2, // SkPoints have 2 floats
- reinterpret_cast<const SkPoint*>(points.data()));
+ reinterpret_cast<const SkPoint*>(points.data()),
+ dl_paint);
}
}
@@ -522,8 +534,9 @@
}
FML_DCHECK(paint.isNotNull());
if (display_list_builder_) {
- paint.sync_to(builder(), kDrawVerticesFlags);
- builder()->drawVertices(vertices->vertices(), blend_mode);
+ DlPaint dl_paint;
+ paint.paint(dl_paint, kDrawVerticesFlags);
+ builder()->DrawVertices(vertices->vertices(), blend_mode, dl_paint);
}
}
@@ -564,14 +577,15 @@
tonic::Int32List colors(colors_handle);
tonic::Float32List cull_rect(cull_rect_handle);
- bool with_attributes = paint.sync_to(builder(), kDrawAtlasWithPaintFlags);
- builder()->drawAtlas(
+ DlPaint dl_paint;
+ const DlPaint* opt_paint = paint.paint(dl_paint, kDrawAtlasWithPaintFlags);
+ builder()->DrawAtlas(
dl_image, reinterpret_cast<const SkRSXform*>(transforms.data()),
reinterpret_cast<const SkRect*>(rects.data()),
reinterpret_cast<const DlColor*>(colors.data()),
rects.num_elements() / 4, // SkRect have four floats.
blend_mode, sampling, reinterpret_cast<const SkRect*>(cull_rect.data()),
- with_attributes);
+ opt_paint);
}
return Dart_Null();
}
@@ -598,7 +612,7 @@
// that situation we bypass the canvas interface and inject the
// shadow parameters directly into the underlying DisplayList.
// See: https://bugs.chromium.org/p/skia/issues/detail?id=12125
- builder()->drawShadow(path->path(), color, elevation, transparentOccluder,
+ builder()->DrawShadow(path->path(), color, elevation, transparentOccluder,
dpr);
}
}
diff --git a/lib/ui/painting/color_filter.cc b/lib/ui/painting/color_filter.cc
index 12b0db9..06d421b 100644
--- a/lib/ui/painting/color_filter.cc
+++ b/lib/ui/painting/color_filter.cc
@@ -23,8 +23,8 @@
}
void ColorFilter::initMode(int color, int blend_mode) {
- filter_ = std::make_shared<DlBlendColorFilter>(
- static_cast<DlColor>(color), static_cast<DlBlendMode>(blend_mode));
+ filter_ = DlBlendColorFilter::Make(static_cast<DlColor>(color),
+ static_cast<DlBlendMode>(blend_mode));
}
void ColorFilter::initMatrix(const tonic::Float32List& color_matrix) {
@@ -39,7 +39,7 @@
matrix[9] *= 1.0f / 255;
matrix[14] *= 1.0f / 255;
matrix[19] *= 1.0f / 255;
- filter_ = std::make_shared<DlMatrixColorFilter>(matrix);
+ filter_ = DlMatrixColorFilter::Make(matrix);
}
void ColorFilter::initLinearToSrgbGamma() {
diff --git a/lib/ui/painting/color_filter.h b/lib/ui/painting/color_filter.h
index f80c48d..b7aa2e2 100644
--- a/lib/ui/painting/color_filter.h
+++ b/lib/ui/painting/color_filter.h
@@ -31,9 +31,6 @@
~ColorFilter() override;
const std::shared_ptr<const DlColorFilter> filter() const { return filter_; }
- const DlColorFilter* dl_filter() const {
- return (filter_ && filter_->skia_object()) ? filter_.get() : nullptr;
- }
private:
std::shared_ptr<const DlColorFilter> filter_;
diff --git a/lib/ui/painting/gradient.cc b/lib/ui/painting/gradient.cc
index 9651982..5f586a3 100644
--- a/lib/ui/painting/gradient.cc
+++ b/lib/ui/painting/gradient.cc
@@ -25,7 +25,7 @@
void CanvasGradient::initLinear(const tonic::Float32List& end_points,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
- SkTileMode tile_mode,
+ DlTileMode tile_mode,
const tonic::Float64List& matrix4) {
FML_DCHECK(end_points.num_elements() == 4);
FML_DCHECK(colors.num_elements() == color_stops.num_elements() ||
@@ -48,7 +48,7 @@
dl_shader_ = DlColorSource::MakeLinear(
p0, p1, colors.num_elements(), colors_array, color_stops.data(),
- ToDl(tile_mode), has_matrix ? &sk_matrix : nullptr);
+ tile_mode, has_matrix ? &sk_matrix : nullptr);
}
void CanvasGradient::initRadial(double center_x,
@@ -56,7 +56,7 @@
double radius,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
- SkTileMode tile_mode,
+ DlTileMode tile_mode,
const tonic::Float64List& matrix4) {
FML_DCHECK(colors.num_elements() == color_stops.num_elements() ||
color_stops.data() == nullptr);
@@ -74,7 +74,7 @@
dl_shader_ = DlColorSource::MakeRadial(
SkPoint::Make(center_x, center_y), radius, colors.num_elements(),
- colors_array, color_stops.data(), ToDl(tile_mode),
+ colors_array, color_stops.data(), tile_mode,
has_matrix ? &sk_matrix : nullptr);
}
@@ -82,7 +82,7 @@
double center_y,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
- SkTileMode tile_mode,
+ DlTileMode tile_mode,
double start_angle,
double end_angle,
const tonic::Float64List& matrix4) {
@@ -103,7 +103,7 @@
dl_shader_ = DlColorSource::MakeSweep(
SkPoint::Make(center_x, center_y), start_angle * 180.0 / M_PI,
end_angle * 180.0 / M_PI, colors.num_elements(), colors_array,
- color_stops.data(), ToDl(tile_mode), has_matrix ? &sk_matrix : nullptr);
+ color_stops.data(), tile_mode, has_matrix ? &sk_matrix : nullptr);
}
void CanvasGradient::initTwoPointConical(double start_x,
@@ -114,7 +114,7 @@
double end_radius,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
- SkTileMode tile_mode,
+ DlTileMode tile_mode,
const tonic::Float64List& matrix4) {
FML_DCHECK(colors.num_elements() == color_stops.num_elements() ||
color_stops.data() == nullptr);
@@ -134,7 +134,7 @@
SkPoint::Make(start_x, start_y), start_radius, //
SkPoint::Make(end_x, end_y), end_radius, //
colors.num_elements(), colors_array, color_stops.data(), //
- ToDl(tile_mode), has_matrix ? &sk_matrix : nullptr);
+ tile_mode, has_matrix ? &sk_matrix : nullptr);
}
CanvasGradient::CanvasGradient() = default;
diff --git a/lib/ui/painting/gradient.h b/lib/ui/painting/gradient.h
index 5041ab2..d510cef 100644
--- a/lib/ui/painting/gradient.h
+++ b/lib/ui/painting/gradient.h
@@ -12,9 +12,6 @@
namespace flutter {
-// TODO: update this if/when Skia adds Decal mode skbug.com/7638
-static_assert(kSkTileModeCount >= 3, "Need to update tile mode enum");
-
class CanvasGradient : public Shader {
DEFINE_WRAPPERTYPEINFO();
FML_FRIEND_MAKE_REF_COUNTED(CanvasGradient);
@@ -26,7 +23,7 @@
void initLinear(const tonic::Float32List& end_points,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
- SkTileMode tile_mode,
+ DlTileMode tile_mode,
const tonic::Float64List& matrix4);
void initRadial(double center_x,
@@ -34,14 +31,14 @@
double radius,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
- SkTileMode tile_mode,
+ DlTileMode tile_mode,
const tonic::Float64List& matrix4);
void initSweep(double center_x,
double center_y,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
- SkTileMode tile_mode,
+ DlTileMode tile_mode,
double start_angle,
double end_angle,
const tonic::Float64List& matrix4);
@@ -54,11 +51,12 @@
double end_radius,
const tonic::Int32List& colors,
const tonic::Float32List& color_stops,
- SkTileMode tile_mode,
+ DlTileMode tile_mode,
const tonic::Float64List& matrix4);
std::shared_ptr<DlColorSource> shader(DlImageSampling sampling) override {
- return dl_shader_->with_sampling(sampling);
+ // Gradient color sources do not have image sampling variants...
+ return dl_shader_;
}
private:
diff --git a/lib/ui/painting/image_filter.cc b/lib/ui/painting/image_filter.cc
index 665d3b0..d92db00 100644
--- a/lib/ui/painting/image_filter.cc
+++ b/lib/ui/painting/image_filter.cc
@@ -52,45 +52,32 @@
void ImageFilter::initBlur(double sigma_x,
double sigma_y,
- SkTileMode tile_mode) {
- filter_ =
- std::make_shared<DlBlurImageFilter>(sigma_x, sigma_y, ToDl(tile_mode));
+ DlTileMode tile_mode) {
+ filter_ = DlBlurImageFilter::Make(sigma_x, sigma_y, tile_mode);
}
void ImageFilter::initDilate(double radius_x, double radius_y) {
- filter_ = std::make_shared<DlDilateImageFilter>(radius_x, radius_y);
+ filter_ = DlDilateImageFilter::Make(radius_x, radius_y);
}
void ImageFilter::initErode(double radius_x, double radius_y) {
- filter_ = std::make_shared<DlErodeImageFilter>(radius_x, radius_y);
+ filter_ = DlErodeImageFilter::Make(radius_x, radius_y);
}
void ImageFilter::initMatrix(const tonic::Float64List& matrix4,
int filterQualityIndex) {
auto sampling = ImageFilter::SamplingFromIndex(filterQualityIndex);
- filter_ =
- std::make_shared<DlMatrixImageFilter>(ToSkMatrix(matrix4), sampling);
+ filter_ = DlMatrixImageFilter::Make(ToSkMatrix(matrix4), sampling);
}
void ImageFilter::initColorFilter(ColorFilter* colorFilter) {
FML_DCHECK(colorFilter);
- auto dl_filter = colorFilter->dl_filter();
- // Skia may return nullptr if the colorfilter is a no-op.
- if (dl_filter) {
- filter_ = std::make_shared<DlColorFilterImageFilter>(dl_filter);
- }
+ filter_ = DlColorFilterImageFilter::Make(colorFilter->filter());
}
void ImageFilter::initComposeFilter(ImageFilter* outer, ImageFilter* inner) {
FML_DCHECK(outer && inner);
- if (!outer->dl_filter()) {
- filter_ = inner->filter();
- } else if (!inner->dl_filter()) {
- filter_ = outer->filter();
- } else {
- filter_ = std::make_shared<DlComposeImageFilter>(outer->dl_filter(),
- inner->dl_filter());
- }
+ filter_ = DlComposeImageFilter::Make(outer->filter(), inner->filter());
}
} // namespace flutter
diff --git a/lib/ui/painting/image_filter.h b/lib/ui/painting/image_filter.h
index 67d9738..66e3012 100644
--- a/lib/ui/painting/image_filter.h
+++ b/lib/ui/painting/image_filter.h
@@ -30,7 +30,7 @@
static DlImageSampling SamplingFromIndex(int filterQualityIndex);
static DlFilterMode FilterModeFromIndex(int index);
- void initBlur(double sigma_x, double sigma_y, SkTileMode tile_mode);
+ void initBlur(double sigma_x, double sigma_y, DlTileMode tile_mode);
void initDilate(double radius_x, double radius_y);
void initErode(double radius_x, double radius_y);
void initMatrix(const tonic::Float64List& matrix4, int filter_quality_index);
@@ -38,9 +38,6 @@
void initComposeFilter(ImageFilter* outer, ImageFilter* inner);
const std::shared_ptr<const DlImageFilter> filter() const { return filter_; }
- const DlImageFilter* dl_filter() const {
- return (filter_ && filter_->skia_object()) ? filter_.get() : nullptr;
- }
static void RegisterNatives(tonic::DartLibraryNatives* natives);
diff --git a/lib/ui/painting/image_shader.cc b/lib/ui/painting/image_shader.cc
index bd00fd1..e2cdae7 100644
--- a/lib/ui/painting/image_shader.cc
+++ b/lib/ui/painting/image_shader.cc
@@ -24,8 +24,8 @@
}
Dart_Handle ImageShader::initWithImage(CanvasImage* image,
- SkTileMode tmx,
- SkTileMode tmy,
+ DlTileMode tmx,
+ DlTileMode tmy,
int filter_quality_index,
Dart_Handle matrix_handle) {
if (!image) {
@@ -41,7 +41,7 @@
sampling_is_locked_ ? ImageFilter::SamplingFromIndex(filter_quality_index)
: DlImageSampling::kLinear;
cached_shader_ = UIDartState::CreateGPUObject(sk_make_sp<DlImageColorSource>(
- image_, ToDl(tmx), ToDl(tmy), sampling, &local_matrix));
+ image_, tmx, tmy, sampling, &local_matrix));
return Dart_Null();
}
diff --git a/lib/ui/painting/image_shader.h b/lib/ui/painting/image_shader.h
index d130c5d..7c69d13 100644
--- a/lib/ui/painting/image_shader.h
+++ b/lib/ui/painting/image_shader.h
@@ -25,8 +25,8 @@
static void Create(Dart_Handle wrapper);
Dart_Handle initWithImage(CanvasImage* image,
- SkTileMode tmx,
- SkTileMode tmy,
+ DlTileMode tmx,
+ DlTileMode tmy,
int filter_quality_index,
Dart_Handle matrix_handle);
diff --git a/lib/ui/painting/paint.cc b/lib/ui/painting/paint.cc
index 2849526..32539c5 100644
--- a/lib/ui/painting/paint.cc
+++ b/lib/ui/painting/paint.cc
@@ -53,148 +53,17 @@
// default SkPaintDefaults_MiterLimit in Skia (which is not in a public header).
constexpr double kStrokeMiterLimitDefault = 4.0;
-// A color matrix which inverts colors.
-// clang-format off
-constexpr float kInvertColors[20] = {
- -1.0, 0, 0, 1.0, 0,
- 0, -1.0, 0, 1.0, 0,
- 0, 0, -1.0, 1.0, 0,
- 1.0, 1.0, 1.0, 1.0, 0
-};
-// clang-format on
-
// Must be kept in sync with the MaskFilter private constants in painting.dart.
enum MaskFilterType { kNull, kBlur };
Paint::Paint(Dart_Handle paint_objects, Dart_Handle paint_data)
: paint_objects_(paint_objects), paint_data_(paint_data) {}
-const SkPaint* Paint::paint(SkPaint& paint) const {
+const DlPaint* Paint::paint(DlPaint& paint,
+ const DisplayListAttributeFlags& flags) const {
if (isNull()) {
return nullptr;
}
- FML_DCHECK(paint == SkPaint());
-
- tonic::DartByteData byte_data(paint_data_);
- FML_CHECK(byte_data.length_in_bytes() == kDataByteCount);
-
- const uint32_t* uint_data = static_cast<const uint32_t*>(byte_data.data());
- const float* float_data = static_cast<const float*>(byte_data.data());
-
- Dart_Handle values[kObjectCount];
- if (!Dart_IsNull(paint_objects_)) {
- FML_DCHECK(Dart_IsList(paint_objects_));
- intptr_t length = 0;
- Dart_ListLength(paint_objects_, &length);
-
- FML_CHECK(length == kObjectCount);
- if (Dart_IsError(
- Dart_ListGetRange(paint_objects_, 0, kObjectCount, values))) {
- return nullptr;
- }
-
- Dart_Handle shader = values[kShaderIndex];
- if (!Dart_IsNull(shader)) {
- if (Shader* decoded = tonic::DartConverter<Shader*>::FromDart(shader)) {
- auto sampling =
- ImageFilter::SamplingFromIndex(uint_data[kFilterQualityIndex]);
- auto color_source = decoded->shader(sampling);
- // TODO(dnfield): Remove this restriction.
- // This currently is only used by paragraph code. Once SkParagraph does
- // not need to take an SkPaint, we won't be restricted in this way
- // because we will not need to access the shader on the UI task runner.
- if (color_source->owning_context() != DlImage::OwningContext::kRaster) {
- paint.setShader(color_source->skia_object());
- }
- }
- }
-
- Dart_Handle color_filter = values[kColorFilterIndex];
- if (!Dart_IsNull(color_filter)) {
- ColorFilter* decoded =
- tonic::DartConverter<ColorFilter*>::FromDart(color_filter);
- paint.setColorFilter(decoded->filter()->skia_object());
- }
-
- Dart_Handle image_filter = values[kImageFilterIndex];
- if (!Dart_IsNull(image_filter)) {
- ImageFilter* decoded =
- tonic::DartConverter<ImageFilter*>::FromDart(image_filter);
- paint.setImageFilter(decoded->filter()->skia_object());
- }
- }
-
- paint.setAntiAlias(uint_data[kIsAntiAliasIndex] == 0);
-
- uint32_t encoded_color = uint_data[kColorIndex];
- if (encoded_color) {
- SkColor color = encoded_color ^ kColorDefault;
- paint.setColor(color);
- }
-
- uint32_t encoded_blend_mode = uint_data[kBlendModeIndex];
- if (encoded_blend_mode) {
- uint32_t blend_mode = encoded_blend_mode ^ kBlendModeDefault;
- paint.setBlendMode(static_cast<SkBlendMode>(blend_mode));
- }
-
- uint32_t style = uint_data[kStyleIndex];
- if (style) {
- paint.setStyle(static_cast<SkPaint::Style>(style));
- }
-
- float stroke_width = float_data[kStrokeWidthIndex];
- if (stroke_width != 0.0) {
- paint.setStrokeWidth(stroke_width);
- }
-
- uint32_t stroke_cap = uint_data[kStrokeCapIndex];
- if (stroke_cap) {
- paint.setStrokeCap(static_cast<SkPaint::Cap>(stroke_cap));
- }
-
- uint32_t stroke_join = uint_data[kStrokeJoinIndex];
- if (stroke_join) {
- paint.setStrokeJoin(static_cast<SkPaint::Join>(stroke_join));
- }
-
- float stroke_miter_limit = float_data[kStrokeMiterLimitIndex];
- if (stroke_miter_limit != 0.0) {
- paint.setStrokeMiter(stroke_miter_limit + kStrokeMiterLimitDefault);
- }
-
- if (uint_data[kInvertColorIndex]) {
- sk_sp<SkColorFilter> invert_filter = SkColorFilters::Matrix(kInvertColors);
- sk_sp<SkColorFilter> current_filter = paint.refColorFilter();
- if (current_filter) {
- invert_filter = invert_filter->makeComposed(current_filter);
- }
- paint.setColorFilter(invert_filter);
- }
-
- if (uint_data[kDitherIndex]) {
- paint.setDither(true);
- }
-
- switch (uint_data[kMaskFilterIndex]) {
- case kNull:
- break;
- case kBlur:
- SkBlurStyle blur_style =
- static_cast<SkBlurStyle>(uint_data[kMaskFilterBlurStyleIndex]);
- double sigma = float_data[kMaskFilterSigmaIndex];
- paint.setMaskFilter(SkMaskFilter::MakeBlur(blur_style, sigma));
- break;
- }
-
- return &paint;
-}
-
-bool Paint::sync_to(DisplayListBuilder* builder,
- const DisplayListAttributeFlags& flags) const {
- if (isNull()) {
- return false;
- }
tonic::DartByteData byte_data(paint_data_);
FML_CHECK(byte_data.length_in_bytes() == kDataByteCount);
@@ -204,13 +73,13 @@
Dart_Handle values[kObjectCount];
if (Dart_IsNull(paint_objects_)) {
if (flags.applies_shader()) {
- builder->setColorSource(nullptr);
+ paint.setColorSource(nullptr);
}
if (flags.applies_color_filter()) {
- builder->setColorFilter(nullptr);
+ paint.setColorFilter(nullptr);
}
if (flags.applies_image_filter()) {
- builder->setImageFilter(nullptr);
+ paint.setImageFilter(nullptr);
}
} else {
FML_DCHECK(Dart_IsList(paint_objects_));
@@ -220,20 +89,20 @@
FML_CHECK(length == kObjectCount);
if (Dart_IsError(
Dart_ListGetRange(paint_objects_, 0, kObjectCount, values))) {
- return false;
+ return nullptr;
}
if (flags.applies_shader()) {
Dart_Handle shader = values[kShaderIndex];
if (Dart_IsNull(shader)) {
- builder->setColorSource(nullptr);
+ paint.setColorSource(nullptr);
} else {
if (Shader* decoded = tonic::DartConverter<Shader*>::FromDart(shader)) {
auto sampling =
ImageFilter::SamplingFromIndex(uint_data[kFilterQualityIndex]);
- builder->setColorSource(decoded->shader(sampling).get());
+ paint.setColorSource(decoded->shader(sampling));
} else {
- builder->setColorSource(nullptr);
+ paint.setColorSource(nullptr);
}
}
}
@@ -241,94 +110,89 @@
if (flags.applies_color_filter()) {
Dart_Handle color_filter = values[kColorFilterIndex];
if (Dart_IsNull(color_filter)) {
- builder->setColorFilter(nullptr);
+ paint.setColorFilter(nullptr);
} else {
ColorFilter* decoded =
tonic::DartConverter<ColorFilter*>::FromDart(color_filter);
- builder->setColorFilter(decoded->dl_filter());
+ paint.setColorFilter(decoded->filter());
}
}
if (flags.applies_image_filter()) {
Dart_Handle image_filter = values[kImageFilterIndex];
if (Dart_IsNull(image_filter)) {
- builder->setImageFilter(nullptr);
+ paint.setImageFilter(nullptr);
} else {
ImageFilter* decoded =
tonic::DartConverter<ImageFilter*>::FromDart(image_filter);
- builder->setImageFilter(decoded->dl_filter());
+ paint.setImageFilter(decoded->filter());
}
}
}
if (flags.applies_anti_alias()) {
- builder->setAntiAlias(uint_data[kIsAntiAliasIndex] == 0);
+ paint.setAntiAlias(uint_data[kIsAntiAliasIndex] == 0);
}
if (flags.applies_alpha_or_color()) {
uint32_t encoded_color = uint_data[kColorIndex];
- builder->setColor(encoded_color ^ kColorDefault);
+ paint.setColor(encoded_color ^ kColorDefault);
}
if (flags.applies_blend()) {
uint32_t encoded_blend_mode = uint_data[kBlendModeIndex];
uint32_t blend_mode = encoded_blend_mode ^ kBlendModeDefault;
- builder->setBlendMode(static_cast<DlBlendMode>(blend_mode));
+ paint.setBlendMode(static_cast<DlBlendMode>(blend_mode));
}
if (flags.applies_style()) {
uint32_t style = uint_data[kStyleIndex];
- builder->setStyle(static_cast<DlDrawStyle>(style));
+ paint.setDrawStyle(static_cast<DlDrawStyle>(style));
}
- if (flags.is_stroked(builder->getStyle())) {
+ if (flags.is_stroked(paint.getDrawStyle())) {
float stroke_width = float_data[kStrokeWidthIndex];
- builder->setStrokeWidth(stroke_width);
+ paint.setStrokeWidth(stroke_width);
float stroke_miter_limit = float_data[kStrokeMiterLimitIndex];
- builder->setStrokeMiter(stroke_miter_limit + kStrokeMiterLimitDefault);
+ paint.setStrokeMiter(stroke_miter_limit + kStrokeMiterLimitDefault);
uint32_t stroke_cap = uint_data[kStrokeCapIndex];
- builder->setStrokeCap(static_cast<DlStrokeCap>(stroke_cap));
+ paint.setStrokeCap(static_cast<DlStrokeCap>(stroke_cap));
uint32_t stroke_join = uint_data[kStrokeJoinIndex];
- builder->setStrokeJoin(static_cast<DlStrokeJoin>(stroke_join));
+ paint.setStrokeJoin(static_cast<DlStrokeJoin>(stroke_join));
}
if (flags.applies_color_filter()) {
- builder->setInvertColors(uint_data[kInvertColorIndex] != 0);
+ paint.setInvertColors(uint_data[kInvertColorIndex] != 0);
}
if (flags.applies_dither()) {
- builder->setDither(uint_data[kDitherIndex] != 0);
+ paint.setDither(uint_data[kDitherIndex] != 0);
}
if (flags.applies_path_effect()) {
// The paint API exposed to Dart does not support path effects. But other
// operations such as text may set a path effect, which must be cleared.
- builder->setPathEffect(nullptr);
+ paint.setPathEffect(nullptr);
}
if (flags.applies_mask_filter()) {
switch (uint_data[kMaskFilterIndex]) {
case kNull:
- builder->setMaskFilter(nullptr);
+ paint.setMaskFilter(nullptr);
break;
case kBlur:
SkBlurStyle blur_style =
static_cast<SkBlurStyle>(uint_data[kMaskFilterBlurStyleIndex]);
double sigma = float_data[kMaskFilterSigmaIndex];
- DlBlurMaskFilter dl_filter(blur_style, sigma);
- if (dl_filter.skia_object()) {
- builder->setMaskFilter(&dl_filter);
- } else {
- builder->setMaskFilter(nullptr);
- }
+ paint.setMaskFilter(DlBlurMaskFilter::Make(blur_style, sigma));
break;
}
}
- return true;
+ return &paint;
}
void Paint::toDlPaint(DlPaint& paint) const {
@@ -414,11 +278,14 @@
SkBlurStyle blur_style =
static_cast<SkBlurStyle>(uint_data[kMaskFilterBlurStyleIndex]);
double sigma = float_data[kMaskFilterSigmaIndex];
- std::shared_ptr<DlBlurMaskFilter> dl_filter =
- std::make_shared<DlBlurMaskFilter>(blur_style, sigma);
- if (dl_filter->skia_object()) {
- paint.setMaskFilter(dl_filter);
- }
+ // Make could return a nullptr here if the values are NOP or
+ // do not make sense. We could interpret that as if there was
+ // no value passed from Dart at all (i.e. don't change the
+ // setting in the paint object as in the kNull branch right
+ // above here), but the maskfilter flag was actually set
+ // indicating that the developer "tried" to set a mask, so we
+ // should set the null value rather than do nothing.
+ paint.setMaskFilter(DlBlurMaskFilter::Make(blur_style, sigma));
break;
}
}
diff --git a/lib/ui/painting/paint.h b/lib/ui/painting/paint.h
index 6e74535..466f26a 100644
--- a/lib/ui/painting/paint.h
+++ b/lib/ui/painting/paint.h
@@ -17,19 +17,11 @@
Paint() = default;
Paint(Dart_Handle paint_objects, Dart_Handle paint_data);
- const SkPaint* paint(SkPaint& paint) const;
+ const DlPaint* paint(DlPaint& paint,
+ const DisplayListAttributeFlags& flags) const;
void toDlPaint(DlPaint& paint) const;
- /// Synchronize the Dart properties to the display list according
- /// to the attribute flags that indicate which properties are needed.
- /// The return value indicates if the paint was non-null and can
- /// either be DCHECKed or used to indicate to the DisplayList
- /// draw operation whether or not to use the synchronized attributes
- /// (mainly the drawImage and saveLayer methods).
- bool sync_to(DisplayListBuilder* builder,
- const DisplayListAttributeFlags& flags) const;
-
bool isNull() const { return Dart_IsNull(paint_data_); }
bool isNotNull() const { return !Dart_IsNull(paint_data_); }
diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc
index d4a43e6..4533587 100644
--- a/shell/common/rasterizer.cc
+++ b/shell/common/rasterizer.cc
@@ -272,9 +272,9 @@
};
sk_sp<SkSurface> surface = SkSurface::MakeRaster(image_info);
- SkCanvas* canvas = surface->getCanvas();
- canvas->clear(SK_ColorTRANSPARENT);
- display_list->RenderTo(canvas);
+ auto canvas = DlSkCanvasAdapter(surface->getCanvas());
+ canvas.Clear(DlColor::kTransparent());
+ canvas.DrawDisplayList(display_list);
sk_sp<SkImage> image = surface->makeImageSnapshot();
return std::make_unique<SnapshotDelegate::GpuImageResult>(
@@ -342,9 +342,9 @@
return;
}
- SkCanvas* canvas = sk_surface->getCanvas();
- canvas->clear(SK_ColorTRANSPARENT);
- display_list->RenderTo(canvas);
+ auto canvas = DlSkCanvasAdapter(sk_surface->getCanvas());
+ canvas.Clear(DlColor::kTransparent());
+ canvas.DrawDisplayList(display_list);
result = std::make_unique<SnapshotDelegate::GpuImageResult>(
texture, sk_ref_sp(context), nullptr, "");
diff --git a/shell/common/snapshot_controller_skia.cc b/shell/common/snapshot_controller_skia.cc
index 27b6700..0e2fdea 100644
--- a/shell/common/snapshot_controller_skia.cc
+++ b/shell/common/snapshot_controller_skia.cc
@@ -126,7 +126,7 @@
sk_sp<DisplayList> display_list,
SkISize size) {
return DoMakeRasterSnapshot(size, [display_list](SkCanvas* canvas) {
- display_list->RenderTo(canvas);
+ DlSkCanvasAdapter(canvas).DrawDisplayList(display_list);
});
}
diff --git a/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm b/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm
index 6e1cea4..4730fff 100644
--- a/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm
+++ b/shell/platform/darwin/graphics/FlutterDarwinExternalTextureMetal.mm
@@ -61,12 +61,12 @@
}
if (_externalImage) {
- context.canvas->DrawImageRect(_externalImage, // image
- SkRect::Make(_externalImage->bounds()), // source rect
- bounds, // destination rect
- sampling, // sampling
- context.paint, // paint
- false // enforce edges
+ context.canvas->DrawImageRect(_externalImage, // image
+ SkRect::Make(_externalImage->bounds()), // source rect
+ bounds, // destination rect
+ sampling, // sampling
+ context.paint, // paint
+ flutter::DlCanvas::SrcRectConstraint::kStrict // enforce edges
);
}
}
diff --git a/testing/display_list_testing.cc b/testing/display_list_testing.cc
index 2caadcb..96a29cf 100644
--- a/testing/display_list_testing.cc
+++ b/testing/display_list_testing.cc
@@ -197,8 +197,15 @@
switch (op) {
case DlCanvas::ClipOp::kDifference: return os << "ClipOp::kDifference";
case DlCanvas::ClipOp::kIntersect: return os << "ClipOp::kIntersect";
+ }
+}
- default: return os << "ClipOp::????";
+std::ostream& operator<<(std::ostream& os, const DlCanvas::SrcRectConstraint& constraint) {
+ switch (constraint) {
+ case DlCanvas::SrcRectConstraint::kFast:
+ return os << "SrcRectConstraint::kFast";
+ case DlCanvas::SrcRectConstraint::kStrict:
+ return os << "SrcRectConstraint::kStrict";
}
}
@@ -207,8 +214,6 @@
case DlStrokeCap::kButt: return os << "Cap::kButt";
case DlStrokeCap::kRound: return os << "Cap::kRound";
case DlStrokeCap::kSquare: return os << "Cap::kSquare";
-
- default: return os << "Cap::????";
}
}
@@ -217,8 +222,6 @@
case DlStrokeJoin::kMiter: return os << "Join::kMiter";
case DlStrokeJoin::kRound: return os << "Join::kRound";
case DlStrokeJoin::kBevel: return os << "Join::kBevel";
-
- default: return os << "Join::????";
}
}
@@ -227,8 +230,6 @@
case DlDrawStyle::kFill: return os << "Style::kFill";
case DlDrawStyle::kStroke: return os << "Style::kStroke";
case DlDrawStyle::kStrokeAndFill: return os << "Style::kStrokeAnFill";
-
- default: return os << "Style::????";
}
}
@@ -238,19 +239,14 @@
case kSolid_SkBlurStyle: return os << "BlurStyle::kSolid";
case kOuter_SkBlurStyle: return os << "BlurStyle::kOuter";
case kInner_SkBlurStyle: return os << "BlurStyle::kInner";
-
- default: return os << "Style::????";
}
}
-static std::ostream& operator<<(std::ostream& os,
- const DlCanvas::PointMode& mode) {
+std::ostream& operator<<(std::ostream& os, const DlCanvas::PointMode& mode) {
switch (mode) {
case DlCanvas::PointMode::kPoints: return os << "PointMode::kPoints";
case DlCanvas::PointMode::kLines: return os << "PointMode::kLines";
case DlCanvas::PointMode::kPolygon: return os << "PointMode::kPolygon";
-
- default: return os << "PointMode::????";
}
}
@@ -448,7 +444,7 @@
break;
}
default:
- os_ << "DlUnknownColorSource(" << source->skia_object().get() << ")";
+ os_ << "?DlUnknownColorSource?()";
break;
}
os_ << ");" << std::endl;
@@ -490,7 +486,7 @@
break;
}
default:
- os_ << "DlUnknownColorFilter(" << filter.skia_object().get() << ")";
+ os_ << "?DlUnknownColorFilter?()";
break;
}
}
@@ -530,7 +526,7 @@
break;
}
default:
- os_ << "DlUnknownMaskFilter(" << filter->skia_object().get() << ")";
+ os_ << "?DlUnknownMaskFilter?()";
break;
}
os_ << ");" << std::endl;
@@ -563,7 +559,7 @@
os_ << "DlMatrixImageFilter(" << matrix->matrix() << ", " << matrix->sampling() << ")";
break;
}
- case DlImageFilterType::kComposeFilter: {
+ case DlImageFilterType::kCompose: {
const DlComposeImageFilter* compose = filter.asCompose();
FML_DCHECK(compose);
os_ << "DlComposeImageFilter(" << std::endl;
@@ -590,7 +586,7 @@
os_ << ")";
break;
}
- case DlImageFilterType::kLocalMatrixFilter: {
+ case DlImageFilterType::kLocalMatrix: {
const DlLocalMatrixImageFilter* local_matrix = filter.asLocalMatrix();
FML_DCHECK(local_matrix);
os_ << "DlLocalMatrixImageFilter(" << local_matrix->matrix();
@@ -810,7 +806,7 @@
const SkRect& dst,
DlImageSampling sampling,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) {
+ SrcRectConstraint constraint) {
startl() << "drawImageRect(" << image.get() << "," << std::endl;
startl() << " src: " << src << "," << std::endl;
startl() << " dst: " << dst << "," << std::endl;
@@ -849,8 +845,12 @@
<< ");" << std::endl;
}
void DisplayListStreamDispatcher::drawDisplayList(
- const sk_sp<DisplayList> display_list) {
- startl() << "drawDisplayList(ID: " << display_list->unique_id() << ", bounds: " << display_list->bounds() << ");" << std::endl;
+ const sk_sp<DisplayList> display_list, SkScalar opacity) {
+ startl() << "drawDisplayList("
+ << "ID: " << display_list->unique_id() << ", "
+ << "bounds: " << display_list->bounds() << ", "
+ << "opacity: " << opacity
+ << ");" << std::endl;
}
void DisplayListStreamDispatcher::drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
diff --git a/testing/display_list_testing.h b/testing/display_list_testing.h
index 26d5af0..60afff2 100644
--- a/testing/display_list_testing.h
+++ b/testing/display_list_testing.h
@@ -8,8 +8,8 @@
#include <ostream>
#include "flutter/display_list/display_list.h"
-#include "flutter/display_list/display_list_dispatcher.h"
#include "flutter/display_list/display_list_path_effect.h"
+#include "flutter/display_list/dl_op_receiver.h"
namespace flutter {
namespace testing {
@@ -36,6 +36,10 @@
extern std::ostream& operator<<(std::ostream& os, const DlPaint& paint);
extern std::ostream& operator<<(std::ostream& os, const DlBlendMode& mode);
extern std::ostream& operator<<(std::ostream& os, const DlCanvas::ClipOp& op);
+extern std::ostream& operator<<(std::ostream& os,
+ const DlCanvas::PointMode& op);
+extern std::ostream& operator<<(std::ostream& os,
+ const DlCanvas::SrcRectConstraint& op);
extern std::ostream& operator<<(std::ostream& os, const DlStrokeCap& cap);
extern std::ostream& operator<<(std::ostream& os, const DlStrokeJoin& join);
extern std::ostream& operator<<(std::ostream& os, const DlDrawStyle& style);
@@ -47,7 +51,7 @@
extern std::ostream& operator<<(std::ostream& os, const DlTileMode& mode);
extern std::ostream& operator<<(std::ostream& os, const DlImage* image);
-class DisplayListStreamDispatcher final : public Dispatcher {
+class DisplayListStreamDispatcher final : public DlOpReceiver {
public:
DisplayListStreamDispatcher(std::ostream& os,
int cur_indent = 2,
@@ -121,7 +125,7 @@
const SkRect& dst,
DlImageSampling sampling,
bool render_with_attributes,
- SkCanvas::SrcRectConstraint constraint) override;
+ SrcRectConstraint constraint) override;
void drawImageNine(const sk_sp<DlImage> image,
const SkIRect& center,
const SkRect& dst,
@@ -136,7 +140,8 @@
DlImageSampling sampling,
const SkRect* cull_rect,
bool render_with_attributes) override;
- void drawDisplayList(const sk_sp<DisplayList> display_list) override;
+ void drawDisplayList(const sk_sp<DisplayList> display_list,
+ SkScalar opacity) override;
void drawTextBlob(const sk_sp<SkTextBlob> blob,
SkScalar x,
SkScalar y) override;
diff --git a/testing/mock_canvas.cc b/testing/mock_canvas.cc
index 837d336..e72a27c 100644
--- a/testing/mock_canvas.cc
+++ b/testing/mock_canvas.cc
@@ -285,7 +285,7 @@
const SkRect&,
const DlImageSampling,
const DlPaint*,
- bool enforce_src_edges) {
+ SrcRectConstraint constraint) {
FML_DCHECK(false);
}
diff --git a/testing/mock_canvas.h b/testing/mock_canvas.h
index 5473432..022793d 100644
--- a/testing/mock_canvas.h
+++ b/testing/mock_canvas.h
@@ -247,12 +247,13 @@
const SkPoint point,
DlImageSampling sampling,
const DlPaint* paint = nullptr) override;
- void DrawImageRect(const sk_sp<DlImage>& image,
- const SkRect& src,
- const SkRect& dst,
- DlImageSampling sampling,
- const DlPaint* paint = nullptr,
- bool enforce_src_edges = false) override;
+ void DrawImageRect(
+ const sk_sp<DlImage>& image,
+ const SkRect& src,
+ const SkRect& dst,
+ DlImageSampling sampling,
+ const DlPaint* paint = nullptr,
+ SrcRectConstraint constraint = SrcRectConstraint::kFast) override;
void DrawImageNine(const sk_sp<DlImage>& image,
const SkIRect& center,
const SkRect& dst,