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

Side by Side Diff: include/core/SkShader.h

Issue 207683004: Extract most of the mutable state of SkShader into a separate Context object. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: clean up Created 6 years, 9 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 8
9 #ifndef SkShader_DEFINED 9 #ifndef SkShader_DEFINED
10 #define SkShader_DEFINED 10 #define SkShader_DEFINED
(...skipping 19 matching lines...) Expand all
30 * to be modified. 30 * to be modified.
31 */ 31 */
32 class SK_API SkShader : public SkFlattenable { 32 class SK_API SkShader : public SkFlattenable {
33 public: 33 public:
34 SK_DECLARE_INST_COUNT(SkShader) 34 SK_DECLARE_INST_COUNT(SkShader)
35 35
36 SkShader(); 36 SkShader();
37 virtual ~SkShader(); 37 virtual ~SkShader();
38 38
39 /** 39 /**
40 * Returns true if the local matrix is not an identity matrix. 40 * Returns true if the local matrix is not an identity matrix.
41 * FIXME: local matrix is moving to SkPaint.
41 */ 42 */
42 bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); } 43 bool hasLocalMatrix() const { return !fLocalMatrix.isIdentity(); }
43 44
44 /** 45 /**
45 * Returns the local matrix. 46 * Returns the local matrix.
47 * FIXME: local matrix is moving to SkPaint.
46 */ 48 */
47 const SkMatrix& getLocalMatrix() const { return fLocalMatrix; } 49 const SkMatrix& getLocalMatrix() const { return fLocalMatrix; }
48 50
49 /** 51 /**
50 * Set the shader's local matrix. 52 * Set the shader's local matrix.
51 * @param localM The shader's new local matrix. 53 * @param localM The shader's new local matrix.
54 *
55 * FIXME: local matrix is moving to SkPaint.
52 */ 56 */
53 void setLocalMatrix(const SkMatrix& localM) { fLocalMatrix = localM; } 57 void setLocalMatrix(const SkMatrix& localM) { fLocalMatrix = localM; }
54 58
55 /** 59 /**
56 * Reset the shader's local matrix to identity. 60 * Reset the shader's local matrix to identity.
61 *
62 * FIXME: local matrix is moving to SkPaint.
57 */ 63 */
58 void resetLocalMatrix() { fLocalMatrix.reset(); } 64 void resetLocalMatrix() { fLocalMatrix.reset(); }
59 65
60 enum TileMode { 66 enum TileMode {
61 /** replicate the edge color if the shader draws outside of its 67 /** replicate the edge color if the shader draws outside of its
62 * original bounds 68 * original bounds
63 */ 69 */
64 kClamp_TileMode, 70 kClamp_TileMode,
65 71
66 /** repeat the shader's image horizontally and vertically */ 72 /** repeat the shader's image horizontally and vertically */
(...skipping 21 matching lines...) Expand all
88 //! set if this shader's shadeSpan16() method can be called 94 //! set if this shader's shadeSpan16() method can be called
89 kHasSpan16_Flag = 0x02, 95 kHasSpan16_Flag = 0x02,
90 96
91 /** Set this bit if the shader's native data type is instrinsically 16 97 /** Set this bit if the shader's native data type is instrinsically 16
92 bit, meaning that calling the 32bit shadeSpan() entry point will 98 bit, meaning that calling the 32bit shadeSpan() entry point will
93 mean the the impl has to up-sample 16bit data into 32bit. Used as a 99 mean the the impl has to up-sample 16bit data into 32bit. Used as a
94 a means of clearing a dither request if the it will have no effect 100 a means of clearing a dither request if the it will have no effect
95 */ 101 */
96 kIntrinsicly16_Flag = 0x04, 102 kIntrinsicly16_Flag = 0x04,
97 103
98 /** set (after setContext) if the spans only vary in X (const in Y). 104 /** set if the spans only vary in X (const in Y).
99 e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient 105 e.g. an Nx1 bitmap that is being tiled in Y, or a linear-gradient
100 that varies from left-to-right. This flag specifies this for 106 that varies from left-to-right. This flag specifies this for
101 shadeSpan(). 107 shadeSpan().
102 */ 108 */
103 kConstInY32_Flag = 0x08, 109 kConstInY32_Flag = 0x08,
104 110
105 /** same as kConstInY32_Flag, but is set if this is true for shadeSpan16 111 /** same as kConstInY32_Flag, but is set if this is true for shadeSpan16
106 which may not always be the case, since shadeSpan16 may be 112 which may not always be the case, since shadeSpan16 may be
107 predithered, which would mean it was not const in Y, even though 113 predithered, which would mean it was not const in Y, even though
108 the 32bit shadeSpan() would be const. 114 the 32bit shadeSpan() would be const.
109 */ 115 */
110 kConstInY16_Flag = 0x10 116 kConstInY16_Flag = 0x10
111 }; 117 };
112 118
113 /** 119 /**
114 * Called sometimes before drawing with this shader. Return the type of
115 * alpha your shader will return. The default implementation returns 0.
116 * Your subclass should override if it can (even sometimes) report a
117 * non-zero value, since that will enable various blitters to perform
118 * faster.
119 */
120 virtual uint32_t getFlags() { return 0; }
121
122 /**
123 * Returns true if the shader is guaranteed to produce only opaque 120 * Returns true if the shader is guaranteed to produce only opaque
124 * colors, subject to the SkPaint using the shader to apply an opaque 121 * colors, subject to the SkPaint using the shader to apply an opaque
125 * alpha value. Subclasses should override this to allow some 122 * alpha value. Subclasses should override this to allow some
126 * optimizations. isOpaque() can be called at any time, unlike getFlags, 123 * optimizations.
127 * which only works properly when the context is set.
128 */ 124 */
129 virtual bool isOpaque() const { return false; } 125 virtual bool isOpaque() const { return false; }
130 126
131 /** 127 class Context : public SkNoncopyable {
132 * Return the alpha associated with the data returned by shadeSpan16(). If 128 public:
133 * kHasSpan16_Flag is not set, this value is meaningless. 129 Context(const SkShader& shader, const SkBitmap& device,
134 */ 130 const SkPaint& paint, const SkMatrix& matrix);
135 virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; } 131
132 virtual ~Context();
133
134 /**
135 * Called sometimes before drawing with this shader. Return the type of
136 * alpha your shader will return. The default implementation returns 0.
137 * Your subclass should override if it can (even sometimes) report a
138 * non-zero value, since that will enable various blitters to perform
139 * faster.
140 */
141 virtual uint32_t getFlags() const { return 0; }
142
143 /**
144 * Return the alpha associated with the data returned by shadeSpan16(). If
145 * kHasSpan16_Flag is not set, this value is meaningless.
146 */
147 virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
148
149 /**
150 * Called for each span of the object being drawn. Your subclass should
151 * set the appropriate colors (with premultiplied alpha) that correspon d
152 * to the specified device coordinates.
153 */
154 virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0;
155
156 typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int coun t);
157 virtual ShadeProc asAShadeProc(void** ctx);
158
159 /**
160 * Called only for 16bit devices when getFlags() returns
161 * kOpaqueAlphaFlag | kHasSpan16_Flag
162 */
163 virtual void shadeSpan16(int x, int y, uint16_t[], int count);
164
165 /**
166 * Similar to shadeSpan, but only returns the alpha-channel for a span.
167 * The default implementation calls shadeSpan() and then extracts the a lpha
168 * values from the returned colors.
169 */
170 virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
171
172 /**
173 * Helper function that returns true if this shader's shadeSpan16() met hod
174 * can be called.
175 */
176 bool canCallShadeSpan16() {
177 return SkShader::CanCallShadeSpan16(this->getFlags());
178 }
179
180 protected:
181 // Reference to generator, so we don't have to dupe information.
182 const SkShader& fShader;
183
184 enum MatrixClass {
185 kLinear_MatrixClass, // no perspective
186 kFixedStepInX_MatrixClass, // fast perspective, need to call fi xedStepInX() each scanline
scroggo 2014/03/24 21:24:46 nit: line too long
Dominik Grewe 2014/03/26 17:22:22 Done.
187 kPerspective_MatrixClass // slow perspective, need to mappoin ts each pixel
188 };
189 static MatrixClass ComputeMatrixClass(const SkMatrix&);
190
191 uint8_t getPaintAlpha() const { return fPaintAlpha; }
192 const SkMatrix& getTotalInverse() const { return fTotalInverse; }
193 MatrixClass getInverseClass() const { return (MatrixClass)fTotal InverseClass; }
194 private:
195 SkMatrix fTotalInverse;
196 uint8_t fPaintAlpha;
197 uint8_t fTotalInverseClass;
198 };
136 199
137 /** 200 /**
138 * Called once before drawing, with the current paint and device matrix. 201 * Subclasses should be sure to call their INHERITED::validContext() if
139 * Return true if your shader supports these parameters, or false if not. 202 * they override this method.
140 * If false is returned, nothing will be drawn. If true is returned, then 203 * FIXME: Make sure device is still needed.
scroggo 2014/03/24 21:24:46 You can remove this line. device is still used by
Dominik Grewe 2014/03/26 17:22:22 Done.
141 * a balancing call to endContext() will be made before the next call to
142 * setContext.
143 *
144 * Subclasses should be sure to call their INHERITED::setContext() if they
145 * override this method.
146 */ 204 */
147 virtual bool setContext(const SkBitmap& device, const SkPaint& paint, 205 virtual bool validContext(const SkBitmap& device, const SkPaint& paint,
148 const SkMatrix& matrix); 206 const SkMatrix& matrix) const;
149 207
150 /** 208 /**
151 * Assuming setContext returned true, endContext() will be called when 209 * Called internally to create the actual object that does the shading.
152 * the draw using the shader has completed. It is an error for setContext 210 * Only valid if validContext() returned true.
153 * to be called twice w/o an intervening call to endContext(). 211 * Size of storage must be >= contextSize.
154 *
155 * Subclasses should be sure to call their INHERITED::endContext() if they
156 * override this method.
157 */ 212 */
158 virtual void endContext(); 213 virtual Context* createContext(const SkBitmap& device,
159 214 const SkPaint& paint,
160 SkDEBUGCODE(bool setContextHasBeenCalled() const { return SkToBool(fInSetCon text); }) 215 const SkMatrix& matrix,
216 void* storage) const = 0;
161 217
162 /** 218 /**
163 * Called for each span of the object being drawn. Your subclass should 219 * Return the size of a Context returned by createContext.
164 * set the appropriate colors (with premultiplied alpha) that correspond
165 * to the specified device coordinates.
166 */ 220 */
167 virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0; 221 virtual size_t contextSize() const = 0;
168
169 typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count);
170 virtual ShadeProc asAShadeProc(void** ctx);
171
172 /**
173 * Called only for 16bit devices when getFlags() returns
174 * kOpaqueAlphaFlag | kHasSpan16_Flag
175 */
176 virtual void shadeSpan16(int x, int y, uint16_t[], int count);
177
178 /**
179 * Similar to shadeSpan, but only returns the alpha-channel for a span.
180 * The default implementation calls shadeSpan() and then extracts the alpha
181 * values from the returned colors.
182 */
183 virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
184
185 /**
186 * Helper function that returns true if this shader's shadeSpan16() method
187 * can be called.
188 */
189 bool canCallShadeSpan16() {
190 return SkShader::CanCallShadeSpan16(this->getFlags());
191 }
192 222
193 /** 223 /**
194 * Helper to check the flags to know if it is legal to call shadeSpan16() 224 * Helper to check the flags to know if it is legal to call shadeSpan16()
195 */ 225 */
196 static bool CanCallShadeSpan16(uint32_t flags) { 226 static bool CanCallShadeSpan16(uint32_t flags) {
197 return (flags & kHasSpan16_Flag) != 0; 227 return (flags & kHasSpan16_Flag) != 0;
198 } 228 }
199 229
200 /** 230 /**
201 Gives method bitmap should be read to implement a shader. 231 Gives method bitmap should be read to implement a shader.
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 uint32_t fGradientFlags; //!< see SkGradientShader::Flags 344 uint32_t fGradientFlags; //!< see SkGradientShader::Flags
315 }; 345 };
316 346
317 virtual GradientType asAGradient(GradientInfo* info) const; 347 virtual GradientType asAGradient(GradientInfo* info) const;
318 348
319 /** 349 /**
320 * If the shader subclass has a GrEffect implementation, this resturns the effect to install. 350 * If the shader subclass has a GrEffect implementation, this resturns the effect to install.
321 * The incoming color to the effect has r=g=b=a all extracted from the SkPa int's alpha. 351 * The incoming color to the effect has r=g=b=a all extracted from the SkPa int's alpha.
322 * The output color should be the computed SkShader premul color modulated by the incoming 352 * The output color should be the computed SkShader premul color modulated by the incoming
323 * color. The GrContext may be used by the effect to create textures. The G PU device does not 353 * color. The GrContext may be used by the effect to create textures. The G PU device does not
324 * call setContext. Instead we pass the SkPaint here in case the shader nee ds paint info. 354 * call createContext. Instead we pass the SkPaint here in case the shader needs paint info.
325 */ 355 */
326 virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) c onst; 356 virtual GrEffectRef* asNewEffect(GrContext* context, const SkPaint& paint) c onst;
327 357
328 ////////////////////////////////////////////////////////////////////////// 358 //////////////////////////////////////////////////////////////////////////
329 // Factory methods for stock shaders 359 // Factory methods for stock shaders
330 360
331 /** Call this to create a new shader that will draw with the specified bitma p. 361 /** Call this to create a new shader that will draw with the specified bitma p.
332 * 362 *
333 * If the bitmap cannot be used (e.g. has no pixels, or its dimensions 363 * If the bitmap cannot be used (e.g. has no pixels, or its dimensions
334 * exceed implementation limits (currently at 64K - 1)) then SkEmptyShader 364 * exceed implementation limits (currently at 64K - 1)) then SkEmptyShader
335 * may be returned. 365 * may be returned.
336 * 366 *
337 * If the src is kA8_Config then that mask will be colorized using the colo r on 367 * If the src is kA8_Config then that mask will be colorized using the colo r on
338 * the paint. 368 * the paint.
339 * 369 *
340 * @param src The bitmap to use inside the shader 370 * @param src The bitmap to use inside the shader
341 * @param tmx The tiling mode to use when sampling the bitmap in the x-dir ection. 371 * @param tmx The tiling mode to use when sampling the bitmap in the x-dir ection.
342 * @param tmy The tiling mode to use when sampling the bitmap in the y-dir ection. 372 * @param tmy The tiling mode to use when sampling the bitmap in the y-dir ection.
343 * @return Returns a new shader object. Note: this function never retur ns null. 373 * @return Returns a new shader object. Note: this function never retur ns null.
344 */ 374 */
345 static SkShader* CreateBitmapShader(const SkBitmap& src, 375 static SkShader* CreateBitmapShader(const SkBitmap& src,
346 TileMode tmx, TileMode tmy); 376 TileMode tmx, TileMode tmy);
347 377
348 SkDEVCODE(virtual void toString(SkString* str) const;) 378 SkDEVCODE(virtual void toString(SkString* str) const;)
349 379
350 SK_DEFINE_FLATTENABLE_TYPE(SkShader) 380 SK_DEFINE_FLATTENABLE_TYPE(SkShader)
351 381
352 protected: 382 protected:
353 enum MatrixClass {
354 kLinear_MatrixClass, // no perspective
355 kFixedStepInX_MatrixClass, // fast perspective, need to call fixedS tepInX() each scanline
356 kPerspective_MatrixClass // slow perspective, need to mappoints e ach pixel
357 };
358 static MatrixClass ComputeMatrixClass(const SkMatrix&);
359
360 // These can be called by your subclass after setContext() has been called
361 uint8_t getPaintAlpha() const { return fPaintAlpha; }
362 const SkMatrix& getTotalInverse() const { return fTotalInverse; }
363 MatrixClass getInverseClass() const { return (MatrixClass)fTotalInve rseClass; }
364 383
365 SkShader(SkReadBuffer& ); 384 SkShader(SkReadBuffer& );
366 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; 385 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
386
367 private: 387 private:
388 // FIXME: Move to SkPaint.
368 SkMatrix fLocalMatrix; 389 SkMatrix fLocalMatrix;
369 SkMatrix fTotalInverse;
370 uint8_t fPaintAlpha;
371 uint8_t fTotalInverseClass;
372 SkDEBUGCODE(SkBool8 fInSetContext;)
373 390
374 typedef SkFlattenable INHERITED; 391 typedef SkFlattenable INHERITED;
375 }; 392 };
376 393
377 #endif 394 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698