Merge "Create wrapper around Shader native implementation"
This commit is contained in:
@@ -3111,7 +3111,7 @@ public class Paint {
|
||||
@CriticalNative
|
||||
private static native boolean nGetFillPath(long paintPtr, long src, long dst);
|
||||
@CriticalNative
|
||||
private static native long nSetShader(long paintPtr, long shader);
|
||||
private static native void nSetShader(long paintPtr, long shader);
|
||||
@CriticalNative
|
||||
private static native long nSetColorFilter(long paintPtr, long filter);
|
||||
@CriticalNative
|
||||
|
||||
@@ -462,6 +462,13 @@ cc_defaults {
|
||||
"RenderNode.cpp",
|
||||
"RenderProperties.cpp",
|
||||
"RootRenderNode.cpp",
|
||||
"shader/Shader.cpp",
|
||||
"shader/BitmapShader.cpp",
|
||||
"shader/ComposeShader.cpp",
|
||||
"shader/LinearGradientShader.cpp",
|
||||
"shader/RadialGradientShader.cpp",
|
||||
"shader/RuntimeShader.cpp",
|
||||
"shader/SweepGradientShader.cpp",
|
||||
"SkiaCanvas.cpp",
|
||||
"VectorDrawable.cpp",
|
||||
],
|
||||
|
||||
@@ -42,6 +42,8 @@
|
||||
#include <SkTextBlob.h>
|
||||
#include <SkVertices.h>
|
||||
|
||||
#include <shader/BitmapShader.h>
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
@@ -49,6 +51,7 @@
|
||||
namespace android {
|
||||
|
||||
using uirenderer::PaintUtils;
|
||||
using uirenderer::BitmapShader;
|
||||
|
||||
Canvas* Canvas::create_canvas(const SkBitmap& bitmap) {
|
||||
return new SkiaCanvas(bitmap);
|
||||
@@ -681,7 +684,9 @@ void SkiaCanvas::drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
|
||||
if (paint) {
|
||||
pnt = *paint;
|
||||
}
|
||||
pnt.setShader(bitmap.makeImage()->makeShader());
|
||||
|
||||
pnt.setShader(sk_ref_sp(new BitmapShader(
|
||||
bitmap.makeImage(), SkTileMode::kClamp, SkTileMode::kClamp, nullptr)));
|
||||
auto v = builder.detach();
|
||||
apply_looper(&pnt, [&](const SkPaint& p) {
|
||||
mCanvas->drawVertices(v, SkBlendMode::kModulate, p);
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include "PathParser.h"
|
||||
#include "SkColorFilter.h"
|
||||
#include "SkImageInfo.h"
|
||||
#include "SkShader.h"
|
||||
#include "hwui/Paint.h"
|
||||
|
||||
#ifdef __ANDROID__
|
||||
@@ -159,10 +158,10 @@ void FullPath::draw(SkCanvas* outCanvas, bool useStagingData) {
|
||||
|
||||
// Draw path's fill, if fill color or gradient is valid
|
||||
bool needsFill = false;
|
||||
SkPaint paint;
|
||||
Paint paint;
|
||||
if (properties.getFillGradient() != nullptr) {
|
||||
paint.setColor(applyAlpha(SK_ColorBLACK, properties.getFillAlpha()));
|
||||
paint.setShader(sk_sp<SkShader>(SkSafeRef(properties.getFillGradient())));
|
||||
paint.setShader(sk_sp<Shader>(SkSafeRef(properties.getFillGradient())));
|
||||
needsFill = true;
|
||||
} else if (properties.getFillColor() != SK_ColorTRANSPARENT) {
|
||||
paint.setColor(applyAlpha(properties.getFillColor(), properties.getFillAlpha()));
|
||||
@@ -179,7 +178,7 @@ void FullPath::draw(SkCanvas* outCanvas, bool useStagingData) {
|
||||
bool needsStroke = false;
|
||||
if (properties.getStrokeGradient() != nullptr) {
|
||||
paint.setColor(applyAlpha(SK_ColorBLACK, properties.getStrokeAlpha()));
|
||||
paint.setShader(sk_sp<SkShader>(SkSafeRef(properties.getStrokeGradient())));
|
||||
paint.setShader(sk_sp<Shader>(SkSafeRef(properties.getStrokeGradient())));
|
||||
needsStroke = true;
|
||||
} else if (properties.getStrokeColor() != SK_ColorTRANSPARENT) {
|
||||
paint.setColor(applyAlpha(properties.getStrokeColor(), properties.getStrokeAlpha()));
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
#include <SkPath.h>
|
||||
#include <SkPathMeasure.h>
|
||||
#include <SkRect.h>
|
||||
#include <SkShader.h>
|
||||
#include <SkSurface.h>
|
||||
#include <shader/Shader.h>
|
||||
|
||||
#include <cutils/compiler.h>
|
||||
#include <stddef.h>
|
||||
@@ -227,20 +227,20 @@ public:
|
||||
strokeGradient = prop.strokeGradient;
|
||||
onPropertyChanged();
|
||||
}
|
||||
void setFillGradient(SkShader* gradient) {
|
||||
void setFillGradient(Shader* gradient) {
|
||||
if (fillGradient.get() != gradient) {
|
||||
fillGradient = sk_ref_sp(gradient);
|
||||
onPropertyChanged();
|
||||
}
|
||||
}
|
||||
void setStrokeGradient(SkShader* gradient) {
|
||||
void setStrokeGradient(Shader* gradient) {
|
||||
if (strokeGradient.get() != gradient) {
|
||||
strokeGradient = sk_ref_sp(gradient);
|
||||
onPropertyChanged();
|
||||
}
|
||||
}
|
||||
SkShader* getFillGradient() const { return fillGradient.get(); }
|
||||
SkShader* getStrokeGradient() const { return strokeGradient.get(); }
|
||||
Shader* getFillGradient() const { return fillGradient.get(); }
|
||||
Shader* getStrokeGradient() const { return strokeGradient.get(); }
|
||||
float getStrokeWidth() const { return mPrimitiveFields.strokeWidth; }
|
||||
void setStrokeWidth(float strokeWidth) {
|
||||
VD_SET_PRIMITIVE_FIELD_AND_NOTIFY(strokeWidth, strokeWidth);
|
||||
@@ -320,8 +320,8 @@ public:
|
||||
count,
|
||||
};
|
||||
PrimitiveFields mPrimitiveFields;
|
||||
sk_sp<SkShader> fillGradient;
|
||||
sk_sp<SkShader> strokeGradient;
|
||||
sk_sp<Shader> fillGradient;
|
||||
sk_sp<Shader> strokeGradient;
|
||||
};
|
||||
|
||||
// Called from UI thread
|
||||
|
||||
@@ -73,7 +73,7 @@ void Canvas::drawTextDecorations(float x, float y, float length, const Paint& pa
|
||||
|
||||
static void simplifyPaint(int color, Paint* paint) {
|
||||
paint->setColor(color);
|
||||
paint->setShader(nullptr);
|
||||
paint->setShader((sk_sp<uirenderer::Shader>)nullptr);
|
||||
paint->setColorFilter(nullptr);
|
||||
paint->setLooper(nullptr);
|
||||
paint->setStrokeWidth(4 + 0.04 * paint->getSkFont().getSize());
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include <minikin/FamilyVariant.h>
|
||||
#include <minikin/Hyphenator.h>
|
||||
|
||||
#include <shader/Shader.h>
|
||||
|
||||
namespace android {
|
||||
|
||||
class Paint : public SkPaint {
|
||||
@@ -149,8 +151,14 @@ public:
|
||||
// The only respected flags are : [ antialias, dither, filterBitmap ]
|
||||
static uint32_t GetSkPaintJavaFlags(const SkPaint&);
|
||||
static void SetSkPaintJavaFlags(SkPaint*, uint32_t flags);
|
||||
|
||||
void setShader(sk_sp<uirenderer::Shader> shader);
|
||||
|
||||
private:
|
||||
|
||||
using SkPaint::setShader;
|
||||
using SkPaint::setImageFilter;
|
||||
|
||||
SkFont mFont;
|
||||
sk_sp<SkDrawLooper> mLooper;
|
||||
|
||||
@@ -169,6 +177,7 @@ private:
|
||||
bool mStrikeThru = false;
|
||||
bool mUnderline = false;
|
||||
bool mDevKern = false;
|
||||
sk_sp<uirenderer::Shader> mShader;
|
||||
};
|
||||
|
||||
} // namespace android
|
||||
|
||||
@@ -24,7 +24,8 @@ Paint::Paint()
|
||||
, mWordSpacing(0)
|
||||
, mFontFeatureSettings()
|
||||
, mMinikinLocaleListId(0)
|
||||
, mFamilyVariant(minikin::FamilyVariant::DEFAULT) {
|
||||
, mFamilyVariant(minikin::FamilyVariant::DEFAULT)
|
||||
, mShader(nullptr) {
|
||||
// SkPaint::antialiasing defaults to false, but
|
||||
// SkFont::edging defaults to kAntiAlias. To keep them
|
||||
// insync, we manually set the font to kAilas.
|
||||
@@ -45,7 +46,8 @@ Paint::Paint(const Paint& paint)
|
||||
, mAlign(paint.mAlign)
|
||||
, mStrikeThru(paint.mStrikeThru)
|
||||
, mUnderline(paint.mUnderline)
|
||||
, mDevKern(paint.mDevKern) {}
|
||||
, mDevKern(paint.mDevKern)
|
||||
, mShader(paint.mShader){}
|
||||
|
||||
|
||||
Paint::~Paint() {}
|
||||
@@ -65,9 +67,30 @@ Paint& Paint::operator=(const Paint& other) {
|
||||
mStrikeThru = other.mStrikeThru;
|
||||
mUnderline = other.mUnderline;
|
||||
mDevKern = other.mDevKern;
|
||||
mShader = other.mShader;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Paint::setShader(sk_sp<uirenderer::Shader> shader) {
|
||||
if (shader) {
|
||||
// If there is an SkShader compatible shader, apply it
|
||||
sk_sp<SkShader> skShader = shader->asSkShader();
|
||||
if (skShader.get()) {
|
||||
SkPaint::setShader(skShader);
|
||||
SkPaint::setImageFilter(nullptr);
|
||||
} else {
|
||||
// ... otherwise the specified shader can only be represented as an ImageFilter
|
||||
SkPaint::setShader(nullptr);
|
||||
SkPaint::setImageFilter(shader->asSkImageFilter());
|
||||
}
|
||||
} else {
|
||||
// No shader is provided at all, clear out both the SkShader and SkImageFilter slots
|
||||
SkPaint::setShader(nullptr);
|
||||
SkPaint::setImageFilter(nullptr);
|
||||
}
|
||||
mShader = shader;
|
||||
}
|
||||
|
||||
bool operator==(const Paint& a, const Paint& b) {
|
||||
return static_cast<const SkPaint&>(a) == static_cast<const SkPaint&>(b) &&
|
||||
a.mFont == b.mFont &&
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include <minikin/LocaleList.h>
|
||||
#include <minikin/Measurement.h>
|
||||
#include <minikin/MinikinPaint.h>
|
||||
#include <shader/Shader.h>
|
||||
#include <unicode/utf16.h>
|
||||
|
||||
#include <cassert>
|
||||
@@ -54,6 +55,8 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
using namespace android::uirenderer;
|
||||
|
||||
namespace android {
|
||||
|
||||
struct JMetricsID {
|
||||
@@ -782,11 +785,10 @@ namespace PaintGlue {
|
||||
return obj->getFillPath(*src, dst) ? JNI_TRUE : JNI_FALSE;
|
||||
}
|
||||
|
||||
static jlong setShader(CRITICAL_JNI_PARAMS_COMMA jlong objHandle, jlong shaderHandle) {
|
||||
Paint* obj = reinterpret_cast<Paint*>(objHandle);
|
||||
SkShader* shader = reinterpret_cast<SkShader*>(shaderHandle);
|
||||
obj->setShader(sk_ref_sp(shader));
|
||||
return reinterpret_cast<jlong>(obj->getShader());
|
||||
static void setShader(CRITICAL_JNI_PARAMS_COMMA jlong objHandle, jlong shaderHandle) {
|
||||
auto* paint = reinterpret_cast<Paint*>(objHandle);
|
||||
auto* shader = reinterpret_cast<Shader*>(shaderHandle);
|
||||
paint->setShader(sk_ref_sp(shader));
|
||||
}
|
||||
|
||||
static jlong setColorFilter(CRITICAL_JNI_PARAMS_COMMA jlong objHandle, jlong filterHandle) {
|
||||
@@ -1097,7 +1099,7 @@ static const JNINativeMethod methods[] = {
|
||||
{"nGetStrokeJoin","(J)I", (void*) PaintGlue::getStrokeJoin},
|
||||
{"nSetStrokeJoin","(JI)V", (void*) PaintGlue::setStrokeJoin},
|
||||
{"nGetFillPath","(JJJ)Z", (void*) PaintGlue::getFillPath},
|
||||
{"nSetShader","(JJ)J", (void*) PaintGlue::setShader},
|
||||
{"nSetShader","(JJ)V", (void*) PaintGlue::setShader},
|
||||
{"nSetColorFilter","(JJ)J", (void*) PaintGlue::setColorFilter},
|
||||
{"nSetXfermode","(JI)V", (void*) PaintGlue::setXfermode},
|
||||
{"nSetPathEffect","(JJ)J", (void*) PaintGlue::setPathEffect},
|
||||
|
||||
@@ -5,6 +5,13 @@
|
||||
#include "SkShader.h"
|
||||
#include "SkBlendMode.h"
|
||||
#include "include/effects/SkRuntimeEffect.h"
|
||||
#include "shader/Shader.h"
|
||||
#include "shader/BitmapShader.h"
|
||||
#include "shader/ComposeShader.h"
|
||||
#include "shader/LinearGradientShader.h"
|
||||
#include "shader/RadialGradientShader.h"
|
||||
#include "shader/RuntimeShader.h"
|
||||
#include "shader/SweepGradientShader.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -50,7 +57,7 @@ static jint Color_HSVToColor(JNIEnv* env, jobject, jint alpha, jfloatArray hsvAr
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Shader_safeUnref(SkShader* shader) {
|
||||
static void Shader_safeUnref(Shader* shader) {
|
||||
SkSafeUnref(shader);
|
||||
}
|
||||
|
||||
@@ -74,15 +81,15 @@ static jlong BitmapShader_constructor(JNIEnv* env, jobject o, jlong matrixPtr, j
|
||||
SkBitmap bitmap;
|
||||
image = SkMakeImageFromRasterBitmap(bitmap, kNever_SkCopyPixelsMode);
|
||||
}
|
||||
sk_sp<SkShader> shader = image->makeShader(
|
||||
(SkTileMode)tileModeX, (SkTileMode)tileModeY);
|
||||
ThrowIAE_IfNull(env, shader.get());
|
||||
|
||||
if (matrix) {
|
||||
shader = shader->makeWithLocalMatrix(*matrix);
|
||||
}
|
||||
auto* shader = new BitmapShader(
|
||||
image,
|
||||
static_cast<SkTileMode>(tileModeX),
|
||||
static_cast<SkTileMode>(tileModeY),
|
||||
matrix
|
||||
);
|
||||
|
||||
return reinterpret_cast<jlong>(shader.release());
|
||||
return reinterpret_cast<jlong>(shader);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -118,17 +125,18 @@ static jlong LinearGradient_create(JNIEnv* env, jobject, jlong matrixPtr,
|
||||
#error Need to convert float array to SkScalar array before calling the following function.
|
||||
#endif
|
||||
|
||||
sk_sp<SkShader> shader(SkGradientShader::MakeLinear(pts, &colors[0],
|
||||
GraphicsJNI::getNativeColorSpace(colorSpaceHandle), pos, colors.size(),
|
||||
static_cast<SkTileMode>(tileMode), sGradientShaderFlags, nullptr));
|
||||
ThrowIAE_IfNull(env, shader);
|
||||
auto* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
auto* shader = new LinearGradientShader(
|
||||
pts,
|
||||
colors,
|
||||
GraphicsJNI::getNativeColorSpace(colorSpaceHandle),
|
||||
pos,
|
||||
static_cast<SkTileMode>(tileMode),
|
||||
sGradientShaderFlags,
|
||||
matrix
|
||||
);
|
||||
|
||||
const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
if (matrix) {
|
||||
shader = shader->makeWithLocalMatrix(*matrix);
|
||||
}
|
||||
|
||||
return reinterpret_cast<jlong>(shader.release());
|
||||
return reinterpret_cast<jlong>(shader);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -148,17 +156,20 @@ static jlong RadialGradient_create(JNIEnv* env, jobject, jlong matrixPtr, jfloat
|
||||
#error Need to convert float array to SkScalar array before calling the following function.
|
||||
#endif
|
||||
|
||||
sk_sp<SkShader> shader = SkGradientShader::MakeRadial(center, radius, &colors[0],
|
||||
GraphicsJNI::getNativeColorSpace(colorSpaceHandle), pos, colors.size(),
|
||||
static_cast<SkTileMode>(tileMode), sGradientShaderFlags, nullptr);
|
||||
ThrowIAE_IfNull(env, shader);
|
||||
auto* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
|
||||
const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
if (matrix) {
|
||||
shader = shader->makeWithLocalMatrix(*matrix);
|
||||
}
|
||||
auto* shader = new RadialGradientShader(
|
||||
center,
|
||||
radius,
|
||||
colors,
|
||||
GraphicsJNI::getNativeColorSpace(colorSpaceHandle),
|
||||
pos,
|
||||
static_cast<SkTileMode>(tileMode),
|
||||
sGradientShaderFlags,
|
||||
matrix
|
||||
);
|
||||
|
||||
return reinterpret_cast<jlong>(shader.release());
|
||||
return reinterpret_cast<jlong>(shader);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -174,54 +185,58 @@ static jlong SweepGradient_create(JNIEnv* env, jobject, jlong matrixPtr, jfloat
|
||||
#error Need to convert float array to SkScalar array before calling the following function.
|
||||
#endif
|
||||
|
||||
sk_sp<SkShader> shader = SkGradientShader::MakeSweep(x, y, &colors[0],
|
||||
GraphicsJNI::getNativeColorSpace(colorSpaceHandle), pos, colors.size(),
|
||||
sGradientShaderFlags, nullptr);
|
||||
ThrowIAE_IfNull(env, shader);
|
||||
auto* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
|
||||
const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
if (matrix) {
|
||||
shader = shader->makeWithLocalMatrix(*matrix);
|
||||
}
|
||||
auto* shader = new SweepGradientShader(
|
||||
x,
|
||||
y,
|
||||
colors,
|
||||
GraphicsJNI::getNativeColorSpace(colorSpaceHandle),
|
||||
pos,
|
||||
sGradientShaderFlags,
|
||||
matrix
|
||||
);
|
||||
|
||||
return reinterpret_cast<jlong>(shader.release());
|
||||
return reinterpret_cast<jlong>(shader);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static jlong ComposeShader_create(JNIEnv* env, jobject o, jlong matrixPtr,
|
||||
jlong shaderAHandle, jlong shaderBHandle, jint xfermodeHandle) {
|
||||
const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
SkShader* shaderA = reinterpret_cast<SkShader *>(shaderAHandle);
|
||||
SkShader* shaderB = reinterpret_cast<SkShader *>(shaderBHandle);
|
||||
SkBlendMode mode = static_cast<SkBlendMode>(xfermodeHandle);
|
||||
sk_sp<SkShader> baseShader(SkShaders::Blend(mode,
|
||||
sk_ref_sp(shaderA), sk_ref_sp(shaderB)));
|
||||
auto* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
auto* shaderA = reinterpret_cast<Shader*>(shaderAHandle);
|
||||
auto* shaderB = reinterpret_cast<Shader*>(shaderBHandle);
|
||||
|
||||
SkShader* shader;
|
||||
auto mode = static_cast<SkBlendMode>(xfermodeHandle);
|
||||
|
||||
if (matrix) {
|
||||
shader = baseShader->makeWithLocalMatrix(*matrix).release();
|
||||
} else {
|
||||
shader = baseShader.release();
|
||||
}
|
||||
return reinterpret_cast<jlong>(shader);
|
||||
auto* composeShader = new ComposeShader(
|
||||
*shaderA,
|
||||
*shaderB,
|
||||
mode,
|
||||
matrix
|
||||
);
|
||||
|
||||
return reinterpret_cast<jlong>(composeShader);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static jlong RuntimeShader_create(JNIEnv* env, jobject, jlong shaderFactory, jlong matrixPtr,
|
||||
jbyteArray inputs, jlong colorSpaceHandle, jboolean isOpaque) {
|
||||
SkRuntimeEffect* effect = reinterpret_cast<SkRuntimeEffect*>(shaderFactory);
|
||||
auto* effect = reinterpret_cast<SkRuntimeEffect*>(shaderFactory);
|
||||
AutoJavaByteArray arInputs(env, inputs);
|
||||
|
||||
sk_sp<SkData> fData;
|
||||
fData = SkData::MakeWithCopy(arInputs.ptr(), arInputs.length());
|
||||
const SkMatrix* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
sk_sp<SkShader> shader = effect->makeShader(fData, nullptr, 0, matrix, isOpaque == JNI_TRUE);
|
||||
ThrowIAE_IfNull(env, shader);
|
||||
auto data = SkData::MakeWithCopy(arInputs.ptr(), arInputs.length());
|
||||
auto* matrix = reinterpret_cast<const SkMatrix*>(matrixPtr);
|
||||
|
||||
return reinterpret_cast<jlong>(shader.release());
|
||||
auto* shader = new RuntimeShader(
|
||||
*effect,
|
||||
std::move(data),
|
||||
isOpaque == JNI_TRUE,
|
||||
matrix
|
||||
);
|
||||
return reinterpret_cast<jlong>(shader);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -239,12 +254,8 @@ static jlong RuntimeShader_createShaderFactory(JNIEnv* env, jobject, jstring sks
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void Effect_safeUnref(SkRuntimeEffect* effect) {
|
||||
SkSafeUnref(effect);
|
||||
}
|
||||
|
||||
static jlong RuntimeShader_getNativeFinalizer(JNIEnv*, jobject) {
|
||||
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Effect_safeUnref));
|
||||
return static_cast<jlong>(reinterpret_cast<uintptr_t>(&Shader_safeUnref));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -143,13 +143,13 @@ static void updateFullPathPropertiesAndStrokeStyles(JNIEnv*, jobject, jlong full
|
||||
|
||||
static void updateFullPathFillGradient(JNIEnv*, jobject, jlong pathPtr, jlong fillGradientPtr) {
|
||||
VectorDrawable::FullPath* path = reinterpret_cast<VectorDrawable::FullPath*>(pathPtr);
|
||||
SkShader* fillShader = reinterpret_cast<SkShader*>(fillGradientPtr);
|
||||
auto* fillShader = reinterpret_cast<Shader*>(fillGradientPtr);
|
||||
path->mutateStagingProperties()->setFillGradient(fillShader);
|
||||
}
|
||||
|
||||
static void updateFullPathStrokeGradient(JNIEnv*, jobject, jlong pathPtr, jlong strokeGradientPtr) {
|
||||
VectorDrawable::FullPath* path = reinterpret_cast<VectorDrawable::FullPath*>(pathPtr);
|
||||
SkShader* strokeShader = reinterpret_cast<SkShader*>(strokeGradientPtr);
|
||||
auto* strokeShader = reinterpret_cast<Shader*>(strokeGradientPtr);
|
||||
path->mutateStagingProperties()->setStrokeGradient(strokeShader);
|
||||
}
|
||||
|
||||
|
||||
31
libs/hwui/shader/BitmapShader.cpp
Normal file
31
libs/hwui/shader/BitmapShader.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "BitmapShader.h"
|
||||
|
||||
#include "SkImagePriv.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
BitmapShader::BitmapShader(const sk_sp<SkImage>& image, const SkTileMode tileModeX,
|
||||
const SkTileMode tileModeY, const SkMatrix* matrix)
|
||||
: Shader(matrix), skShader(image->makeShader(tileModeX, tileModeY)) {}
|
||||
|
||||
sk_sp<SkShader> BitmapShader::makeSkShader() {
|
||||
return skShader;
|
||||
}
|
||||
|
||||
BitmapShader::~BitmapShader() {}
|
||||
} // namespace android::uirenderer
|
||||
39
libs/hwui/shader/BitmapShader.h
Normal file
39
libs/hwui/shader/BitmapShader.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Shader.h"
|
||||
#include "SkShader.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
/**
|
||||
* Shader implementation that renders a Bitmap as either a SkShader or SkImageFilter
|
||||
*/
|
||||
class BitmapShader : public Shader {
|
||||
public:
|
||||
BitmapShader(const sk_sp<SkImage>& image, const SkTileMode tileModeX,
|
||||
const SkTileMode tileModeY, const SkMatrix* matrix);
|
||||
~BitmapShader() override;
|
||||
|
||||
protected:
|
||||
sk_sp<SkShader> makeSkShader() override;
|
||||
|
||||
private:
|
||||
sk_sp<SkShader> skShader;
|
||||
};
|
||||
} // namespace android::uirenderer
|
||||
51
libs/hwui/shader/ComposeShader.cpp
Normal file
51
libs/hwui/shader/ComposeShader.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ComposeShader.h"
|
||||
|
||||
#include "SkImageFilters.h"
|
||||
#include "SkShader.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
ComposeShader::ComposeShader(Shader& shaderA, Shader& shaderB, const SkBlendMode blendMode,
|
||||
const SkMatrix* matrix)
|
||||
: Shader(matrix) {
|
||||
// If both Shaders can be represented as SkShaders then use those, if not
|
||||
// create an SkImageFilter from both Shaders and create the equivalent SkImageFilter
|
||||
sk_sp<SkShader> skShaderA = shaderA.asSkShader();
|
||||
sk_sp<SkShader> skShaderB = shaderB.asSkShader();
|
||||
if (skShaderA.get() && skShaderB.get()) {
|
||||
skShader = SkShaders::Blend(blendMode, skShaderA, skShaderB);
|
||||
skImageFilter = nullptr;
|
||||
} else {
|
||||
sk_sp<SkImageFilter> skImageFilterA = shaderA.asSkImageFilter();
|
||||
sk_sp<SkImageFilter> skImageFilterB = shaderB.asSkImageFilter();
|
||||
skShader = nullptr;
|
||||
skImageFilter = SkImageFilters::Xfermode(blendMode, skImageFilterA, skImageFilterB);
|
||||
}
|
||||
}
|
||||
|
||||
sk_sp<SkShader> ComposeShader::makeSkShader() {
|
||||
return skShader;
|
||||
}
|
||||
|
||||
sk_sp<SkImageFilter> ComposeShader::makeSkImageFilter() {
|
||||
return skImageFilter;
|
||||
}
|
||||
|
||||
ComposeShader::~ComposeShader() {}
|
||||
} // namespace android::uirenderer
|
||||
43
libs/hwui/shader/ComposeShader.h
Normal file
43
libs/hwui/shader/ComposeShader.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Shader.h"
|
||||
#include "SkShader.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
/**
|
||||
* Shader implementation that can composite 2 Shaders together with the specified blend mode.
|
||||
* This implementation can appropriately convert the composed result to either an SkShader or
|
||||
* SkImageFilter depending on the inputs
|
||||
*/
|
||||
class ComposeShader : public Shader {
|
||||
public:
|
||||
ComposeShader(Shader& shaderA, Shader& shaderB, const SkBlendMode blendMode,
|
||||
const SkMatrix* matrix);
|
||||
~ComposeShader() override;
|
||||
|
||||
protected:
|
||||
sk_sp<SkShader> makeSkShader() override;
|
||||
sk_sp<SkImageFilter> makeSkImageFilter() override;
|
||||
|
||||
private:
|
||||
sk_sp<SkShader> skShader;
|
||||
sk_sp<SkImageFilter> skImageFilter;
|
||||
};
|
||||
} // namespace android::uirenderer
|
||||
39
libs/hwui/shader/LinearGradientShader.cpp
Normal file
39
libs/hwui/shader/LinearGradientShader.cpp
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "LinearGradientShader.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "SkGradientShader.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
LinearGradientShader::LinearGradientShader(const SkPoint pts[2],
|
||||
const std::vector<SkColor4f>& colors,
|
||||
sk_sp<SkColorSpace> colorspace, const SkScalar pos[],
|
||||
const SkTileMode tileMode, const uint32_t shaderFlags,
|
||||
const SkMatrix* matrix)
|
||||
: Shader(matrix)
|
||||
, skShader(SkGradientShader::MakeLinear(pts, colors.data(), colorspace, pos, colors.size(),
|
||||
tileMode, shaderFlags, nullptr)) {}
|
||||
|
||||
sk_sp<SkShader> LinearGradientShader::makeSkShader() {
|
||||
return skShader;
|
||||
}
|
||||
|
||||
LinearGradientShader::~LinearGradientShader() {}
|
||||
} // namespace android::uirenderer
|
||||
42
libs/hwui/shader/LinearGradientShader.h
Normal file
42
libs/hwui/shader/LinearGradientShader.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Shader.h"
|
||||
#include "SkShader.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
/**
|
||||
* Shader implementation that renders a color ramp of colors to either as either SkShader or
|
||||
* SkImageFilter
|
||||
*/
|
||||
class LinearGradientShader : public Shader {
|
||||
public:
|
||||
LinearGradientShader(const SkPoint pts[2], const std::vector<SkColor4f>& colors,
|
||||
sk_sp<SkColorSpace> colorspace, const SkScalar pos[],
|
||||
const SkTileMode tileMode, const uint32_t shaderFlags,
|
||||
const SkMatrix* matrix);
|
||||
~LinearGradientShader() override;
|
||||
|
||||
protected:
|
||||
sk_sp<SkShader> makeSkShader() override;
|
||||
|
||||
private:
|
||||
sk_sp<SkShader> skShader;
|
||||
};
|
||||
} // namespace android::uirenderer
|
||||
38
libs/hwui/shader/RadialGradientShader.cpp
Normal file
38
libs/hwui/shader/RadialGradientShader.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "RadialGradientShader.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "SkGradientShader.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
RadialGradientShader::RadialGradientShader(const SkPoint& center, const float radius,
|
||||
const std::vector<SkColor4f>& colors,
|
||||
sk_sp<SkColorSpace> colorspace, const SkScalar pos[],
|
||||
const SkTileMode tileMode, const uint32_t shaderFlags,
|
||||
const SkMatrix* matrix)
|
||||
: Shader(matrix)
|
||||
, skShader(SkGradientShader::MakeRadial(center, radius, colors.data(), colorspace, pos,
|
||||
colors.size(), tileMode, shaderFlags, nullptr)) {}
|
||||
|
||||
sk_sp<SkShader> RadialGradientShader::makeSkShader() {
|
||||
return skShader;
|
||||
}
|
||||
|
||||
RadialGradientShader::~RadialGradientShader() {}
|
||||
} // namespace android::uirenderer
|
||||
42
libs/hwui/shader/RadialGradientShader.h
Normal file
42
libs/hwui/shader/RadialGradientShader.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Shader.h"
|
||||
#include "SkShader.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
/**
|
||||
* Shader implementation that renders a color ramp from the center outward to either as either
|
||||
* a SkShader or SkImageFilter
|
||||
*/
|
||||
class RadialGradientShader : public Shader {
|
||||
public:
|
||||
RadialGradientShader(const SkPoint& center, const float radius,
|
||||
const std::vector<SkColor4f>& colors, sk_sp<SkColorSpace> colorSpace,
|
||||
const SkScalar pos[], const SkTileMode tileMode, const uint32_t shaderFlags,
|
||||
const SkMatrix* matrix);
|
||||
~RadialGradientShader() override;
|
||||
|
||||
protected:
|
||||
sk_sp<SkShader> makeSkShader() override;
|
||||
|
||||
private:
|
||||
sk_sp<SkShader> skShader;
|
||||
};
|
||||
} // namespace android::uirenderer
|
||||
36
libs/hwui/shader/RuntimeShader.cpp
Normal file
36
libs/hwui/shader/RuntimeShader.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "RuntimeShader.h"
|
||||
|
||||
#include "SkShader.h"
|
||||
#include "include/effects/SkRuntimeEffect.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
RuntimeShader::RuntimeShader(SkRuntimeEffect& effect, sk_sp<SkData> data, bool isOpaque,
|
||||
const SkMatrix* matrix)
|
||||
: Shader(nullptr)
|
||||
, // Explicitly passing null as RuntimeShader is created with the
|
||||
// matrix directly
|
||||
skShader(effect.makeShader(std::move(data), nullptr, 0, matrix, isOpaque)) {}
|
||||
|
||||
sk_sp<SkShader> RuntimeShader::makeSkShader() {
|
||||
return skShader;
|
||||
}
|
||||
|
||||
RuntimeShader::~RuntimeShader() {}
|
||||
} // namespace android::uirenderer
|
||||
40
libs/hwui/shader/RuntimeShader.h
Normal file
40
libs/hwui/shader/RuntimeShader.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Shader.h"
|
||||
#include "SkShader.h"
|
||||
#include "include/effects/SkRuntimeEffect.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
/**
|
||||
* RuntimeShader implementation that can map to either a SkShader or SkImageFilter
|
||||
*/
|
||||
class RuntimeShader : public Shader {
|
||||
public:
|
||||
RuntimeShader(SkRuntimeEffect& effect, sk_sp<SkData> data, bool isOpaque,
|
||||
const SkMatrix* matrix);
|
||||
~RuntimeShader() override;
|
||||
|
||||
protected:
|
||||
sk_sp<SkShader> makeSkShader() override;
|
||||
|
||||
private:
|
||||
sk_sp<SkShader> skShader;
|
||||
};
|
||||
} // namespace android::uirenderer
|
||||
87
libs/hwui/shader/Shader.cpp
Normal file
87
libs/hwui/shader/Shader.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "Shader.h"
|
||||
|
||||
#include "SkImageFilters.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
Shader::Shader(const SkMatrix* matrix)
|
||||
: localMatrix(matrix ? *matrix : SkMatrix::I())
|
||||
, skShader(nullptr)
|
||||
, skImageFilter(nullptr) {}
|
||||
|
||||
Shader::~Shader() {}
|
||||
|
||||
sk_sp<SkShader> Shader::asSkShader() {
|
||||
// If we already have created a shader with these parameters just return the existing
|
||||
// shader we have already created
|
||||
if (!this->skShader.get()) {
|
||||
this->skShader = makeSkShader();
|
||||
if (this->skShader.get()) {
|
||||
if (!localMatrix.isIdentity()) {
|
||||
this->skShader = this->skShader->makeWithLocalMatrix(localMatrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this->skShader;
|
||||
}
|
||||
|
||||
/**
|
||||
* By default return null as we cannot convert all visual effects to SkShader instances
|
||||
*/
|
||||
sk_sp<SkShader> Shader::makeSkShader() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<SkImageFilter> Shader::asSkImageFilter() {
|
||||
// If we already have created an ImageFilter with these parameters just return the existing
|
||||
// ImageFilter we have already created
|
||||
if (!this->skImageFilter.get()) {
|
||||
// Attempt to create an SkImageFilter from the current Shader implementation
|
||||
this->skImageFilter = makeSkImageFilter();
|
||||
if (this->skImageFilter) {
|
||||
if (!localMatrix.isIdentity()) {
|
||||
// If we have created an SkImageFilter and we have a transformation, wrap
|
||||
// the created SkImageFilter to apply the given matrix
|
||||
this->skImageFilter = SkImageFilters::MatrixTransform(
|
||||
localMatrix, kMedium_SkFilterQuality, this->skImageFilter);
|
||||
}
|
||||
} else {
|
||||
// Otherwise if no SkImageFilter implementation is provided, create one from
|
||||
// the result of asSkShader. Note the matrix is already applied to the shader in
|
||||
// this case so just convert it to an SkImageFilter using SkImageFilters::Paint
|
||||
SkPaint paint;
|
||||
paint.setShader(asSkShader());
|
||||
sk_sp<SkImageFilter> paintFilter = SkImageFilters::Paint(paint);
|
||||
this->skImageFilter = SkImageFilters::Xfermode(SkBlendMode::kDstIn,
|
||||
std::move(paintFilter));
|
||||
}
|
||||
}
|
||||
return this->skImageFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* By default return null for subclasses to implement. If there is not a direct SkImageFilter
|
||||
* conversion
|
||||
*/
|
||||
sk_sp<SkImageFilter> Shader::makeSkImageFilter() {
|
||||
return nullptr;
|
||||
}
|
||||
} // namespace android::uirenderer
|
||||
82
libs/hwui/shader/Shader.h
Normal file
82
libs/hwui/shader/Shader.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "SkImageFilter.h"
|
||||
#include "SkShader.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkRefCnt.h"
|
||||
|
||||
class SkMatrix;
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
/**
|
||||
* Shader class that can optionally wrap an SkShader or SkImageFilter depending
|
||||
* on the implementation
|
||||
*/
|
||||
class Shader: public SkRefCnt {
|
||||
public:
|
||||
/**
|
||||
* Creates a Shader instance with an optional transformation matrix
|
||||
* @param matrix Optional matrix to transform the underlying SkShader or SkImageFilter
|
||||
*/
|
||||
Shader(const SkMatrix* matrix);
|
||||
virtual ~Shader();
|
||||
|
||||
/**
|
||||
* Create an SkShader from the current Shader instance or return a previously
|
||||
* created instance. This can be null if no SkShader could be created from this
|
||||
* Shader instance.
|
||||
*/
|
||||
sk_sp<SkShader> asSkShader();
|
||||
|
||||
/**
|
||||
* Create an SkImageFilter from the current Shader instance or return a previously
|
||||
* created instance. Unlike asSkShader, this method cannot return null.
|
||||
*/
|
||||
sk_sp<SkImageFilter> asSkImageFilter();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Create a new SkShader instance based on this Shader instance
|
||||
*/
|
||||
virtual sk_sp<SkShader> makeSkShader();
|
||||
|
||||
/**
|
||||
* Create a new SkImageFilter instance based on this Shader instance. If no SkImageFilter
|
||||
* can be created then return nullptr
|
||||
*/
|
||||
virtual sk_sp<SkImageFilter> makeSkImageFilter();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Optional matrix transform
|
||||
*/
|
||||
const SkMatrix localMatrix;
|
||||
|
||||
/**
|
||||
* Cached SkShader instance to be returned on subsequent queries
|
||||
*/
|
||||
sk_sp<SkShader> skShader;
|
||||
|
||||
/**
|
||||
* Cached SkImageFilter instance to be returned on subsequent queries
|
||||
*/
|
||||
sk_sp<SkImageFilter> skImageFilter;
|
||||
};
|
||||
} // namespace android::uirenderer
|
||||
38
libs/hwui/shader/SweepGradientShader.cpp
Normal file
38
libs/hwui/shader/SweepGradientShader.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "SweepGradientShader.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "SkGradientShader.h"
|
||||
#include "SkImageFilters.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
SweepGradientShader::SweepGradientShader(float x, float y, const std::vector<SkColor4f>& colors,
|
||||
const sk_sp<SkColorSpace>& colorspace, const SkScalar pos[],
|
||||
const uint32_t shaderFlags, const SkMatrix* matrix)
|
||||
: Shader(matrix)
|
||||
, skShader(SkGradientShader::MakeSweep(x, y, colors.data(), colorspace, pos, colors.size(),
|
||||
shaderFlags, nullptr)) {}
|
||||
|
||||
sk_sp<SkShader> SweepGradientShader::makeSkShader() {
|
||||
return skShader;
|
||||
}
|
||||
|
||||
SweepGradientShader::~SweepGradientShader() {}
|
||||
} // namespace android::uirenderer
|
||||
41
libs/hwui/shader/SweepGradientShader.h
Normal file
41
libs/hwui/shader/SweepGradientShader.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2020 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Shader.h"
|
||||
#include "SkShader.h"
|
||||
|
||||
namespace android::uirenderer {
|
||||
|
||||
/**
|
||||
* Shader implementation that renders a color ramp clockwise such that the start and end colors
|
||||
* are visible at 3 o'clock. This handles converting to either an SkShader or SkImageFilter
|
||||
*/
|
||||
class SweepGradientShader : public Shader {
|
||||
public:
|
||||
SweepGradientShader(float x, float y, const std::vector<SkColor4f>& colors,
|
||||
const sk_sp<SkColorSpace>& colorspace, const SkScalar pos[],
|
||||
const uint32_t shaderFlags, const SkMatrix* matrix);
|
||||
virtual ~SweepGradientShader() override;
|
||||
|
||||
protected:
|
||||
virtual sk_sp<SkShader> makeSkShader() override;
|
||||
|
||||
private:
|
||||
sk_sp<SkShader> skShader;
|
||||
};
|
||||
} // namespace android::uirenderer
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "hwui/Paint.h"
|
||||
#include "TestSceneBase.h"
|
||||
#include "tests/common/BitmapAllocationTestUtils.h"
|
||||
#include <shader/BitmapShader.h>
|
||||
#include "utils/Color.h"
|
||||
|
||||
class BitmapShaders;
|
||||
@@ -45,15 +46,24 @@ public:
|
||||
});
|
||||
|
||||
Paint paint;
|
||||
sk_sp<BitmapShader> bitmapShader = sk_make_sp<BitmapShader>(
|
||||
hwuiBitmap->makeImage(),
|
||||
SkTileMode::kRepeat,
|
||||
SkTileMode::kRepeat,
|
||||
nullptr
|
||||
);
|
||||
|
||||
sk_sp<SkImage> image = hwuiBitmap->makeImage();
|
||||
sk_sp<SkShader> repeatShader =
|
||||
image->makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat);
|
||||
paint.setShader(std::move(repeatShader));
|
||||
paint.setShader(std::move(bitmapShader));
|
||||
canvas.drawRoundRect(0, 0, 500, 500, 50.0f, 50.0f, paint);
|
||||
|
||||
sk_sp<SkShader> mirrorShader =
|
||||
image->makeShader(SkTileMode::kMirror, SkTileMode::kMirror);
|
||||
paint.setShader(std::move(mirrorShader));
|
||||
sk_sp<BitmapShader> mirrorBitmapShader = sk_make_sp<BitmapShader>(
|
||||
image,
|
||||
SkTileMode::kMirror,
|
||||
SkTileMode::kMirror,
|
||||
nullptr
|
||||
);
|
||||
paint.setShader(std::move(mirrorBitmapShader));
|
||||
canvas.drawRoundRect(0, 600, 500, 1100, 50.0f, 50.0f, paint);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
#include <SkGradientShader.h>
|
||||
#include <SkImagePriv.h>
|
||||
#include <ui/PixelFormat.h>
|
||||
#include <shader/BitmapShader.h>
|
||||
#include <shader/LinearGradientShader.h>
|
||||
#include <shader/RadialGradientShader.h>
|
||||
#include <shader/ComposeShader.h>
|
||||
|
||||
class HwBitmapInCompositeShader;
|
||||
|
||||
@@ -50,20 +54,41 @@ public:
|
||||
pixels[4000 + 4 * i + 3] = 255;
|
||||
}
|
||||
buffer->unlock();
|
||||
sk_sp<Bitmap> hardwareBitmap(Bitmap::createFrom(buffer->toAHardwareBuffer(),
|
||||
SkColorSpace::MakeSRGB()));
|
||||
sk_sp<SkShader> hardwareShader(createBitmapShader(*hardwareBitmap));
|
||||
|
||||
sk_sp<BitmapShader> bitmapShader = sk_make_sp<BitmapShader>(
|
||||
Bitmap::createFrom(
|
||||
buffer->toAHardwareBuffer(),
|
||||
SkColorSpace::MakeSRGB()
|
||||
)->makeImage(),
|
||||
SkTileMode::kClamp,
|
||||
SkTileMode::kClamp,
|
||||
nullptr
|
||||
);
|
||||
|
||||
SkPoint center;
|
||||
center.set(50, 50);
|
||||
SkColor colors[2];
|
||||
colors[0] = Color::Black;
|
||||
colors[1] = Color::White;
|
||||
sk_sp<SkShader> gradientShader = SkGradientShader::MakeRadial(
|
||||
center, 50, colors, nullptr, 2, SkTileMode::kRepeat);
|
||||
|
||||
sk_sp<SkShader> compositeShader(
|
||||
SkShaders::Blend(SkBlendMode::kDstATop, hardwareShader, gradientShader));
|
||||
std::vector<SkColor4f> vColors(2);
|
||||
vColors[0] = SkColors::kBlack;
|
||||
vColors[1] = SkColors::kWhite;
|
||||
|
||||
sk_sp<RadialGradientShader> radialShader = sk_make_sp<RadialGradientShader>(
|
||||
center,
|
||||
50,
|
||||
vColors,
|
||||
SkColorSpace::MakeSRGB(),
|
||||
nullptr,
|
||||
SkTileMode::kRepeat,
|
||||
0,
|
||||
nullptr
|
||||
);
|
||||
|
||||
sk_sp<ComposeShader> compositeShader = sk_make_sp<ComposeShader>(
|
||||
*bitmapShader.get(),
|
||||
*radialShader.get(),
|
||||
SkBlendMode::kDstATop,
|
||||
nullptr
|
||||
);
|
||||
|
||||
Paint paint;
|
||||
paint.setShader(std::move(compositeShader));
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
#include "TestSceneBase.h"
|
||||
#include "tests/common/TestListViewSceneBase.h"
|
||||
#include "hwui/Paint.h"
|
||||
#include <SkGradientShader.h>
|
||||
#include "SkColor.h"
|
||||
#include <shader/LinearGradientShader.h>
|
||||
|
||||
class ListOfFadedTextAnimation;
|
||||
|
||||
@@ -42,15 +43,26 @@ class ListOfFadedTextAnimation : public TestListViewSceneBase {
|
||||
pts[0].set(0, 0);
|
||||
pts[1].set(0, 1);
|
||||
|
||||
SkColor colors[2] = {Color::Black, Color::Transparent};
|
||||
sk_sp<SkShader> s(
|
||||
SkGradientShader::MakeLinear(pts, colors, NULL, 2, SkTileMode::kClamp));
|
||||
|
||||
SkMatrix matrix;
|
||||
matrix.setScale(1, length);
|
||||
matrix.postRotate(-90);
|
||||
|
||||
std::vector<SkColor4f> vColors(2);
|
||||
vColors[0] = SkColors::kBlack;
|
||||
vColors[1] = SkColors::kTransparent;
|
||||
|
||||
sk_sp<LinearGradientShader> linearGradientShader = sk_make_sp<LinearGradientShader>(
|
||||
pts,
|
||||
vColors,
|
||||
SkColorSpace::MakeSRGB(),
|
||||
nullptr,
|
||||
SkTileMode::kClamp,
|
||||
0,
|
||||
&matrix
|
||||
);
|
||||
|
||||
Paint fadingPaint;
|
||||
fadingPaint.setShader(s->makeWithLocalMatrix(matrix));
|
||||
fadingPaint.setShader(linearGradientShader);
|
||||
fadingPaint.setBlendMode(SkBlendMode::kDstOut);
|
||||
canvas.drawRect(0, 0, length, itemHeight, fadingPaint);
|
||||
canvas.restore();
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
#include "TestSceneBase.h"
|
||||
|
||||
#include <SkColorMatrixFilter.h>
|
||||
#include <SkGradientShader.h>
|
||||
#include <shader/LinearGradientShader.h>
|
||||
|
||||
class SimpleColorMatrixAnimation;
|
||||
|
||||
@@ -65,9 +65,12 @@ private:
|
||||
// enough renderer might apply it directly to the paint color)
|
||||
float pos[] = {0, 1};
|
||||
SkPoint pts[] = {SkPoint::Make(0, 0), SkPoint::Make(width, height)};
|
||||
SkColor colors[2] = {Color::DeepPurple_500, Color::DeepOrange_500};
|
||||
paint.setShader(SkGradientShader::MakeLinear(pts, colors, pos, 2,
|
||||
SkTileMode::kClamp));
|
||||
std::vector<SkColor4f> colors(2);
|
||||
colors[0] = SkColor4f::FromColor(Color::DeepPurple_500);
|
||||
colors[1] = SkColor4f::FromColor(Color::DeepOrange_500);
|
||||
paint.setShader(sk_make_sp<LinearGradientShader>(
|
||||
pts, colors, SkColorSpace::MakeSRGB(), pos, SkTileMode::kClamp,
|
||||
0, nullptr));
|
||||
|
||||
// overdraw several times to emphasize shader cost
|
||||
for (int i = 0; i < 10; i++) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "TestSceneBase.h"
|
||||
|
||||
#include <SkGradientShader.h>
|
||||
#include <shader/LinearGradientShader.h>
|
||||
|
||||
class SimpleGradientAnimation;
|
||||
|
||||
@@ -55,9 +56,24 @@ private:
|
||||
// overdraw several times to emphasize shader cost
|
||||
for (int i = 0; i < 10; i++) {
|
||||
// use i%2 start position to pick 2 color combo with black in it
|
||||
SkColor colors[3] = {Color::Transparent, Color::Black, Color::Cyan_500};
|
||||
paint.setShader(SkGradientShader::MakeLinear(pts, colors + (i % 2), pos, 2,
|
||||
SkTileMode::kClamp));
|
||||
std::vector<SkColor4f> vColors(2);
|
||||
vColors[0] = ((i % 2) == 0) ?
|
||||
SkColor4f::FromColor(Color::Transparent) :
|
||||
SkColor4f::FromColor(Color::Black);
|
||||
vColors[1] = (((i + 1) % 2) == 0) ?
|
||||
SkColor4f::FromColor(Color::Black) :
|
||||
SkColor4f::FromColor(Color::Cyan_500);
|
||||
|
||||
sk_sp<LinearGradientShader> gradient = sk_make_sp<LinearGradientShader>(
|
||||
pts,
|
||||
vColors,
|
||||
SkColorSpace::MakeSRGB(),
|
||||
pos,
|
||||
SkTileMode::kClamp,
|
||||
0,
|
||||
nullptr
|
||||
);
|
||||
paint.setShader(gradient);
|
||||
canvas.drawRect(i, i, width, height, paint);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -17,9 +17,14 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "PathParser.h"
|
||||
#include "GraphicsJNI.h"
|
||||
#include "SkGradientShader.h"
|
||||
#include "SkShader.h"
|
||||
#include "VectorDrawable.h"
|
||||
#include "utils/MathUtils.h"
|
||||
#include "utils/VectorDrawableUtils.h"
|
||||
#include <shader/Shader.h>
|
||||
#include <shader/LinearGradientShader.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
@@ -395,7 +400,21 @@ TEST(VectorDrawable, drawPathWithoutIncrementingShaderRefCount) {
|
||||
bitmap.allocN32Pixels(5, 5, false);
|
||||
SkCanvas canvas(bitmap);
|
||||
|
||||
sk_sp<SkShader> shader = SkShaders::Color(SK_ColorBLACK);
|
||||
SkPoint pts[2];
|
||||
pts[0].set(0, 0);
|
||||
pts[1].set(0, 0);
|
||||
|
||||
std::vector<SkColor4f> colors(2);
|
||||
colors[0] = SkColors::kBlack;
|
||||
colors[1] = SkColors::kBlack;
|
||||
|
||||
sk_sp<LinearGradientShader> shader = sk_sp(new LinearGradientShader(pts,
|
||||
colors,
|
||||
SkColorSpace::MakeSRGB(),
|
||||
nullptr,
|
||||
SkTileMode::kClamp,
|
||||
SkGradientShader::kInterpolateColorsInPremul_Flag,
|
||||
nullptr));
|
||||
// Initial ref count is 1
|
||||
EXPECT_TRUE(shader->unique());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user