#include "SkImage.h"
#include "SkLinearBitmapPipeline.h"
#include "SkPM4f.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
struct CommonBitmapFPBenchmark : public Benchmark {
CommonBitmapFPBenchmark(
SkAutoTMalloc<SkPMColor> buffer4b(width*height);
SkArenaAlloc alloc{0};
- const SkShader::ContextRec rec(fPaint, fM, nullptr,
- SkShader::ContextRec::kPMColor_DstType,
- nullptr);
- SkShader::Context* ctx = fPaint.getShader()->makeContext(rec, &alloc);
+ const SkShaderBase::ContextRec rec(fPaint, fM, nullptr,
+ SkShaderBase::ContextRec::kPMColor_DstType,
+ nullptr);
+ SkShaderBase::Context* ctx = as_SB(fPaint.getShader())->makeContext(rec, &alloc);
int count = 100;
return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
}
-SkShader::Context* SkPerlinNoiseShader2::onMakeContext(const ContextRec& rec,
- SkArenaAlloc* alloc) const {
+SkShaderBase::Context* SkPerlinNoiseShader2::onMakeContext(const ContextRec& rec,
+ SkArenaAlloc* alloc) const {
return alloc->make<PerlinNoiseShaderContext>(*this, rec);
}
stitchTiles ? &tileSize : nullptr));
GrTest::TestAsFPArgs asFPArgs(d);
- return shader->asFragmentProcessor(asFPArgs.args());
+ return as_SB(shader)->asFragmentProcessor(asFPArgs.args());
}
#endif
z));
GrTest::TestAsFPArgs asFPArgs(d);
- return shader->asFragmentProcessor(asFPArgs.args());
+ return as_SB(shader)->asFragmentProcessor(asFPArgs.args());
}
#endif
#ifndef SkPerlinNoiseShader2_DEFINED
#define SkPerlinNoiseShader2_DEFINED
-#include "SkShader.h"
+#include "SkShaderBase.h"
/** \class SkPerlinNoiseShader2
The algorithm used is described here :
http://www.w3.org/TR/SVG/filters.html#feTurbulenceElement
*/
-class SK_API SkPerlinNoiseShader2 : public SkShader {
+class SK_API SkPerlinNoiseShader2 : public SkShaderBase {
public:
struct StitchData;
struct PaintingData;
return MakeTurbulence(baseFrequencyX, baseFrequencyY, numOctaves, seed, tileSize);
}
- class PerlinNoiseShaderContext : public SkShader::Context {
+ class PerlinNoiseShaderContext : public Context {
public:
PerlinNoiseShaderContext(const SkPerlinNoiseShader2& shader, const ContextRec&);
~PerlinNoiseShaderContext() override;
SkMatrix fMatrix;
PaintingData* fPaintingData;
- typedef SkShader::Context INHERITED;
+ typedef Context INHERITED;
};
#if SK_SUPPORT_GPU
const SkISize fTileSize;
const bool fStitchTiles;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
#endif
#include "SkLinearBitmapPipeline.h"
#include "SkXfermodePriv.h"
#include "SkPM4fPriv.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
static void fill_in_bits(SkBitmap& bm, SkIRect ir, SkColor c, bool premul) {
bm.allocN32Pixels(ir.width(), ir.height());
paint.setFilterQuality(SkFilterQuality::kNone_SkFilterQuality);
}
paint.setShader(std::move(shader));
- const SkShader::ContextRec rec(paint, *mat, nullptr,
- SkBlitter::PreferredShaderDest(pmsrc.info()),
- canvas->imageInfo().colorSpace());
+ const SkShaderBase::ContextRec rec(paint, *mat, nullptr,
+ SkBlitter::PreferredShaderDest(pmsrc.info()),
+ canvas->imageInfo().colorSpace());
- SkShader::Context* ctx = paint.getShader()->makeContext(rec, &alloc);
+ SkShaderBase::Context* ctx = as_SB(paint.getShader())->makeContext(rec, &alloc);
for (int y = 0; y < ir.height(); y++) {
ctx->shadeSpan(0, y, pmdst.writable_addr32(0, y), ir.width());
"$_src/core/SkScan_Path.cpp",
"$_src/core/SkSemaphore.cpp",
"$_src/core/SkShader.cpp",
+ "$_src/core/SkShaderBase.h",
"$_src/core/SkSharedMutex.cpp",
"$_src/core/SkSharedMutex.h",
"$_src/core/SkSinglyLinkedList.h",
kSkPathEffect_Type,
kSkPixelRef_Type,
kSkRasterizer_Type,
- kSkShader_Type,
+ kSkShaderBase_Type,
kSkUnused_Type, // used to be SkUnitMapper
kSkXfermode_Type,
kSkNormalSource_Type,
*/
class SK_API SkShader : public SkFlattenable {
public:
- SkShader(const SkMatrix* localMatrix = NULL);
- ~SkShader() override;
-
- /**
- * Returns the local matrix.
- *
- * FIXME: This can be incorrect for a Shader with its own local matrix
- * that is also wrapped via CreateLocalMatrixShader.
- */
- const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
-
enum TileMode {
/** replicate the edge color if the shader draws outside of its
* original bounds
kTileModeCount = kMirror_TileMode + 1
};
- // override these in your subclass
-
- enum Flags {
- //!< set if all of the colors will be opaque
- kOpaqueAlpha_Flag = 1 << 0,
-
- /** set if the spans only vary in X (const in Y).
- e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient
- that varies from left-to-right. This flag specifies this for
- shadeSpan().
- */
- kConstInY32_Flag = 1 << 1,
-
- /** hint for the blitter that 4f is the preferred shading mode.
- */
- kPrefers4f_Flag = 1 << 2,
- };
+ /**
+ * Returns the local matrix.
+ *
+ * FIXME: This can be incorrect for a Shader with its own local matrix
+ * that is also wrapped via CreateLocalMatrixShader.
+ */
+ const SkMatrix& getLocalMatrix() const;
/**
* Returns true if the shader is guaranteed to produce only opaque
*/
virtual bool isOpaque() const { return false; }
- /**
- * Returns true if the shader is guaranteed to produce only a single color.
- * Subclasses can override this to allow loop-hoisting optimization.
- */
- virtual bool isConstant() const { return false; }
-
- /**
- * ContextRec acts as a parameter bundle for creating Contexts.
- */
- struct ContextRec {
- enum DstType {
- kPMColor_DstType, // clients prefer shading into PMColor dest
- kPM4f_DstType, // clients prefer shading into PM4f dest
- };
-
- ContextRec(const SkPaint& paint, const SkMatrix& matrix, const SkMatrix* localM,
- DstType dstType, SkColorSpace* dstColorSpace)
- : fPaint(&paint)
- , fMatrix(&matrix)
- , fLocalMatrix(localM)
- , fPreferredDstType(dstType)
- , fDstColorSpace(dstColorSpace) {}
-
- const SkPaint* fPaint; // the current paint associated with the draw
- const SkMatrix* fMatrix; // the current matrix in the canvas
- const SkMatrix* fLocalMatrix; // optional local matrix
- const DstType fPreferredDstType; // the "natural" client dest type
- SkColorSpace* fDstColorSpace; // the color space of the dest surface (if any)
- };
-
- class Context : public ::SkNoncopyable {
- public:
- Context(const SkShader& shader, const ContextRec&);
-
- virtual ~Context();
-
- /**
- * Called sometimes before drawing with this shader. Return the type of
- * alpha your shader will return. The default implementation returns 0.
- * Your subclass should override if it can (even sometimes) report a
- * non-zero value, since that will enable various blitters to perform
- * faster.
- */
- virtual uint32_t getFlags() const { return 0; }
-
- /**
- * Called for each span of the object being drawn. Your subclass should
- * set the appropriate colors (with premultiplied alpha) that correspond
- * to the specified device coordinates.
- */
- virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
-
- virtual void shadeSpan4f(int x, int y, SkPM4f[], int count);
-
- struct BlitState;
- typedef void (*BlitBW)(BlitState*,
- int x, int y, const SkPixmap&, int count);
- typedef void (*BlitAA)(BlitState*,
- int x, int y, const SkPixmap&, int count, const SkAlpha[]);
-
- struct BlitState {
- // inputs
- Context* fCtx;
- SkBlendMode fMode;
-
- // outputs
- enum { N = 2 };
- void* fStorage[N];
- BlitBW fBlitBW;
- BlitAA fBlitAA;
- };
-
- // Returns true if one or more of the blitprocs are set in the BlitState
- bool chooseBlitProcs(const SkImageInfo& info, BlitState* state) {
- state->fBlitBW = nullptr;
- state->fBlitAA = nullptr;
- if (this->onChooseBlitProcs(info, state)) {
- SkASSERT(state->fBlitBW || state->fBlitAA);
- return true;
- }
- return false;
- }
-
- /**
- * The const void* ctx is only const because all the implementations are const.
- * This can be changed to non-const if a new shade proc needs to change the ctx.
- */
- typedef void (*ShadeProc)(const void* ctx, int x, int y, SkPMColor[], int count);
- virtual ShadeProc asAShadeProc(void** ctx);
-
- /**
- * Similar to shadeSpan, but only returns the alpha-channel for a span.
- * The default implementation calls shadeSpan() and then extracts the alpha
- * values from the returned colors.
- */
- virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
-
- // Notification from blitter::blitMask in case we need to see the non-alpha channels
- virtual void set3DMask(const SkMask*) {}
-
- protected:
- // Reference to shader, so we don't have to dupe information.
- const SkShader& fShader;
-
- enum MatrixClass {
- kLinear_MatrixClass, // no perspective
- kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each
- // scanline
- kPerspective_MatrixClass // slow perspective, need to mappoints each pixel
- };
- static MatrixClass ComputeMatrixClass(const SkMatrix&);
-
- uint8_t getPaintAlpha() const { return fPaintAlpha; }
- const SkMatrix& getTotalInverse() const { return fTotalInverse; }
- MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
- const SkMatrix& getCTM() const { return fCTM; }
-
- virtual bool onChooseBlitProcs(const SkImageInfo&, BlitState*) { return false; }
-
- private:
- SkMatrix fCTM;
- SkMatrix fTotalInverse;
- uint8_t fPaintAlpha;
- uint8_t fTotalInverseClass;
-
- typedef SkNoncopyable INHERITED;
- };
-
- /**
- * Make a context using the memory provided by the arena.
- *
- * @return pointer to context or nullptr if can't be created
- */
- Context* makeContext(const ContextRec&, SkArenaAlloc*) const;
-
#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
/**
* Returns true if this shader is just a bitmap, and if not null, returns the bitmap,
* localMatrix, and tilemodes. If this is not a bitmap, returns false and ignores the
* out-parameters.
*/
- bool isABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, TileMode xy[2]) const {
- return this->onIsABitmap(outTexture, outMatrix, xy);
- }
+ bool isABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, TileMode xy[2]) const;
bool isABitmap() const {
return this->isABitmap(nullptr, nullptr, nullptr);
* Iff this shader is backed by a single SkImage, return its ptr (the caller must ref this
* if they want to keep it longer than the lifetime of the shader). If not, return nullptr.
*/
- SkImage* isAImage(SkMatrix* localMatrix, TileMode xy[2]) const {
- return this->onIsAImage(localMatrix, xy);
- }
+ SkImage* isAImage(SkMatrix* localMatrix, TileMode xy[2]) const;
bool isAImage() const {
return this->isAImage(nullptr, nullptr) != nullptr;
virtual GradientType asAGradient(GradientInfo* info) const;
- /**
- * If the shader subclass is composed of two shaders, return true, and if rec is not NULL,
- * fill it out with info about the shader.
- *
- * These are bare pointers; the ownership and reference count are unchanged.
- */
-
- struct ComposeRec {
- const SkShader* fShaderA;
- const SkShader* fShaderB;
- SkBlendMode fBlendMode;
- };
-
- virtual bool asACompose(ComposeRec*) const { return false; }
-
-#if SK_SUPPORT_GPU
- struct AsFPArgs {
- AsFPArgs() {}
- AsFPArgs(GrContext* context,
- const SkMatrix* viewMatrix,
- const SkMatrix* localMatrix,
- SkFilterQuality filterQuality,
- SkColorSpace* dstColorSpace)
- : fContext(context)
- , fViewMatrix(viewMatrix)
- , fLocalMatrix(localMatrix)
- , fFilterQuality(filterQuality)
- , fDstColorSpace(dstColorSpace) {}
-
- GrContext* fContext;
- const SkMatrix* fViewMatrix;
- const SkMatrix* fLocalMatrix;
- SkFilterQuality fFilterQuality;
- SkColorSpace* fDstColorSpace;
- };
-
- /**
- * Returns a GrFragmentProcessor that implements the shader for the GPU backend. NULL is
- * returned if there is no GPU implementation.
- *
- * The GPU device does not call SkShader::createContext(), instead we pass the view matrix,
- * local matrix, and filter quality directly.
- *
- * The GrContext may be used by the to create textures that are required by the returned
- * processor.
- *
- * The returned GrFragmentProcessor should expect an unpremultiplied input color and
- * produce a premultiplied output.
- */
- virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const;
-#endif
-
- /**
- * If the shader can represent its "average" luminance in a single color, return true and
- * if color is not NULL, return that color. If it cannot, return false and ignore the color
- * parameter.
- *
- * Note: if this returns true, the returned color will always be opaque, as only the RGB
- * components are used to compute luminance.
- */
- bool asLuminanceColor(SkColor*) const;
-
//////////////////////////////////////////////////////////////////////////
// Methods to create combinations or variants of shaders
static sk_sp<SkShader> MakePictureShader(sk_sp<SkPicture> src, TileMode tmx, TileMode tmy,
const SkMatrix* localMatrix, const SkRect* tile);
- /**
- * If this shader can be represented by another shader + a localMatrix, return that shader and
- * the localMatrix. If not, return nullptr and ignore the localMatrix parameter.
- */
- virtual sk_sp<SkShader> makeAsALocalMatrixShader(SkMatrix* localMatrix) const;
-
- SK_TO_STRING_VIRT()
- SK_DEFINE_FLATTENABLE_TYPE(SkShader)
- SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
-
- bool appendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
- const SkMatrix& ctm, const SkPaint&, const SkMatrix* localM=nullptr) const;
-
protected:
- void flatten(SkWriteBuffer&) const override;
-
- bool computeTotalInverse(const SkMatrix& ctm,
- const SkMatrix* outerLocalMatrix,
- SkMatrix* totalInverse) const;
-
- /**
- * Specialize creating a SkShader context using the supplied allocator.
- * @return pointer to context owned by the arena allocator.
- */
- virtual Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const {
- return nullptr;
- }
-
- virtual bool onAsLuminanceColor(SkColor*) const {
- return false;
- }
-
-#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
- virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const {
- return false;
- }
-#endif
-
- virtual SkImage* onIsAImage(SkMatrix*, TileMode[2]) const {
- return nullptr;
- }
-
- /**
- * Returns a shader transformed into a new color space via the |xformer|.
- */
- sk_sp<SkShader> makeColorSpace(SkColorSpaceXformer* xformer) const {
- return this->onMakeColorSpace(xformer);
- }
- virtual sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer*) const {
- return sk_ref_sp(const_cast<SkShader*>(this));
- }
-
- virtual bool isRasterPipelineOnly() const { return false; }
+ SkShader() = default;
private:
- virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
- const SkMatrix&, const SkPaint&, const SkMatrix* localM) const;
-
- // This is essentially const, but not officially so it can be modified in constructors.
- SkMatrix fLocalMatrix;
-
- friend class SkLocalMatrixShader; // sets fLocalMatrix in SkReadBuffer constructor
- friend class SkBitmapProcLegacyShader; // calls computeTotalInverse()
- friend class SkColorSpaceXformer; // calls makeColorSpace()
- friend class SkBlitter; // calls isRasterPipelineOnly()
- friend class SkComposeShader; // calls isRasterPipelineOnly()
-
typedef SkFlattenable INHERITED;
};
return (matrix.getType() & ~mask) == 0;
}
-class BitmapProcInfoContext : public SkShader::Context {
+class BitmapProcInfoContext : public SkShaderBase::Context {
public:
// The info has been allocated elsewhere, but we are responsible for calling its destructor.
- BitmapProcInfoContext(const SkShader& shader, const SkShader::ContextRec& rec,
+ BitmapProcInfoContext(const SkShaderBase& shader, const SkShaderBase::ContextRec& rec,
SkBitmapProcInfo* info)
: INHERITED(shader, rec)
, fInfo(info)
{
fFlags = 0;
if (fInfo->fPixmap.isOpaque() && (255 == this->getPaintAlpha())) {
- fFlags |= SkShader::kOpaqueAlpha_Flag;
+ fFlags |= SkShaderBase::kOpaqueAlpha_Flag;
}
if (1 == fInfo->fPixmap.height() && only_scale_and_translate(this->getTotalInverse())) {
- fFlags |= SkShader::kConstInY32_Flag;
+ fFlags |= SkShaderBase::kConstInY32_Flag;
}
}
SkBitmapProcInfo* fInfo;
uint32_t fFlags;
- typedef SkShader::Context INHERITED;
+ typedef SkShaderBase::Context INHERITED;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
class BitmapProcShaderContext : public BitmapProcInfoContext {
public:
- BitmapProcShaderContext(const SkShader& shader, const SkShader::ContextRec& rec,
+ BitmapProcShaderContext(const SkShaderBase& shader, const SkShaderBase::ContextRec& rec,
SkBitmapProcState* state)
: INHERITED(shader, rec, state)
, fState(state)
class LinearPipelineContext : public BitmapProcInfoContext {
public:
- LinearPipelineContext(const SkShader& shader, const SkShader::ContextRec& rec,
+ LinearPipelineContext(const SkShaderBase& shader, const SkShaderBase::ContextRec& rec,
SkBitmapProcInfo* info, SkArenaAlloc* alloc)
: INHERITED(shader, rec, info), fAllocator{alloc}
{
///////////////////////////////////////////////////////////////////////////////////////////////////
-static bool choose_linear_pipeline(const SkShader::ContextRec& rec, const SkImageInfo& srcInfo) {
+static bool choose_linear_pipeline(const SkShaderBase::ContextRec& rec, const SkImageInfo& srcInfo) {
// If we get here, we can reasonably use either context, respect the caller's preference
//
bool needsPremul = srcInfo.alphaType() == kUnpremul_SkAlphaType;
bool needsSwizzle = srcInfo.bytesPerPixel() == 4 && srcInfo.colorType() != kN32_SkColorType;
- return SkShader::ContextRec::kPM4f_DstType == rec.fPreferredDstType
+ return SkShaderBase::ContextRec::kPM4f_DstType == rec.fPreferredDstType
|| needsPremul || needsSwizzle;
}
return s;
}
-SkShader::Context* SkBitmapProcLegacyShader::MakeContext(
- const SkShader& shader, TileMode tmx, TileMode tmy,
+SkShaderBase::Context* SkBitmapProcLegacyShader::MakeContext(
+ const SkShaderBase& shader, TileMode tmx, TileMode tmy,
const SkBitmapProvider& provider, const ContextRec& rec, SkArenaAlloc* alloc)
{
SkMatrix totalInverse;
#define SkBitmapProcShader_DEFINED
#include "SkImagePriv.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
class SkBitmapProvider;
-class SkBitmapProcLegacyShader : public SkShader {
+class SkBitmapProcLegacyShader : public SkShaderBase {
private:
friend class SkImageShader;
static size_t ContextSize(const ContextRec&, const SkImageInfo& srcInfo);
- static Context* MakeContext(const SkShader&, TileMode tmx, TileMode tmy,
+ static Context* MakeContext(const SkShaderBase&, TileMode tmx, TileMode tmy,
const SkBitmapProvider&, const ContextRec&, SkArenaAlloc* alloc);
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
#endif
#include "SkWriteBuffer.h"
#include "SkMask.h"
#include "SkMaskFilter.h"
+#include "SkShaderBase.h"
#include "SkString.h"
#include "SkTLazy.h"
#include "SkUtils.h"
#include "SkColorShader.h"
#include "SkColorPriv.h"
-class Sk3DShader : public SkShader {
+class Sk3DShader : public SkShaderBase {
public:
Sk3DShader(sk_sp<SkShader> proxy) : fProxy(std::move(proxy)) {}
Context* onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const override {
- SkShader::Context* proxyContext = nullptr;
+ SkShaderBase::Context* proxyContext = nullptr;
if (fProxy) {
- proxyContext = fProxy->makeContext(rec, alloc);
+ proxyContext = as_SB(fProxy)->makeContext(rec, alloc);
if (!proxyContext) {
return nullptr;
}
return alloc->make<Sk3DShaderContext>(*this, rec, proxyContext);
}
- class Sk3DShaderContext : public SkShader::Context {
+ class Sk3DShaderContext : public Context {
public:
// Calls proxyContext's destructor but will NOT free its memory.
Sk3DShaderContext(const Sk3DShader& shader, const ContextRec& rec,
- SkShader::Context* proxyContext)
+ Context* proxyContext)
: INHERITED(shader, rec)
, fMask(nullptr)
, fProxyContext(proxyContext)
private:
// Unowned.
- const SkMask* fMask;
+ const SkMask* fMask;
// Memory is unowned, but we need to call the destructor.
- SkShader::Context* fProxyContext;
- SkPMColor fPMColor;
+ Context* fProxyContext;
+ SkPMColor fPMColor;
- typedef SkShader::Context INHERITED;
+ typedef Context INHERITED;
};
#ifndef SK_IGNORE_TO_STRING
if (fProxy) {
str->append("Proxy: ");
- fProxy->toString(str);
+ as_SB(fProxy)->toString(str);
}
this->INHERITED::toString(str);
private:
sk_sp<SkShader> fProxy;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
sk_sp<SkFlattenable> Sk3DShader::CreateProc(SkReadBuffer& buffer) {
class Sk3DBlitter : public SkBlitter {
public:
- Sk3DBlitter(SkBlitter* proxy, SkShader::Context* shaderContext)
+ Sk3DBlitter(SkBlitter* proxy, SkShaderBase::Context* shaderContext)
: fProxy(proxy)
, fShaderContext(shaderContext)
{}
private:
// Both pointers are unowned. They will be deleted by SkSmallAllocator.
- SkBlitter* fProxy;
- SkShader::Context* fShaderContext;
+ SkBlitter* fProxy;
+ SkShaderBase::Context* fShaderContext;
};
///////////////////////////////////////////////////////////////////////////////
#include "SkCoreBlitters.h"
-SkShader::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) {
+SkShaderBase::ContextRec::DstType SkBlitter::PreferredShaderDest(const SkImageInfo& dstInfo) {
#ifdef SK_FORCE_PM4f_FOR_L32_BLITS
return SkShader::ContextRec::kPM4f_DstType;
#else
return (dstInfo.gammaCloseToSRGB() || dstInfo.colorType() == kRGBA_F16_SkColorType)
- ? SkShader::ContextRec::kPM4f_DstType
- : SkShader::ContextRec::kPMColor_DstType;
+ ? SkShaderBase::ContextRec::kPM4f_DstType
+ : SkShaderBase::ContextRec::kPMColor_DstType;
#endif
}
}
// ... unless the shader is raster pipeline-only.
- if (paint.getShader() && paint.getShader()->isRasterPipelineOnly()) {
+ if (paint.getShader() && as_SB(paint.getShader())->isRasterPipelineOnly()) {
return true;
}
return alloc->make<SkNullBlitter>();
}
- SkShader* shader = origPaint.getShader();
+ auto* shader = as_SB(origPaint.getShader());
SkColorFilter* cf = origPaint.getColorFilter();
SkBlendMode mode = origPaint.getBlendMode();
sk_sp<Sk3DShader> shader3D;
shader3D = sk_make_sp<Sk3DShader>(sk_ref_sp(shader));
// we know we haven't initialized lazyPaint yet, so just do it
paint.writable()->setShader(shader3D);
- shader = shader3D.get();
+ shader = as_SB(shader3D.get());
}
if (mode != SkBlendMode::kSrcOver) {
// xfermodes (and filters) require shaders for our current blitters
paint.writable()->setShader(SkShader::MakeColorShader(paint->getColor()));
paint.writable()->setAlpha(0xFF);
- shader = paint->getShader();
+ shader = as_SB(paint->getShader());
} else if (cf) {
// if no shader && no xfermode, we just apply the colorfilter to
// our color and move on.
if (cf) {
SkASSERT(shader);
paint.writable()->setShader(shader->makeWithColorFilter(sk_ref_sp(cf)));
- shader = paint->getShader();
+ shader = as_SB(paint->getShader());
// blitters should ignore the presence/absence of a filter, since
// if there is one, the shader will take care of it.
}
/*
* We create a SkShader::Context object, and store it on the blitter.
*/
- SkShader::Context* shaderContext = nullptr;
+ SkShaderBase::Context* shaderContext = nullptr;
if (shader) {
- const SkShader::ContextRec rec(*paint, matrix, nullptr,
+ const SkShaderBase::ContextRec rec(*paint, matrix, nullptr,
PreferredShaderDest(device.info()),
device.colorSpace());
// Try to create the ShaderContext
///////////////////////////////////////////////////////////////////////////////
SkShaderBlitter::SkShaderBlitter(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext)
+ SkShaderBase::Context* shaderContext)
: INHERITED(device)
, fShader(paint.getShader())
, fShaderContext(shaderContext) {
fShader->ref();
fShaderFlags = fShaderContext->getFlags();
- fConstInY = SkToBool(fShaderFlags & SkShader::kConstInY32_Flag);
+ fConstInY = SkToBool(fShaderFlags & SkShaderBase::kConstInY32_Flag);
}
SkShaderBlitter::~SkShaderBlitter() {
#include "SkColor.h"
#include "SkRect.h"
#include "SkRegion.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
class SkArenaAlloc;
class SkMatrix;
SkArenaAlloc*);
///@}
- static SkShader::ContextRec::DstType PreferredShaderDest(const SkImageInfo&);
+ static SkShaderBase::ContextRec::DstType PreferredShaderDest(const SkImageInfo&);
static bool UseRasterPipelineBlitter(const SkPixmap&, const SkPaint&);
///////////////////////////////////////////////////////////////////////
SkA8_Shader_Blitter::SkA8_Shader_Blitter(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext)
+ SkShaderBase::Context* shaderContext)
: INHERITED(device, paint, shaderContext)
{
fXfermode = SkXfermode::Peek(paint.getBlendMode());
(unsigned)(x + width) <= (unsigned)fDevice.width());
uint8_t* device = fDevice.writable_addr8(x, y);
- SkShader::Context* shaderContext = fShaderContext;
+ auto* shaderContext = fShaderContext;
- if ((shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) && !fXfermode) {
+ if ((shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag) && !fXfermode) {
memset(device, 0xFF, width);
} else {
SkPMColor* span = fBuffer;
void SkA8_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
const int16_t runs[]) {
- SkShader::Context* shaderContext = fShaderContext;
+ auto* shaderContext = fShaderContext;
SkXfermode* mode = fXfermode;
uint8_t* aaExpand = fAAExpand;
SkPMColor* span = fBuffer;
uint8_t* device = fDevice.writable_addr8(x, y);
- int opaque = shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag;
+ int opaque = shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag;
for (;;) {
int count = *runs;
int height = clip.height();
uint8_t* device = fDevice.writable_addr8(x, y);
const uint8_t* alpha = mask.getAddr8(x, y);
- SkShader::Context* shaderContext = fShaderContext;
+ auto* shaderContext = fShaderContext;
SkPMColor* span = fBuffer;
}
SkARGB32_Shader_Blitter::SkARGB32_Shader_Blitter(const SkPixmap& device,
- const SkPaint& paint, SkShader::Context* shaderContext)
+ const SkPaint& paint, SkShaderBase::Context* shaderContext)
: INHERITED(device, paint, shaderContext)
{
fBuffer = (SkPMColor*)sk_malloc_throw(device.width() * (sizeof(SkPMColor)));
fXfermode = SkXfermode::Peek(paint.getBlendMode());
int flags = 0;
- if (!(shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
+ if (!(shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag)) {
flags |= SkBlitRow::kSrcPixelAlpha_Flag32;
}
// we call this on the output from the shader
fShadeDirectlyIntoDevice = false;
if (fXfermode == nullptr) {
- if (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) {
+ if (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag) {
fShadeDirectlyIntoDevice = true;
}
} else {
}
}
- fConstInY = SkToBool(shaderContext->getFlags() & SkShader::kConstInY32_Flag);
+ fConstInY = SkToBool(shaderContext->getFlags() & SkShaderBase::kConstInY32_Flag);
}
SkARGB32_Shader_Blitter::~SkARGB32_Shader_Blitter() {
SkASSERT(x >= 0 && y >= 0 &&
x + width <= fDevice.width() && y + height <= fDevice.height());
- uint32_t* device = fDevice.writable_addr32(x, y);
- size_t deviceRB = fDevice.rowBytes();
- SkShader::Context* shaderContext = fShaderContext;
- SkPMColor* span = fBuffer;
+ uint32_t* device = fDevice.writable_addr32(x, y);
+ size_t deviceRB = fDevice.rowBytes();
+ auto* shaderContext = fShaderContext;
+ SkPMColor* span = fBuffer;
if (fConstInY) {
if (fShadeDirectlyIntoDevice) {
if (fShadeDirectlyIntoDevice) {
void* ctx;
- SkShader::Context::ShadeProc shadeProc = shaderContext->asAShadeProc(&ctx);
+ auto shadeProc = shaderContext->asAShadeProc(&ctx);
if (shadeProc) {
do {
shadeProc(ctx, x, y, device, width);
void SkARGB32_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
const int16_t runs[]) {
- SkPMColor* span = fBuffer;
- uint32_t* device = fDevice.writable_addr32(x, y);
- SkShader::Context* shaderContext = fShaderContext;
+ SkPMColor* span = fBuffer;
+ uint32_t* device = fDevice.writable_addr32(x, y);
+ auto* shaderContext = fShaderContext;
if (fXfermode && !fShadeDirectlyIntoDevice) {
for (;;) {
x += count;
}
} else if (fShadeDirectlyIntoDevice ||
- (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag)) {
+ (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag)) {
for (;;) {
int count = *runs;
if (count <= 0) {
SkASSERT(mask.fBounds.contains(clip));
- SkShader::Context* shaderContext = fShaderContext;
+ auto* shaderContext = fShaderContext;
SkBlitMask::RowProc proc = nullptr;
if (!fXfermode) {
unsigned flags = 0;
- if (shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) {
+ if (shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag) {
flags |= SkBlitMask::kSrcIsOpaque_RowFlag;
}
proc = SkBlitMask::RowFactory(kN32_SkColorType, mask.fFormat,
void SkARGB32_Shader_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
SkASSERT(x >= 0 && y >= 0 && y + height <= fDevice.height());
- uint32_t* device = fDevice.writable_addr32(x, y);
- size_t deviceRB = fDevice.rowBytes();
- SkShader::Context* shaderContext = fShaderContext;
+ uint32_t* device = fDevice.writable_addr32(x, y);
+ size_t deviceRB = fDevice.rowBytes();
+ auto* shaderContext = fShaderContext;
if (fConstInY) {
SkPMColor c;
if (fShadeDirectlyIntoDevice) {
void* ctx;
- SkShader::Context::ShadeProc shadeProc = shaderContext->asAShadeProc(&ctx);
+ auto shadeProc = shaderContext->asAShadeProc(&ctx);
if (255 == alpha) {
if (shadeProc) {
do {
template <typename State> class SkState_Shader_Blitter : public SkShaderBlitter {
public:
SkState_Shader_Blitter(const SkPixmap& device, const SkPaint& paint,
- const SkShader::Context::BlitState& bstate)
+ const SkShaderBase::Context::BlitState& bstate)
: INHERITED(device, paint, bstate.fCtx)
, fState(device.info(), paint, bstate.fCtx)
, fBState(bstate)
}
protected:
- State fState;
- SkShader::Context::BlitState fBState;
- SkShader::Context::BlitBW fBlitBW;
- SkShader::Context::BlitAA fBlitAA;
+ State fState;
+ SkShaderBase::Context::BlitState fBState;
+ SkShaderBase::Context::BlitBW fBlitBW;
+ SkShaderBase::Context::BlitAA fBlitAA;
typedef SkShaderBlitter INHERITED;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
-static bool is_opaque(const SkPaint& paint, const SkShader::Context* shaderContext) {
- return shaderContext ? SkToBool(shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag)
+static bool is_opaque(const SkPaint& paint, const SkShaderBase::Context* shaderContext) {
+ return shaderContext ? SkToBool(shaderContext->getFlags() & SkShaderBase::kOpaqueAlpha_Flag)
: 0xFF == paint.getAlpha();
}
struct State4f {
- State4f(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext) {
+ State4f(const SkImageInfo& info, const SkPaint& paint,
+ const SkShaderBase::Context* shaderContext) {
fMode = paint.getBlendMode();
if (shaderContext) {
fBuffer.reset(info.width());
fFlags = 0;
}
- SkPM4f fPM4f;
- SkAutoTMalloc<SkPM4f> fBuffer;
- uint32_t fFlags;
- SkBlendMode fMode;
-
- SkShader::Context::BlitState fBState;
+ SkPM4f fPM4f;
+ SkAutoTMalloc<SkPM4f> fBuffer;
+ uint32_t fFlags;
+ SkBlendMode fMode;
+ SkShaderBase::Context::BlitState fBState;
};
struct State32 : State4f {
SkXfermode::D32Proc fProc1;
SkXfermode::D32Proc fProcN;
- State32(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext)
+ State32(const SkImageInfo& info, const SkPaint& paint,
+ const SkShaderBase::Context* shaderContext)
: State4f(info, paint, shaderContext)
{
if (is_opaque(paint, shaderContext)) {
SkXfermode::F16Proc fProc1;
SkXfermode::F16Proc fProcN;
- StateF16(const SkImageInfo& info, const SkPaint& paint, const SkShader::Context* shaderContext)
+ StateF16(const SkImageInfo& info, const SkPaint& paint,
+ const SkShaderBase::Context* shaderContext)
: State4f(info, paint, shaderContext)
{
if (is_opaque(paint, shaderContext)) {
};
template <typename State> SkBlitter* create(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext,
+ SkShaderBase::Context* shaderContext,
SkArenaAlloc* alloc) {
SkASSERT(alloc != nullptr);
if (shaderContext) {
- SkShader::Context::BlitState bstate;
+ SkShaderBase::Context::BlitState bstate;
sk_bzero(&bstate, sizeof(bstate));
bstate.fCtx = shaderContext;
bstate.fMode = paint.getBlendMode();
}
SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext,
+ SkShaderBase::Context* shaderContext,
SkArenaAlloc* alloc) {
return create<State32>(device, paint, shaderContext, alloc);
}
SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext,
+ SkShaderBase::Context* shaderContext,
SkArenaAlloc* alloc) {
return create<StateF16>(device, paint, shaderContext, alloc);
}
class SkRGB16_Shader_Blitter : public SkShaderBlitter {
public:
SkRGB16_Shader_Blitter(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext);
+ SkShaderBase::Context* shaderContext);
~SkRGB16_Shader_Blitter() override;
void blitH(int x, int y, int width) override;
virtual void blitAntiH(int x, int y, const SkAlpha* antialias,
class SkRGB16_Shader_Xfermode_Blitter : public SkShaderBlitter {
public:
SkRGB16_Shader_Xfermode_Blitter(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext);
+ SkShaderBase::Context* shaderContext);
~SkRGB16_Shader_Xfermode_Blitter() override;
void blitH(int x, int y, int width) override;
virtual void blitAntiH(int x, int y, const SkAlpha* antialias,
SkRGB16_Shader_Blitter::SkRGB16_Shader_Blitter(const SkPixmap& device,
const SkPaint& paint,
- SkShader::Context* shaderContext)
+ SkShaderBase::Context* shaderContext)
: INHERITED(device, paint, shaderContext)
{
SkASSERT(paint.isSrcOver());
uint32_t shaderFlags = fShaderFlags;
// shaders take care of global alpha, so we never set it in SkBlitRow
- if (!(shaderFlags & SkShader::kOpaqueAlpha_Flag)) {
+ if (!(shaderFlags & SkShaderBase::kOpaqueAlpha_Flag)) {
flags |= SkBlitRow::kSrcPixelAlpha_Flag;
}
if (paint.isDither()) {
}
void SkRGB16_Shader_Blitter::blitRect(int x, int y, int width, int height) {
- SkShader::Context* shaderContext = fShaderContext;
+ auto* shaderContext = fShaderContext;
SkBlitRow::Proc16 proc = fOpaqueProc;
SkPMColor* buffer = fBuffer;
uint16_t* dst = fDevice.writable_addr16(x, y);
size_t dstRB = fDevice.rowBytes();
- if (fShaderFlags & SkShader::kConstInY32_Flag) {
+ if (fShaderFlags & SkShaderBase::kConstInY32_Flag) {
shaderContext->shadeSpan(x, y, buffer, width);
do {
proc(dst, buffer, width, 0xFF, x, y);
void SkRGB16_Shader_Blitter::blitAntiH(int x, int y,
const SkAlpha* SK_RESTRICT antialias,
const int16_t* SK_RESTRICT runs) {
- SkShader::Context* shaderContext = fShaderContext;
+ auto* shaderContext = fShaderContext;
SkPMColor* SK_RESTRICT span = fBuffer;
uint16_t* SK_RESTRICT device = fDevice.writable_addr16(x, y);
SkRGB16_Shader_Xfermode_Blitter::SkRGB16_Shader_Xfermode_Blitter(
const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext)
+ SkShaderBase::Context* shaderContext)
: INHERITED(device, paint, shaderContext)
{
fXfermode = SkXfermode::Peek(paint.getBlendMode());
void SkRGB16_Shader_Xfermode_Blitter::blitAntiH(int x, int y,
const SkAlpha* SK_RESTRICT antialias,
const int16_t* SK_RESTRICT runs) {
- SkShader::Context* shaderContext = fShaderContext;
+ auto* shaderContext = fShaderContext;
SkXfermode* mode = fXfermode;
SkPMColor* SK_RESTRICT span = fBuffer;
uint8_t* SK_RESTRICT aaExpand = fAAExpand;
///////////////////////////////////////////////////////////////////////////////
SkBlitter* SkBlitter_ChooseD565(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext,
+ SkShaderBase::Context* shaderContext,
SkArenaAlloc* alloc) {
SkASSERT(alloc != nullptr);
// in the shader flags.
//
if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) {
- shaderF &= ~SkShader::kOpaqueAlpha_Flag;
+ shaderF &= ~kOpaqueAlpha_Flag;
}
return shaderF;
}
-SkShader::Context* SkColorFilterShader::onMakeContext(const ContextRec& rec,
- SkArenaAlloc* alloc) const {
- SkShader::Context* shaderContext = fShader->makeContext(rec, alloc);
+SkShaderBase::Context* SkColorFilterShader::onMakeContext(const ContextRec& rec,
+ SkArenaAlloc* alloc) const {
+ auto* shaderContext = as_SB(fShader)->makeContext(rec, alloc);
if (nullptr == shaderContext) {
return nullptr;
}
SkColorFilterShader::FilterShaderContext::FilterShaderContext(
const SkColorFilterShader& filterShader,
- SkShader::Context* shaderContext,
+ SkShaderBase::Context* shaderContext,
const ContextRec& rec)
: INHERITED(filterShader, rec)
, fShaderContext(shaderContext)
sk_sp<GrFragmentProcessor> SkColorFilterShader::asFragmentProcessor(const AsFPArgs& args) const {
- sk_sp<GrFragmentProcessor> fp1(fShader->asFragmentProcessor(args));
+ sk_sp<GrFragmentProcessor> fp1(as_SB(fShader)->asFragmentProcessor(args));
if (!fp1) {
return nullptr;
}
str->append("SkColorFilterShader: (");
str->append("Shader: ");
- fShader->toString(str);
+ as_SB(fShader)->toString(str);
str->append(" Filter: ");
// TODO: add "fFilter->toString(str);" once SkColorFilter::toString is added
#define SkColorFilterShader_DEFINED
#include "SkColorFilter.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
class SkArenaAlloc;
-class SkColorFilterShader : public SkShader {
+class SkColorFilterShader : public SkShaderBase {
public:
SkColorFilterShader(sk_sp<SkShader> shader, sk_sp<SkColorFilter> filter);
sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
#endif
- class FilterShaderContext : public SkShader::Context {
+ class FilterShaderContext : public Context {
public:
// Takes ownership of shaderContext and calls its destructor.
- FilterShaderContext(const SkColorFilterShader&, SkShader::Context*, const ContextRec&);
+ FilterShaderContext(const SkColorFilterShader&, SkShaderBase::Context*, const ContextRec&);
uint32_t getFlags() const override;
}
private:
- SkShader::Context* fShaderContext;
+ SkShaderBase::Context* fShaderContext;
- typedef SkShader::Context INHERITED;
+ typedef Context INHERITED;
};
SK_TO_STRING_OVERRIDE()
sk_sp<SkShader> fShader;
sk_sp<SkColorFilter> fFilter;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
#endif
return fFlags;
}
-SkShader::Context* SkColorShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
+SkShaderBase::Context* SkColorShader::onMakeContext(const ContextRec& rec,
+ SkArenaAlloc* alloc) const {
return alloc->make<ColorShaderContext>(*this, rec);
}
return fFlags;
}
-SkShader::Context* SkColor4Shader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
+SkShaderBase::Context* SkColor4Shader::onMakeContext(const ContextRec& rec,
+ SkArenaAlloc* alloc) const {
return alloc->make<Color4Context>(*this, rec);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
-static void D32_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+static void D32_BlitBW(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst,
int count) {
SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0];
const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
proc(state->fMode, dst.writable_addr32(x, y), src, count, nullptr);
}
-static void D32_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+static void D32_BlitAA(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst,
int count, const SkAlpha aa[]) {
SkXfermode::D32Proc proc = (SkXfermode::D32Proc)state->fStorage[0];
const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
proc(state->fMode, dst.writable_addr32(x, y), src, count, aa);
}
-static void F16_BlitBW(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+static void F16_BlitBW(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst,
int count) {
SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0];
const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
proc(state->fMode, dst.writable_addr64(x, y), src, count, nullptr);
}
-static void F16_BlitAA(SkShader::Context::BlitState* state, int x, int y, const SkPixmap& dst,
+static void F16_BlitAA(SkShaderBase::Context::BlitState* state, int x, int y, const SkPixmap& dst,
int count, const SkAlpha aa[]) {
SkXfermode::F16Proc proc = (SkXfermode::F16Proc)state->fStorage[0];
const SkPM4f* src = (const SkPM4f*)state->fStorage[1];
}
static bool choose_blitprocs(const SkPM4f* pm4, const SkImageInfo& info,
- SkShader::Context::BlitState* state) {
+ SkShaderBase::Context::BlitState* state) {
uint32_t flags = SkXfermode::kSrcIsSingle_D32Flag;
if (pm4->a() == 1) {
flags |= SkXfermode::kSrcIsOpaque_D32Flag;
#define SkColorShader_DEFINED
#include "SkColorSpaceXformer.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkPM4f.h"
/** \class SkColorShader
accomplished by just using the color field on the paint, but if an
actual shader object is needed, this provides that feature.
*/
-class SK_API SkColorShader : public SkShader {
+class SK_API SkColorShader : public SkShaderBase {
public:
/** Create a ColorShader that ignores the color in the paint, and uses the
specified color. Note: like all shaders, at draw time the paint's alpha
bool isOpaque() const override;
bool isConstant() const override { return true; }
- class ColorShaderContext : public SkShader::Context {
+ class ColorShaderContext : public Context {
public:
ColorShaderContext(const SkColorShader& shader, const ContextRec&);
SkPMColor fPMColor;
uint32_t fFlags;
- typedef SkShader::Context INHERITED;
+ typedef Context INHERITED;
};
GradientType asAGradient(GradientInfo* info) const override;
private:
SkColor fColor;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
-class SkColor4Shader : public SkShader {
+class SkColor4Shader : public SkShaderBase {
public:
SkColor4Shader(const SkColor4f&, sk_sp<SkColorSpace>);
}
bool isConstant() const override { return true; }
- class Color4Context : public SkShader::Context {
+ class Color4Context : public Context {
public:
Color4Context(const SkColor4Shader& shader, const ContextRec&);
SkPMColor fPMColor;
uint32_t fFlags;
- typedef SkShader::Context INHERITED;
+ typedef Context INHERITED;
};
GradientType asAGradient(GradientInfo* info) const override;
const SkColor4f fColor4;
const SkColor fCachedByteColor;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
#endif
#include "SkImageFilter.h"
#include "SkImagePriv.h"
#include "SkMakeUnique.h"
+#include "SkShaderBase.h"
std::unique_ptr<SkColorSpaceXformer> SkColorSpaceXformer::Make(sk_sp<SkColorSpace> dst) {
std::unique_ptr<SkColorSpaceXform> fromSRGB = SkColorSpaceXform_Base::New(
}
sk_sp<SkShader> SkColorSpaceXformer::apply(const SkShader* shader) {
- return shader->makeColorSpace(this);
+ return as_SB(shader)->makeColorSpace(this);
}
void SkColorSpaceXformer::apply(SkColor* xformed, const SkColor* srgb, int n) {
buffer.write32((int)fMode);
}
-SkShader::Context* SkComposeShader::onMakeContext(
+SkShaderBase::Context* SkComposeShader::onMakeContext(
const ContextRec& rec, SkArenaAlloc* alloc) const
{
// we preconcat our localMatrix (if any) with the device matrix
newRec.fMatrix = &tmpM;
newRec.fPaint = &opaquePaint;
- SkShader::Context* contextA = fShaderA->makeContext(newRec, alloc);
- SkShader::Context* contextB = fShaderB->makeContext(newRec, alloc);
+ SkShaderBase::Context* contextA = as_SB(fShaderA)->makeContext(newRec, alloc);
+ SkShaderBase::Context* contextB = as_SB(fShaderB)->makeContext(newRec, alloc);
if (!contextA || !contextB) {
return nullptr;
}
SkComposeShader::ComposeShaderContext::ComposeShaderContext(
const SkComposeShader& shader, const ContextRec& rec,
- SkShader::Context* contextA, SkShader::Context* contextB)
+ SkShaderBase::Context* contextA, SkShaderBase::Context* contextB)
: INHERITED(shader, rec)
, fShaderContextA(contextA)
, fShaderContextB(contextB) {}
}
bool SkComposeShader::isRasterPipelineOnly() const {
- return fShaderA->isRasterPipelineOnly() || fShaderB->isRasterPipelineOnly();
+ return as_SB(fShaderA)->isRasterPipelineOnly() || as_SB(fShaderB)->isRasterPipelineOnly();
}
bool SkComposeShader::onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* dstCS,
// will be smashed, and I'll need them again for fShaderB. store_rgba saves off 4 registers
// even though we only need to save r,g.
pipeline->append(SkRasterPipeline::store_rgba, storage->fXY);
- if (!fShaderB->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // SRC
+ if (!as_SB(fShaderB)->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // SRC
return false;
}
// This outputs r,g,b,a, which we'll need later when we apply the mode, but we save it off now
pipeline->append(SkRasterPipeline::store_rgba, storage->fRGBA);
// Now we restore the device x,y for the next shader
pipeline->append(SkRasterPipeline::load_rgba, storage->fXY);
- if (!fShaderA->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // DST
+ if (!as_SB(fShaderA)->appendStages(pipeline, dstCS, alloc, ctm, paint, localM)) { // DST
return false;
}
// We now have our logical 'dst' in r,g,b,a, but we need it in dr,dg,db,da for the mode
#define TMP_COLOR_COUNT 64
void SkComposeShader::ComposeShaderContext::shadeSpan(int x, int y, SkPMColor result[], int count) {
- SkShader::Context* shaderContextA = fShaderContextA;
- SkShader::Context* shaderContextB = fShaderContextB;
+ auto* shaderContextA = fShaderContextA;
+ auto* shaderContextB = fShaderContextB;
SkBlendMode mode = static_cast<const SkComposeShader&>(fShader).fMode;
unsigned scale = SkAlpha255To256(this->getPaintAlpha());
}
void SkComposeShader::ComposeShaderContext::shadeSpan4f(int x, int y, SkPM4f result[], int count) {
- SkShader::Context* shaderContextA = fShaderContextA;
- SkShader::Context* shaderContextB = fShaderContextB;
+ auto* shaderContextA = fShaderContextA;
+ auto* shaderContextB = fShaderContextB;
SkBlendMode mode = static_cast<const SkComposeShader&>(fShader).fMode;
unsigned alpha = this->getPaintAlpha();
Sk4f scale(alpha * (1.0f / 255));
GrConstColorProcessor::kIgnore_InputMode);
break;
case SkBlendMode::kSrc:
- return fShaderB->asFragmentProcessor(args);
+ return as_SB(fShaderB)->asFragmentProcessor(args);
break;
case SkBlendMode::kDst:
- return fShaderA->asFragmentProcessor(args);
+ return as_SB(fShaderA)->asFragmentProcessor(args);
break;
default:
- sk_sp<GrFragmentProcessor> fpA(fShaderA->asFragmentProcessor(args));
+ sk_sp<GrFragmentProcessor> fpA(as_SB(fShaderA)->asFragmentProcessor(args));
if (!fpA) {
return nullptr;
}
- sk_sp<GrFragmentProcessor> fpB(fShaderB->asFragmentProcessor(args));
+ sk_sp<GrFragmentProcessor> fpB(as_SB(fShaderB)->asFragmentProcessor(args));
if (!fpB) {
return nullptr;
}
str->append("SkComposeShader: (");
str->append("ShaderA: ");
- fShaderA->toString(str);
+ as_SB(fShaderA)->toString(str);
str->append(" ShaderB: ");
- fShaderB->toString(str);
+ as_SB(fShaderB)->toString(str);
if (SkBlendMode::kSrcOver != fMode) {
str->appendf(" Xfermode: %s", SkXfermode::ModeName(fMode));
}
#ifndef SkComposeShader_DEFINED
#define SkComposeShader_DEFINED
-#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkBlendMode.h"
class SkColorSpacXformer;
This subclass of shader returns the composition of two other shaders, combined by
a xfermode.
*/
-class SK_API SkComposeShader : public SkShader {
+class SK_API SkComposeShader : public SkShaderBase {
public:
/** Create a new compose shader, given shaders A, B, and a combining xfermode mode.
When the xfermode is called, it will be given the result from shader A as its
sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
#endif
- class ComposeShaderContext : public SkShader::Context {
+ class ComposeShaderContext : public Context {
public:
// When this object gets destroyed, it will call contextA and contextB's destructor
// but it will NOT free the memory.
ComposeShaderContext(const SkComposeShader&, const ContextRec&,
- SkShader::Context* contextA, SkShader::Context* contextB);
+ SkShaderBase::Context* contextA, SkShaderBase::Context* contextB);
void shadeSpan(int x, int y, SkPMColor[], int count) override;
void shadeSpan4f(int x, int y, SkPM4f[], int count) override;
private:
- SkShader::Context* fShaderContextA;
- SkShader::Context* fShaderContextB;
+ SkShaderBase::Context* fShaderContextA;
+ SkShaderBase::Context* fShaderContextB;
- typedef SkShader::Context INHERITED;
+ typedef Context INHERITED;
};
#ifdef SK_DEBUG
sk_sp<SkShader> fShaderB;
SkBlendMode fMode;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
#endif
#include "SkBitmapProcShader.h"
#include "SkBlitter.h"
#include "SkBlitRow.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkXfermodePriv.h"
class SkRasterBlitter : public SkBlitter {
* exchange that object.
*/
SkShaderBlitter(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext);
+ SkShaderBase::Context* shaderContext);
virtual ~SkShaderBlitter();
protected:
- uint32_t fShaderFlags;
- const SkShader* fShader;
- SkShader::Context* fShaderContext;
- bool fConstInY;
+ uint32_t fShaderFlags;
+ const SkShader* fShader;
+ SkShaderBase::Context* fShaderContext;
+ bool fConstInY;
private:
// illegal
class SkA8_Shader_Blitter : public SkShaderBlitter {
public:
SkA8_Shader_Blitter(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext);
+ SkShaderBase::Context* shaderContext);
~SkA8_Shader_Blitter() override;
void blitH(int x, int y, int width) override;
void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) override;
class SkARGB32_Shader_Blitter : public SkShaderBlitter {
public:
SkARGB32_Shader_Blitter(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext);
+ SkShaderBase::Context* shaderContext);
~SkARGB32_Shader_Blitter() override;
void blitH(int x, int y, int width) override;
void blitV(int x, int y, int height, SkAlpha alpha) override;
typedef SkShaderBlitter INHERITED;
};
-SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint&, SkShader::Context*,
+SkBlitter* SkBlitter_ARGB32_Create(const SkPixmap& device, const SkPaint&, SkShaderBase::Context*,
SkArenaAlloc*);
-SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint&, SkShader::Context*,
+SkBlitter* SkBlitter_F16_Create(const SkPixmap& device, const SkPaint&, SkShaderBase::Context*,
SkArenaAlloc*);
///////////////////////////////////////////////////////////////////////////////
*/
SkBlitter* SkBlitter_ChooseD565(const SkPixmap& device, const SkPaint& paint,
- SkShader::Context* shaderContext,
+ SkShaderBase::Context* shaderContext,
SkArenaAlloc* allocator);
#include "SkPM4fPriv.h"
#include "SkRasterClip.h"
#include "SkScan.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkString.h"
#include "SkVertState.h"
return matrix->setPolyToPoly(src, dst, 3);
}
-class SkTriColorShader : public SkShader {
+class SkTriColorShader : public SkShaderBase {
public:
SkTriColorShader(bool isOpaque) : fIsOpaque(isOpaque) {}
Matrix43 fM43;
const bool fIsOpaque;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
#ifndef SK_IGNORE_TO_STRING
#ifndef SkEmptyShader_DEFINED
#define SkEmptyShader_DEFINED
-#include "SkShader.h"
+#include "SkShaderBase.h"
// TODO: move this to private, as there is a public factory on SkShader
* \class SkEmptyShader
* A Shader that always draws nothing. Its createContext always returns nullptr.
*/
-class SK_API SkEmptyShader : public SkShader {
+class SK_API SkEmptyShader : public SkShaderBase {
public:
SkEmptyShader() {}
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader)
protected:
- SkShader::Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override {
+ Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const override {
return nullptr;
}
}
private:
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
#endif
#include "SkPathEffect.h"
#include "SkPictureShader.h"
#include "SkRecordedDrawable.h"
+#include "SkShaderBase.h"
/*
* Registers all of the required effects subclasses for picture deserialization.
SkColorFilter::InitializeFlattenables();
SkPathEffect::InitializeFlattenables();
- SkShader::InitializeFlattenables();
+ SkShaderBase::InitializeFlattenables();
SkXfermode::InitializeFlattenables();
// Drawable
#include "SkNormalSource.h"
#include "SkPoint3.h"
#include "SkReadBuffer.h"
+#include "SkShaderBase.h"
#include "SkWriteBuffer.h"
////////////////////////////////////////////////////////////////////////////
/** \class SkLightingShaderImpl
This subclass of shader applies lighting.
*/
-class SkLightingShaderImpl : public SkShader {
+class SkLightingShaderImpl : public SkShaderBase {
public:
/** Create a new lighting shader that uses the provided normal map and
lights to light the diffuse bitmap.
sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
#endif
- class LightingShaderContext : public SkShader::Context {
+ class LightingShaderContext : public Context {
public:
// The context takes ownership of the context and provider. It will call their destructors
// and then indirectly free their memory by calling free() on heapAllocated
LightingShaderContext(const SkLightingShaderImpl&, const ContextRec&,
- SkShader::Context* diffuseContext, SkNormalSource::Provider*,
+ SkShaderBase::Context* diffuseContext, SkNormalSource::Provider*,
void* heapAllocated);
void shadeSpan(int x, int y, SkPMColor[], int count) override;
uint32_t getFlags() const override { return fFlags; }
private:
- SkShader::Context* fDiffuseContext;
+ SkShaderBase::Context* fDiffuseContext;
SkNormalSource::Provider* fNormalProvider;
SkColor fPaintColor;
uint32_t fFlags;
- typedef SkShader::Context INHERITED;
+ typedef Context INHERITED;
};
SK_TO_STRING_OVERRIDE()
friend class SkLightingShader;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
////////////////////////////////////////////////////////////////////////////
if (fDiffuseShader) {
sk_sp<GrFragmentProcessor> fpPipeline[] = {
- fDiffuseShader->asFragmentProcessor(args),
+ as_SB(fDiffuseShader)->asFragmentProcessor(args),
sk_make_sp<LightingFP>(std::move(normalFP), fLights)
};
if(!fpPipeline[0]) {
SkLightingShaderImpl::LightingShaderContext::LightingShaderContext(
const SkLightingShaderImpl& shader, const ContextRec& rec,
- SkShader::Context* diffuseContext, SkNormalSource::Provider* normalProvider,
+ SkShaderBase::Context* diffuseContext, SkNormalSource::Provider* normalProvider,
void* heapAllocated)
: INHERITED(shader, rec)
, fDiffuseContext(diffuseContext)
bool hasDiffuse = buf.readBool();
sk_sp<SkShader> diffuseShader = nullptr;
if (hasDiffuse) {
- diffuseShader = buf.readFlattenable<SkShader>();
+ diffuseShader = buf.readFlattenable<SkShaderBase>();
}
return sk_make_sp<SkLightingShaderImpl>(std::move(diffuseShader), std::move(normalSource),
}
}
-SkShader::Context* SkLightingShaderImpl::onMakeContext(
+SkShaderBase::Context* SkLightingShaderImpl::onMakeContext(
const ContextRec& rec, SkArenaAlloc* alloc) const
{
- SkShader::Context *diffuseContext = nullptr;
+ SkShaderBase::Context *diffuseContext = nullptr;
if (fDiffuseShader) {
- diffuseContext = fDiffuseShader->makeContext(rec, alloc);
+ diffuseContext = as_SB(fDiffuseShader)->makeContext(rec, alloc);
if (!diffuseContext) {
return nullptr;
}
if (args.fLocalMatrix) {
tmp.preConcat(*args.fLocalMatrix);
}
- return fProxyShader->asFragmentProcessor(AsFPArgs(
+ return as_SB(fProxyShader)->asFragmentProcessor(AsFPArgs(
args.fContext, args.fViewMatrix, &tmp, args.fFilterQuality, args.fDstColorSpace));
}
#endif
buffer.writeFlattenable(fProxyShader.get());
}
-SkShader::Context* SkLocalMatrixShader::onMakeContext(
+SkShaderBase::Context* SkLocalMatrixShader::onMakeContext(
const ContextRec& rec, SkArenaAlloc* alloc) const
{
ContextRec newRec(rec);
} else {
newRec.fLocalMatrix = &this->getLocalMatrix();
}
- return fProxyShader->makeContext(newRec, alloc);
+ return as_SB(fProxyShader)->makeContext(newRec, alloc);
}
SkImage* SkLocalMatrixShader::onIsAImage(SkMatrix* outMatrix, enum TileMode* mode) const {
if (localM) {
tmp.setConcat(*localM, this->getLocalMatrix());
}
- return fProxyShader->appendStages(p, dst, scratch, ctm, paint,
- localM ? &tmp : &this->getLocalMatrix());
+ return as_SB(fProxyShader)->appendStages(p, dst, scratch, ctm, paint,
+ localM ? &tmp : &this->getLocalMatrix());
}
#ifndef SK_IGNORE_TO_STRING
void SkLocalMatrixShader::toString(SkString* str) const {
str->append("SkLocalMatrixShader: (");
- fProxyShader->toString(str);
+ as_SB(fProxyShader)->toString(str);
this->INHERITED::toString(str);
sk_sp<SkShader> baseShader;
SkMatrix otherLocalMatrix;
- sk_sp<SkShader> proxy(this->makeAsALocalMatrixShader(&otherLocalMatrix));
+ sk_sp<SkShader> proxy(as_SB(this)->makeAsALocalMatrixShader(&otherLocalMatrix));
if (proxy) {
otherLocalMatrix.preConcat(localMatrix);
lm = &otherLocalMatrix;
#ifndef SkLocalMatrixShader_DEFINED
#define SkLocalMatrixShader_DEFINED
-#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
class SkArenaAlloc;
class SkColorSpaceXformer;
-class SkLocalMatrixShader : public SkShader {
+class SkLocalMatrixShader : public SkShaderBase {
public:
SkLocalMatrixShader(sk_sp<SkShader> proxy, const SkMatrix& localMatrix)
: INHERITED(&localMatrix)
const SkMatrix&, const SkPaint&, const SkMatrix*) const override;
sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override {
- return fProxyShader->makeColorSpace(xformer)->makeWithLocalMatrix(this->getLocalMatrix());
+ return as_SB(fProxyShader)->makeColorSpace(xformer)->makeWithLocalMatrix(
+ this->getLocalMatrix());
}
#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
#endif
bool isRasterPipelineOnly() const final {
- return fProxyShader->isRasterPipelineOnly();
+ return as_SB(fProxyShader)->isRasterPipelineOnly();
}
private:
sk_sp<SkShader> fProxyShader;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
#endif
#include "SkPixmap.h"
#include "SkScalar.h"
#include "SkSize.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
class SkBitmap;
class SkDiscardableMemory;
static SkMipMap* Build(const SkBitmap& src, SkDestinationSurfaceColorMode,
SkDiscardableFactoryProc);
- static SkDestinationSurfaceColorMode DeduceColorMode(const SkShader::ContextRec& rec) {
- return (SkShader::ContextRec::kPMColor_DstType == rec.fPreferredDstType)
+ static SkDestinationSurfaceColorMode DeduceColorMode(const SkShaderBase::ContextRec& rec) {
+ return (SkShaderBase::ContextRec::kPMColor_DstType == rec.fPreferredDstType)
? SkDestinationSurfaceColorMode::kLegacy
: SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware;
}
};
sk_sp<GrFragmentProcessor> SkNormalBevelSourceImpl::asFragmentProcessor(
- const SkShader::AsFPArgs& args) const {
+ const SkShaderBase::AsFPArgs& args) const {
// This assumes a uniform scale. Anisotropic scaling might not be handled gracefully.
SkScalar maxScale = args.fViewMatrix->getMaxScale();
SkNormalBevelSourceImpl::Provider::~Provider() {}
-SkNormalSource::Provider* SkNormalBevelSourceImpl::asProvider(const SkShader::ContextRec &rec,
+SkNormalSource::Provider* SkNormalBevelSourceImpl::asProvider(const SkShaderBase::ContextRec &rec,
SkArenaAlloc* alloc) const {
return alloc->make<Provider>();
}
, fHeight(height) {}
#if SK_SUPPORT_GPU
- sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShader::AsFPArgs&) const override;
+ sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const override;
#endif
- SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec,
+ SkNormalSource::Provider* asProvider(const SkShaderBase::ContextRec& rec,
SkArenaAlloc*) const override;
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalBevelSourceImpl)
};
sk_sp<GrFragmentProcessor> SkNormalFlatSourceImpl::asFragmentProcessor(
- const SkShader::AsFPArgs&) const {
+ const SkShaderBase::AsFPArgs&) const {
return sk_make_sp<NormalFlatFP>();
}
SkNormalFlatSourceImpl::Provider::~Provider() {}
-SkNormalSource::Provider* SkNormalFlatSourceImpl::asProvider(const SkShader::ContextRec &rec,
+SkNormalSource::Provider* SkNormalFlatSourceImpl::asProvider(const SkShaderBase::ContextRec &rec,
SkArenaAlloc *alloc) const {
return alloc->make<Provider>();
}
SkNormalFlatSourceImpl(){}
#if SK_SUPPORT_GPU
- sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShader::AsFPArgs&) const override;
+ sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const override;
#endif
- SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec,
+ SkNormalSource::Provider* asProvider(const SkShaderBase::ContextRec& rec,
SkArenaAlloc* alloc) const override;
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalFlatSourceImpl)
};
sk_sp<GrFragmentProcessor> SkNormalMapSourceImpl::asFragmentProcessor(
- const SkShader::AsFPArgs& args) const {
- sk_sp<GrFragmentProcessor> mapFP = fMapShader->asFragmentProcessor(args);
+ const SkShaderBase::AsFPArgs& args) const {
+ sk_sp<GrFragmentProcessor> mapFP = as_SB(fMapShader)->asFragmentProcessor(args);
if (!mapFP) {
return nullptr;
}
////////////////////////////////////////////////////////////////////////////
SkNormalMapSourceImpl::Provider::Provider(const SkNormalMapSourceImpl& source,
- SkShader::Context* mapContext)
+ SkShaderBase::Context* mapContext)
: fSource(source)
, fMapContext(mapContext) {}
-SkNormalSource::Provider* SkNormalMapSourceImpl::asProvider(const SkShader::ContextRec &rec,
+SkNormalSource::Provider* SkNormalMapSourceImpl::asProvider(const SkShaderBase::ContextRec &rec,
SkArenaAlloc* alloc) const {
SkMatrix normTotalInv;
if (!this->computeNormTotalInverse(rec, &normTotalInv)) {
// Overriding paint's alpha because we need the normal map's RGB channels to be unpremul'd
SkPaint overridePaint {*(rec.fPaint)};
overridePaint.setAlpha(0xFF);
- SkShader::ContextRec overrideRec(overridePaint, *(rec.fMatrix), rec.fLocalMatrix,
- rec.fPreferredDstType, rec.fDstColorSpace);
+ SkShaderBase::ContextRec overrideRec(overridePaint, *(rec.fMatrix), rec.fLocalMatrix,
+ rec.fPreferredDstType, rec.fDstColorSpace);
- SkShader::Context* context = fMapShader->makeContext(overrideRec, alloc);
+ auto* context = as_SB(fMapShader)->makeContext(overrideRec, alloc);
if (!context) {
return nullptr;
}
return alloc->make<Provider>(*this, context);
}
-bool SkNormalMapSourceImpl::computeNormTotalInverse(const SkShader::ContextRec& rec,
+bool SkNormalMapSourceImpl::computeNormTotalInverse(const SkShaderBase::ContextRec& rec,
SkMatrix* normTotalInverse) const {
SkMatrix total = SkMatrix::Concat(*rec.fMatrix, fMapShader->getLocalMatrix());
if (rec.fLocalMatrix) {
sk_sp<SkFlattenable> SkNormalMapSourceImpl::CreateProc(SkReadBuffer& buf) {
- sk_sp<SkShader> mapShader = buf.readFlattenable<SkShader>();
+ sk_sp<SkShader> mapShader = buf.readFlattenable<SkShaderBase>();
SkMatrix invCTM;
buf.readMatrix(&invCTM);
, fInvCTM(invCTM) {}
#if SK_SUPPORT_GPU
- sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShader::AsFPArgs&) const override;
+ sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const override;
#endif
- SkNormalSource::Provider* asProvider(const SkShader::ContextRec& rec,
+ SkNormalSource::Provider* asProvider(const SkShaderBase::ContextRec& rec,
SkArenaAlloc* alloc) const override;
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkNormalMapSourceImpl)
protected:
void flatten(SkWriteBuffer& buf) const override;
- bool computeNormTotalInverse(const SkShader::ContextRec& rec, SkMatrix* normTotalInverse) const;
+ bool computeNormTotalInverse(const SkShaderBase::ContextRec& rec,
+ SkMatrix* normTotalInverse) const;
private:
class Provider : public SkNormalSource::Provider {
public:
- Provider(const SkNormalMapSourceImpl& source, SkShader::Context* mapContext);
+ Provider(const SkNormalMapSourceImpl& source, SkShaderBase::Context* mapContext);
void fillScanLine(int x, int y, SkPoint3 output[], int count) const override;
private:
const SkNormalMapSourceImpl& fSource;
- SkShader::Context* fMapContext;
+ SkShaderBase::Context* fMapContext;
typedef SkNormalSource::Provider INHERITED;
};
#define SkNormalSource_DEFINED
#include "SkFlattenable.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
class SkMatrix;
struct SkPoint3;
/** Returns a fragment processor that takes no input and outputs a normal (already rotated)
as its output color. To be used as a child fragment processor.
*/
- virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShader::AsFPArgs&) const = 0;
+ virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const SkShaderBase::AsFPArgs&) const = 0;
#endif
class Provider {
/** Returns an instance of 'Provider' that provides normals for the CPU pipeline. The
necessary data will be initialized in place at 'storage'.
*/
- virtual Provider* asProvider(const SkShader::ContextRec&, SkArenaAlloc*) const = 0;
+ virtual Provider* asProvider(const SkShaderBase::ContextRec&, SkArenaAlloc*) const = 0;
/** Returns a normal source that provides normals sourced from the the normal map argument.
#include "SkScalar.h"
#include "SkScalerContext.h"
#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkStringUtils.h"
#include "SkStroke.h"
#include "SkStrokeRec.h"
static bool justAColor(const SkPaint& paint, SkColor* color) {
SkColor c = paint.getColor();
- SkShader* shader = paint.getShader();
+ const auto* shader = as_SB(paint.getShader());
if (shader && !shader->asLuminanceColor(&c)) {
return false;
}
str->append("</dd>");
}
- SkShader* shader = this->getShader();
- if (shader) {
+ if (const auto* shader = as_SB(this->getShader())) {
str->append("<dt>Shader:</dt><dd>");
shader->toString(str);
str->append("</dd>");
// Keep bitmapShader alive by using alloc instead of stack memory
auto& bitmapShader = *alloc->make<sk_sp<SkShader>>();
bitmapShader = this->refBitmapShader(ctm, localMatrix, cs);
- return bitmapShader && bitmapShader->appendStages(p, cs, alloc, ctm, paint);
+ return bitmapShader && as_SB(bitmapShader)->appendStages(p, cs, alloc, ctm, paint);
}
/////////////////////////////////////////////////////////////////////////////////////////
-SkShader::Context* SkPictureShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc)
+SkShaderBase::Context* SkPictureShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc)
const {
sk_sp<SkShader> bitmapShader(this->refBitmapShader(*rec.fMatrix, rec.fLocalMatrix,
rec.fDstColorSpace));
: INHERITED(shader, rec)
, fBitmapShader(std::move(bitmapShader))
{
- fBitmapShaderContext = fBitmapShader->makeContext(rec, alloc);
+ fBitmapShaderContext = as_SB(fBitmapShader)->makeContext(rec, alloc);
//if fBitmapShaderContext is null, we are invalid
}
return fBitmapShaderContext->getFlags();
}
-SkShader::Context::ShadeProc SkPictureShader::PictureShaderContext::asAShadeProc(void** ctx) {
+SkShaderBase::Context::ShadeProc SkPictureShader::PictureShaderContext::asAShadeProc(void** ctx) {
SkASSERT(fBitmapShaderContext);
return fBitmapShaderContext->asAShadeProc(ctx);
}
if (!bitmapShader) {
return nullptr;
}
- return bitmapShader->asFragmentProcessor(SkShader::AsFPArgs(
+ return as_SB(bitmapShader)->asFragmentProcessor(SkShaderBase::AsFPArgs(
args.fContext, args.fViewMatrix, nullptr, args.fFilterQuality, args.fDstColorSpace));
}
#endif
#ifndef SkPictureShader_DEFINED
#define SkPictureShader_DEFINED
-#include "SkShader.h"
+#include "SkShaderBase.h"
class SkArenaAlloc;
class SkBitmap;
* The SkPicture is first rendered into a tile, which is then used to shade the area according
* to specified tiling rules.
*/
-class SkPictureShader : public SkShader {
+class SkPictureShader : public SkShaderBase {
public:
static sk_sp<SkShader> Make(sk_sp<SkPicture>, TileMode, TileMode, const SkMatrix*,
const SkRect*);
SkRect fTile;
TileMode fTmx, fTmy;
- class PictureShaderContext : public SkShader::Context {
+ class PictureShaderContext : public Context {
public:
PictureShaderContext(
const SkPictureShader&, const ContextRec&, sk_sp<SkShader> bitmapShader, SkArenaAlloc*);
ShadeProc asAShadeProc(void** ctx) override;
void shadeSpan(int x, int y, SkPMColor dstC[], int count) override;
- sk_sp<SkShader> fBitmapShader;
- SkShader::Context* fBitmapShaderContext;
- void* fBitmapShaderContextStorage;
+ sk_sp<SkShader> fBitmapShader;
+ SkShaderBase::Context* fBitmapShaderContext;
+ void* fBitmapShaderContextStorage;
- typedef SkShader::Context INHERITED;
+ typedef Context INHERITED;
};
// Should never be set by a public constructor. This is only used when onMakeColorSpace()
// forces a deferred color space xform.
sk_sp<SkColorSpace> fColorSpace;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
#endif // SkPictureShader_DEFINED
#include "SkPM4fPriv.h"
#include "SkRasterPipeline.h"
#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkUtils.h"
#include "../jumper/SkJumper.h"
public:
// This is our common entrypoint for creating the blitter once we've sorted out shaders.
static SkBlitter* Create(const SkPixmap&, const SkPaint&, SkArenaAlloc*,
- const SkRasterPipeline& shaderPipeline, SkShader::Context* shaderCtx,
+ const SkRasterPipeline& shaderPipeline,
+ SkShaderBase::Context* shaderCtx,
bool is_opaque, bool is_constant, bool wants_dither);
SkRasterPipelineBlitter(SkPixmap dst,
SkBlendMode blend,
SkArenaAlloc* alloc,
- SkShader::Context* shaderCtx)
+ SkShaderBase::Context* shaderCtx)
: fDst(dst)
, fBlend(blend)
, fAlloc(alloc)
// If we have an SkShader::Context, use it to fill our shader buffer.
void maybe_shade(int x, int y, int w);
- SkPixmap fDst;
- SkBlendMode fBlend;
- SkArenaAlloc* fAlloc;
- SkShader::Context* fShaderCtx;
- SkRasterPipeline fColorPipeline;
+ SkPixmap fDst;
+ SkBlendMode fBlend;
+ SkArenaAlloc* fAlloc;
+ SkShaderBase::Context* fShaderCtx;
+ SkRasterPipeline fColorPipeline;
// We may be able to specialize blitH() into a memset.
bool fCanMemsetInBlitH = false;
SkArenaAlloc* alloc) {
SkColorSpace* dstCS = dst.colorSpace();
auto paintColor = alloc->make<SkPM4f>(SkPM4f_from_SkColor(paint.getColor(), dstCS));
- auto shader = paint.getShader();
+ auto shader = as_SB(paint.getShader());
SkRasterPipeline_<256> shaderPipeline;
if (!shader) {
if (dstCS) {
// We need to transform the shader into the dst color space, and extend its lifetime.
sk_sp<SkShader> in_dstCS = SkColorSpaceXformer::Make(sk_ref_sp(dstCS))->apply(shader);
- shader = in_dstCS.get();
+ shader = as_SB(in_dstCS.get());
alloc->make<sk_sp<SkShader>>(std::move(in_dstCS));
}
- SkShader::ContextRec rec(paint, ctm, nullptr, SkShader::ContextRec::kPM4f_DstType, dstCS);
- SkShader::Context* shaderCtx = shader->makeContext(rec, alloc);
+ SkShaderBase::ContextRec rec(paint, ctm, nullptr, SkShaderBase::ContextRec::kPM4f_DstType,
+ dstCS);
+ SkShaderBase::Context* shaderCtx = shader->makeContext(rec, alloc);
if (!shaderCtx) {
// When a shader fails to create a context, it has vetoed drawing entirely.
return alloc->make<SkNullBlitter>();
const SkPaint& paint,
SkArenaAlloc* alloc,
const SkRasterPipeline& shaderPipeline,
- SkShader::Context* shaderCtx,
+ SkShaderBase::Context* shaderCtx,
bool is_opaque,
bool is_constant,
bool wants_dither) {
#include "SkReadBuffer.h"
#include "SkReader32.h"
#include "SkRefCnt.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkTHash.h"
#include "SkWriteBuffer.h"
#include "SkXfermodePriv.h"
sk_sp<SkMaskFilter> readMaskFilter() { return this->readFlattenable<SkMaskFilter>(); }
sk_sp<SkPathEffect> readPathEffect() { return this->readFlattenable<SkPathEffect>(); }
sk_sp<SkRasterizer> readRasterizer() { return this->readFlattenable<SkRasterizer>(); }
- sk_sp<SkShader> readShader() { return this->readFlattenable<SkShader>(); }
+ sk_sp<SkShader> readShader() { return this->readFlattenable<SkShaderBase>(); }
sk_sp<SkXfermode> readXfermode() { return this->readFlattenable<SkXfermode>(); }
// binary data and arrays
#include "SkRasterPipeline.h"
#include "SkReadBuffer.h"
#include "SkScalar.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkTLazy.h"
#include "SkWriteBuffer.h"
#include "../jumper/SkJumper.h"
#endif
}
-SkShader::SkShader(const SkMatrix* localMatrix) {
+SkShaderBase::SkShaderBase(const SkMatrix* localMatrix)
+ : fLocalMatrix(localMatrix ? *localMatrix : SkMatrix::I()) {
inc_shader_counter();
- if (localMatrix) {
- fLocalMatrix = *localMatrix;
- } else {
- fLocalMatrix.reset();
- }
// Pre-cache so future calls to fLocalMatrix.getType() are threadsafe.
(void)fLocalMatrix.getType();
}
-SkShader::~SkShader() {
+SkShaderBase::~SkShaderBase() {
dec_shader_counter();
}
-void SkShader::flatten(SkWriteBuffer& buffer) const {
+void SkShaderBase::flatten(SkWriteBuffer& buffer) const {
this->INHERITED::flatten(buffer);
bool hasLocalM = !fLocalMatrix.isIdentity();
buffer.writeBool(hasLocalM);
}
}
-bool SkShader::computeTotalInverse(const SkMatrix& ctm,
- const SkMatrix* outerLocalMatrix,
- SkMatrix* totalInverse) const {
+bool SkShaderBase::computeTotalInverse(const SkMatrix& ctm,
+ const SkMatrix* outerLocalMatrix,
+ SkMatrix* totalInverse) const {
SkMatrix total = SkMatrix::Concat(ctm, fLocalMatrix);
if (outerLocalMatrix) {
total.preConcat(*outerLocalMatrix);
return total.invert(totalInverse);
}
-bool SkShader::asLuminanceColor(SkColor* colorPtr) const {
+bool SkShaderBase::asLuminanceColor(SkColor* colorPtr) const {
SkColor storage;
if (nullptr == colorPtr) {
colorPtr = &storage;
return false;
}
-SkShader::Context* SkShader::makeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
+SkShaderBase::Context* SkShaderBase::makeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
if (!this->computeTotalInverse(*rec.fMatrix, rec.fLocalMatrix, nullptr)) {
return nullptr;
}
return this->onMakeContext(rec, alloc);
}
-SkShader::Context::Context(const SkShader& shader, const ContextRec& rec)
+SkShaderBase::Context::Context(const SkShaderBase& shader, const ContextRec& rec)
: fShader(shader), fCTM(*rec.fMatrix)
{
// We should never use a context for RP-only shaders.
fPaintAlpha = rec.fPaint->getAlpha();
}
-SkShader::Context::~Context() {}
+SkShaderBase::Context::~Context() {}
-SkShader::Context::ShadeProc SkShader::Context::asAShadeProc(void** ctx) {
+SkShaderBase::Context::ShadeProc SkShaderBase::Context::asAShadeProc(void** ctx) {
return nullptr;
}
-void SkShader::Context::shadeSpan4f(int x, int y, SkPM4f dst[], int count) {
+void SkShaderBase::Context::shadeSpan4f(int x, int y, SkPM4f dst[], int count) {
const int N = 128;
SkPMColor tmp[N];
while (count > 0) {
#define SkU32BitShiftToByteOffset(shift) ((shift) >> 3)
#endif
-void SkShader::Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
+void SkShaderBase::Context::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) {
SkASSERT(count > 0);
SkPMColor colors[kTempColorCount];
#endif
}
-SkShader::Context::MatrixClass SkShader::Context::ComputeMatrixClass(const SkMatrix& mat) {
+SkShaderBase::Context::MatrixClass SkShaderBase::Context::ComputeMatrixClass(const SkMatrix& mat) {
MatrixClass mc = kLinear_MatrixClass;
if (mat.hasPerspective()) {
//////////////////////////////////////////////////////////////////////////////
+const SkMatrix& SkShader::getLocalMatrix() const {
+ return as_SB(this)->getLocalMatrix();
+}
+
+#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
+bool SkShader::isABitmap(SkBitmap* outTexture, SkMatrix* outMatrix, TileMode xy[2]) const {
+ return as_SB(this)->onIsABitmap(outTexture, outMatrix, xy);
+}
+#endif
+
+SkImage* SkShader::isAImage(SkMatrix* localMatrix, TileMode xy[2]) const {
+ return as_SB(this)->onIsAImage(localMatrix, xy);
+}
+
SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const {
return kNone_GradientType;
}
#if SK_SUPPORT_GPU
-sk_sp<GrFragmentProcessor> SkShader::asFragmentProcessor(const AsFPArgs&) const {
+sk_sp<GrFragmentProcessor> SkShaderBase::asFragmentProcessor(const AsFPArgs&) const {
return nullptr;
}
#endif
-sk_sp<SkShader> SkShader::makeAsALocalMatrixShader(SkMatrix*) const {
+sk_sp<SkShader> SkShaderBase::makeAsALocalMatrixShader(SkMatrix*) const {
return nullptr;
}
}
#ifndef SK_IGNORE_TO_STRING
-void SkShader::toString(SkString* str) const {
+void SkShaderBase::toString(SkString* str) const {
if (!fLocalMatrix.isIdentity()) {
str->append(" ");
fLocalMatrix.toString(str);
}
#endif
-bool SkShader::appendStages(SkRasterPipeline* p,
- SkColorSpace* dstCS,
- SkArenaAlloc* alloc,
- const SkMatrix& ctm,
- const SkPaint& paint,
- const SkMatrix* localM) const {
+bool SkShaderBase::appendStages(SkRasterPipeline* p,
+ SkColorSpace* dstCS,
+ SkArenaAlloc* alloc,
+ const SkMatrix& ctm,
+ const SkPaint& paint,
+ const SkMatrix* localM) const {
return this->onAppendStages(p, dstCS, alloc, ctm, paint, localM);
}
-bool SkShader::onAppendStages(SkRasterPipeline* p,
- SkColorSpace* dstCS,
- SkArenaAlloc* alloc,
- const SkMatrix& ctm,
- const SkPaint& paint,
- const SkMatrix* localM) const {
+bool SkShaderBase::onAppendStages(SkRasterPipeline* p,
+ SkColorSpace* dstCS,
+ SkArenaAlloc* alloc,
+ const SkMatrix& ctm,
+ const SkPaint& paint,
+ const SkMatrix* localM) const {
return false;
}
--- /dev/null
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkShaderBase_DEFINED
+#define SkShaderBase_DEFINED
+
+#include "SkFilterQuality.h"
+#include "SkMatrix.h"
+#include "SkShader.h"
+
+class GrContext;
+class GrFragmentProcessor;
+class SkArenaAlloc;
+class SkColorSpace;
+class SkColorSpaceXformer;
+class SkImage;
+struct SkImageInfo;
+class SkPaint;
+class SkRasterPipeline;
+
+class SkShaderBase : public SkShader {
+public:
+ SkShaderBase(const SkMatrix* localMatrix = nullptr);
+
+ ~SkShaderBase() override;
+
+ /**
+ * Returns true if the shader is guaranteed to produce only a single color.
+ * Subclasses can override this to allow loop-hoisting optimization.
+ */
+ virtual bool isConstant() const { return false; }
+
+ const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
+
+ enum Flags {
+ //!< set if all of the colors will be opaque
+ kOpaqueAlpha_Flag = 1 << 0,
+
+ /** set if the spans only vary in X (const in Y).
+ e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient
+ that varies from left-to-right. This flag specifies this for
+ shadeSpan().
+ */
+ kConstInY32_Flag = 1 << 1,
+
+ /** hint for the blitter that 4f is the preferred shading mode.
+ */
+ kPrefers4f_Flag = 1 << 2,
+ };
+
+ /**
+ * ContextRec acts as a parameter bundle for creating Contexts.
+ */
+ struct ContextRec {
+ enum DstType {
+ kPMColor_DstType, // clients prefer shading into PMColor dest
+ kPM4f_DstType, // clients prefer shading into PM4f dest
+ };
+
+ ContextRec(const SkPaint& paint, const SkMatrix& matrix, const SkMatrix* localM,
+ DstType dstType, SkColorSpace* dstColorSpace)
+ : fPaint(&paint)
+ , fMatrix(&matrix)
+ , fLocalMatrix(localM)
+ , fPreferredDstType(dstType)
+ , fDstColorSpace(dstColorSpace) {}
+
+ const SkPaint* fPaint; // the current paint associated with the draw
+ const SkMatrix* fMatrix; // the current matrix in the canvas
+ const SkMatrix* fLocalMatrix; // optional local matrix
+ const DstType fPreferredDstType; // the "natural" client dest type
+ SkColorSpace* fDstColorSpace; // the color space of the dest surface (if any)
+ };
+
+ class Context : public ::SkNoncopyable {
+ public:
+ Context(const SkShaderBase& shader, const ContextRec&);
+
+ virtual ~Context();
+
+ /**
+ * Called sometimes before drawing with this shader. Return the type of
+ * alpha your shader will return. The default implementation returns 0.
+ * Your subclass should override if it can (even sometimes) report a
+ * non-zero value, since that will enable various blitters to perform
+ * faster.
+ */
+ virtual uint32_t getFlags() const { return 0; }
+
+ /**
+ * Called for each span of the object being drawn. Your subclass should
+ * set the appropriate colors (with premultiplied alpha) that correspond
+ * to the specified device coordinates.
+ */
+ virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
+
+ virtual void shadeSpan4f(int x, int y, SkPM4f[], int count);
+
+ struct BlitState;
+ typedef void (*BlitBW)(BlitState*,
+ int x, int y, const SkPixmap&, int count);
+ typedef void (*BlitAA)(BlitState*,
+ int x, int y, const SkPixmap&, int count, const SkAlpha[]);
+
+ struct BlitState {
+ // inputs
+ Context* fCtx;
+ SkBlendMode fMode;
+
+ // outputs
+ enum { N = 2 };
+ void* fStorage[N];
+ BlitBW fBlitBW;
+ BlitAA fBlitAA;
+ };
+
+ // Returns true if one or more of the blitprocs are set in the BlitState
+ bool chooseBlitProcs(const SkImageInfo& info, BlitState* state) {
+ state->fBlitBW = nullptr;
+ state->fBlitAA = nullptr;
+ if (this->onChooseBlitProcs(info, state)) {
+ SkASSERT(state->fBlitBW || state->fBlitAA);
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * The const void* ctx is only const because all the implementations are const.
+ * This can be changed to non-const if a new shade proc needs to change the ctx.
+ */
+ typedef void (*ShadeProc)(const void* ctx, int x, int y, SkPMColor[], int count);
+ virtual ShadeProc asAShadeProc(void** ctx);
+
+ /**
+ * Similar to shadeSpan, but only returns the alpha-channel for a span.
+ * The default implementation calls shadeSpan() and then extracts the alpha
+ * values from the returned colors.
+ */
+ virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
+
+ // Notification from blitter::blitMask in case we need to see the non-alpha channels
+ virtual void set3DMask(const SkMask*) {}
+
+ protected:
+ // Reference to shader, so we don't have to dupe information.
+ const SkShaderBase& fShader;
+
+ enum MatrixClass {
+ kLinear_MatrixClass, // no perspective
+ kFixedStepInX_MatrixClass, // fast perspective, need to call fixedStepInX() each
+ // scanline
+ kPerspective_MatrixClass // slow perspective, need to mappoints each pixel
+ };
+ static MatrixClass ComputeMatrixClass(const SkMatrix&);
+
+ uint8_t getPaintAlpha() const { return fPaintAlpha; }
+ const SkMatrix& getTotalInverse() const { return fTotalInverse; }
+ MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
+ const SkMatrix& getCTM() const { return fCTM; }
+
+ virtual bool onChooseBlitProcs(const SkImageInfo&, BlitState*) { return false; }
+
+ private:
+ SkMatrix fCTM;
+ SkMatrix fTotalInverse;
+ uint8_t fPaintAlpha;
+ uint8_t fTotalInverseClass;
+
+ typedef SkNoncopyable INHERITED;
+ };
+
+ /**
+ * Make a context using the memory provided by the arena.
+ *
+ * @return pointer to context or nullptr if can't be created
+ */
+ Context* makeContext(const ContextRec&, SkArenaAlloc*) const;
+
+ /**
+ * If the shader subclass is composed of two shaders, return true, and if rec is not NULL,
+ * fill it out with info about the shader.
+ *
+ * These are bare pointers; the ownership and reference count are unchanged.
+ */
+
+ struct ComposeRec {
+ const SkShader* fShaderA;
+ const SkShader* fShaderB;
+ SkBlendMode fBlendMode;
+ };
+
+ virtual bool asACompose(ComposeRec*) const { return false; }
+
+#if SK_SUPPORT_GPU
+ struct AsFPArgs {
+ AsFPArgs() {}
+ AsFPArgs(GrContext* context,
+ const SkMatrix* viewMatrix,
+ const SkMatrix* localMatrix,
+ SkFilterQuality filterQuality,
+ SkColorSpace* dstColorSpace)
+ : fContext(context)
+ , fViewMatrix(viewMatrix)
+ , fLocalMatrix(localMatrix)
+ , fFilterQuality(filterQuality)
+ , fDstColorSpace(dstColorSpace) {}
+
+ GrContext* fContext;
+ const SkMatrix* fViewMatrix;
+ const SkMatrix* fLocalMatrix;
+ SkFilterQuality fFilterQuality;
+ SkColorSpace* fDstColorSpace;
+ };
+
+ /**
+ * Returns a GrFragmentProcessor that implements the shader for the GPU backend. NULL is
+ * returned if there is no GPU implementation.
+ *
+ * The GPU device does not call SkShader::createContext(), instead we pass the view matrix,
+ * local matrix, and filter quality directly.
+ *
+ * The GrContext may be used by the to create textures that are required by the returned
+ * processor.
+ *
+ * The returned GrFragmentProcessor should expect an unpremultiplied input color and
+ * produce a premultiplied output.
+ */
+ virtual sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const;
+#endif
+
+ /**
+ * If the shader can represent its "average" luminance in a single color, return true and
+ * if color is not NULL, return that color. If it cannot, return false and ignore the color
+ * parameter.
+ *
+ * Note: if this returns true, the returned color will always be opaque, as only the RGB
+ * components are used to compute luminance.
+ */
+ bool asLuminanceColor(SkColor*) const;
+
+ /**
+ * Returns a shader transformed into a new color space via the |xformer|.
+ */
+ sk_sp<SkShader> makeColorSpace(SkColorSpaceXformer* xformer) const {
+ return this->onMakeColorSpace(xformer);
+ }
+
+ /**
+ * If this shader can be represented by another shader + a localMatrix, return that shader and
+ * the localMatrix. If not, return nullptr and ignore the localMatrix parameter.
+ */
+ virtual sk_sp<SkShader> makeAsALocalMatrixShader(SkMatrix* localMatrix) const;
+
+ virtual bool isRasterPipelineOnly() const { return false; }
+
+ bool appendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
+ const SkMatrix& ctm, const SkPaint&, const SkMatrix* localM=nullptr) const;
+
+ bool computeTotalInverse(const SkMatrix& ctm,
+ const SkMatrix* outerLocalMatrix,
+ SkMatrix* totalInverse) const;
+
+#ifdef SK_SUPPORT_LEGACY_SHADER_ISABITMAP
+ virtual bool onIsABitmap(SkBitmap*, SkMatrix*, TileMode[2]) const {
+ return false;
+ }
+#endif
+
+ virtual SkImage* onIsAImage(SkMatrix*, TileMode[2]) const {
+ return nullptr;
+ }
+
+ SK_TO_STRING_VIRT()
+
+ SK_DEFINE_FLATTENABLE_TYPE(SkShaderBase)
+ SK_DECLARE_FLATTENABLE_REGISTRAR_GROUP()
+
+protected:
+ void flatten(SkWriteBuffer&) const override;
+
+ /**
+ * Specialize creating a SkShader context using the supplied allocator.
+ * @return pointer to context owned by the arena allocator.
+ */
+ virtual Context* onMakeContext(const ContextRec&, SkArenaAlloc*) const {
+ return nullptr;
+ }
+
+ virtual bool onAsLuminanceColor(SkColor*) const {
+ return false;
+ }
+
+ virtual sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer*) const {
+ return sk_ref_sp(const_cast<SkShaderBase*>(this));
+ }
+
+ virtual bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
+ const SkMatrix&, const SkPaint&, const SkMatrix* localM) const;
+
+private:
+ // This is essentially const, but not officially so it can be modified in constructors.
+ SkMatrix fLocalMatrix;
+
+ typedef SkShader INHERITED;
+};
+
+inline SkShaderBase* as_SB(SkShader* shader) {
+ return static_cast<SkShaderBase*>(shader);
+}
+
+inline const SkShaderBase* as_SB(const SkShader* shader) {
+ return static_cast<const SkShaderBase*>(shader);
+}
+
+inline const SkShaderBase* as_SB(const sk_sp<SkShader>& shader) {
+ return static_cast<SkShaderBase*>(shader.get());
+}
+
+#endif // SkShaderBase_DEFINED
When not using implicit distance, then b in the input color represents the input to the
blur function.
*/
-class SkGaussianEdgeShaderImpl : public SkShader {
+class SkGaussianEdgeShaderImpl : public SkShaderBase {
public:
SkGaussianEdgeShaderImpl() {}
private:
friend class SkGaussianEdgeShader;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
////////////////////////////////////////////////////////////////////////////
#ifndef SkGaussianEdgeShader_DEFINED
#define SkGaussianEdgeShader_DEFINED
-#include "SkShader.h"
+#include "SkShaderBase.h"
class SK_API SkGaussianEdgeShader {
public:
#include "SkArenaAlloc.h"
#include "SkColorFilter.h"
#include "SkReadBuffer.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkString.h"
#include "SkUnPreMultiply.h"
#include "SkWriteBuffer.h"
return t * t * (3 - 2 * t);
}
-class SkPerlinNoiseShaderImpl final : public SkShader {
+class SkPerlinNoiseShaderImpl final : public SkShaderBase {
public:
/**
* About the noise types : the difference between the 2 is just minor tweaks to the algorithm,
Context* onMakeContext(const ContextRec&, SkArenaAlloc* storage) const override;
private:
- class PerlinNoiseShaderContext final : public SkShader::Context {
+ class PerlinNoiseShaderContext final : public Context {
public:
PerlinNoiseShaderContext(const SkPerlinNoiseShaderImpl& shader, const ContextRec&);
~PerlinNoiseShaderContext() override;
SkMatrix fMatrix;
PaintingData* fPaintingData;
- typedef SkShader::Context INHERITED;
+ typedef Context INHERITED;
};
const Type fType;
friend class ::SkPerlinNoiseShader;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
} // end namespace
return SkPreMultiplyARGB(rgba[3], rgba[0], rgba[1], rgba[2]);
}
-SkShader::Context* SkPerlinNoiseShaderImpl::onMakeContext(
+SkShaderBase::Context* SkPerlinNoiseShaderImpl::onMakeContext(
const ContextRec& rec, SkArenaAlloc* alloc) const {
return alloc->make<PerlinNoiseShaderContext>(*this, rec);
}
stitchTiles ? &tileSize : nullptr));
GrTest::TestAsFPArgs asFPArgs(d);
- return shader->asFragmentProcessor(asFPArgs.args());
+ return as_SB(shader)->asFragmentProcessor(asFPArgs.args());
}
#endif
#include "SkMatrix.h"
#include "SkNx.h"
#include "SkPM4f.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkTArray.h"
struct Sk4fGradientInterval {
};
class SkGradientShaderBase::
-GradientShaderBase4fContext : public SkShader::Context {
+GradientShaderBase4fContext : public Context {
public:
GradientShaderBase4fContext(const SkGradientShaderBase&,
const ContextRec&);
bool fColorsArePremul;
private:
- using INHERITED = SkShader::Context;
+ using INHERITED = Context;
void addMirrorIntervals(const SkGradientShaderBase&,
const Sk4f& componentScale, bool reverse);
fDstToIndex.setConcat(shader.fPtsToUnit, inverse);
fDstToIndexProc = fDstToIndex.getMapXYProc();
- fDstToIndexClass = (uint8_t)SkShader::Context::ComputeMatrixClass(fDstToIndex);
+ fDstToIndexClass = (uint8_t)SkShaderBase::Context::ComputeMatrixClass(fDstToIndex);
// now convert our colors in to PMColors
unsigned paintAlpha = this->getPaintAlpha();
#include "SkPM4fPriv.h"
#include "SkRasterPipeline.h"
#include "SkReadBuffer.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkUtils.h"
#include "SkWriteBuffer.h"
///////////////////////////////////////////////////////////////////////////////
-class SkGradientShaderBase : public SkShader {
+class SkGradientShaderBase : public SkShaderBase {
public:
struct Descriptor {
Descriptor() {
U8CPU alpha, uint32_t gradFlags, bool dither);
};
- class GradientShaderBaseContext : public SkShader::Context {
+ class GradientShaderBaseContext : public Context {
public:
GradientShaderBaseContext(const SkGradientShaderBase& shader, const ContextRec&);
sk_sp<GradientShaderCache> fCache;
private:
- typedef SkShader::Context INHERITED;
+ typedef Context INHERITED;
};
bool isOpaque() const override;
void initCommon();
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
return matrix;
}
-static bool use_4f_context(const SkShader::ContextRec& rec, uint32_t flags) {
+static bool use_4f_context(const SkShaderBase::ContextRec& rec, uint32_t flags) {
#ifdef FORCE_4F_CONTEXT
return true;
#else
- return rec.fPreferredDstType == SkShader::ContextRec::kPM4f_DstType
+ return rec.fPreferredDstType == SkShaderBase::ContextRec::kPM4f_DstType
|| SkToBool(flags & SkLinearGradient::kForce4fContext_PrivateFlag);
#endif
}
buffer.writePoint(fEnd);
}
-SkShader::Context* SkLinearGradient::onMakeContext(
+SkShaderBase::Context* SkLinearGradient::onMakeContext(
const ContextRec& rec, SkArenaAlloc* alloc) const
{
return use_4f_context(rec, fGradFlags)
SkGradientShader::MakeLinear(points, params.fColors, params.fStops,
params.fColorCount, params.fTileMode);
GrTest::TestAsFPArgs asFPArgs(d);
- sk_sp<GrFragmentProcessor> fp = shader->asFragmentProcessor(asFPArgs.args());
+ sk_sp<GrFragmentProcessor> fp = as_SB(shader)->asFragmentProcessor(asFPArgs.args());
GrAlwaysAssert(fp);
return fp;
}
, fRadius(radius) {
}
-SkShader::Context* SkRadialGradient::onMakeContext(
+SkShaderBase::Context* SkRadialGradient::onMakeContext(
const ContextRec& rec, SkArenaAlloc* alloc) const
{
return CheckedMakeContext<RadialGradientContext>(alloc, *this, rec);
params.fTileMode);
} while (!shader);
GrTest::TestAsFPArgs asFPArgs(d);
- sk_sp<GrFragmentProcessor> fp = shader->asFragmentProcessor(asFPArgs.args());
+ sk_sp<GrFragmentProcessor> fp = as_SB(shader)->asFragmentProcessor(asFPArgs.args());
GrAlwaysAssert(fp);
return fp;
}
buffer.writePoint(fCenter);
}
-SkShader::Context* SkSweepGradient::onMakeContext(
+SkShaderBase::Context* SkSweepGradient::onMakeContext(
const ContextRec& rec, SkArenaAlloc* alloc) const
{
return CheckedMakeContext<SweepGradientContext>(alloc, *this, rec);
SkGradientShader::MakeSweep(center.fX, center.fY, params.fColors,
params.fStops, params.fColorCount);
GrTest::TestAsFPArgs asFPArgs(d);
- sk_sp<GrFragmentProcessor> fp = shader->asFragmentProcessor(asFPArgs.args());
+ sk_sp<GrFragmentProcessor> fp = as_SB(shader)->asFragmentProcessor(asFPArgs.args());
GrAlwaysAssert(fp);
return fp;
}
return false;
}
-SkShader::Context* SkTwoPointConicalGradient::onMakeContext(
+SkShaderBase::Context* SkTwoPointConicalGradient::onMakeContext(
const ContextRec& rec, SkArenaAlloc* alloc) const {
return CheckedMakeContext<TwoPointConicalGradientContext>(alloc, *this, rec);
}
params.fColors, params.fStops,
params.fColorCount, params.fTileMode);
GrTest::TestAsFPArgs asFPArgs(d);
- sk_sp<GrFragmentProcessor> fp = shader->asFragmentProcessor(asFPArgs.args());
+ sk_sp<GrFragmentProcessor> fp = as_SB(shader)->asFragmentProcessor(asFPArgs.args());
GrAlwaysAssert(fp);
return fp;
}
params.fColors, params.fStops,
params.fColorCount, params.fTileMode);
GrTest::TestAsFPArgs asFPArgs(d);
- sk_sp<GrFragmentProcessor> fp = shader->asFragmentProcessor(asFPArgs.args());
+ sk_sp<GrFragmentProcessor> fp = as_SB(shader)->asFragmentProcessor(asFPArgs.args());
GrAlwaysAssert(fp);
return fp;
}
params.fColors, params.fStops,
params.fColorCount, params.fTileMode);
GrTest::TestAsFPArgs asFPArgs(d);
- sk_sp<GrFragmentProcessor> fp = shader->asFragmentProcessor(asFPArgs.args());
+ sk_sp<GrFragmentProcessor> fp = as_SB(shader)->asFragmentProcessor(asFPArgs.args());
GrAlwaysAssert(fp);
return fp;
}
params.fColors, params.fStops,
params.fColorCount, params.fTileMode);
GrTest::TestAsFPArgs asFPArgs(d);
- sk_sp<GrFragmentProcessor> fp = shader->asFragmentProcessor(asFPArgs.args());
+ sk_sp<GrFragmentProcessor> fp = as_SB(shader)->asFragmentProcessor(asFPArgs.args());
GrAlwaysAssert(fp);
return fp;
}
params.fColors, params.fStops,
params.fColorCount, params.fTileMode);
GrTest::TestAsFPArgs asFPArgs(d);
- sk_sp<GrFragmentProcessor> fp = shader->asFragmentProcessor(asFPArgs.args());
+ sk_sp<GrFragmentProcessor> fp = as_SB(shader)->asFragmentProcessor(asFPArgs.args());
GrAlwaysAssert(fp);
return fp;
}
#include "GrColorSpaceXform.h"
#include "SkPathEffect.h"
#include "SkRandom.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
#include "SkStrokeRec.h"
#include "../private/SkTemplates.h"
class TestAsFPArgs {
public:
TestAsFPArgs(GrProcessorTestData*);
- const SkShader::AsFPArgs& args() const { return fArgs; }
+ const SkShaderBase::AsFPArgs& args() const { return fArgs; }
private:
- SkShader::AsFPArgs fArgs;
+ SkShaderBase::AsFPArgs fArgs;
SkMatrix fViewMatrixStorage;
sk_sp<SkColorSpace> fColorSpaceStorage;
};
#include "SkPM4fPriv.h"
#include "SkPixelRef.h"
#include "SkResourceCache.h"
+#include "SkShaderBase.h"
#include "SkTemplates.h"
#include "effects/GrBicubicEffect.h"
#include "effects/GrConstColorProcessor.h"
if (!primColorMode || blend_requires_shader(*primColorMode)) {
if (shaderProcessor) {
shaderFP = *shaderProcessor;
- } else if (const SkShader* shader = skPaint.getShader()) {
- shaderFP = shader->asFragmentProcessor(SkShader::AsFPArgs(context, &viewM, nullptr,
- skPaint.getFilterQuality(),
- rtc->getColorSpace()));
+ } else if (const auto* shader = as_SB(skPaint.getShader())) {
+ shaderFP = shader->asFragmentProcessor(
+ SkShaderBase::AsFPArgs(context, &viewM, nullptr, skPaint.getFilterQuality(),
+ rtc->getColorSpace()));
if (!shaderFP) {
return false;
}
GrPaint* grPaint) {
sk_sp<GrFragmentProcessor> shaderFP;
if (textureIsAlphaOnly) {
- if (const SkShader* shader = paint.getShader()) {
- shaderFP = shader->asFragmentProcessor(SkShader::AsFPArgs(context,
- &viewM,
- nullptr,
- paint.getFilterQuality(),
- rtc->getColorSpace()));
+ if (const auto* shader = as_SB(paint.getShader())) {
+ shaderFP = shader->asFragmentProcessor(
+ SkShaderBase::AsFPArgs(context, &viewM, nullptr, paint.getFilterQuality(),
+ rtc->getColorSpace()));
if (!shaderFP) {
return false;
}
return fImage->isOpaque();
}
-SkShader::Context* SkImageShader::onMakeContext(const ContextRec& rec, SkArenaAlloc* alloc) const {
+SkShaderBase::Context* SkImageShader::onMakeContext(const ContextRec& rec,
+ SkArenaAlloc* alloc) const {
return SkBitmapProcLegacyShader::MakeContext(*this, fTileModeX, fTileModeY,
SkBitmapProvider(fImage.get(), rec.fDstColorSpace),
rec, alloc);
return image ? image->makeShader(mx, my, &lm) : nullptr;
}
-SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShader)
+SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkShaderBase)
SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkImageShader)
-SkFlattenable::Register("SkBitmapProcShader", SkBitmapProcShader_CreateProc, kSkShader_Type);
+SkFlattenable::Register("SkBitmapProcShader", SkBitmapProcShader_CreateProc, kSkShaderBase_Type);
SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
#include "SkBitmapProcShader.h"
#include "SkColorSpaceXformer.h"
#include "SkImage.h"
-#include "SkShader.h"
+#include "SkShaderBase.h"
-class SkImageShader : public SkShader {
+class SkImageShader : public SkShaderBase {
public:
static sk_sp<SkShader> Make(sk_sp<SkImage>, TileMode tx, TileMode ty,
const SkMatrix* localMatrix);
const TileMode fTileModeY;
private:
- friend class SkShader;
+ friend class SkShaderBase;
- typedef SkShader INHERITED;
+ typedef SkShaderBase INHERITED;
};
#endif
#include "SkNormalSource.h"
#include "SkOSFile.h"
#include "SkPictureRecorder.h"
+#include "SkShaderBase.h"
#include "SkTableColorFilter.h"
#include "SkTemplates.h"
#include "SkTypeface.h"
sk_sp<SkShader> lightingShader = SkLightingShader::Make(diffuseShader,
normalSource,
fLights);
- sk_sp<SkShader>(TestFlattenableSerialization(lightingShader.get(), true, reporter));
+ sk_sp<SkShader>(TestFlattenableSerialization(as_SB(lightingShader.get()), true, reporter));
lightingShader = SkLightingShader::Make(std::move(diffuseShader),
nullptr,
fLights);
- sk_sp<SkShader>(TestFlattenableSerialization(lightingShader.get(), true, reporter));
+ sk_sp<SkShader>(TestFlattenableSerialization(as_SB(lightingShader.get()), true, reporter));
lightingShader = SkLightingShader::Make(nullptr,
std::move(normalSource),
fLights);
- sk_sp<SkShader>(TestFlattenableSerialization(lightingShader.get(), true, reporter));
+ sk_sp<SkShader>(TestFlattenableSerialization(as_SB(lightingShader.get()), true, reporter));
lightingShader = SkLightingShader::Make(nullptr,
nullptr,
fLights);
- sk_sp<SkShader>(TestFlattenableSerialization(lightingShader.get(), true, reporter));
+ sk_sp<SkShader>(TestFlattenableSerialization(as_SB(lightingShader.get()), true, reporter));
}
// Test NormalBevelSource serialization
#include "GrClip.h"
#include "GrContext.h"
#include "SkGradientShader.h"
+#include "SkShaderBase.h"
#include "ops/GrTessellatingPathRenderer.h"
/*
SkColor colors[2] = { SK_ColorGREEN, SK_ColorBLUE };
sk_sp<SkShader> shader = SkGradientShader::MakeLinear(
pts, colors, nullptr, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode);
- SkShader::AsFPArgs args(
+ SkShaderBase::AsFPArgs args(
ctx, &SkMatrix::I(), &SkMatrix::I(), SkFilterQuality::kLow_SkFilterQuality, nullptr);
- return shader->asFragmentProcessor(args);
+ return as_SB(shader)->asFragmentProcessor(args);
}
static void test_path(GrContext* ctx,