| 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 |