Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RoundSuperellipse to drawing OP #57205

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -43199,6 +43199,8 @@ ORIGIN: ../../../flutter/impeller/geometry/rect.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/rect.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/round_rect.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/round_rect.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/round_superellipse.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/round_superellipse.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/saturated_math.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/scalar.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/impeller/geometry/separated_vector.cc + ../../../flutter/LICENSE
Expand Down Expand Up @@ -46134,6 +46136,8 @@ FILE: ../../../flutter/impeller/geometry/rect.cc
FILE: ../../../flutter/impeller/geometry/rect.h
FILE: ../../../flutter/impeller/geometry/round_rect.cc
FILE: ../../../flutter/impeller/geometry/round_rect.h
FILE: ../../../flutter/impeller/geometry/round_superellipse.cc
FILE: ../../../flutter/impeller/geometry/round_superellipse.h
FILE: ../../../flutter/impeller/geometry/saturated_math.h
FILE: ../../../flutter/impeller/geometry/scalar.h
FILE: ../../../flutter/impeller/geometry/separated_vector.cc
Expand Down
5 changes: 5 additions & 0 deletions display_list/benchmarking/dl_complexity_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,11 @@ void DisplayListGLComplexityCalculator::GLHelper::drawDiffRoundRect(
AccumulateComplexity(complexity);
}

void DisplayListGLComplexityCalculator::GLHelper::drawRoundSuperellipse(
const DlRoundSuperellipse& rse) {
// TODO(dkwingsmt): implement
}

