Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Unified Diff: include/core/SkShader.h

Issue 160103002: Work in progress to make SkShader immutable. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/core/SkComposeShader.h ('k') | src/core/SkBlitter.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: include/core/SkShader.h
diff --git a/include/core/SkShader.h b/include/core/SkShader.h
index 108c6b0829b22ddb764a1aba14417b52f0a4f781..6a25f53101ce5819ef0554f676965bf3401e4358 100644
--- a/include/core/SkShader.h
+++ b/include/core/SkShader.h
@@ -128,59 +128,130 @@ public:
*/
virtual bool isOpaque() const { return false; }
+ // Moved to public so it could on a Context object. May not be the right place for it.
+ 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
+ };
+
/**
- * Return the alpha associated with the data returned by shadeSpan16(). If
- * kHasSpan16_Flag is not set, this value is meaningless.
+ * Total number of bytes needed to store subclass specific Context information.
+ * Each class will override this by including the macro DEFINE_CONTEXT_RETRIEVAL_FUNCTIONS()
+ * in its private section, and defining getMySpaceNeededForContext(), which returns the
+ * number of bytes required by that specific subclass (not including its parents).
+ */
+ virtual size_t getTotalSpaceNeededForContext() const { return 0; }
+
+ /**
+ * Called to get a pointer to subclass-specific information.
*/
- virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
+ virtual void* getMyContext(Context* c) const = 0;
+
+ class Context : public SkNoncopyable {
+ public:
+ Context(const SkMatrix& totalInverse, uint8_t paintAlpha,
+ SkBitmap::Config deviceConfig);
+
+ uint8_t getPaintAlpha() const { return fPaintAlpha; }
+ SkBitmap::Config getDeviceConfig() const { return (SkBitmap::Config)fDeviceConfig; }
+ const SkMatrix& getTotalInverse() const { return fTotalInverse; }
+ MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
+
+ /**
+ * Should not be called directly. Instead, the subclass should call getMyContext.
+ */
+ void* getExtraStorage() {
+ SkAssert(fStorageAllocated);
+ return fExtraStorage;
+ }
+
+ void reset(const SkShader& shader) {
+ // This can only be called once
+ SkAssert(!fStorageAllocated);
+ fExtraStorage = fStorage.reset(shader.getTotalSpaceNeededForContext());
+ // What should we do if this fails?
+ SkASSERT(fExtraStorage != NULL);
+ fStorageAllocated = true;
+ }
+
+ private:
+ SkMatrix fTotalInverse;
+ uint8_t fPaintAlpha;
+ uint8_t fDeviceConfig;
+ uint8_t fTotalInverseClass;
+ // This size is arbitrary, for now, but probably should be related to the size of the
+ // subclasses needed.
+ SkAutoSMalloc<1024> fStorage;
+ // Should be debugcode
+ bool fStorageAllocated;
+ // Space for the subclasses' Context information. Will pint to fStorage.
+ void* fExtraStorage;
+ };
/**
* 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
+ * Return a new Context object if your shader supports these parameters,
+ * or NULL if not. If NULL is returned, nothing will be drawn. On success,
* 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);
+ Context* setContext(const SkBitmap& device, const SkPaint& paint,
+ const SkMatrix& matrix);
+
+ /**
+ * Subclasses should be sure to call their INHERITED::onSetContext() if they
+ * override this method.
+ */
+ virtual bool onSetContext(Context* context, const SkBitmap& device,
+ const SkPaint& paint,
+ const SkMatrix& matrix) { return true; }
/**
* 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().
*
+ * This method will delete the Context object.
+ *
* Subclasses should be sure to call their INHERITED::endContext() if they
- * override this method.
+ * override this method, after deleting their subclass-specific info.
*/
- virtual void endContext();
+ virtual void endContext(Context*);
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(Context* c) const { return c->getPaintAlpha(); }
+
+ /**
* 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;
+ // FIXME: It may make more sense for Context to be a const ref? (Same for others)
+ virtual void shadeSpan(Context* c, int x, int y, SkPMColor[], int count) = 0;
+ // Used by SkBlitter_ARGB32.cpp
typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count);
+ // Will need to pass a Context to this as well.
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);
+ virtual void shadeSpan16(Context* c, 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);
+ virtual void shadeSpanAlpha(Context* c, int x, int y, uint8_t alpha[], int count);
/**
* Helper function that returns true if this shader's shadeSpan16() method
@@ -350,27 +421,13 @@ 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; }
- SkBitmap::Config getDeviceConfig() const { return (SkBitmap::Config)fDeviceConfig; }
- const SkMatrix& getTotalInverse() const { return fTotalInverse; }
- MatrixClass getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
-
SkShader(SkReadBuffer& );
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
private:
+ // FIXME: Move onto SkPaint.
SkMatrix fLocalMatrix;
- SkMatrix fTotalInverse;
- uint8_t fPaintAlpha;
- uint8_t fDeviceConfig;
- uint8_t fTotalInverseClass;
SkDEBUGCODE(SkBool8 fInSetContext;)
static SkShader* CreateBitmapShader(const SkBitmap& src,
@@ -380,4 +437,30 @@ private:
typedef SkFlattenable INHERITED;
};
+/**
+ * Each SkShader subclass must include the following macro in its private
+ * section (defined below):
+ *
+ * DEFINE_CONTEXT_RETRIEVAL_FUNCTIONS()
+ *
+ * It defines functions for accessing the particular subclass's specific
+ * information from the Context. The subclass must also implement the
+ * following function:
+ *
+ * size_t getMySpaceNeededForContext() const;
+ *
+ * This function will return the number of bytes required to store that
+ * subclasses Context information.
+ */
+
+#define DEFINE_CONTEXT_RETRIEVAL_FUNCTIONS() \
+ virtual size_t getTotalSpaceNeededForContext() const SK_OVERRIDE { \
+ return this->INHERITED::getTotalSpaceNeededForContext() \
+ + this->getMySpaceNeededForContext(); \
+ } \
+ virtual void* getMyContext(Context* c) const SK_OVERRIDE { \
+ return c->getExtraStorage() + this->INHERITED::getTotalSpaceNeededForContext(); \
+ }
+
+
#endif
« no previous file with comments | « include/core/SkComposeShader.h ('k') | src/core/SkBlitter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698