From 87fcd950198a16211b3988610beebb5ca5bcf323 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Wed, 23 Apr 2014 19:10:51 +0000 Subject: Revert of Revert of Extract most of the mutable state of SkShader into a separate Context object. (https://codereview.chromium.org/249643002/) Reason for revert: Chromium side change landed along side DEPS roll that includes r14323. Original issue's description: > Revert of Extract most of the mutable state of SkShader into a separate Context object. (https://codereview.chromium.org/207683004/) > > Reason for revert: > This is blocking the DEPS roll into Chromium. Failures can be seen here: > > http://build.chromium.org/p/tryserver.chromium/builders/android_dbg/builds/174333 > > Original issue's description: > > Extract most of the mutable state of SkShader into a separate Context object. > > > > SkShader currently stores some state during draw calls via setContext(...). > > Move that mutable state into a separate SkShader::Context class that is > > constructed on demand for the duration of the draw. > > > > Calls to setContext() are replaced with createContext() which returns a context > > corresponding to the shader object or NULL if the parameters to createContext > > are invalid. > > > > TEST=out/Debug/dm > > BUG=skia:1976 > > > > Committed: http://code.google.com/p/skia/source/detail?r=14216 > > > > Committed: http://code.google.com/p/skia/source/detail?r=14323 > > TBR=scroggo@google.com,skyostil@chromium.org,tomhudson@chromium.org,senorblanco@chromium.org,reed@google.com,bungeman@google.com,dominikg@chromium.org > NOTREECHECKS=true > NOTRY=true > BUG=skia:1976 > > Committed: http://code.google.com/p/skia/source/detail?r=14326 R=scroggo@google.com, skyostil@chromium.org, tomhudson@chromium.org, senorblanco@chromium.org, reed@google.com, bungeman@google.com, dominikg@chromium.org TBR=bungeman@google.com, dominikg@chromium.org, reed@google.com, scroggo@google.com, senorblanco@chromium.org, skyostil@chromium.org, tomhudson@chromium.org NOTREECHECKS=true NOTRY=true BUG=skia:1976 Author: bsalomon@google.com Review URL: https://codereview.chromium.org/246403013 git-svn-id: http://skia.googlecode.com/svn/trunk@14328 2bbb7eff-a529-9590-31e7-b0007b416f81 --- include/core/SkColorShader.h | 41 ++++++--- include/core/SkComposeShader.h | 37 +++++++- include/core/SkEmptyShader.h | 26 ++++-- include/core/SkShader.h | 167 ++++++++++++++++++---------------- include/effects/SkPerlinNoiseShader.h | 40 +++++--- include/effects/SkTransparentShader.h | 30 ++++-- 6 files changed, 214 insertions(+), 127 deletions(-) (limited to 'include') diff --git a/include/core/SkColorShader.h b/include/core/SkColorShader.h index 975156c0eb..56e5add4a3 100644 --- a/include/core/SkColorShader.h +++ b/include/core/SkColorShader.h @@ -30,16 +30,35 @@ public: */ SkColorShader(SkColor c); - virtual ~SkColorShader(); - - virtual uint32_t getFlags() SK_OVERRIDE; - virtual uint8_t getSpan16Alpha() const SK_OVERRIDE; virtual bool isOpaque() const SK_OVERRIDE; - virtual bool setContext(const SkBitmap& device, const SkPaint& paint, - const SkMatrix& matrix) SK_OVERRIDE; - virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE; - virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE; - virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) SK_OVERRIDE; + + virtual SkShader::Context* createContext(const SkBitmap& device, + const SkPaint& paint, + const SkMatrix& matrix, + void* storage) const SK_OVERRIDE; + + virtual size_t contextSize() const SK_OVERRIDE { + return sizeof(ColorShaderContext); + } + + class ColorShaderContext : public SkShader::Context { + public: + ColorShaderContext(const SkColorShader& shader, const SkBitmap& device, + const SkPaint& paint, const SkMatrix& matrix); + + virtual uint32_t getFlags() const SK_OVERRIDE; + virtual uint8_t getSpan16Alpha() const SK_OVERRIDE; + virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE; + virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE; + virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) SK_OVERRIDE; + + private: + SkPMColor fPMColor; + uint32_t fFlags; + uint16_t fColor16; + + typedef SkShader::Context INHERITED; + }; // we return false for this, use asAGradient virtual BitmapType asABitmap(SkBitmap* outTexture, @@ -56,11 +75,7 @@ protected: virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; private: - SkColor fColor; // ignored if fInheritColor is true - SkPMColor fPMColor; // cached after setContext() - uint32_t fFlags; // cached after setContext() - uint16_t fColor16; // cached after setContext() SkBool8 fInheritColor; typedef SkShader INHERITED; diff --git a/include/core/SkComposeShader.h b/include/core/SkComposeShader.h index b54e5efa97..d42da0c2f3 100644 --- a/include/core/SkComposeShader.h +++ b/include/core/SkComposeShader.h @@ -34,10 +34,38 @@ public: SkComposeShader(SkShader* sA, SkShader* sB, SkXfermode* mode = NULL); virtual ~SkComposeShader(); - virtual bool setContext(const SkBitmap&, const SkPaint&, - const SkMatrix&) SK_OVERRIDE; - virtual void endContext() SK_OVERRIDE; - virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; + virtual bool validContext(const SkBitmap&, const SkPaint&, + const SkMatrix&, SkMatrix* totalInverse = NULL) const SK_OVERRIDE; + virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, + const SkMatrix&, void*) const SK_OVERRIDE; + virtual size_t contextSize() const SK_OVERRIDE; + + class ComposeShaderContext : public SkShader::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 SkBitmap&, + const SkPaint&, const SkMatrix&, + SkShader::Context* contextA, SkShader::Context* contextB); + + SkShader::Context* getShaderContextA() const { return fShaderContextA; } + SkShader::Context* getShaderContextB() const { return fShaderContextB; } + + virtual ~ComposeShaderContext(); + + virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; + + private: + SkShader::Context* fShaderContextA; + SkShader::Context* fShaderContextB; + + typedef SkShader::Context INHERITED; + }; + +#ifdef SK_DEBUG + SkShader* getShaderA() { return fShaderA; } + SkShader* getShaderB() { return fShaderB; } +#endif SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader) @@ -47,7 +75,6 @@ protected: virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; private: - SkShader* fShaderA; SkShader* fShaderB; SkXfermode* fMode; diff --git a/include/core/SkEmptyShader.h b/include/core/SkEmptyShader.h index d2ebb61221..7494eff3d0 100644 --- a/include/core/SkEmptyShader.h +++ b/include/core/SkEmptyShader.h @@ -15,20 +15,28 @@ /** * \class SkEmptyShader - * A Shader that always draws nothing. Its setContext always returns false, - * so it never expects that its shadeSpan() methods will get called. + * A Shader that always draws nothing. Its createContext always returns NULL. */ class SK_API SkEmptyShader : public SkShader { public: SkEmptyShader() {} - virtual uint32_t getFlags() SK_OVERRIDE; - virtual uint8_t getSpan16Alpha() const SK_OVERRIDE; - virtual bool setContext(const SkBitmap&, const SkPaint&, - const SkMatrix&) SK_OVERRIDE; - virtual void shadeSpan(int x, int y, SkPMColor span[], int count) SK_OVERRIDE; - virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE; - virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) SK_OVERRIDE; + virtual size_t contextSize() const SK_OVERRIDE { + // Even though createContext returns NULL we have to return a value of at least + // sizeof(SkShader::Context) to satisfy SkSmallAllocator. + return sizeof(SkShader::Context); + } + + virtual bool validContext(const SkBitmap&, const SkPaint&, + const SkMatrix&, SkMatrix* totalInverse = NULL) const SK_OVERRIDE { + return false; + } + + virtual SkShader::Context* createContext(const SkBitmap&, const SkPaint&, + const SkMatrix&, void*) const SK_OVERRIDE { + // validContext returns false. + return NULL; + } SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader) diff --git a/include/core/SkShader.h b/include/core/SkShader.h index 6566e691a4..cc2cc751d8 100644 --- a/include/core/SkShader.h +++ b/include/core/SkShader.h @@ -38,7 +38,7 @@ public: virtual ~SkShader(); /** - * Returns true if the local matrix is not an identity matrix. + * Returns true if the local matrix is not an identity matrix. */ bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); } @@ -96,7 +96,7 @@ public: */ kIntrinsicly16_Flag = 0x04, - /** set (after setContext) if the spans only vary in X (const in Y). + /** 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(). @@ -111,85 +111,112 @@ public: kConstInY16_Flag = 0x10 }; - /** - * 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() { return 0; } - /** * Returns true if the shader is guaranteed to produce only opaque * colors, subject to the SkPaint using the shader to apply an opaque * alpha value. Subclasses should override this to allow some - * optimizations. isOpaque() can be called at any time, unlike getFlags, - * which only works properly when the context is set. + * optimizations. */ virtual bool isOpaque() const { return false; } - /** - * Return the alpha associated with the data returned by shadeSpan16(). If - * kHasSpan16_Flag is not set, this value is meaningless. - */ - virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; } + class Context : public ::SkNoncopyable { + public: + Context(const SkShader& shader, const SkBitmap& device, + const SkPaint& paint, const SkMatrix& matrix); - /** - * Called once before drawing, with the current paint and device matrix. - * Return true if your shader supports these parameters, or false if not. - * If false is returned, nothing will be drawn. If true is returned, then - * a balancing call to endContext() will be made before the next call to - * setContext. - * - * Subclasses should be sure to call their INHERITED::setContext() if they - * override this method. - */ - virtual bool setContext(const SkBitmap& device, const SkPaint& paint, - const SkMatrix& matrix); + virtual ~Context(); - /** - * Assuming setContext returned true, endContext() will be called when - * the draw using the shader has completed. It is an error for setContext - * to be called twice w/o an intervening call to endContext(). - * - * Subclasses should be sure to call their INHERITED::endContext() if they - * override this method. - */ - virtual void endContext(); + /** + * 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; } - SkDEBUGCODE(bool setContextHasBeenCalled() const { return SkToBool(fInSetContext); }) + /** + * Return the alpha associated with the data returned by shadeSpan16(). If + * kHasSpan16_Flag is not set, this value is meaningless. + */ + virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; } - /** - * 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; + /** + * 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; + + typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count); + virtual ShadeProc asAShadeProc(void** ctx); + + /** + * Called only for 16bit devices when getFlags() returns + * kOpaqueAlphaFlag | kHasSpan16_Flag + */ + virtual void shadeSpan16(int x, int y, uint16_t[], int count); + + /** + * 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); - typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count); - virtual ShadeProc asAShadeProc(void** ctx); + /** + * Helper function that returns true if this shader's shadeSpan16() method + * can be called. + */ + bool canCallShadeSpan16() { + return SkShader::CanCallShadeSpan16(this->getFlags()); + } + + 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; } + + private: + SkMatrix fTotalInverse; + uint8_t fPaintAlpha; + uint8_t fTotalInverseClass; + + typedef SkNoncopyable INHERITED; + }; /** - * Called only for 16bit devices when getFlags() returns - * kOpaqueAlphaFlag | kHasSpan16_Flag + * Subclasses should be sure to call their INHERITED::validContext() if + * they override this method. */ - virtual void shadeSpan16(int x, int y, uint16_t[], int count); + virtual bool validContext(const SkBitmap& device, const SkPaint& paint, + const SkMatrix& matrix, SkMatrix* totalInverse = NULL) const; /** - * 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. + * Create the actual object that does the shading. + * Returns NULL if validContext() returns false. + * Size of storage must be >= contextSize. */ - virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count); + virtual Context* createContext(const SkBitmap& device, + const SkPaint& paint, + const SkMatrix& matrix, + void* storage) const = 0; /** - * Helper function that returns true if this shader's shadeSpan16() method - * can be called. + * Return the size of a Context returned by createContext. */ - bool canCallShadeSpan16() { - return SkShader::CanCallShadeSpan16(this->getFlags()); - } + virtual size_t contextSize() const = 0; /** * Helper to check the flags to know if it is legal to call shadeSpan16() @@ -322,7 +349,7 @@ public: * The incoming color to the effect has r=g=b=a all extracted from the SkPaint's alpha. * The output color should be the computed SkShader premul color modulated by the incoming * color. The GrContext may be used by the effect to create textures. The GPU device does not - * call setContext. Instead we pass the SkPaint here in case the shader needs paint info. + * call createContext. Instead we pass the SkPaint here in case the shader needs paint info. */ virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const; @@ -362,26 +389,14 @@ public: SK_DEFINE_FLATTENABLE_TYPE(SkShader) protected: - 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&); - - // These can be called by your subclass after setContext() has been called - uint8_t getPaintAlpha() const { return fPaintAlpha; } - const SkMatrix& getTotalInverse() const { return fTotalInverse; } - MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; } SkShader(SkReadBuffer& ); virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; + private: SkMatrix fLocalMatrix; - SkMatrix fTotalInverse; - uint8_t fPaintAlpha; - uint8_t fTotalInverseClass; - SkDEBUGCODE(SkBool8 fInSetContext;) + + bool computeTotalInverse(const SkMatrix& matrix, SkMatrix* totalInverse) const; typedef SkFlattenable INHERITED; }; diff --git a/include/effects/SkPerlinNoiseShader.h b/include/effects/SkPerlinNoiseShader.h index dfd5a8c1e7..5b270293b1 100644 --- a/include/effects/SkPerlinNoiseShader.h +++ b/include/effects/SkPerlinNoiseShader.h @@ -72,10 +72,32 @@ public: } - virtual bool setContext(const SkBitmap& device, const SkPaint& paint, - const SkMatrix& matrix); - virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; - virtual void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE; + virtual SkShader::Context* createContext( + const SkBitmap& device, const SkPaint& paint, + const SkMatrix& matrix, void* storage) const SK_OVERRIDE; + virtual size_t contextSize() const SK_OVERRIDE; + + class PerlinNoiseShaderContext : public SkShader::Context { + public: + PerlinNoiseShaderContext(const SkPerlinNoiseShader& shader, const SkBitmap& device, + const SkPaint& paint, const SkMatrix& matrix); + virtual ~PerlinNoiseShaderContext() {} + + virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; + virtual void shadeSpan16(int x, int y, uint16_t[], int count) SK_OVERRIDE; + + private: + SkPMColor shade(const SkPoint& point, StitchData& stitchData) const; + SkScalar calculateTurbulenceValueForPoint( + int channel, const PaintingData& paintingData, + StitchData& stitchData, const SkPoint& point) const; + SkScalar noise2D(int channel, const PaintingData& paintingData, + const StitchData& stitchData, const SkPoint& noiseVector) const; + + SkMatrix fMatrix; + + typedef SkShader::Context INHERITED; + }; virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint&) const SK_OVERRIDE; @@ -92,14 +114,6 @@ private: const SkISize* tileSize); virtual ~SkPerlinNoiseShader(); - SkScalar noise2D(int channel, const PaintingData& paintingData, - const StitchData& stitchData, const SkPoint& noiseVector) const; - - SkScalar calculateTurbulenceValueForPoint(int channel, const PaintingData& paintingData, - StitchData& stitchData, const SkPoint& point) const; - - SkPMColor shade(const SkPoint& point, StitchData& stitchData) const; - // TODO (scroggo): Once all SkShaders are created from a factory, and we have removed the // constructor that creates SkPerlinNoiseShader from an SkReadBuffer, several fields can // be made constant. @@ -110,8 +124,6 @@ private: /*const*/ SkScalar fSeed; /*const*/ SkISize fTileSize; /*const*/ bool fStitchTiles; - // TODO (scroggo): Once setContext creates a new object, place this on that object. - SkMatrix fMatrix; PaintingData* fPaintingData; diff --git a/include/effects/SkTransparentShader.h b/include/effects/SkTransparentShader.h index 7428d442e3..790e5ae9fd 100644 --- a/include/effects/SkTransparentShader.h +++ b/include/effects/SkTransparentShader.h @@ -14,21 +14,31 @@ class SK_API SkTransparentShader : public SkShader { public: SkTransparentShader() {} - virtual uint32_t getFlags() SK_OVERRIDE; - virtual bool setContext(const SkBitmap& device, - const SkPaint& paint, - const SkMatrix& matrix) SK_OVERRIDE; - virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; - virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE; + virtual SkShader::Context* createContext(const SkBitmap& device, const SkPaint& paint, + const SkMatrix& matrix, void* storage) const + SK_OVERRIDE; + virtual size_t contextSize() const SK_OVERRIDE; + + class TransparentShaderContext : public SkShader::Context { + public: + TransparentShaderContext(const SkTransparentShader& shader, const SkBitmap& device, + const SkPaint& paint, const SkMatrix& matrix); + virtual ~TransparentShaderContext(); + + virtual uint32_t getFlags() const SK_OVERRIDE; + virtual void shadeSpan(int x, int y, SkPMColor[], int count) SK_OVERRIDE; + virtual void shadeSpan16(int x, int y, uint16_t span[], int count) SK_OVERRIDE; + + private: + const SkBitmap* fDevice; + + typedef SkShader::Context INHERITED; + }; SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTransparentShader) private: - // these are a cache from the call to setContext() - const SkBitmap* fDevice; - uint8_t fAlpha; - SkTransparentShader(SkReadBuffer& buffer) : INHERITED(buffer) {} typedef SkShader INHERITED; -- cgit v1.2.3