Merge "Initial framework needed to draw circle with RuntimeShader."
This commit is contained in:
committed by
Android (Google) Code Review
commit
a6a7ea7ed2
@@ -203,6 +203,26 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
|
||||
radius.getNativeContainer(), paint.getNativeContainer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a ripple
|
||||
*
|
||||
* @param cx
|
||||
* @param cy
|
||||
* @param radius
|
||||
* @param paint
|
||||
* @param progress
|
||||
* @param shader
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void drawRipple(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
|
||||
CanvasProperty<Float> radius, CanvasProperty<Paint> paint,
|
||||
CanvasProperty<Float> progress, RuntimeShader shader) {
|
||||
nDrawRipple(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
|
||||
radius.getNativeContainer(), paint.getNativeContainer(),
|
||||
progress.getNativeContainer(), shader.getNativeShaderFactory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws a round rect
|
||||
*
|
||||
@@ -260,6 +280,9 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
|
||||
private static native void nDrawCircle(long renderer, long propCx,
|
||||
long propCy, long propRadius, long propPaint);
|
||||
@CriticalNative
|
||||
private static native void nDrawRipple(long renderer, long propCx, long propCy, long propRadius,
|
||||
long propPaint, long propProgress, long runtimeEffect);
|
||||
@CriticalNative
|
||||
private static native void nDrawRoundRect(long renderer, long propLeft, long propTop,
|
||||
long propRight, long propBottom, long propRx, long propRy, long propPaint);
|
||||
@CriticalNative
|
||||
|
||||
@@ -115,6 +115,10 @@ public class RuntimeShader extends Shader {
|
||||
nativeShaders, colorSpace().getNativeInstance(), mIsOpaque);
|
||||
}
|
||||
|
||||
public long getNativeShaderFactory() {
|
||||
return mNativeInstanceRuntimeShaderFactory;
|
||||
}
|
||||
|
||||
private static native long nativeCreate(long shaderFactory, long matrix, byte[] inputs,
|
||||
long[] shaderInputs, long colorSpaceHandle, boolean isOpaque);
|
||||
|
||||
|
||||
@@ -814,6 +814,18 @@ void SkiaCanvas::drawCircle(uirenderer::CanvasPropertyPrimitive* x,
|
||||
mCanvas->drawDrawable(drawable.get());
|
||||
}
|
||||
|
||||
void SkiaCanvas::drawRipple(uirenderer::CanvasPropertyPrimitive* x,
|
||||
uirenderer::CanvasPropertyPrimitive* y,
|
||||
uirenderer::CanvasPropertyPrimitive* radius,
|
||||
uirenderer::CanvasPropertyPaint* paint,
|
||||
uirenderer::CanvasPropertyPrimitive* progress,
|
||||
sk_sp<SkRuntimeEffect> runtimeEffect) {
|
||||
sk_sp<uirenderer::skiapipeline::AnimatedRipple> drawable(
|
||||
new uirenderer::skiapipeline::AnimatedRipple(x, y, radius, paint, progress,
|
||||
runtimeEffect));
|
||||
mCanvas->drawDrawable(drawable.get());
|
||||
}
|
||||
|
||||
void SkiaCanvas::drawPicture(const SkPicture& picture) {
|
||||
// TODO: Change to mCanvas->drawPicture()? SkCanvas::drawPicture seems to be
|
||||
// where the logic is for playback vs. ref picture. Using picture.playback here
|
||||
|
||||
@@ -147,6 +147,12 @@ public:
|
||||
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,
|
||||
sk_sp<SkRuntimeEffect> runtimeEffect) override;
|
||||
|
||||
virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) override;
|
||||
virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
|
||||
|
||||
@@ -42,6 +42,7 @@ enum class CanvasOpType : int8_t {
|
||||
DrawRoundRectProperty,
|
||||
DrawDoubleRoundRect,
|
||||
DrawCircleProperty,
|
||||
DrawRippleProperty,
|
||||
DrawCircle,
|
||||
DrawOval,
|
||||
DrawArc,
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <SkVertices.h>
|
||||
#include <SkImage.h>
|
||||
#include <SkPicture.h>
|
||||
#include <SkRuntimeEffect.h>
|
||||
#include <hwui/Bitmap.h>
|
||||
#include <log/log.h>
|
||||
#include "CanvasProperty.h"
|
||||
@@ -142,6 +143,42 @@ struct CanvasOp<CanvasOpType::DrawCircleProperty> {
|
||||
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;
|
||||
sk_sp<SkRuntimeEffect> effect;
|
||||
|
||||
void draw(SkCanvas* canvas) const {
|
||||
SkRuntimeShaderBuilder runtimeEffectBuilder(effect);
|
||||
|
||||
SkRuntimeShaderBuilder::BuilderUniform center = runtimeEffectBuilder.uniform("in_origin");
|
||||
if (center.fVar != nullptr) {
|
||||
center = SkV2{x->value, y->value};
|
||||
}
|
||||
|
||||
SkRuntimeShaderBuilder::BuilderUniform radiusU =
|
||||
runtimeEffectBuilder.uniform("in_maxRadius");
|
||||
if (radiusU.fVar != nullptr) {
|
||||
radiusU = radius->value;
|
||||
}
|
||||
|
||||
SkRuntimeShaderBuilder::BuilderUniform progressU =
|
||||
runtimeEffectBuilder.uniform("in_progress");
|
||||
if (progressU.fVar != nullptr) {
|
||||
progressU = progress->value;
|
||||
}
|
||||
|
||||
SkPaint paintMod = paint->value;
|
||||
paintMod.setShader(runtimeEffectBuilder.makeShader(nullptr, false));
|
||||
canvas->drawCircle(x->value, y->value, radius->value, paintMod);
|
||||
}
|
||||
ASSERT_DRAWABLE()
|
||||
};
|
||||
|
||||
template <>
|
||||
struct CanvasOp<CanvasOpType::DrawColor> {
|
||||
SkColor4f color;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
class SkAnimatedImage;
|
||||
class SkCanvasState;
|
||||
class SkRuntimeEffect;
|
||||
class SkVertices;
|
||||
|
||||
namespace minikin {
|
||||
@@ -133,6 +134,12 @@ public:
|
||||
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,
|
||||
sk_sp<SkRuntimeEffect> runtimeEffect) = 0;
|
||||
|
||||
virtual void drawLayer(uirenderer::DeferredLayerUpdater* layerHandle) = 0;
|
||||
virtual void drawRenderNode(uirenderer::RenderNode* renderNode) = 0;
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#include <utils/Looper.h>
|
||||
#endif
|
||||
|
||||
#include <SkBitmap.h>
|
||||
#include <SkRegion.h>
|
||||
#include <SkRuntimeEffect.h>
|
||||
|
||||
#include <Rect.h>
|
||||
#include <RenderNode.h>
|
||||
@@ -139,6 +139,21 @@ static void android_view_DisplayListCanvas_drawCircleProps(CRITICAL_JNI_PARAMS_C
|
||||
canvas->drawCircle(xProp, yProp, radiusProp, paintProp);
|
||||
}
|
||||
|
||||
static void android_view_DisplayListCanvas_drawRippleProps(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr,
|
||||
jlong xPropPtr, jlong yPropPtr,
|
||||
jlong radiusPropPtr, jlong paintPropPtr,
|
||||
jlong progressPropPtr, jlong effectPtr) {
|
||||
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
|
||||
CanvasPropertyPrimitive* xProp = reinterpret_cast<CanvasPropertyPrimitive*>(xPropPtr);
|
||||
CanvasPropertyPrimitive* yProp = reinterpret_cast<CanvasPropertyPrimitive*>(yPropPtr);
|
||||
CanvasPropertyPrimitive* radiusProp = reinterpret_cast<CanvasPropertyPrimitive*>(radiusPropPtr);
|
||||
CanvasPropertyPaint* paintProp = reinterpret_cast<CanvasPropertyPaint*>(paintPropPtr);
|
||||
CanvasPropertyPrimitive* progressProp =
|
||||
reinterpret_cast<CanvasPropertyPrimitive*>(progressPropPtr);
|
||||
SkRuntimeEffect* effect = reinterpret_cast<SkRuntimeEffect*>(effectPtr);
|
||||
canvas->drawRipple(xProp, yProp, radiusProp, paintProp, progressProp, sk_ref_sp(effect));
|
||||
}
|
||||
|
||||
static void android_view_DisplayListCanvas_drawWebViewFunctor(CRITICAL_JNI_PARAMS_COMMA jlong canvasPtr, jint functor) {
|
||||
Canvas* canvas = reinterpret_cast<Canvas*>(canvasPtr);
|
||||
canvas->drawWebViewFunctor(functor);
|
||||
@@ -163,6 +178,7 @@ static JNINativeMethod gMethods[] = {
|
||||
{ "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", "(JJJJJJJ)V", (void*) android_view_DisplayListCanvas_drawRippleProps },
|
||||
};
|
||||
|
||||
int register_android_view_DisplayListCanvas(JNIEnv* env) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include <SkCanvas.h>
|
||||
#include <SkDrawable.h>
|
||||
#include <SkRuntimeEffect.h>
|
||||
#include <utils/RefBase.h>
|
||||
#include "CanvasProperty.h"
|
||||
|
||||
@@ -54,6 +55,59 @@ private:
|
||||
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,
|
||||
sk_sp<SkRuntimeEffect> runtimeEffect)
|
||||
: mX(x)
|
||||
, mY(y)
|
||||
, mRadius(radius)
|
||||
, mPaint(paint)
|
||||
, mProgress(progress)
|
||||
, mRuntimeEffectBuilder(std::move(runtimeEffect)) {}
|
||||
|
||||
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 {
|
||||
SkRuntimeShaderBuilder::BuilderUniform center = mRuntimeEffectBuilder.uniform("in_origin");
|
||||
if (center.fVar != nullptr) {
|
||||
center = SkV2{mX->value, mY->value};
|
||||
}
|
||||
|
||||
SkRuntimeShaderBuilder::BuilderUniform radiusU =
|
||||
mRuntimeEffectBuilder.uniform("in_maxRadius");
|
||||
if (radiusU.fVar != nullptr) {
|
||||
radiusU = mRadius->value;
|
||||
}
|
||||
|
||||
SkRuntimeShaderBuilder::BuilderUniform progressU =
|
||||
mRuntimeEffectBuilder.uniform("in_progress");
|
||||
if (progressU.fVar != nullptr) {
|
||||
progressU = mProgress->value;
|
||||
}
|
||||
|
||||
SkPaint paint = mPaint->value;
|
||||
paint.setShader(mRuntimeEffectBuilder.makeShader(nullptr, false));
|
||||
canvas->drawCircle(mX->value, mY->value, mRadius->value, paint);
|
||||
}
|
||||
|
||||
private:
|
||||
sp<uirenderer::CanvasPropertyPrimitive> mX;
|
||||
sp<uirenderer::CanvasPropertyPrimitive> mY;
|
||||
sp<uirenderer::CanvasPropertyPrimitive> mRadius;
|
||||
sp<uirenderer::CanvasPropertyPaint> mPaint;
|
||||
sp<uirenderer::CanvasPropertyPrimitive> mProgress;
|
||||
SkRuntimeShaderBuilder mRuntimeEffectBuilder;
|
||||
};
|
||||
|
||||
class AnimatedCircle : public SkDrawable {
|
||||
public:
|
||||
AnimatedCircle(uirenderer::CanvasPropertyPrimitive* x, uirenderer::CanvasPropertyPrimitive* y,
|
||||
|
||||
@@ -85,6 +85,16 @@ void SkiaRecordingCanvas::drawCircle(uirenderer::CanvasPropertyPrimitive* x,
|
||||
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,
|
||||
sk_sp<SkRuntimeEffect> runtimeEffect) {
|
||||
drawDrawable(mDisplayList->allocateDrawable<AnimatedRipple>(x, y, radius, paint, progress,
|
||||
runtimeEffect));
|
||||
}
|
||||
|
||||
void SkiaRecordingCanvas::enableZ(bool enableZ) {
|
||||
if (mCurrentBarrier && enableZ) {
|
||||
// Already in a re-order section, nothing to do
|
||||
|
||||
@@ -66,6 +66,12 @@ public:
|
||||
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,
|
||||
sk_sp<SkRuntimeEffect> runtimeEffect) override;
|
||||
|
||||
virtual void drawVectorDrawable(VectorDrawableRoot* vectorDrawable) override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user