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

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

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

Powered by Google App Engine
This is Rietveld 408576698