OLD | NEW |
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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 | 121 |
122 /** | 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. isOpaque() can be called at any time, unlike getFlags, |
127 * which only works properly when the context is set. | 127 * which only works properly when the context is set. |
128 */ | 128 */ |
129 virtual bool isOpaque() const { return false; } | 129 virtual bool isOpaque() const { return false; } |
130 | 130 |
| 131 // Moved to public so it could on a Context object. May not be the right pla
ce for it. |
| 132 enum MatrixClass { |
| 133 kLinear_MatrixClass, // no perspective |
| 134 kFixedStepInX_MatrixClass, // fast perspective, need to call fixedS
tepInX() each scanline |
| 135 kPerspective_MatrixClass // slow perspective, need to mappoints e
ach pixel |
| 136 }; |
| 137 |
| 138 /** |
| 139 * Total number of bytes needed to store subclass specific Context informat
ion. |
| 140 * Each class will override this by including the macro DEFINE_CONTEXT_RETR
IEVAL_FUNCTIONS() |
| 141 * in its private section, and defining getMySpaceNeededForContext(), which
returns the |
| 142 * number of bytes required by that specific subclass (not including its pa
rents). |
| 143 */ |
| 144 virtual size_t getTotalSpaceNeededForContext() const { return 0; } |
| 145 |
| 146 /** |
| 147 * Called to get a pointer to subclass-specific information. |
| 148 */ |
| 149 virtual void* getMyContext(Context* c) const = 0; |
| 150 |
| 151 class Context : public SkNoncopyable { |
| 152 public: |
| 153 Context(const SkMatrix& totalInverse, uint8_t paintAlpha, |
| 154 SkBitmap::Config deviceConfig); |
| 155 |
| 156 uint8_t getPaintAlpha() const { return fPaintAlpha; } |
| 157 SkBitmap::Config getDeviceConfig() const { return (SkBitmap::Config)f
DeviceConfig; } |
| 158 const SkMatrix& getTotalInverse() const { return fTotalInverse; } |
| 159 MatrixClass getInverseClass() const { return (MatrixClass)fTotal
InverseClass; } |
| 160 |
| 161 /** |
| 162 * Should not be called directly. Instead, the subclass should call get
MyContext. |
| 163 */ |
| 164 void* getExtraStorage() { |
| 165 SkAssert(fStorageAllocated); |
| 166 return fExtraStorage; |
| 167 } |
| 168 |
| 169 void reset(const SkShader& shader) { |
| 170 // This can only be called once |
| 171 SkAssert(!fStorageAllocated); |
| 172 fExtraStorage = fStorage.reset(shader.getTotalSpaceNeededForContext(
)); |
| 173 // What should we do if this fails? |
| 174 SkASSERT(fExtraStorage != NULL); |
| 175 fStorageAllocated = true; |
| 176 } |
| 177 |
| 178 private: |
| 179 SkMatrix fTotalInverse; |
| 180 uint8_t fPaintAlpha; |
| 181 uint8_t fDeviceConfig; |
| 182 uint8_t fTotalInverseClass; |
| 183 // This size is arbitrary, for now, but probably should be related to th
e size of the |
| 184 // subclasses needed. |
| 185 SkAutoSMalloc<1024> fStorage; |
| 186 // Should be debugcode |
| 187 bool fStorageAllocated; |
| 188 // Space for the subclasses' Context information. Will pint to fStorage. |
| 189 void* fExtraStorage; |
| 190 }; |
| 191 |
| 192 /** |
| 193 * Called once before drawing, with the current paint and device matrix. |
| 194 * Return a new Context object if your shader supports these parameters, |
| 195 * or NULL if not. If NULL is returned, nothing will be drawn. On success, |
| 196 * a balancing call to endContext() will be made before the next call to |
| 197 * setContext. |
| 198 */ |
| 199 |
| 200 Context* setContext(const SkBitmap& device, const SkPaint& paint, |
| 201 const SkMatrix& matrix); |
| 202 |
| 203 /** |
| 204 * Subclasses should be sure to call their INHERITED::onSetContext() if the
y |
| 205 * override this method. |
| 206 */ |
| 207 virtual bool onSetContext(Context* context, const SkBitmap& device, |
| 208 const SkPaint& paint, |
| 209 const SkMatrix& matrix) { return true; } |
| 210 /** |
| 211 * Assuming setContext returned true, endContext() will be called when |
| 212 * the draw using the shader has completed. It is an error for setContext |
| 213 * to be called twice w/o an intervening call to endContext(). |
| 214 * |
| 215 * This method will delete the Context object. |
| 216 * |
| 217 * Subclasses should be sure to call their INHERITED::endContext() if they |
| 218 * override this method, after deleting their subclass-specific info. |
| 219 */ |
| 220 virtual void endContext(Context*); |
| 221 |
| 222 SkDEBUGCODE(bool setContextHasBeenCalled() const { return SkToBool(fInSetCon
text); }) |
| 223 |
131 /** | 224 /** |
132 * Return the alpha associated with the data returned by shadeSpan16(). If | 225 * Return the alpha associated with the data returned by shadeSpan16(). If |
133 * kHasSpan16_Flag is not set, this value is meaningless. | 226 * kHasSpan16_Flag is not set, this value is meaningless. |
134 */ | 227 */ |
135 virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; } | 228 virtual uint8_t getSpan16Alpha(Context* c) const { return c->getPaintAlpha()
; } |
136 | |
137 /** | |
138 * Called once before drawing, with the current paint and device matrix. | |
139 * Return true if your shader supports these parameters, or false if not. | |
140 * If false is returned, nothing will be drawn. If true is returned, then | |
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 */ | |
147 virtual bool setContext(const SkBitmap& device, const SkPaint& paint, | |
148 const SkMatrix& matrix); | |
149 | |
150 /** | |
151 * Assuming setContext returned true, endContext() will be called when | |
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 */ | |
158 virtual void endContext(); | |
159 | |
160 SkDEBUGCODE(bool setContextHasBeenCalled() const { return SkToBool(fInSetCon
text); }) | |
161 | 229 |
162 /** | 230 /** |
163 * Called for each span of the object being drawn. Your subclass should | 231 * Called for each span of the object being drawn. Your subclass should |
164 * set the appropriate colors (with premultiplied alpha) that correspond | 232 * set the appropriate colors (with premultiplied alpha) that correspond |
165 * to the specified device coordinates. | 233 * to the specified device coordinates. |
166 */ | 234 */ |
167 virtual void shadeSpan(int x, int y, SkPMColor[], int count) = 0; | 235 // FIXME: It may make more sense for Context to be a const ref? (Same for ot
hers) |
| 236 virtual void shadeSpan(Context* c, int x, int y, SkPMColor[], int count) = 0
; |
168 | 237 |
| 238 // Used by SkBlitter_ARGB32.cpp |
169 typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count); | 239 typedef void (*ShadeProc)(void* ctx, int x, int y, SkPMColor[], int count); |
| 240 // Will need to pass a Context to this as well. |
170 virtual ShadeProc asAShadeProc(void** ctx); | 241 virtual ShadeProc asAShadeProc(void** ctx); |
171 | 242 |
172 /** | 243 /** |
173 * Called only for 16bit devices when getFlags() returns | 244 * Called only for 16bit devices when getFlags() returns |
174 * kOpaqueAlphaFlag | kHasSpan16_Flag | 245 * kOpaqueAlphaFlag | kHasSpan16_Flag |
175 */ | 246 */ |
176 virtual void shadeSpan16(int x, int y, uint16_t[], int count); | 247 virtual void shadeSpan16(Context* c, int x, int y, uint16_t[], int count); |
177 | 248 |
178 /** | 249 /** |
179 * Similar to shadeSpan, but only returns the alpha-channel for a span. | 250 * Similar to shadeSpan, but only returns the alpha-channel for a span. |
180 * The default implementation calls shadeSpan() and then extracts the alpha | 251 * The default implementation calls shadeSpan() and then extracts the alpha |
181 * values from the returned colors. | 252 * values from the returned colors. |
182 */ | 253 */ |
183 virtual void shadeSpanAlpha(int x, int y, uint8_t alpha[], int count); | 254 virtual void shadeSpanAlpha(Context* c, int x, int y, uint8_t alpha[], int c
ount); |
184 | 255 |
185 /** | 256 /** |
186 * Helper function that returns true if this shader's shadeSpan16() method | 257 * Helper function that returns true if this shader's shadeSpan16() method |
187 * can be called. | 258 * can be called. |
188 */ | 259 */ |
189 bool canCallShadeSpan16() { | 260 bool canCallShadeSpan16() { |
190 return SkShader::CanCallShadeSpan16(this->getFlags()); | 261 return SkShader::CanCallShadeSpan16(this->getFlags()); |
191 } | 262 } |
192 | 263 |
193 /** | 264 /** |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 * @return Returns a new shader object. Note: this function never retur
ns null. | 414 * @return Returns a new shader object. Note: this function never retur
ns null. |
344 */ | 415 */ |
345 static SkShader* CreateBitmapShader(const SkBitmap& src, | 416 static SkShader* CreateBitmapShader(const SkBitmap& src, |
346 TileMode tmx, TileMode tmy); | 417 TileMode tmx, TileMode tmy); |
347 | 418 |
348 SkDEVCODE(virtual void toString(SkString* str) const;) | 419 SkDEVCODE(virtual void toString(SkString* str) const;) |
349 | 420 |
350 SK_DEFINE_FLATTENABLE_TYPE(SkShader) | 421 SK_DEFINE_FLATTENABLE_TYPE(SkShader) |
351 | 422 |
352 protected: | 423 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&); | 424 static MatrixClass ComputeMatrixClass(const SkMatrix&); |
359 | 425 |
360 // These can be called by your subclass after setContext() has been called | |
361 uint8_t getPaintAlpha() const { return fPaintAlpha; } | |
362 SkBitmap::Config getDeviceConfig() const { return (SkBitmap::Config)fDevi
ceConfig; } | |
363 const SkMatrix& getTotalInverse() const { return fTotalInverse; } | |
364 MatrixClass getInverseClass() const { return (MatrixClass)fTotalInve
rseClass; } | |
365 | |
366 SkShader(SkReadBuffer& ); | 426 SkShader(SkReadBuffer& ); |
367 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; | 427 virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE; |
368 private: | 428 private: |
| 429 // FIXME: Move onto SkPaint. |
369 SkMatrix fLocalMatrix; | 430 SkMatrix fLocalMatrix; |
370 SkMatrix fTotalInverse; | |
371 uint8_t fPaintAlpha; | |
372 uint8_t fDeviceConfig; | |
373 uint8_t fTotalInverseClass; | |
374 SkDEBUGCODE(SkBool8 fInSetContext;) | 431 SkDEBUGCODE(SkBool8 fInSetContext;) |
375 | 432 |
376 static SkShader* CreateBitmapShader(const SkBitmap& src, | 433 static SkShader* CreateBitmapShader(const SkBitmap& src, |
377 TileMode, TileMode, | 434 TileMode, TileMode, |
378 void* storage, size_t storageSize); | 435 void* storage, size_t storageSize); |
379 friend class SkAutoBitmapShaderInstall; | 436 friend class SkAutoBitmapShaderInstall; |
380 typedef SkFlattenable INHERITED; | 437 typedef SkFlattenable INHERITED; |
381 }; | 438 }; |
382 | 439 |
| 440 /** |
| 441 * Each SkShader subclass must include the following macro in its private |
| 442 * section (defined below): |
| 443 * |
| 444 * DEFINE_CONTEXT_RETRIEVAL_FUNCTIONS() |
| 445 * |
| 446 * It defines functions for accessing the particular subclass's specific |
| 447 * information from the Context. The subclass must also implement the |
| 448 * following function: |
| 449 * |
| 450 * size_t getMySpaceNeededForContext() const; |
| 451 * |
| 452 * This function will return the number of bytes required to store that |
| 453 * subclasses Context information. |
| 454 */ |
| 455 |
| 456 #define DEFINE_CONTEXT_RETRIEVAL_FUNCTIONS()
\ |
| 457 virtual size_t getTotalSpaceNeededForContext() const SK_OVERRIDE {
\ |
| 458 return this->INHERITED::getTotalSpaceNeededForContext()
\ |
| 459 + this->getMySpaceNeededForContext();
\ |
| 460 }
\ |
| 461 virtual void* getMyContext(Context* c) const SK_OVERRIDE {
\ |
| 462 return c->getExtraStorage() + this->INHERITED::getTotalSpaceNeededForCon
text(); \ |
| 463 } |
| 464 |
| 465 |
383 #endif | 466 #endif |
OLD | NEW |