1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/core/SkShader.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,359 @@ 1.4 +/* 1.5 + * Copyright 2006 The Android Open Source Project 1.6 + * 1.7 + * Use of this source code is governed by a BSD-style license that can be 1.8 + * found in the LICENSE file. 1.9 + */ 1.10 + 1.11 +#include "SkBitmapProcShader.h" 1.12 +#include "SkReadBuffer.h" 1.13 +#include "SkMallocPixelRef.h" 1.14 +#include "SkPaint.h" 1.15 +#include "SkScalar.h" 1.16 +#include "SkShader.h" 1.17 +#include "SkWriteBuffer.h" 1.18 + 1.19 +SkShader::SkShader() { 1.20 + fLocalMatrix.reset(); 1.21 + SkDEBUGCODE(fInSetContext = false;) 1.22 +} 1.23 + 1.24 +SkShader::SkShader(SkReadBuffer& buffer) 1.25 + : INHERITED(buffer) { 1.26 + if (buffer.readBool()) { 1.27 + buffer.readMatrix(&fLocalMatrix); 1.28 + } else { 1.29 + fLocalMatrix.reset(); 1.30 + } 1.31 + 1.32 + SkDEBUGCODE(fInSetContext = false;) 1.33 +} 1.34 + 1.35 +SkShader::~SkShader() { 1.36 + SkASSERT(!fInSetContext); 1.37 +} 1.38 + 1.39 +void SkShader::flatten(SkWriteBuffer& buffer) const { 1.40 + this->INHERITED::flatten(buffer); 1.41 + bool hasLocalM = this->hasLocalMatrix(); 1.42 + buffer.writeBool(hasLocalM); 1.43 + if (hasLocalM) { 1.44 + buffer.writeMatrix(fLocalMatrix); 1.45 + } 1.46 +} 1.47 + 1.48 +bool SkShader::setContext(const SkBitmap& device, 1.49 + const SkPaint& paint, 1.50 + const SkMatrix& matrix) { 1.51 + SkASSERT(!this->setContextHasBeenCalled()); 1.52 + 1.53 + const SkMatrix* m = &matrix; 1.54 + SkMatrix total; 1.55 + 1.56 + fPaintAlpha = paint.getAlpha(); 1.57 + if (this->hasLocalMatrix()) { 1.58 + total.setConcat(matrix, this->getLocalMatrix()); 1.59 + m = &total; 1.60 + } 1.61 + if (m->invert(&fTotalInverse)) { 1.62 + fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); 1.63 + SkDEBUGCODE(fInSetContext = true;) 1.64 + return true; 1.65 + } 1.66 + return false; 1.67 +} 1.68 + 1.69 +void SkShader::endContext() { 1.70 + SkASSERT(fInSetContext); 1.71 + SkDEBUGCODE(fInSetContext = false;) 1.72 +} 1.73 + 1.74 +SkShader::ShadeProc SkShader::asAShadeProc(void** ctx) { 1.75 + return NULL; 1.76 +} 1.77 + 1.78 +#include "SkColorPriv.h" 1.79 + 1.80 +void SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) { 1.81 + SkASSERT(span16); 1.82 + SkASSERT(count > 0); 1.83 + SkASSERT(this->canCallShadeSpan16()); 1.84 + 1.85 + // basically, if we get here, the subclass screwed up 1.86 + SkDEBUGFAIL("kHasSpan16 flag is set, but shadeSpan16() not implemented"); 1.87 +} 1.88 + 1.89 +#define kTempColorQuadCount 6 // balance between speed (larger) and saving stack-space 1.90 +#define kTempColorCount (kTempColorQuadCount << 2) 1.91 + 1.92 +#ifdef SK_CPU_BENDIAN 1.93 + #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) 1.94 +#else 1.95 + #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) 1.96 +#endif 1.97 + 1.98 +void SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 1.99 + SkASSERT(count > 0); 1.100 + 1.101 + SkPMColor colors[kTempColorCount]; 1.102 + 1.103 + while ((count -= kTempColorCount) >= 0) { 1.104 + this->shadeSpan(x, y, colors, kTempColorCount); 1.105 + x += kTempColorCount; 1.106 + 1.107 + const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1.108 + int quads = kTempColorQuadCount; 1.109 + do { 1.110 + U8CPU a0 = srcA[0]; 1.111 + U8CPU a1 = srcA[4]; 1.112 + U8CPU a2 = srcA[8]; 1.113 + U8CPU a3 = srcA[12]; 1.114 + srcA += 4*4; 1.115 + *alpha++ = SkToU8(a0); 1.116 + *alpha++ = SkToU8(a1); 1.117 + *alpha++ = SkToU8(a2); 1.118 + *alpha++ = SkToU8(a3); 1.119 + } while (--quads != 0); 1.120 + } 1.121 + SkASSERT(count < 0); 1.122 + SkASSERT(count + kTempColorCount >= 0); 1.123 + if (count += kTempColorCount) { 1.124 + this->shadeSpan(x, y, colors, count); 1.125 + 1.126 + const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1.127 + do { 1.128 + *alpha++ = *srcA; 1.129 + srcA += 4; 1.130 + } while (--count != 0); 1.131 + } 1.132 +#if 0 1.133 + do { 1.134 + int n = count; 1.135 + if (n > kTempColorCount) 1.136 + n = kTempColorCount; 1.137 + SkASSERT(n > 0); 1.138 + 1.139 + this->shadeSpan(x, y, colors, n); 1.140 + x += n; 1.141 + count -= n; 1.142 + 1.143 + const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset(SK_A32_SHIFT); 1.144 + do { 1.145 + *alpha++ = *srcA; 1.146 + srcA += 4; 1.147 + } while (--n != 0); 1.148 + } while (count > 0); 1.149 +#endif 1.150 +} 1.151 + 1.152 +SkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) { 1.153 + MatrixClass mc = kLinear_MatrixClass; 1.154 + 1.155 + if (mat.hasPerspective()) { 1.156 + if (mat.fixedStepInX(0, NULL, NULL)) { 1.157 + mc = kFixedStepInX_MatrixClass; 1.158 + } else { 1.159 + mc = kPerspective_MatrixClass; 1.160 + } 1.161 + } 1.162 + return mc; 1.163 +} 1.164 + 1.165 +////////////////////////////////////////////////////////////////////////////// 1.166 + 1.167 +SkShader::BitmapType SkShader::asABitmap(SkBitmap*, SkMatrix*, 1.168 + TileMode*) const { 1.169 + return kNone_BitmapType; 1.170 +} 1.171 + 1.172 +SkShader::GradientType SkShader::asAGradient(GradientInfo* info) const { 1.173 + return kNone_GradientType; 1.174 +} 1.175 + 1.176 +GrEffectRef* SkShader::asNewEffect(GrContext*, const SkPaint&) const { 1.177 + return NULL; 1.178 +} 1.179 + 1.180 +SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, 1.181 + TileMode tmx, TileMode tmy) { 1.182 + return ::CreateBitmapShader(src, tmx, tmy, NULL); 1.183 +} 1.184 + 1.185 +#ifndef SK_IGNORE_TO_STRING 1.186 +void SkShader::toString(SkString* str) const { 1.187 + if (this->hasLocalMatrix()) { 1.188 + str->append(" "); 1.189 + this->getLocalMatrix().toString(str); 1.190 + } 1.191 +} 1.192 +#endif 1.193 + 1.194 +////////////////////////////////////////////////////////////////////////////// 1.195 + 1.196 +#include "SkColorShader.h" 1.197 +#include "SkUtils.h" 1.198 + 1.199 +SkColorShader::SkColorShader() { 1.200 + fFlags = 0; 1.201 + fInheritColor = true; 1.202 +} 1.203 + 1.204 +SkColorShader::SkColorShader(SkColor c) { 1.205 + fFlags = 0; 1.206 + fColor = c; 1.207 + fInheritColor = false; 1.208 +} 1.209 + 1.210 +SkColorShader::~SkColorShader() {} 1.211 + 1.212 +bool SkColorShader::isOpaque() const { 1.213 + if (fInheritColor) { 1.214 + return true; // using paint's alpha 1.215 + } 1.216 + return SkColorGetA(fColor) == 255; 1.217 +} 1.218 + 1.219 +SkColorShader::SkColorShader(SkReadBuffer& b) : INHERITED(b) { 1.220 + fFlags = 0; // computed in setContext 1.221 + 1.222 + fInheritColor = b.readBool(); 1.223 + if (fInheritColor) { 1.224 + return; 1.225 + } 1.226 + fColor = b.readColor(); 1.227 +} 1.228 + 1.229 +void SkColorShader::flatten(SkWriteBuffer& buffer) const { 1.230 + this->INHERITED::flatten(buffer); 1.231 + buffer.writeBool(fInheritColor); 1.232 + if (fInheritColor) { 1.233 + return; 1.234 + } 1.235 + buffer.writeColor(fColor); 1.236 +} 1.237 + 1.238 +uint32_t SkColorShader::getFlags() { 1.239 + return fFlags; 1.240 +} 1.241 + 1.242 +uint8_t SkColorShader::getSpan16Alpha() const { 1.243 + return SkGetPackedA32(fPMColor); 1.244 +} 1.245 + 1.246 +bool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint, 1.247 + const SkMatrix& matrix) { 1.248 + if (!this->INHERITED::setContext(device, paint, matrix)) { 1.249 + return false; 1.250 + } 1.251 + 1.252 + unsigned a; 1.253 + 1.254 + if (fInheritColor) { 1.255 + fColor = paint.getColor(); 1.256 + a = SkColorGetA(fColor); 1.257 + } else { 1.258 + a = SkAlphaMul(SkColorGetA(fColor), SkAlpha255To256(paint.getAlpha())); 1.259 + } 1.260 + 1.261 + unsigned r = SkColorGetR(fColor); 1.262 + unsigned g = SkColorGetG(fColor); 1.263 + unsigned b = SkColorGetB(fColor); 1.264 + 1.265 + // we want this before we apply any alpha 1.266 + fColor16 = SkPack888ToRGB16(r, g, b); 1.267 + 1.268 + if (a != 255) { 1.269 + r = SkMulDiv255Round(r, a); 1.270 + g = SkMulDiv255Round(g, a); 1.271 + b = SkMulDiv255Round(b, a); 1.272 + } 1.273 + fPMColor = SkPackARGB32(a, r, g, b); 1.274 + 1.275 + fFlags = kConstInY32_Flag; 1.276 + if (255 == a) { 1.277 + fFlags |= kOpaqueAlpha_Flag; 1.278 + if (paint.isDither() == false) { 1.279 + fFlags |= kHasSpan16_Flag; 1.280 + } 1.281 + } 1.282 + 1.283 + return true; 1.284 +} 1.285 + 1.286 +void SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) { 1.287 + sk_memset32(span, fPMColor, count); 1.288 +} 1.289 + 1.290 +void SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) { 1.291 + sk_memset16(span, fColor16, count); 1.292 +} 1.293 + 1.294 +void SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 1.295 + memset(alpha, SkGetPackedA32(fPMColor), count); 1.296 +} 1.297 + 1.298 +// if we had a asAColor method, that would be more efficient... 1.299 +SkShader::BitmapType SkColorShader::asABitmap(SkBitmap* bitmap, SkMatrix* matrix, 1.300 + TileMode modes[]) const { 1.301 + return kNone_BitmapType; 1.302 +} 1.303 + 1.304 +SkShader::GradientType SkColorShader::asAGradient(GradientInfo* info) const { 1.305 + if (info) { 1.306 + if (info->fColors && info->fColorCount >= 1) { 1.307 + info->fColors[0] = fColor; 1.308 + } 1.309 + info->fColorCount = 1; 1.310 + info->fTileMode = SkShader::kRepeat_TileMode; 1.311 + } 1.312 + return kColor_GradientType; 1.313 +} 1.314 + 1.315 +#ifndef SK_IGNORE_TO_STRING 1.316 +void SkColorShader::toString(SkString* str) const { 1.317 + str->append("SkColorShader: ("); 1.318 + 1.319 + if (fInheritColor) { 1.320 + str->append("Color: inherited from paint"); 1.321 + } else { 1.322 + str->append("Color: "); 1.323 + str->appendHex(fColor); 1.324 + } 1.325 + 1.326 + this->INHERITED::toString(str); 1.327 + 1.328 + str->append(")"); 1.329 +} 1.330 +#endif 1.331 + 1.332 +/////////////////////////////////////////////////////////////////////////////// 1.333 + 1.334 +#include "SkEmptyShader.h" 1.335 + 1.336 +uint32_t SkEmptyShader::getFlags() { return 0; } 1.337 +uint8_t SkEmptyShader::getSpan16Alpha() const { return 0; } 1.338 + 1.339 +bool SkEmptyShader::setContext(const SkBitmap&, const SkPaint&, 1.340 + const SkMatrix&) { return false; } 1.341 + 1.342 +void SkEmptyShader::shadeSpan(int x, int y, SkPMColor span[], int count) { 1.343 + SkDEBUGFAIL("should never get called, since setContext() returned false"); 1.344 +} 1.345 + 1.346 +void SkEmptyShader::shadeSpan16(int x, int y, uint16_t span[], int count) { 1.347 + SkDEBUGFAIL("should never get called, since setContext() returned false"); 1.348 +} 1.349 + 1.350 +void SkEmptyShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { 1.351 + SkDEBUGFAIL("should never get called, since setContext() returned false"); 1.352 +} 1.353 + 1.354 +#ifndef SK_IGNORE_TO_STRING 1.355 +void SkEmptyShader::toString(SkString* str) const { 1.356 + str->append("SkEmptyShader: ("); 1.357 + 1.358 + this->INHERITED::toString(str); 1.359 + 1.360 + str->append(")"); 1.361 +} 1.362 +#endif