aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/core
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-04-17 21:09:49 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-04-17 21:09:49 +0000
commit53783b026a00683c1fb504127c3398dabb61ea73 (patch)
tree0dd91705720040c78d85b26e1cd3c082fa822db2 /include/core
parentec2d8b37b069a9871cf2228f1ff83f8d70628cab (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.h41
-rw-r--r--include/core/SkComposeShader.h37
-rw-r--r--include/core/SkEmptyShader.h26
-rw-r--r--include/core/SkShader.h167
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;
};