diff options
author | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-04-17 21:09:49 +0000 |
---|---|---|
committer | commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2014-04-17 21:09:49 +0000 |
commit | 53783b026a00683c1fb504127c3398dabb61ea73 (patch) | |
tree | 0dd91705720040c78d85b26e1cd3c082fa822db2 /include/core | |
parent | ec2d8b37b069a9871cf2228f1ff83f8d70628cab (diff) |
Revert of Extract most of the mutable state of SkShader into a separate Context object. (https://codereview.chromium.org/207683004/)
Reason for revert:
Causing memory leaks in Chromium.
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
R=scroggo@google.com, skyostil@chromium.org, tomhudson@chromium.org, senorblanco@chromium.org, reed@google.com, dominikg@chromium.org
TBR=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: bungeman@google.com
Review URL: https://codereview.chromium.org/241283003
git-svn-id: http://skia.googlecode.com/svn/trunk@14247 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/core')
-rw-r--r-- | include/core/SkColorShader.h | 41 | ||||
-rw-r--r-- | include/core/SkComposeShader.h | 37 | ||||
-rw-r--r-- | include/core/SkEmptyShader.h | 26 | ||||
-rw-r--r-- | include/core/SkShader.h | 167 |
4 files changed, 103 insertions, 168 deletions
diff --git a/include/core/SkColorShader.h b/include/core/SkColorShader.h index 56e5add4a3..975156c0eb 100644 --- a/include/core/SkColorShader.h +++ b/include/core/SkColorShader.h @@ -30,35 +30,16 @@ public: */ SkColorShader(SkColor c); - virtual bool isOpaque() const 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 ~SkColorShader(); - 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; - }; + 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; // we return false for this, use asAGradient virtual BitmapType asABitmap(SkBitmap* outTexture, @@ -75,7 +56,11 @@ 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 9833a9f4ad..b54e5efa97 100644 --- a/include/core/SkComposeShader.h +++ b/include/core/SkComposeShader.h @@ -34,38 +34,10 @@ public: SkComposeShader(SkShader* sA, SkShader* sB, SkXfermode* mode = NULL); virtual ~SkComposeShader(); - 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; - }; - -#if SK_DEBUG - SkShader* getShaderA() { return fShaderA; } - SkShader* getShaderB() { return fShaderB; } -#endif + 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; SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposeShader) @@ -75,6 +47,7 @@ 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 7494eff3d0..d2ebb61221 100644 --- a/include/core/SkEmptyShader.h +++ b/include/core/SkEmptyShader.h @@ -15,28 +15,20 @@ /** * \class SkEmptyShader - * A Shader that always draws nothing. Its createContext always returns NULL. + * A Shader that always draws nothing. Its setContext always returns false, + * so it never expects that its shadeSpan() methods will get called. */ class SK_API SkEmptyShader : public SkShader { public: SkEmptyShader() {} - 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; - } + 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; SK_TO_STRING_OVERRIDE() SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkEmptyShader) diff --git a/include/core/SkShader.h b/include/core/SkShader.h index 58e5a6ad2e..076ecf5460 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 if the spans only vary in X (const in Y). + /** set (after setContext) 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(). @@ -112,111 +112,84 @@ public: }; /** + * 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. + * optimizations. isOpaque() can be called at any time, unlike getFlags, + * which only works properly when the context is set. */ virtual bool isOpaque() const { return false; } - class Context : public ::SkNoncopyable { - public: - Context(const SkShader& shader, const SkBitmap& device, - const SkPaint& paint, const SkMatrix& matrix); - - 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; } - - /** - * 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; } + /** + * 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 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); - typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count); - virtual ShadeProc asAShadeProc(void** ctx); + /** + * 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 only for 16bit devices when getFlags() returns - * kOpaqueAlphaFlag | kHasSpan16_Flag - */ - virtual void shadeSpan16(int x, int y, uint16_t[], int count); + SkDEBUGCODE(bool setContextHasBeenCalled() const { return SkToBool(fInSetContext); }) - /** - * 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); + /** + * 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; - /** - * 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; - }; + typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count); + virtual ShadeProc asAShadeProc(void** ctx); /** - * Subclasses should be sure to call their INHERITED::validContext() if - * they override this method. + * Called only for 16bit devices when getFlags() returns + * kOpaqueAlphaFlag | kHasSpan16_Flag */ - virtual bool validContext(const SkBitmap& device, const SkPaint& paint, - const SkMatrix& matrix, SkMatrix* totalInverse = NULL) const; + virtual void shadeSpan16(int x, int y, uint16_t[], int count); /** - * Create the actual object that does the shading. - * Returns NULL if validContext() returns false. - * Size of storage must be >= contextSize. + * 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 Context* createContext(const SkBitmap& device, - const SkPaint& paint, - const SkMatrix& matrix, - void* storage) const = 0; + virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count); /** - * Return the size of a Context returned by createContext. + * Helper function that returns true if this shader's shadeSpan16() method + * can be called. */ - virtual size_t contextSize() const = 0; + bool canCallShadeSpan16() { + return SkShader::CanCallShadeSpan16(this->getFlags()); + } /** * Helper to check the flags to know if it is legal to call shadeSpan16() @@ -349,7 +322,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 createContext. Instead we pass the SkPaint here in case the shader needs paint info. + * call setContext. Instead we pass the SkPaint here in case the shader needs paint info. */ virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) const; @@ -387,14 +360,26 @@ 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; - - bool computeTotalInverse(const SkMatrix& matrix, SkMatrix* totalInverse) const; + SkMatrix fTotalInverse; + uint8_t fPaintAlpha; + uint8_t fTotalInverseClass; + SkDEBUGCODE(SkBool8 fInSetContext;) typedef SkFlattenable INHERITED; }; |