From 10487e3c1c80ed3c847e4c2ef10296a88cc680a2 Mon Sep 17 00:00:00 2001 From: Chinmay Garde Date: Wed, 8 Dec 2021 14:22:57 -0800 Subject: [PATCH] Stub out a display list dispatcher. --- impeller/BUILD.gn | 2 + impeller/compiler/BUILD.gn | 1 - impeller/display_list/BUILD.gn | 30 ++ .../display_list/display_list_impeller.cc | 411 ++++++++++++++++++ impeller/display_list/display_list_impeller.h | 235 ++++++++++ .../display_list/display_list_unittests.cc | 13 + 6 files changed, 691 insertions(+), 1 deletion(-) create mode 100644 impeller/display_list/BUILD.gn create mode 100644 impeller/display_list/display_list_impeller.cc create mode 100644 impeller/display_list/display_list_impeller.h create mode 100644 impeller/display_list/display_list_unittests.cc diff --git a/impeller/BUILD.gn b/impeller/BUILD.gn index e9a840fb1b102..e7db23c224dc2 100644 --- a/impeller/BUILD.gn +++ b/impeller/BUILD.gn @@ -11,6 +11,7 @@ group("impeller") { "aiks", "base", "compiler", + "display_list", "entity", "geometry", "image", @@ -25,6 +26,7 @@ executable("impeller_unittests") { "aiks:aiks_unittests", "base:base_unittests", "compiler:compiler_unittests", + "display_list:display_list_unittests", "entity:entity_unittests", "fixtures", "geometry:geometry_unittests", diff --git a/impeller/compiler/BUILD.gn b/impeller/compiler/BUILD.gn index dcef761963d5e..363377b10d5b7 100644 --- a/impeller/compiler/BUILD.gn +++ b/impeller/compiler/BUILD.gn @@ -25,7 +25,6 @@ impeller_component("compiler_lib") { "//flutter/fml", "//flutter/runtime:libdart", "//third_party/inja", - "//third_party/rapidjson", "//third_party/shaderc_flutter", "//third_party/spirv_cross_flutter", ] diff --git a/impeller/display_list/BUILD.gn b/impeller/display_list/BUILD.gn new file mode 100644 index 0000000000000..6a697baab4968 --- /dev/null +++ b/impeller/display_list/BUILD.gn @@ -0,0 +1,30 @@ +# 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. + +import("//flutter/impeller/tools/impeller.gni") + +impeller_component("display_list") { + sources = [ + "display_list_impeller.cc", + "display_list_impeller.h", + ] + + deps = [ + "../aiks", + "//flutter/flow", + "//flutter/fml", + "//third_party/skia", + ] +} + +impeller_component("display_list_unittests") { + testonly = true + + sources = [ "display_list_unittests.cc" ] + + deps = [ + ":display_list", + "../playground", + ] +} diff --git a/impeller/display_list/display_list_impeller.cc b/impeller/display_list/display_list_impeller.cc new file mode 100644 index 0000000000000..68213eebba3f8 --- /dev/null +++ b/impeller/display_list/display_list_impeller.cc @@ -0,0 +1,411 @@ +// 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 "impeller/display_list/display_list_impeller.h" + +#include "impeller/geometry/path_builder.h" + +namespace impeller { + +#define UNIMPLEMENTED \ + FML_LOG(ERROR) << "Unimplemented detail in " << __FUNCTION__; + +DisplayListImpeller::DisplayListImpeller() = default; + +DisplayListImpeller::~DisplayListImpeller() = default; + +// |flutter::Dispatcher| +void DisplayListImpeller::setAntiAlias(bool aa) { + // Nothing to do because AA is implicit. +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setDither(bool dither) {} + +static Paint::Style ToStyle(SkPaint::Style style) { + switch (style) { + case SkPaint::kFill_Style: + return Paint::Style::kFill; + case SkPaint::kStroke_Style: + return Paint::Style::kStroke; + case SkPaint::kStrokeAndFill_Style: + UNIMPLEMENTED; + break; + } + return Paint::Style::kFill; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setStyle(SkPaint::Style style) { + paint_.style = ToStyle(style); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setColor(SkColor color) { + paint_.color = { + SkColorGetR(color) / 255.0f, // red + SkColorGetG(color) / 255.0f, // green + SkColorGetB(color) / 255.0f, // blue + SkColorGetA(color) / 255.0f // alpha + }; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setStrokeWidth(SkScalar width) { + paint_.stroke_width = width; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setStrokeMiter(SkScalar limit) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setStrokeCap(SkPaint::Cap cap) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setStrokeJoin(SkPaint::Join join) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setShader(sk_sp shader) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setColorFilter(sk_sp filter) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setInvertColors(bool invert) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setBlendMode(SkBlendMode mode) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setBlender(sk_sp blender) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setPathEffect(sk_sp effect) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setMaskFilter(sk_sp filter) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setMaskBlurFilter(SkBlurStyle style, SkScalar sigma) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::setImageFilter(sk_sp filter) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::save() { + canvas_.Save(); +} + +static std::optional ToRect(const SkRect* rect) { + if (rect == nullptr) { + return std::nullopt; + } + return Rect::MakeLTRB(rect->fLeft, rect->fTop, rect->fRight, rect->fBottom); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::saveLayer(const SkRect* bounds, + bool restore_with_paint) { + canvas_.SaveLayer(restore_with_paint ? paint_ : Paint{}, ToRect(bounds)); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::restore() { + canvas_.Restore(); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::translate(SkScalar tx, SkScalar ty) { + canvas_.Translate({tx, ty, 0.0}); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::scale(SkScalar sx, SkScalar sy) { + canvas_.Scale({sx, sy, 1.0}); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::rotate(SkScalar degrees) { + canvas_.Rotate(Degrees{degrees}); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::skew(SkScalar sx, SkScalar sy) { + canvas_.Skew(sx, sy); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::transform2DAffine(SkScalar mxx, + SkScalar mxy, + SkScalar mxt, + SkScalar myx, + SkScalar myy, + SkScalar myt) { + // clang-format off + transformFullPerspective( + mxx, mxy, 0, mxt, + myx, myy, 0, myt, + 0 , 0, 1, 0, + 0 , 0, 0, 1 + ); + // clang-format on +} + +// |flutter::Dispatcher| +void DisplayListImpeller::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) { + // The order of arguments is row-major but Impeller matrices are column-major. + // clang-format off + auto xformation = Matrix{ + mxx, myx, mzx, mwx, + mxy, myy, mzy, mwy, + mxz, myz, mzz, mwz, + mxt, myt, mzt, mwt + }; + // clang-format on + canvas_.Transform(xformation); +} + +static Rect ToRect(const SkRect& rect) { + return Rect::MakeLTRB(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::clipRect(const SkRect& rect, + SkClipOp clip_op, + bool is_aa) { + auto path = PathBuilder{}.AddRect(ToRect(rect)).CreatePath(); + canvas_.ClipPath(std::move(path)); +} + +static Point ToPoint(const SkVector& vector) { + return {vector.fX, vector.fY}; +} + +static PathBuilder::RoundingRadii ToRoundingRadii(const SkRRect& rrect) { + using Corner = SkRRect::Corner; + PathBuilder::RoundingRadii radii; + radii.bottom_left = ToPoint(rrect.radii(Corner::kLowerLeft_Corner)); + radii.bottom_right = ToPoint(rrect.radii(Corner::kLowerRight_Corner)); + radii.top_left = ToPoint(rrect.radii(Corner::kUpperLeft_Corner)); + radii.top_right = ToPoint(rrect.radii(Corner::kUpperRight_Corner)); + return radii; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::clipRRect(const SkRRect& rrect, + SkClipOp clip_op, + bool is_aa) { + auto path = + PathBuilder{} + .AddRoundedRect(ToRect(rrect.getBounds()), ToRoundingRadii(rrect)) + .CreatePath(); + canvas_.ClipPath(std::move(path)); +} + +static Path ToPath(const SkPath& path) { + UNIMPLEMENTED; + return Path{}; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::clipPath(const SkPath& path, + SkClipOp clip_op, + bool is_aa) { + canvas_.ClipPath(ToPath(path)); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawColor(SkColor color, SkBlendMode mode) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawPaint() { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawLine(const SkPoint& p0, const SkPoint& p1) { + auto path = PathBuilder{}.AddLine(ToPoint(p0), ToPoint(p1)).CreatePath(); + canvas_.DrawPath(std::move(path), paint_); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawRect(const SkRect& rect) { + auto path = PathBuilder{}.AddRect(ToRect(rect)).CreatePath(); + canvas_.DrawPath(std::move(path), paint_); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawOval(const SkRect& bounds) { + auto path = PathBuilder{}.AddOval(ToRect(bounds)).CreatePath(); + canvas_.DrawPath(std::move(path), paint_); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawCircle(const SkPoint& center, SkScalar radius) { + auto path = PathBuilder{}.AddCircle(ToPoint(center), radius).CreatePath(); + canvas_.DrawPath(std::move(path), paint_); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawRRect(const SkRRect& rrect) { + auto path = + PathBuilder{} + .AddRoundedRect(ToRect(rrect.getBounds()), ToRoundingRadii(rrect)) + .CreatePath(); + canvas_.DrawPath(std::move(path), paint_); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawDRRect(const SkRRect& outer, + const SkRRect& inner) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawPath(const SkPath& path) { + canvas_.DrawPath(ToPath(path), paint_); +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawArc(const SkRect& oval_bounds, + SkScalar start_degrees, + SkScalar sweep_degrees, + bool use_center) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawPoints(SkCanvas::PointMode mode, + uint32_t count, + const SkPoint points[]) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawVertices(const sk_sp vertices, + SkBlendMode mode) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawImage(const sk_sp image, + const SkPoint point, + const SkSamplingOptions& sampling, + bool render_with_attributes) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawImageRect( + const sk_sp image, + const SkRect& src, + const SkRect& dst, + const SkSamplingOptions& sampling, + bool render_with_attributes, + SkCanvas::SrcRectConstraint constraint) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawImageNine(const sk_sp image, + const SkIRect& center, + const SkRect& dst, + SkFilterMode filter, + bool render_with_attributes) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawImageLattice(const sk_sp image, + const SkCanvas::Lattice& lattice, + const SkRect& dst, + SkFilterMode filter, + bool render_with_attributes) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawAtlas(const sk_sp atlas, + const SkRSXform xform[], + const SkRect tex[], + const SkColor colors[], + int count, + SkBlendMode mode, + const SkSamplingOptions& sampling, + const SkRect* cull_rect, + bool render_with_attributes) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawPicture(const sk_sp picture, + const SkMatrix* matrix, + bool render_with_attributes) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawDisplayList( + const sk_sp display_list) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawTextBlob(const sk_sp blob, + SkScalar x, + SkScalar y) { + UNIMPLEMENTED; +} + +// |flutter::Dispatcher| +void DisplayListImpeller::drawShadow(const SkPath& path, + const SkColor color, + const SkScalar elevation, + bool transparent_occluder, + SkScalar dpr) { + UNIMPLEMENTED; +} + +} // namespace impeller diff --git a/impeller/display_list/display_list_impeller.h b/impeller/display_list/display_list_impeller.h new file mode 100644 index 0000000000000..8bea69f4cf926 --- /dev/null +++ b/impeller/display_list/display_list_impeller.h @@ -0,0 +1,235 @@ +// 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. + +#pragma once + +#include "flutter/flow/display_list.h" +#include "flutter/fml/macros.h" +#include "impeller/aiks/canvas.h" +#include "impeller/aiks/paint.h" + +namespace impeller { + +class DisplayListImpeller final : public flutter::Dispatcher { + public: + DisplayListImpeller(); + + ~DisplayListImpeller(); + + // |flutter::Dispatcher| + void setAntiAlias(bool aa) override; + + // |flutter::Dispatcher| + void setDither(bool dither) override; + + // |flutter::Dispatcher| + void setStyle(SkPaint::Style style) override; + + // |flutter::Dispatcher| + void setColor(SkColor color) override; + + // |flutter::Dispatcher| + void setStrokeWidth(SkScalar width) override; + + // |flutter::Dispatcher| + void setStrokeMiter(SkScalar limit) override; + + // |flutter::Dispatcher| + void setStrokeCap(SkPaint::Cap cap) override; + + // |flutter::Dispatcher| + void setStrokeJoin(SkPaint::Join join) override; + + // |flutter::Dispatcher| + void setShader(sk_sp shader) override; + + // |flutter::Dispatcher| + void setColorFilter(sk_sp filter) override; + + // |flutter::Dispatcher| + void setInvertColors(bool invert) override; + + // |flutter::Dispatcher| + void setBlendMode(SkBlendMode mode) override; + + // |flutter::Dispatcher| + void setBlender(sk_sp blender) override; + + // |flutter::Dispatcher| + void setPathEffect(sk_sp effect) override; + + // |flutter::Dispatcher| + void setMaskFilter(sk_sp filter) override; + + // |flutter::Dispatcher| + void setMaskBlurFilter(SkBlurStyle style, SkScalar sigma) override; + + // |flutter::Dispatcher| + void setImageFilter(sk_sp filter) override; + + // |flutter::Dispatcher| + void save() override; + + // |flutter::Dispatcher| + void saveLayer(const SkRect* bounds, bool restore_with_paint) override; + + // |flutter::Dispatcher| + void restore() override; + + // |flutter::Dispatcher| + void translate(SkScalar tx, SkScalar ty) override; + + // |flutter::Dispatcher| + void scale(SkScalar sx, SkScalar sy) override; + + // |flutter::Dispatcher| + void rotate(SkScalar degrees) override; + + // |flutter::Dispatcher| + void skew(SkScalar sx, SkScalar sy) override; + + // |flutter::Dispatcher| + void transform2DAffine(SkScalar mxx, + SkScalar mxy, + SkScalar mxt, + SkScalar myx, + SkScalar myy, + SkScalar myt) override; + + // |flutter::Dispatcher| + 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; + + // |flutter::Dispatcher| + void clipRect(const SkRect& rect, SkClipOp clip_op, bool is_aa) override; + + // |flutter::Dispatcher| + void clipRRect(const SkRRect& rrect, SkClipOp clip_op, bool is_aa) override; + + // |flutter::Dispatcher| + void clipPath(const SkPath& path, SkClipOp clip_op, bool is_aa) override; + + // |flutter::Dispatcher| + void drawColor(SkColor color, SkBlendMode mode) override; + + // |flutter::Dispatcher| + void drawPaint() override; + + // |flutter::Dispatcher| + void drawLine(const SkPoint& p0, const SkPoint& p1) override; + + // |flutter::Dispatcher| + void drawRect(const SkRect& rect) override; + + // |flutter::Dispatcher| + void drawOval(const SkRect& bounds) override; + + // |flutter::Dispatcher| + void drawCircle(const SkPoint& center, SkScalar radius) override; + + // |flutter::Dispatcher| + void drawRRect(const SkRRect& rrect) override; + + // |flutter::Dispatcher| + void drawDRRect(const SkRRect& outer, const SkRRect& inner) override; + + // |flutter::Dispatcher| + void drawPath(const SkPath& path) override; + + // |flutter::Dispatcher| + void drawArc(const SkRect& oval_bounds, + SkScalar start_degrees, + SkScalar sweep_degrees, + bool use_center) override; + + // |flutter::Dispatcher| + void drawPoints(SkCanvas::PointMode mode, + uint32_t count, + const SkPoint points[]) override; + + // |flutter::Dispatcher| + void drawVertices(const sk_sp vertices, + SkBlendMode mode) override; + + // |flutter::Dispatcher| + void drawImage(const sk_sp image, + const SkPoint point, + const SkSamplingOptions& sampling, + bool render_with_attributes) override; + + // |flutter::Dispatcher| + void drawImageRect(const sk_sp image, + const SkRect& src, + const SkRect& dst, + const SkSamplingOptions& sampling, + bool render_with_attributes, + SkCanvas::SrcRectConstraint constraint) override; + + // |flutter::Dispatcher| + void drawImageNine(const sk_sp image, + const SkIRect& center, + const SkRect& dst, + SkFilterMode filter, + bool render_with_attributes) override; + + // |flutter::Dispatcher| + void drawImageLattice(const sk_sp image, + const SkCanvas::Lattice& lattice, + const SkRect& dst, + SkFilterMode filter, + bool render_with_attributes) override; + + // |flutter::Dispatcher| + void drawAtlas(const sk_sp atlas, + const SkRSXform xform[], + const SkRect tex[], + const SkColor colors[], + int count, + SkBlendMode mode, + const SkSamplingOptions& sampling, + const SkRect* cull_rect, + bool render_with_attributes) override; + + // |flutter::Dispatcher| + void drawPicture(const sk_sp picture, + const SkMatrix* matrix, + bool render_with_attributes) override; + + // |flutter::Dispatcher| + void drawDisplayList(const sk_sp display_list) override; + + // |flutter::Dispatcher| + void drawTextBlob(const sk_sp blob, + SkScalar x, + SkScalar y) override; + + // |flutter::Dispatcher| + void drawShadow(const SkPath& path, + const SkColor color, + const SkScalar elevation, + bool transparent_occluder, + SkScalar dpr) override; + + private: + Paint paint_; + Canvas canvas_; + + FML_DISALLOW_COPY_AND_ASSIGN(DisplayListImpeller); +}; + +} // namespace impeller diff --git a/impeller/display_list/display_list_unittests.cc b/impeller/display_list/display_list_unittests.cc new file mode 100644 index 0000000000000..4a1ad3f52f11c --- /dev/null +++ b/impeller/display_list/display_list_unittests.cc @@ -0,0 +1,13 @@ +// 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/testing/testing.h" + +namespace impeller { +namespace testing { + +TEST(DisplayListTest, CanCreateDisatcher) {} + +} // namespace testing +} // namespace impeller