void DisplayListGLComplexityCalculator::GLHelper::drawPath(const DlPath& path) {
if (IsComplex()) {
return;
Expand Down
1 change: 1 addition & 0 deletions display_list/benchmarking/dl_complexity_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class DisplayListGLComplexityCalculator
void drawRoundRect(const DlRoundRect& rrect) override;
void drawDiffRoundRect(const DlRoundRect& outer,
const DlRoundRect& inner) override;
void drawRoundSuperellipse(const DlRoundSuperellipse& rse) override;
void drawPath(const DlPath& path) override;
void drawArc(const DlRect& oval_bounds,
DlScalar start_degrees,
Expand Down
5 changes: 5 additions & 0 deletions display_list/benchmarking/dl_complexity_metal.cc
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,11 @@ void DisplayListMetalComplexityCalculator::MetalHelper::drawDiffRoundRect(
AccumulateComplexity(complexity);
}

void DisplayListMetalComplexityCalculator::MetalHelper::drawRoundSuperellipse(
const DlRoundSuperellipse& rse) {
// TODO(dkwingsmt): implement
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just FYI you do not need to implement this, as the complexity calculator is irrelevant for Impeller and never used.

Copy link
Contributor Author

@dkwingsmt dkwingsmt Dec 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see. Does it mean I should leave this unimplemented since round superellipse is not supported in Skia?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would vote for leaving it unimplemented.

}

void DisplayListMetalComplexityCalculator::MetalHelper::drawPath(
const DlPath& path) {
if (IsComplex()) {
Expand Down
1 change: 1 addition & 0 deletions display_list/benchmarking/dl_complexity_metal.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class DisplayListMetalComplexityCalculator
void drawRoundRect(const DlRoundRect& rrect) override;
void drawDiffRoundRect(const DlRoundRect& outer,
const DlRoundRect& inner) override;
void drawRoundSuperellipse(const DlRoundSuperellipse& rse) override;
void drawPath(const DlPath& path) override;
void drawArc(const DlRect& oval_bounds,
DlScalar start_degrees,
Expand Down
1 change: 1 addition & 0 deletions display_list/display_list.cc
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ DisplayListOpCategory DisplayList::GetOpCategory(DisplayListOpType type) {
case DisplayListOpType::kDrawCircle:
case DisplayListOpType::kDrawRoundRect:
case DisplayListOpType::kDrawDiffRoundRect:
case DisplayListOpType::kDrawRoundSuperellipse:
case DisplayListOpType::kDrawArc:
case DisplayListOpType::kDrawPath:
case DisplayListOpType::kDrawPoints:
Expand Down
1 change: 1 addition & 0 deletions display_list/display_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ namespace flutter {
V(DrawCircle) \
V(DrawRoundRect) \
V(DrawDiffRoundRect) \
V(DrawRoundSuperellipse) \
V(DrawArc) \
V(DrawPath) \
\
Expand Down
21 changes: 21 additions & 0 deletions display_list/dl_builder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1225,6 +1225,27 @@ void DisplayListBuilder::DrawDiffRoundRect(const DlRoundRect& outer,
SetAttributesFromPaint(paint, DisplayListOpFlags::kDrawDRRectFlags);
drawDiffRoundRect(outer, inner);
}
void DisplayListBuilder::DrawRoundSuperellipse(const DlRoundSuperellipse& rse,
const DlPaint& paint) {
SetAttributesFromPaint(paint, DisplayListOpFlags::kDrawRSuperellipseFlags);
drawRoundSuperellipse(rse);
}
void DisplayListBuilder::drawRoundSuperellipse(const DlRoundSuperellipse& rse) {
if (rse.IsRect()) {
drawRect(rse.GetBounds());
} else if (rse.IsCircle()) {
drawOval(rse.GetBounds());
} else {
DisplayListAttributeFlags flags = kDrawRSuperellipseFlags;
OpResult result = PaintResult(current_, flags);
if (result != OpResult::kNoEffect &&
AccumulateOpBounds(ToSkRect(rse.GetBounds()), flags)) {
Push<DrawRoundSuperellipseOp>(0, rse);
CheckLayerOpacityCompatibility();
UpdateLayerResult(result);
}
}
}
void DisplayListBuilder::drawPath(const DlPath& path) {
DisplayListAttributeFlags flags = kDrawPathFlags;
OpResult result = PaintResult(current_, flags);
Expand Down
5 changes: 5 additions & 0 deletions display_list/dl_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,9 @@ class DisplayListBuilder final : public virtual DlCanvas,
const DlRoundRect& inner,
const DlPaint& paint) override;
// |DlCanvas|
void DrawRoundSuperellipse(const DlRoundSuperellipse& rse,
const DlPaint& paint) override;
// |DlCanvas|
void DrawPath(const DlPath& path, const DlPaint& paint) override;
// |DlCanvas|
void DrawArc(const DlRect& bounds,
Expand Down Expand Up @@ -438,6 +441,8 @@ class DisplayListBuilder final : public virtual DlCanvas,
void drawDiffRoundRect(const DlRoundRect& outer,
const DlRoundRect& inner) override;
// |DlOpReceiver|
void drawRoundSuperellipse(const DlRoundSuperellipse& rse) override;
// |DlOpReceiver|
void drawPath(const DlPath& path) override;
// |DlOpReceiver|
void drawArc(const DlRect& bounds,
Expand Down
2 changes: 2 additions & 0 deletions display_list/dl_canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ class DlCanvas {
virtual void DrawDiffRoundRect(const DlRoundRect& outer,
const DlRoundRect& inner,
const DlPaint& paint) = 0;
virtual void DrawRoundSuperellipse(const DlRoundSuperellipse& rse,
const DlPaint& paint) = 0;
virtual void DrawPath(const DlPath& path, const DlPaint& paint) = 0;
virtual void DrawArc(const DlRect& bounds,
DlScalar start,
Expand Down
4 changes: 4 additions & 0 deletions display_list/dl_op_flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,10 @@ class DisplayListOpFlags : DisplayListFlags {
kBasePaintFlags | //
kBaseStrokeOrFillFlags //
};
static constexpr DisplayListAttributeFlags kDrawRSuperellipseFlags{
kBasePaintFlags | //
kBaseStrokeOrFillFlags //
};
static constexpr DisplayListAttributeFlags kDrawPathFlags{
kBasePaintFlags | //
kBaseStrokeOrFillFlags | //
Expand Down
1 change: 1 addition & 0 deletions display_list/dl_op_receiver.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ class DlOpReceiver {
virtual void drawRoundRect(const DlRoundRect& rrect) = 0;
virtual void drawDiffRoundRect(const DlRoundRect& outer,
const DlRoundRect& inner) = 0;
virtual void drawRoundSuperellipse(const DlRoundSuperellipse& rse) = 0;
virtual void drawPath(const DlPath& path) = 0;
virtual void drawArc(const DlRect& oval_bounds,
DlScalar start_degrees,
Expand Down
2 changes: 2 additions & 0 deletions display_list/dl_op_records.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,7 @@ struct DrawColorOp final : DrawOpBase {
// SkOval is same as DlRect
// DlRoundRect is 48 more bytes, using 52 bytes which rounds up to 56 bytes
// total (4 bytes unused)
// TODO(dkwingsmt): Evaluate DlRoundSuperellipse here
#define DEFINE_DRAW_1ARG_OP(op_name, arg_type, arg_name) \
struct Draw##op_name##Op final : DrawOpBase { \
static constexpr auto kType = DisplayListOpType::kDraw##op_name; \
Expand All @@ -595,6 +596,7 @@ struct DrawColorOp final : DrawOpBase {
DEFINE_DRAW_1ARG_OP(Rect, DlRect, rect)
DEFINE_DRAW_1ARG_OP(Oval, DlRect, oval)
DEFINE_DRAW_1ARG_OP(RoundRect, DlRoundRect, rrect)
DEFINE_DRAW_1ARG_OP(RoundSuperellipse, DlRoundSuperellipse, rse)
#undef DEFINE_DRAW_1ARG_OP

// 4 byte header + 16 byte payload uses 20 bytes but is rounded
Expand Down
2 changes: 2 additions & 0 deletions display_list/geometry/dl_geometry_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "flutter/impeller/geometry/matrix.h"
#include "flutter/impeller/geometry/rect.h"
#include "flutter/impeller/geometry/round_rect.h"
#include "flutter/impeller/geometry/round_superellipse.h"
#include "flutter/impeller/geometry/scalar.h"

#include "flutter/third_party/skia/include/core/SkM44.h"
Expand All @@ -30,6 +31,7 @@ using DlISize = impeller::ISize32;
using DlRect = impeller::Rect;
using DlIRect = impeller::IRect32;
using DlRoundRect = impeller::RoundRect;
using DlRoundSuperellipse = impeller::RoundSuperellipse;
using DlMatrix = impeller::Matrix;
using DlQuad = impeller::Quad;

Expand Down
9 changes: 9 additions & 0 deletions display_list/skia/dl_sk_canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,15 @@ void DlSkCanvasAdapter::DrawDiffRoundRect(const DlRoundRect& outer,
delegate_->drawDRRect(ToSkRRect(outer), ToSkRRect(inner), ToSk(paint));
}

void DlSkCanvasAdapter::DrawRoundSuperellipse(const DlRoundSuperellipse& rse,
const DlPaint& paint) {
// Skia doesn't support round superellipse, thus fallback to round rectangle.
// TODO(dkwingsmt): Figure out the corner radius mapping.
delegate_->drawRRect(ToSkRRect(DlRoundRect::MakeRectRadius(
rse.GetBounds(), rse.GetCornerRadius())),
ToSk(paint));
}

void DlSkCanvasAdapter::DrawPath(const DlPath& path, const DlPaint& paint) {
path.WillRenderSkPath();
delegate_->drawPath(path.GetSkPath(), ToSk(paint));
Expand Down
2 changes: 2 additions & 0 deletions display_list/skia/dl_sk_canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ class DlSkCanvasAdapter final : public virtual DlCanvas {
void DrawDiffRoundRect(const DlRoundRect& outer,
const DlRoundRect& inner,
const DlPaint& paint) override;
void DrawRoundSuperellipse(const DlRoundSuperellipse& rse,
const DlPaint& paint) override;
void DrawPath(const DlPath& path, const DlPaint& paint) override;
void DrawArc(const DlRect& bounds,
DlScalar start,
Expand Down
8 changes: 8 additions & 0 deletions display_list/skia/dl_sk_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,14 @@ void DlSkCanvasDispatcher::drawDiffRoundRect(const DlRoundRect& outer,
const DlRoundRect& inner) {
canvas_->drawDRRect(ToSkRRect(outer), ToSkRRect(inner), paint());
}
void DlSkCanvasDispatcher::drawRoundSuperellipse(
const DlRoundSuperellipse& rse) {
// Skia doesn't support round superellipse, thus fallback to round rectangle.
// TODO(dkwingsmt): Figure out the corner radius mapping.
canvas_->drawRRect(ToSkRRect(DlRoundRect::MakeRectRadius(
rse.GetBounds(), rse.GetCornerRadius())),
paint());
}
void DlSkCanvasDispatcher::drawPath(const DlPath& path) {
path.WillRenderSkPath();
canvas_->drawPath(path.GetSkPath(), paint());
Expand Down
1 change: 1 addition & 0 deletions display_list/skia/dl_sk_dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ class DlSkCanvasDispatcher : public virtual DlOpReceiver,
void drawRoundRect(const DlRoundRect& rrect) override;
void drawDiffRoundRect(const DlRoundRect& outer,
const DlRoundRect& inner) override;
void drawRoundSuperellipse(const DlRoundSuperellipse& rse) override;
void drawPath(const DlPath& path) override;
void drawArc(const DlRect& bounds,
DlScalar start,
Expand Down
1 change: 1 addition & 0 deletions display_list/utils/dl_receiver_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class IgnoreDrawDispatchHelper : public virtual DlOpReceiver {
void drawRoundRect(const DlRoundRect& rrect) override {}
void drawDiffRoundRect(const DlRoundRect& outer,
const DlRoundRect& inner) override {}
void drawRoundSuperellipse(const DlRoundSuperellipse& rse) override {}
void drawPath(const DlPath& path) override {}
void drawArc(const DlRect& oval_bounds,
DlScalar start_degrees,
Expand Down
24 changes: 24 additions & 0 deletions impeller/display_list/canvas.cc
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,30 @@ void Canvas::DrawRoundRect(const RoundRect& round_rect, const Paint& paint) {
DrawPath(path, paint);
}

void Canvas::DrawRoundSuperellipse(const RoundSuperellipse& rse,
const Paint& paint) {
auto& rect = rse.GetBounds();
Scalar corner_radius = rse.GetCornerRadius();

if (paint.style == Paint::Style::kStroke) {
// TODO(dkwingsmt): Add path
// DrawPath(PathBuilder{}.AddRect(rect).TakePath(), paint);
return;
}

// TODO(dkwingsmt): Add blurred rrect approximation
// if (AttemptDrawBlurredRRect(rect, {}, paint)) {
// return;
// }

Entity entity;
entity.SetTransform(GetCurrentTransform());
entity.SetBlendMode(paint.blend_mode);

RoundSuperellipseGeometry geom(rect, corner_radius);
AddRenderEntityWithFiltersToCurrentPass(entity, &geom, paint);
}

void Canvas::DrawCircle(const Point& center,
Scalar radius,
const Paint& paint) {
Expand Down
2 changes: 2 additions & 0 deletions impeller/display_list/canvas.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ class Canvas {

void DrawRoundRect(const RoundRect& rect, const Paint& paint);

void DrawRoundSuperellipse(const RoundSuperellipse& rse, const Paint& paint);

void DrawCircle(const Point& center, Scalar radius, const Paint& paint);

void DrawPoints(const Point points[],
Expand Down
7 changes: 7 additions & 0 deletions impeller/display_list/dl_dispatcher.cc
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,13 @@ void DlDispatcherBase::drawDiffRoundRect(const DlRoundRect& outer,
GetCanvas().DrawPath(builder.TakePath(FillType::kOdd), paint_);
}

// |flutter::DlOpReceiver|
void DlDispatcherBase::drawRoundSuperellipse(const DlRoundSuperellipse& rse) {
AUTO_DEPTH_WATCHER(1u);

GetCanvas().DrawRoundSuperellipse(rse, paint_);
}

// |flutter::DlOpReceiver|
void DlDispatcherBase::drawPath(const DlPath& path) {
AUTO_DEPTH_WATCHER(1u);
Expand Down
4 changes: 4 additions & 0 deletions impeller/display_list/dl_dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ using DlPoint = flutter::DlPoint;
using DlRect = flutter::DlRect;
using DlIRect = flutter::DlIRect;
using DlRoundRect = flutter::DlRoundRect;
using DlRoundSuperellipse = flutter::DlRoundSuperellipse;
using DlPath = flutter::DlPath;

class DlDispatcherBase : public flutter::DlOpReceiver {
Expand Down Expand Up @@ -168,6 +169,9 @@ class DlDispatcherBase : public flutter::DlOpReceiver {
void drawDiffRoundRect(const DlRoundRect& outer,
const DlRoundRect& inner) override;

// |flutter::DlOpReceiver|
void drawRoundSuperellipse(const DlRoundSuperellipse& rse) override;

// |flutter::DlOpReceiver|
void drawPath(const DlPath& path) override;

Expand Down
7 changes: 7 additions & 0 deletions impeller/entity/geometry/geometry.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "impeller/entity/geometry/line_geometry.h"
#include "impeller/entity/geometry/rect_geometry.h"
#include "impeller/entity/geometry/round_rect_geometry.h"
#include "impeller/entity/geometry/round_superellipse_geometry.h"
#include "impeller/entity/geometry/stroke_path_geometry.h"
#include "impeller/geometry/rect.h"

Expand Down Expand Up @@ -110,6 +111,12 @@ std::unique_ptr<Geometry> Geometry::MakeRoundRect(const Rect& rect,
return std::make_unique<RoundRectGeometry>(rect, radii);
}

std::unique_ptr<Geometry> Geometry::MakeRoundSuperellipse(
const Rect& rect,
Scalar corner_radius) {
return std::make_unique<RoundSuperellipseGeometry>(rect, corner_radius);
}

bool Geometry::CoversArea(const Matrix& transform, const Rect& rect) const {
return false;
}
Expand Down
3 changes: 3 additions & 0 deletions impeller/entity/geometry/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,9 @@ class Geometry {
static std::unique_ptr<Geometry> MakeRoundRect(const Rect& rect,
const Size& radii);

static std::unique_ptr<Geometry> MakeRoundSuperellipse(const Rect& rect,
Scalar corner_radius);

virtual GeometryResult GetPositionBuffer(const ContentContext& renderer,
const Entity& entity,
RenderPass& pass) const = 0;
Expand Down
2 changes: 2 additions & 0 deletions impeller/geometry/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ impeller_component("geometry") {
"rect.h",
"round_rect.cc",
"round_rect.h",
"round_superellipse.cc",
"round_superellipse.h",
"saturated_math.h",
"scalar.h",
"separated_vector.cc",
Expand Down
22 changes: 22 additions & 0 deletions impeller/geometry/round_superellipse.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// 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/impeller/geometry/round_superellipse.h"

#include <cmath>

namespace impeller {

RoundSuperellipse RoundSuperellipse::MakeRectRadius(const Rect& rect,
Scalar corner_radius) {
if (rect.IsEmpty() || !rect.IsFinite() || //
!std::isfinite(corner_radius)) {
// preserve the empty bounds as they might be strokable
return RoundSuperellipse(rect, 0);
}

return RoundSuperellipse(rect, corner_radius);
}

} // namespace impeller
Loading
Loading