Adding force-dark support to RippleDrawable
Add force-dark support to RippleDrawable by modifying the ink color.
Test: manual
Test: atest CanvasOp
Fixes: 186130682
Change-Id: I89eaaf3afa5ec53a74d2d08de8cff6484e55a912
diff --git a/libs/hwui/CanvasTransform.cpp b/libs/hwui/CanvasTransform.cpp
index 9d03ce5..d0d24a8 100644
--- a/libs/hwui/CanvasTransform.cpp
+++ b/libs/hwui/CanvasTransform.cpp
@@ -31,7 +31,7 @@
namespace android::uirenderer {
-static SkColor makeLight(SkColor color) {
+SkColor makeLight(SkColor color) {
Lab lab = sRGBToLab(color);
float invertedL = std::min(110 - lab.L, 100.0f);
if (invertedL > lab.L) {
@@ -42,7 +42,7 @@
}
}
-static SkColor makeDark(SkColor color) {
+SkColor makeDark(SkColor color) {
Lab lab = sRGBToLab(color);
float invertedL = std::min(110 - lab.L, 100.0f);
if (invertedL < lab.L) {
@@ -53,7 +53,7 @@
}
}
-static SkColor transformColor(ColorTransform transform, SkColor color) {
+SkColor transformColor(ColorTransform transform, SkColor color) {
switch (transform) {
case ColorTransform::Light:
return makeLight(color);
@@ -64,6 +64,17 @@
}
}
+SkColor transformColorInverse(ColorTransform transform, SkColor color) {
+ switch (transform) {
+ case ColorTransform::Dark:
+ return makeLight(color);
+ case ColorTransform::Light:
+ return makeDark(color);
+ default:
+ return color;
+ }
+}
+
static void applyColorTransform(ColorTransform transform, SkPaint& paint) {
if (transform == ColorTransform::None) return;
diff --git a/libs/hwui/CanvasTransform.h b/libs/hwui/CanvasTransform.h
index e723d64..c46a2d3 100644
--- a/libs/hwui/CanvasTransform.h
+++ b/libs/hwui/CanvasTransform.h
@@ -42,4 +42,7 @@
bool transformPaint(ColorTransform transform, SkPaint* paint, BitmapPalette palette);
+SkColor transformColor(ColorTransform transform, SkColor color);
+SkColor transformColorInverse(ColorTransform transform, SkColor color);
+
} // namespace android::uirenderer;
\ No newline at end of file
diff --git a/libs/hwui/DisplayListOps.in b/libs/hwui/DisplayListOps.in
index 1b1be43..fb3e21f 100644
--- a/libs/hwui/DisplayListOps.in
+++ b/libs/hwui/DisplayListOps.in
@@ -49,4 +49,5 @@
X(DrawAtlas)
X(DrawShadowRec)
X(DrawVectorDrawable)
+X(DrawRippleDrawable)
X(DrawWebView)
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 170f731..442ae0f 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -36,6 +36,7 @@
#include "SkTextBlob.h"
#include "SkVertices.h"
#include "VectorDrawable.h"
+#include "pipeline/skia/AnimatedDrawables.h"
#include "pipeline/skia/FunctorDrawable.h"
namespace android {
@@ -497,6 +498,18 @@
SkPaint paint;
BitmapPalette palette;
};
+
+struct DrawRippleDrawable final : Op {
+ static const auto kType = Type::DrawRippleDrawable;
+ DrawRippleDrawable(const skiapipeline::RippleDrawableParams& params) : mParams(params) {}
+
+ void draw(SkCanvas* canvas, const SkMatrix&) const {
+ skiapipeline::AnimatedRippleDrawable::draw(canvas, mParams);
+ }
+
+ skiapipeline::RippleDrawableParams mParams;
+};
+
struct DrawWebView final : Op {
static const auto kType = Type::DrawWebView;
DrawWebView(skiapipeline::FunctorDrawable* drawable) : drawable(sk_ref_sp(drawable)) {}
@@ -721,6 +734,10 @@
mHasText = true;
}
+void DisplayListData::drawRippleDrawable(const skiapipeline::RippleDrawableParams& params) {
+ this->push<DrawRippleDrawable>(0, params);
+}
+
void DisplayListData::drawPatch(const SkPoint points[12], const SkColor colors[4],
const SkPoint texs[4], SkBlendMode bmode, const SkPaint& paint) {
this->push<DrawPatch>(0, points, colors, texs, bmode, paint);
@@ -851,6 +868,16 @@
};
}
+template <>
+constexpr color_transform_fn colorTransformForOp<DrawRippleDrawable>() {
+ return [](const void* opRaw, ColorTransform transform) {
+ const DrawRippleDrawable* op = reinterpret_cast<const DrawRippleDrawable*>(opRaw);
+ // Ripple drawable needs to contrast against the background, so we need the inverse color.
+ SkColor color = transformColorInverse(transform, op->mParams.color);
+ const_cast<DrawRippleDrawable*>(op)->mParams.color = color;
+ };
+}
+
#define X(T) colorTransformForOp<T>(),
static const color_transform_fn color_transform_fns[] = {
#include "DisplayListOps.in"
@@ -985,6 +1012,10 @@
fDL->drawTextBlob(blob, x, y, paint);
}
+void RecordingCanvas::drawRippleDrawable(const skiapipeline::RippleDrawableParams& params) {
+ fDL->drawRippleDrawable(params);
+}
+
void RecordingCanvas::drawImage(const sk_sp<SkImage>& image, SkScalar x, SkScalar y,
const SkSamplingOptions& sampling, const SkPaint* paint,
BitmapPalette palette) {
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index a6a7b12..4fae6a1 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -29,6 +29,9 @@
#include "SkPath.h"
#include "SkRect.h"
+#include "pipeline/skia/AnimatedDrawables.h"
+
+#include <SkRuntimeEffect.h>
#include <vector>
namespace android {
@@ -125,6 +128,7 @@
void drawVertices(const SkVertices*, SkBlendMode, const SkPaint&);
void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
SkBlendMode, const SkSamplingOptions&, const SkRect*, const SkPaint*);
+ void drawRippleDrawable(const skiapipeline::RippleDrawableParams& params);
void drawShadowRec(const SkPath&, const SkDrawShadowRec&);
void drawVectorDrawable(VectorDrawableRoot* tree);
void drawWebView(skiapipeline::FunctorDrawable*);
@@ -184,6 +188,7 @@
void drawImage(const sk_sp<SkImage>&, SkScalar left, SkScalar top, const SkSamplingOptions&,
const SkPaint* paint, BitmapPalette pallete);
+ void drawRippleDrawable(const skiapipeline::RippleDrawableParams& params);
void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
const SkSamplingOptions&, const SkPaint*, SrcRectConstraint, BitmapPalette);
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 3056e97..d032e2b 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -815,17 +815,8 @@
mCanvas->drawDrawable(drawable.get());
}
-void SkiaCanvas::drawRipple(uirenderer::CanvasPropertyPrimitive* x,
- uirenderer::CanvasPropertyPrimitive* y,
- uirenderer::CanvasPropertyPrimitive* radius,
- uirenderer::CanvasPropertyPaint* paint,
- uirenderer::CanvasPropertyPrimitive* progress,
- uirenderer::CanvasPropertyPrimitive* turbulencePhase,
- const SkRuntimeShaderBuilder& effectBuilder) {
- sk_sp<uirenderer::skiapipeline::AnimatedRipple> drawable(
- new uirenderer::skiapipeline::AnimatedRipple(x, y, radius, paint, progress,
- turbulencePhase, effectBuilder));
- mCanvas->drawDrawable(drawable.get());
+void SkiaCanvas::drawRipple(const uirenderer::skiapipeline::RippleDrawableParams& params) {
+ uirenderer::skiapipeline::AnimatedRippleDrawable::draw(mCanvas, params);
}
void SkiaCanvas::drawPicture(const SkPicture& picture) {
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 995f00c..438a40c 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -25,6 +25,7 @@
#include "hwui/Paint.h"
#include <SkCanvas.h>
+#include "pipeline/skia/AnimatedDrawables.h"
#include "src/core/SkArenaAlloc.h"
#include <cassert>
@@ -148,13 +149,7 @@
uirenderer::CanvasPropertyPrimitive* y,
uirenderer::CanvasPropertyPrimitive* radius,
uirenderer::CanvasPropertyPaint* paint) override;
- virtual void drawRipple(uirenderer::CanvasPropertyPrimitive* x,
- uirenderer::CanvasPropertyPrimitive* y,
- uirenderer::CanvasPropertyPrimitive* radius,
- uirenderer::CanvasPropertyPaint* paint,
- uirenderer::CanvasPropertyPrimitive* progress,
- uirenderer::CanvasPropertyPrimitive* turbulencePhase,
- const SkRuntimeShaderBuilder& effectBuilder) override;
+ virtual void drawRipple(const uirenderer::skiapipeline::RippleDrawableParams& params) override;
virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
diff --git a/libs/hwui/canvas/CanvasOpTypes.h b/libs/hwui/canvas/CanvasOpTypes.h
index b55ef9d..6e18e49 100644
--- a/libs/hwui/canvas/CanvasOpTypes.h
+++ b/libs/hwui/canvas/CanvasOpTypes.h
@@ -43,7 +43,7 @@
DrawRoundRectProperty,
DrawDoubleRoundRect,
DrawCircleProperty,
- DrawRippleProperty,
+ DrawRippleDrawable,
DrawCircle,
DrawOval,
DrawArc,
diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h
index 173f394..fdc97a4 100644
--- a/libs/hwui/canvas/CanvasOps.h
+++ b/libs/hwui/canvas/CanvasOps.h
@@ -145,73 +145,13 @@
ASSERT_DRAWABLE()
};
-template<>
-struct CanvasOp<CanvasOpType::DrawRippleProperty> {
- sp<uirenderer::CanvasPropertyPrimitive> x;
- sp<uirenderer::CanvasPropertyPrimitive> y;
- sp<uirenderer::CanvasPropertyPrimitive> radius;
- sp<uirenderer::CanvasPropertyPaint> paint;
- sp<uirenderer::CanvasPropertyPrimitive> progress;
- sp<uirenderer::CanvasPropertyPrimitive> turbulencePhase;
- sk_sp<SkRuntimeEffect> effect;
-
- const float PI = 3.1415926535897932384626;
- const float PI_ROTATE_RIGHT = PI * 0.0078125;
- const float PI_ROTATE_LEFT = PI * -0.0078125;
- const float SCALE = 1.5;
- const float CIRCLE_X_1 = 0.01 * cos(SCALE * 0.55);
- const float CIRCLE_Y_1 = 0.01 * sin(SCALE * 0.55);
- const float CIRCLE_X_2 = -0.0066 * cos(SCALE * 0.45);
- const float CIRCLE_Y_2 = -0.0066 * sin(SCALE * 0.45);
- const float CIRCLE_X_3 = -0.0066 * cos(SCALE * 0.35);
- const float CIRCLE_Y_3 = -0.0066 * sin(SCALE * 0.35);
+template <>
+struct CanvasOp<CanvasOpType::DrawRippleDrawable> {
+ skiapipeline::RippleDrawableParams params;
void draw(SkCanvas* canvas) const {
- SkRuntimeShaderBuilder runtimeEffectBuilder(effect);
-
- setUniform2f(runtimeEffectBuilder, "in_origin", x->value, y->value);
- setUniform(runtimeEffectBuilder, "in_radius", radius);
- setUniform(runtimeEffectBuilder, "in_progress", progress);
- setUniform(runtimeEffectBuilder, "in_turbulencePhase", turbulencePhase);
-
- //
- // Keep in sync with:
- // frameworks/base/graphics/java/android/graphics/drawable/RippleShader.java
- //
- const float turbulence = turbulencePhase->value;
- setUniform2f(runtimeEffectBuilder, "in_tCircle1", SCALE * 0.5 + (turbulence * CIRCLE_X_1),
- SCALE * 0.5 + (turbulence * CIRCLE_Y_1));
- setUniform2f(runtimeEffectBuilder, "in_tCircle2", SCALE * 0.2 + (turbulence * CIRCLE_X_2),
- SCALE * 0.2 + (turbulence * CIRCLE_Y_2));
- setUniform2f(runtimeEffectBuilder, "in_tCircle3", SCALE + (turbulence * CIRCLE_X_3),
- SCALE + (turbulence * CIRCLE_Y_3));
- const float rotation1 = turbulence * PI_ROTATE_RIGHT + 1.7 * PI;
- setUniform2f(runtimeEffectBuilder, "in_tRotation1", cos(rotation1), sin(rotation1));
- const float rotation2 = turbulence * PI_ROTATE_LEFT + 2 * PI;
- setUniform2f(runtimeEffectBuilder, "in_tRotation2", cos(rotation2), sin(rotation2));
- const float rotation3 = turbulence * PI_ROTATE_RIGHT + 2.75 * PI;
- setUniform2f(runtimeEffectBuilder, "in_tRotation3", cos(rotation3), sin(rotation3));
-
- SkPaint paintMod = paint->value;
- paintMod.setShader(runtimeEffectBuilder.makeShader(nullptr, false));
- canvas->drawCircle(x->value, y->value, radius->value, paintMod);
+ skiapipeline::AnimatedRippleDrawable::draw(canvas, params);
}
-
- void setUniform(SkRuntimeShaderBuilder& effect, std::string name,
- sp<uirenderer::CanvasPropertyPrimitive> property) const {
- SkRuntimeShaderBuilder::BuilderUniform uniform = effect.uniform(name.c_str());
- if (uniform.fVar != nullptr) {
- uniform = property->value;
- }
- }
-
- void setUniform2f(SkRuntimeShaderBuilder effect, std::string name, float a, float b) const {
- SkRuntimeShaderBuilder::BuilderUniform uniform = effect.uniform(name.c_str());
- if (uniform.fVar != nullptr) {
- uniform = SkV2{a, b};
- }
- }
-
ASSERT_DRAWABLE()
};
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 837b055..9023613 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -22,6 +22,7 @@
#include <androidfw/ResourceTypes.h>
#include "Properties.h"
+#include "pipeline/skia/AnimatedDrawables.h"
#include "utils/Macros.h"
#include <SkBitmap.h>
@@ -141,13 +142,7 @@
uirenderer::CanvasPropertyPrimitive* y,
uirenderer::CanvasPropertyPrimitive* radius,
uirenderer::CanvasPropertyPaint* paint) = 0;
- virtual void drawRipple(uirenderer::CanvasPropertyPrimitive* x,
- uirenderer::CanvasPropertyPrimitive* y,
- uirenderer::CanvasPropertyPrimitive* radius,
- uirenderer::CanvasPropertyPaint* paint,
- uirenderer::CanvasPropertyPrimitive* progress,
- uirenderer::CanvasPropertyPrimitive* turbulencePhase,
- const SkRuntimeShaderBuilder& effectBuilder) = 0;
+ virtual void drawRipple(const uirenderer::skiapipeline::RippleDrawableParams& params) = 0;
virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) = 0;
virtual void drawRenderNode(uirenderer::RenderNode* renderNode) = 0;
diff --git a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp
index eb5a88a..f060bb3 100644
--- a/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp
+++ b/libs/hwui/jni/android_graphics_DisplayListCanvas.cpp
@@ -144,7 +144,7 @@
static void android_view_DisplayListCanvas_drawRippleProps(
CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jlong xPropPtr, jlong yPropPtr,
jlong radiusPropPtr, jlong paintPropPtr, jlong progressPropPtr, jlong turbulencePhasePtr,
- jlong builderPtr) {
+ jint color, jlong builderPtr) {
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
@@ -155,8 +155,12 @@
CanvasPropertyPrimitive* progressProp =
reinterpret_cast<CanvasPropertyPrimitive*>(progressPropPtr);
SkRuntimeShaderBuilder* builder = reinterpret_cast<SkRuntimeShaderBuilder*>(builderPtr);
- canvas->drawRipple(xProp, yProp, radiusProp, paintProp, progressProp, turbulencePhaseProp,
- *builder);
+
+ const uirenderer::skiapipeline::RippleDrawableParams params =
+ uirenderer::skiapipeline::RippleDrawableParams{
+ xProp, yProp, radiusProp, progressProp, turbulencePhaseProp,
+ (SkColor)color, paintProp, *builder};
+ canvas->drawRipple(params);
}
static void android_view_DisplayListCanvas_drawWebViewFunctor(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jint functor) {
@@ -186,7 +190,7 @@
{"nDrawCircle", "(JJJJJ)V", (void*)android_view_DisplayListCanvas_drawCircleProps},
{"nDrawRoundRect", "(JJJJJJJJ)V", (void*)android_view_DisplayListCanvas_drawRoundRectProps},
{"nDrawWebViewFunctor", "(JI)V", (void*)android_view_DisplayListCanvas_drawWebViewFunctor},
- {"nDrawRipple", "(JJJJJJJJ)V", (void*)android_view_DisplayListCanvas_drawRippleProps},
+ {"nDrawRipple", "(JJJJJJJIJ)V", (void*)android_view_DisplayListCanvas_drawRippleProps},
};
int register_android_view_DisplayListCanvas(JNIEnv* env) {
diff --git a/libs/hwui/pipeline/skia/AnimatedDrawables.h b/libs/hwui/pipeline/skia/AnimatedDrawables.h
index 7d65be1..10889e7 100644
--- a/libs/hwui/pipeline/skia/AnimatedDrawables.h
+++ b/libs/hwui/pipeline/skia/AnimatedDrawables.h
@@ -22,6 +22,7 @@
#include <math.h>
#include <utils/RefBase.h>
#include "CanvasProperty.h"
+#include "CanvasTransform.h"
namespace android {
namespace uirenderer {
@@ -56,89 +57,80 @@
sp<uirenderer::CanvasPropertyPaint> mPaint;
};
-class AnimatedRipple : public SkDrawable {
-public:
- AnimatedRipple(uirenderer::CanvasPropertyPrimitive* x, uirenderer::CanvasPropertyPrimitive* y,
- uirenderer::CanvasPropertyPrimitive* radius,
- uirenderer::CanvasPropertyPaint* paint,
- uirenderer::CanvasPropertyPrimitive* progress,
- uirenderer::CanvasPropertyPrimitive* turbulencePhase,
- const SkRuntimeShaderBuilder& effectBuilder)
- : mX(x)
- , mY(y)
- , mRadius(radius)
- , mPaint(paint)
- , mProgress(progress)
- , mTurbulencePhase(turbulencePhase)
- , mRuntimeEffectBuilder(effectBuilder) {}
+struct RippleDrawableParams {
+ sp<uirenderer::CanvasPropertyPrimitive> x;
+ sp<uirenderer::CanvasPropertyPrimitive> y;
+ sp<uirenderer::CanvasPropertyPrimitive> radius;
+ sp<uirenderer::CanvasPropertyPrimitive> progress;
+ sp<uirenderer::CanvasPropertyPrimitive> turbulencePhase;
+ SkColor color;
+ sp<uirenderer::CanvasPropertyPaint> paint;
+ SkRuntimeShaderBuilder effectBuilder;
+};
-protected:
- virtual SkRect onGetBounds() override {
- const float x = mX->value;
- const float y = mY->value;
- const float radius = mRadius->value;
- return SkRect::MakeLTRB(x - radius, y - radius, x + radius, y + radius);
- }
- virtual void onDraw(SkCanvas* canvas) override {
- setUniform2f("in_origin", mX->value, mY->value);
- setUniform("in_radius", mRadius);
- setUniform("in_progress", mProgress);
- setUniform("in_turbulencePhase", mTurbulencePhase);
+class AnimatedRippleDrawable {
+public:
+ static void draw(SkCanvas* canvas, const RippleDrawableParams& params) {
+ auto& effectBuilder = const_cast<SkRuntimeShaderBuilder&>(params.effectBuilder);
+
+ setUniform2f(effectBuilder, "in_origin", params.x->value, params.y->value);
+ setUniform(effectBuilder, "in_radius", params.radius);
+ setUniform(effectBuilder, "in_progress", params.progress);
+ setUniform(effectBuilder, "in_turbulencePhase", params.turbulencePhase);
+
+ SkRuntimeShaderBuilder::BuilderUniform uniform = effectBuilder.uniform("in_color");
+ if (uniform.fVar != nullptr) {
+ uniform = SkV4{SkColorGetR(params.color) / 255.0f, SkColorGetG(params.color) / 255.0f,
+ SkColorGetB(params.color) / 255.0f, SkColorGetA(params.color) / 255.0f};
+ }
+
+ const float CIRCLE_X_1 = 0.01 * cos(SCALE * 0.55);
+ const float CIRCLE_Y_1 = 0.01 * sin(SCALE * 0.55);
+ const float CIRCLE_X_2 = -0.0066 * cos(SCALE * 0.45);
+ const float CIRCLE_Y_2 = -0.0066 * sin(SCALE * 0.45);
+ const float CIRCLE_X_3 = -0.0066 * cos(SCALE * 0.35);
+ const float CIRCLE_Y_3 = -0.0066 * sin(SCALE * 0.35);
//
// Keep in sync with:
// frameworks/base/graphics/java/android/graphics/drawable/RippleShader.java
//
- const float turbulencePhase = mTurbulencePhase->value;
- setUniform2f("in_tCircle1", SCALE * 0.5 + (turbulencePhase * CIRCLE_X_1),
+ const float turbulencePhase = params.turbulencePhase->value;
+ setUniform2f(effectBuilder, "in_tCircle1", SCALE * 0.5 + (turbulencePhase * CIRCLE_X_1),
SCALE * 0.5 + (turbulencePhase * CIRCLE_Y_1));
- setUniform2f("in_tCircle2", SCALE * 0.2 + (turbulencePhase * CIRCLE_X_2),
+ setUniform2f(effectBuilder, "in_tCircle2", SCALE * 0.2 + (turbulencePhase * CIRCLE_X_2),
SCALE * 0.2 + (turbulencePhase * CIRCLE_Y_2));
- setUniform2f("in_tCircle3", SCALE + (turbulencePhase * CIRCLE_X_3),
+ setUniform2f(effectBuilder, "in_tCircle3", SCALE + (turbulencePhase * CIRCLE_X_3),
SCALE + (turbulencePhase * CIRCLE_Y_3));
const float rotation1 = turbulencePhase * PI_ROTATE_RIGHT + 1.7 * PI;
- setUniform2f("in_tRotation1", cos(rotation1), sin(rotation1));
+ setUniform2f(effectBuilder, "in_tRotation1", cos(rotation1), sin(rotation1));
const float rotation2 = turbulencePhase * PI_ROTATE_LEFT + 2 * PI;
- setUniform2f("in_tRotation2", cos(rotation2), sin(rotation2));
+ setUniform2f(effectBuilder, "in_tRotation2", cos(rotation2), sin(rotation2));
const float rotation3 = turbulencePhase * PI_ROTATE_RIGHT + 2.75 * PI;
- setUniform2f("in_tRotation3", cos(rotation3), sin(rotation3));
+ setUniform2f(effectBuilder, "in_tRotation3", cos(rotation3), sin(rotation3));
- SkPaint paint = mPaint->value;
- paint.setShader(mRuntimeEffectBuilder.makeShader(nullptr, false));
- canvas->drawCircle(mX->value, mY->value, mRadius->value, paint);
+ params.paint->value.setShader(effectBuilder.makeShader(nullptr, false));
+ canvas->drawCircle(params.x->value, params.y->value, params.radius->value,
+ params.paint->value);
}
private:
- sp<uirenderer::CanvasPropertyPrimitive> mX;
- sp<uirenderer::CanvasPropertyPrimitive> mY;
- sp<uirenderer::CanvasPropertyPrimitive> mRadius;
- sp<uirenderer::CanvasPropertyPaint> mPaint;
- sp<uirenderer::CanvasPropertyPrimitive> mProgress;
- sp<uirenderer::CanvasPropertyPrimitive> mTurbulencePhase;
- SkRuntimeShaderBuilder mRuntimeEffectBuilder;
+ static constexpr float PI = 3.1415926535897932384626;
+ static constexpr float PI_ROTATE_RIGHT = PI * 0.0078125;
+ static constexpr float PI_ROTATE_LEFT = PI * -0.0078125;
+ static constexpr float SCALE = 1.5;
- const float PI = 3.1415926535897932384626;
- const float PI_ROTATE_RIGHT = PI * 0.0078125;
- const float PI_ROTATE_LEFT = PI * -0.0078125;
- const float SCALE = 1.5;
- const float CIRCLE_X_1 = 0.01 * cos(SCALE * 0.55);
- const float CIRCLE_Y_1 = 0.01 * sin(SCALE * 0.55);
- const float CIRCLE_X_2 = -0.0066 * cos(SCALE * 0.45);
- const float CIRCLE_Y_2 = -0.0066 * sin(SCALE * 0.45);
- const float CIRCLE_X_3 = -0.0066 * cos(SCALE * 0.35);
- const float CIRCLE_Y_3 = -0.0066 * sin(SCALE * 0.35);
-
- virtual void setUniform(std::string name, sp<uirenderer::CanvasPropertyPrimitive> property) {
- SkRuntimeShaderBuilder::BuilderUniform uniform =
- mRuntimeEffectBuilder.uniform(name.c_str());
+ static void setUniform(SkRuntimeShaderBuilder& effectBuilder, std::string name,
+ sp<uirenderer::CanvasPropertyPrimitive> property) {
+ SkRuntimeShaderBuilder::BuilderUniform uniform = effectBuilder.uniform(name.c_str());
if (uniform.fVar != nullptr) {
uniform = property->value;
}
}
- virtual void setUniform2f(std::string name, float a, float b) {
- SkRuntimeShaderBuilder::BuilderUniform uniform =
- mRuntimeEffectBuilder.uniform(name.c_str());
+ static void setUniform2f(SkRuntimeShaderBuilder& effectBuilder, std::string name, float a,
+ float b) {
+ SkRuntimeShaderBuilder::BuilderUniform uniform = effectBuilder.uniform(name.c_str());
if (uniform.fVar != nullptr) {
uniform = SkV2{a, b};
}
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 9e73f04..76c4a03 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -109,15 +109,8 @@
drawDrawable(mDisplayList->allocateDrawable<AnimatedCircle>(x, y, radius, paint));
}
-void SkiaRecordingCanvas::drawRipple(uirenderer::CanvasPropertyPrimitive* x,
- uirenderer::CanvasPropertyPrimitive* y,
- uirenderer::CanvasPropertyPrimitive* radius,
- uirenderer::CanvasPropertyPaint* paint,
- uirenderer::CanvasPropertyPrimitive* progress,
- uirenderer::CanvasPropertyPrimitive* turbulencePhase,
- const SkRuntimeShaderBuilder& effectBuilder) {
- drawDrawable(mDisplayList->allocateDrawable<AnimatedRipple>(x, y, radius, paint, progress,
- turbulencePhase, effectBuilder));
+void SkiaRecordingCanvas::drawRipple(const skiapipeline::RippleDrawableParams& params) {
+ mRecorder.drawRippleDrawable(params);
}
void SkiaRecordingCanvas::enableZ(bool enableZ) {
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index 4deb3b9..1445a27 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -20,6 +20,7 @@
#include "ReorderBarrierDrawables.h"
#include "SkiaCanvas.h"
#include "SkiaDisplayList.h"
+#include "pipeline/skia/AnimatedDrawables.h"
namespace android {
namespace uirenderer {
@@ -70,13 +71,7 @@
uirenderer::CanvasPropertyPrimitive* y,
uirenderer::CanvasPropertyPrimitive* radius,
uirenderer::CanvasPropertyPaint* paint) override;
- virtual void drawRipple(uirenderer::CanvasPropertyPrimitive* x,
- uirenderer::CanvasPropertyPrimitive* y,
- uirenderer::CanvasPropertyPrimitive* radius,
- uirenderer::CanvasPropertyPaint* paint,
- uirenderer::CanvasPropertyPrimitive* progress,
- uirenderer::CanvasPropertyPrimitive* turbulencePhase,
- const SkRuntimeShaderBuilder& effectBuilder) override;
+ virtual void drawRipple(const RippleDrawableParams& params) override;
virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
diff --git a/libs/hwui/tests/unit/CanvasOpTests.cpp b/libs/hwui/tests/unit/CanvasOpTests.cpp
index a718d46..2cf3456 100644
--- a/libs/hwui/tests/unit/CanvasOpTests.cpp
+++ b/libs/hwui/tests/unit/CanvasOpTests.cpp
@@ -31,6 +31,7 @@
using namespace android;
using namespace android::uirenderer;
+using namespace android::uirenderer::skiapipeline;
using namespace android::uirenderer::test;
// We lazy
@@ -569,6 +570,33 @@
EXPECT_EQ(2, canvas.sumTotalDrawCalls());
}
+TEST(CanvasOp, simpleDrawRipple) {
+ CanvasOpBuffer buffer;
+ EXPECT_EQ(buffer.size(), 0);
+
+ const char* sksl =
+ "half4 main(float2 coord) {"
+ " return half4(1.);"
+ "}";
+ auto [effect, error] = SkRuntimeEffect::MakeForShader(SkString(sksl));
+ auto params = RippleDrawableParams{
+ .x = sp<CanvasPropertyPrimitive>(new CanvasPropertyPrimitive(100)),
+ .y = sp<CanvasPropertyPrimitive>(new CanvasPropertyPrimitive(200)),
+ .radius = sp<CanvasPropertyPrimitive>(new CanvasPropertyPrimitive(50)),
+ .progress = sp<CanvasPropertyPrimitive>(new CanvasPropertyPrimitive(0.5)),
+ .turbulencePhase = sp<CanvasPropertyPrimitive>(new CanvasPropertyPrimitive(1)),
+ .color = 0xff00ff,
+ .paint = sp<CanvasPropertyPaint>(new CanvasPropertyPaint(SkPaint{})),
+ .effectBuilder = SkRuntimeShaderBuilder(effect)};
+ buffer.push<Op::DrawRippleDrawable>({.params = params});
+
+ CallCountingCanvas canvas;
+ EXPECT_EQ(0, canvas.sumTotalDrawCalls());
+ rasterizeCanvasBuffer(buffer, &canvas);
+ EXPECT_EQ(1, canvas.drawOvalCount);
+ EXPECT_EQ(1, canvas.sumTotalDrawCalls());
+}
+
TEST(CanvasOp, immediateRendering) {
auto canvas = std::make_shared<CallCountingCanvas>();