| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 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 #include "SkArithmeticMode.h" | 8 #include "SkArithmeticMode.h" |
| 9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
| 10 #include "SkFlattenableBuffers.h" | 10 #include "SkFlattenableBuffers.h" |
| 11 #include "SkString.h" | 11 #include "SkString.h" |
| 12 #include "SkUnPreMultiply.h" | 12 #include "SkUnPreMultiply.h" |
| 13 #if SK_SUPPORT_GPU | 13 #if SK_SUPPORT_GPU |
| 14 #include "GrContext.h" | 14 #include "GrContext.h" |
| 15 #include "gl/GrGLEffect.h" | 15 #include "gl/GrGLEffect.h" |
| 16 #include "gl/GrGLEffectMatrix.h" | 16 #include "gl/GrGLEffectMatrix.h" |
| 17 #include "GrTBackendEffectFactory.h" | 17 #include "GrTBackendEffectFactory.h" |
| 18 #include "SkImageFilterUtils.h" | 18 #include "SkImageFilterUtils.h" |
| 19 #endif | 19 #endif |
| 20 | 20 |
| 21 class SkArithmeticMode_scalar : public SkXfermode { | 21 class SkArithmeticMode_scalar : public SkXfermode { |
| 22 public: | 22 public: |
| 23 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4)
{ | 23 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4,
bool unpremultiply) { |
| 24 fK[0] = k1; | 24 fK[0] = k1; |
| 25 fK[1] = k2; | 25 fK[1] = k2; |
| 26 fK[2] = k3; | 26 fK[2] = k3; |
| 27 fK[3] = k4; | 27 fK[3] = k4; |
| 28 fUnpremultiply = unpremultiply; |
| 28 } | 29 } |
| 29 | 30 |
| 30 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, | 31 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, |
| 31 const SkAlpha aa[]) const SK_OVERRIDE; | 32 const SkAlpha aa[]) const SK_OVERRIDE; |
| 32 | 33 |
| 33 SK_DEVELOPER_TO_STRING() | 34 SK_DEVELOPER_TO_STRING() |
| 34 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) | 35 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) |
| 35 | 36 |
| 36 #if SK_SUPPORT_GPU | 37 #if SK_SUPPORT_GPU |
| 37 virtual bool asNewEffectOrCoeff(GrContext*, GrEffectRef** effect, Coeff*, Co
eff*, GrTexture* background) const SK_OVERRIDE; | 38 virtual bool asNewEffectOrCoeff(GrContext*, GrEffectRef** effect, Coeff*, Co
eff*, GrTexture* background) const SK_OVERRIDE; |
| 38 #endif | 39 #endif |
| 39 | 40 |
| 40 private: | 41 private: |
| 41 SkArithmeticMode_scalar(SkFlattenableReadBuffer& buffer) : INHERITED(buffer)
{ | 42 SkArithmeticMode_scalar(SkFlattenableReadBuffer& buffer) : INHERITED(buffer)
{ |
| 42 fK[0] = buffer.readScalar(); | 43 fK[0] = buffer.readScalar(); |
| 43 fK[1] = buffer.readScalar(); | 44 fK[1] = buffer.readScalar(); |
| 44 fK[2] = buffer.readScalar(); | 45 fK[2] = buffer.readScalar(); |
| 45 fK[3] = buffer.readScalar(); | 46 fK[3] = buffer.readScalar(); |
| 47 fUnpremultiply = buffer.readBool(); |
| 46 } | 48 } |
| 47 | 49 |
| 48 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { | 50 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { |
| 49 INHERITED::flatten(buffer); | 51 INHERITED::flatten(buffer); |
| 50 buffer.writeScalar(fK[0]); | 52 buffer.writeScalar(fK[0]); |
| 51 buffer.writeScalar(fK[1]); | 53 buffer.writeScalar(fK[1]); |
| 52 buffer.writeScalar(fK[2]); | 54 buffer.writeScalar(fK[2]); |
| 53 buffer.writeScalar(fK[3]); | 55 buffer.writeScalar(fK[3]); |
| 56 buffer.writeBool(fUnpremultiply); |
| 54 } | 57 } |
| 55 SkScalar fK[4]; | 58 SkScalar fK[4]; |
| 59 bool fUnpremultiply; |
| 56 | 60 |
| 57 typedef SkXfermode INHERITED; | 61 typedef SkXfermode INHERITED; |
| 58 }; | 62 }; |
| 59 | 63 |
| 60 static int pinToByte(int value) { | 64 static int pinToByte(int value) { |
| 61 if (value < 0) { | 65 if (value < 0) { |
| 62 value = 0; | 66 value = 0; |
| 63 } else if (value > 255) { | 67 } else if (value > 255) { |
| 64 value = 255; | 68 value = 255; |
| 65 } | 69 } |
| (...skipping 25 matching lines...) Expand all Loading... |
| 91 SkScalar k3 = fK[2]; | 95 SkScalar k3 = fK[2]; |
| 92 SkScalar k4 = fK[3] * 255; | 96 SkScalar k4 = fK[3] * 255; |
| 93 | 97 |
| 94 for (int i = 0; i < count; ++i) { | 98 for (int i = 0; i < count; ++i) { |
| 95 if ((NULL == aaCoverage) || aaCoverage[i]) { | 99 if ((NULL == aaCoverage) || aaCoverage[i]) { |
| 96 SkPMColor sc = src[i]; | 100 SkPMColor sc = src[i]; |
| 97 SkPMColor dc = dst[i]; | 101 SkPMColor dc = dst[i]; |
| 98 int sa = SkGetPackedA32(sc); | 102 int sa = SkGetPackedA32(sc); |
| 99 int da = SkGetPackedA32(dc); | 103 int da = SkGetPackedA32(dc); |
| 100 | 104 |
| 101 int srcNeedsUnpremul = needsUnpremul(sa); | 105 int srcNeedsUnpremul = fUnpremultiply && needsUnpremul(sa); |
| 102 int dstNeedsUnpremul = needsUnpremul(da); | 106 int dstNeedsUnpremul = fUnpremultiply && needsUnpremul(da); |
| 103 | 107 |
| 104 int a, r, g, b; | 108 int a, r, g, b; |
| 105 | 109 |
| 106 if (!srcNeedsUnpremul && !dstNeedsUnpremul) { | 110 if (!srcNeedsUnpremul && !dstNeedsUnpremul) { |
| 107 a = arith(k1, k2, k3, k4, sa, da); | 111 a = arith(k1, k2, k3, k4, sa, da); |
| 108 r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc)
); | 112 r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc)
); |
| 109 g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc)
); | 113 g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc)
); |
| 110 b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc)
); | 114 b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc)
); |
| 111 } else { | 115 } else { |
| 112 int sr = SkGetPackedR32(sc); | 116 int sr = SkGetPackedR32(sc); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 138 // apply antialias coverage if necessary | 142 // apply antialias coverage if necessary |
| 139 if (aaCoverage && 0xFF != aaCoverage[i]) { | 143 if (aaCoverage && 0xFF != aaCoverage[i]) { |
| 140 int scale = aaCoverage[i] + (aaCoverage[i] >> 7); | 144 int scale = aaCoverage[i] + (aaCoverage[i] >> 7); |
| 141 a = blend(a, SkGetPackedA32(sc), scale); | 145 a = blend(a, SkGetPackedA32(sc), scale); |
| 142 r = blend(r, SkGetPackedR32(sc), scale); | 146 r = blend(r, SkGetPackedR32(sc), scale); |
| 143 g = blend(g, SkGetPackedG32(sc), scale); | 147 g = blend(g, SkGetPackedG32(sc), scale); |
| 144 b = blend(b, SkGetPackedB32(sc), scale); | 148 b = blend(b, SkGetPackedB32(sc), scale); |
| 145 } | 149 } |
| 146 | 150 |
| 147 // turn the result back into premul | 151 // turn the result back into premul |
| 148 if (0xFF != a) { | 152 if (fUnpremultiply && 0xFF != a) { |
| 149 int scale = a + (a >> 7); | 153 int scale = a + (a >> 7); |
| 150 r = SkAlphaMul(r, scale); | 154 r = SkAlphaMul(r, scale); |
| 151 g = SkAlphaMul(g, scale); | 155 g = SkAlphaMul(g, scale); |
| 152 b = SkAlphaMul(b, scale); | 156 b = SkAlphaMul(b, scale); |
| 153 } | 157 } |
| 154 dst[i] = SkPackARGB32(a, r, g, b); | 158 dst[i] = SkPackARGB32(a, r, g, b); |
| 155 } | 159 } |
| 156 } | 160 } |
| 157 } | 161 } |
| 158 | 162 |
| (...skipping 28 matching lines...) Expand all Loading... |
| 187 x += 1 << 7; | 191 x += 1 << 7; |
| 188 x >>= 8; | 192 x >>= 8; |
| 189 return x; | 193 return x; |
| 190 #else | 194 #else |
| 191 return (int32_t)(x * 256); | 195 return (int32_t)(x * 256); |
| 192 #endif | 196 #endif |
| 193 } | 197 } |
| 194 #endif | 198 #endif |
| 195 | 199 |
| 196 SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, | 200 SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2, |
| 197 SkScalar k3, SkScalar k4) { | 201 SkScalar k3, SkScalar k4, bool unpremultipl
y) { |
| 198 if (fitsInBits(k1, 8) && fitsInBits(k2, 16) && | 202 if (fitsInBits(k1, 8) && fitsInBits(k2, 16) && |
| 199 fitsInBits(k2, 16) && fitsInBits(k2, 24)) { | 203 fitsInBits(k2, 16) && fitsInBits(k2, 24)) { |
| 200 | 204 |
| 201 #if 0 // UNUSED | 205 #if 0 // UNUSED |
| 202 int32_t i1 = toDot8(k1); | 206 int32_t i1 = toDot8(k1); |
| 203 int32_t i2 = toDot8(k2); | 207 int32_t i2 = toDot8(k2); |
| 204 int32_t i3 = toDot8(k3); | 208 int32_t i3 = toDot8(k3); |
| 205 int32_t i4 = toDot8(k4); | 209 int32_t i4 = toDot8(k4); |
| 206 if (i1) { | 210 if (i1) { |
| 207 return SkNEW_ARGS(SkArithmeticMode_quad, (i1, i2, i3, i4)); | 211 return SkNEW_ARGS(SkArithmeticMode_quad, (i1, i2, i3, i4)); |
| 208 } | 212 } |
| 209 if (0 == i2) { | 213 if (0 == i2) { |
| 210 return SkNEW_ARGS(SkArithmeticMode_dst, (i3, i4)); | 214 return SkNEW_ARGS(SkArithmeticMode_dst, (i3, i4)); |
| 211 } | 215 } |
| 212 if (0 == i3) { | 216 if (0 == i3) { |
| 213 return SkNEW_ARGS(SkArithmeticMode_src, (i2, i4)); | 217 return SkNEW_ARGS(SkArithmeticMode_src, (i2, i4)); |
| 214 } | 218 } |
| 215 return SkNEW_ARGS(SkArithmeticMode_linear, (i2, i3, i4)); | 219 return SkNEW_ARGS(SkArithmeticMode_linear, (i2, i3, i4)); |
| 216 #endif | 220 #endif |
| 217 } | 221 } |
| 218 return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4)); | 222 return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4, unpremultiply)); |
| 219 } | 223 } |
| 220 | 224 |
| 221 | 225 |
| 222 ////////////////////////////////////////////////////////////////////////////// | 226 ////////////////////////////////////////////////////////////////////////////// |
| 223 | 227 |
| 224 #if SK_SUPPORT_GPU | 228 #if SK_SUPPORT_GPU |
| 225 | 229 |
| 226 class GrGLArithmeticEffect : public GrGLEffect { | 230 class GrGLArithmeticEffect : public GrGLEffect { |
| 227 public: | 231 public: |
| 228 GrGLArithmeticEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | 232 GrGLArithmeticEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 244 GrGLEffectMatrix fBackgroundEffectMatrix; | 248 GrGLEffectMatrix fBackgroundEffectMatrix; |
| 245 GrGLUniformManager::UniformHandle fKUni; | 249 GrGLUniformManager::UniformHandle fKUni; |
| 246 | 250 |
| 247 typedef GrGLEffect INHERITED; | 251 typedef GrGLEffect INHERITED; |
| 248 }; | 252 }; |
| 249 | 253 |
| 250 /////////////////////////////////////////////////////////////////////////////// | 254 /////////////////////////////////////////////////////////////////////////////// |
| 251 | 255 |
| 252 class GrArithmeticEffect : public GrEffect { | 256 class GrArithmeticEffect : public GrEffect { |
| 253 public: | 257 public: |
| 254 static GrEffectRef* Create(float k1, float k2, float k3, float k4, GrTexture
* background) { | 258 static GrEffectRef* Create(float k1, float k2, float k3, float k4, bool unpr
emultiply, GrTexture* background) { |
| 255 AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, b
ackground))); | 259 AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, u
npremultiply, background))); |
| 256 return CreateEffectRef(effect); | 260 return CreateEffectRef(effect); |
| 257 } | 261 } |
| 258 | 262 |
| 259 virtual ~GrArithmeticEffect(); | 263 virtual ~GrArithmeticEffect(); |
| 260 | 264 |
| 261 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 265 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
| 262 | 266 |
| 263 typedef GrGLArithmeticEffect GLEffect; | 267 typedef GrGLArithmeticEffect GLEffect; |
| 264 static const char* Name() { return "Arithmetic"; } | 268 static const char* Name() { return "Arithmetic"; } |
| 265 GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture()
; } | 269 GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture()
; } |
| 266 | 270 |
| 267 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 271 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
| 268 | 272 |
| 269 float k1() const { return fK1; } | 273 float k1() const { return fK1; } |
| 270 float k2() const { return fK2; } | 274 float k2() const { return fK2; } |
| 271 float k3() const { return fK3; } | 275 float k3() const { return fK3; } |
| 272 float k4() const { return fK4; } | 276 float k4() const { return fK4; } |
| 277 bool unpremultiply() const { return fUnpremultiply; } |
| 273 | 278 |
| 274 private: | 279 private: |
| 275 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; | 280 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; |
| 276 | 281 |
| 277 GrArithmeticEffect(float k1, float k2, float k3, float k4, GrTexture* backgr
ound); | 282 GrArithmeticEffect(float k1, float k2, float k3, float k4, bool unpremultipl
y, GrTexture* background); |
| 278 float fK1, fK2, fK3, fK4; | 283 float fK1, fK2, fK3, fK4; |
| 284 bool fUnpremultiply; |
| 279 GrTextureAccess fBackgroundAccess; | 285 GrTextureAccess fBackgroundAccess; |
| 280 | 286 |
| 281 GR_DECLARE_EFFECT_TEST; | 287 GR_DECLARE_EFFECT_TEST; |
| 282 typedef GrEffect INHERITED; | 288 typedef GrEffect INHERITED; |
| 283 | 289 |
| 284 }; | 290 }; |
| 285 | 291 |
| 286 /////////////////////////////////////////////////////////////////////////////// | 292 /////////////////////////////////////////////////////////////////////////////// |
| 287 | 293 |
| 288 GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4, | 294 GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4, |
| 289 GrTexture* background) | 295 bool unpremultiply, GrTexture* background
) |
| 290 : fK1(k1), fK2(k2), fK3(k3), fK4(k4) { | 296 : fK1(k1), fK2(k2), fK3(k3), fK4(k4), fUnpremultiply(unpremultiply) { |
| 291 if (background) { | 297 if (background) { |
| 292 fBackgroundAccess.reset(background); | 298 fBackgroundAccess.reset(background); |
| 293 this->addTextureAccess(&fBackgroundAccess); | 299 this->addTextureAccess(&fBackgroundAccess); |
| 294 } else { | 300 } else { |
| 295 this->setWillReadDstColor(); | 301 this->setWillReadDstColor(); |
| 296 } | 302 } |
| 297 } | 303 } |
| 298 | 304 |
| 299 GrArithmeticEffect::~GrArithmeticEffect() { | 305 GrArithmeticEffect::~GrArithmeticEffect() { |
| 300 } | 306 } |
| 301 | 307 |
| 302 bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const { | 308 bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const { |
| 303 const GrArithmeticEffect& s = CastEffect<GrArithmeticEffect>(sBase); | 309 const GrArithmeticEffect& s = CastEffect<GrArithmeticEffect>(sBase); |
| 304 return fK1 == s.fK1 && | 310 return fK1 == s.fK1 && |
| 305 fK2 == s.fK2 && | 311 fK2 == s.fK2 && |
| 306 fK3 == s.fK3 && | 312 fK3 == s.fK3 && |
| 307 fK4 == s.fK4 && | 313 fK4 == s.fK4 && |
| 314 fUnpremultiply == s.fUnpremultiply && |
| 308 backgroundTexture() == s.backgroundTexture(); | 315 backgroundTexture() == s.backgroundTexture(); |
| 309 } | 316 } |
| 310 | 317 |
| 311 const GrBackendEffectFactory& GrArithmeticEffect::getFactory() const { | 318 const GrBackendEffectFactory& GrArithmeticEffect::getFactory() const { |
| 312 return GrTBackendEffectFactory<GrArithmeticEffect>::getInstance(); | 319 return GrTBackendEffectFactory<GrArithmeticEffect>::getInstance(); |
| 313 } | 320 } |
| 314 | 321 |
| 315 void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* va
lidFlags) const { | 322 void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* va
lidFlags) const { |
| 316 // TODO: optimize this | 323 // TODO: optimize this |
| 317 *validFlags = 0; | 324 *validFlags = 0; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 328 GrGLArithmeticEffect::~GrGLArithmeticEffect() { | 335 GrGLArithmeticEffect::~GrGLArithmeticEffect() { |
| 329 } | 336 } |
| 330 | 337 |
| 331 void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder, | 338 void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder, |
| 332 const GrDrawEffect& drawEffect, | 339 const GrDrawEffect& drawEffect, |
| 333 EffectKey key, | 340 EffectKey key, |
| 334 const char* outputColor, | 341 const char* outputColor, |
| 335 const char* inputColor, | 342 const char* inputColor, |
| 336 const TextureSamplerArray& samplers) { | 343 const TextureSamplerArray& samplers) { |
| 337 | 344 |
| 338 GrTexture* backgroundTex = drawEffect.castEffect<GrArithmeticEffect>().backg
roundTexture(); | 345 const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>(
); |
| 346 GrTexture* backgroundTex = arith.backgroundTexture(); |
| 347 bool unpremultiply = arith.unpremultiply(); |
| 339 const char* dstColor; | 348 const char* dstColor; |
| 340 if (backgroundTex) { | 349 if (backgroundTex) { |
| 341 const char* bgCoords; | 350 const char* bgCoords; |
| 342 GrSLType bgCoordsType = fBackgroundEffectMatrix.emitCode(builder, key, &
bgCoords, NULL, "BG"); | 351 GrSLType bgCoordsType = fBackgroundEffectMatrix.emitCode(builder, key, &
bgCoords, NULL, "BG"); |
| 343 builder->fsCodeAppend("\t\tvec4 bgColor = "); | 352 builder->fsCodeAppend("\t\tvec4 bgColor = "); |
| 344 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType, | 353 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType, |
| 345 samplers[0], | 354 samplers[0], |
| 346 bgCoords, | 355 bgCoords, |
| 347 bgCoordsType); | 356 bgCoordsType); |
| 348 builder->fsCodeAppendf(";\n"); | 357 builder->fsCodeAppendf(";\n"); |
| 349 dstColor = "bgColor"; | 358 dstColor = "bgColor"; |
| 350 } else { | 359 } else { |
| 351 dstColor = builder->dstColor(); | 360 dstColor = builder->dstColor(); |
| 352 } | 361 } |
| 353 | 362 |
| 354 GrAssert(NULL != dstColor); | 363 GrAssert(NULL != dstColor); |
| 355 fKUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, | 364 fKUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, |
| 356 kVec4f_GrSLType, "k"); | 365 kVec4f_GrSLType, "k"); |
| 357 const char* kUni = builder->getUniformCStr(fKUni); | 366 const char* kUni = builder->getUniformCStr(fKUni); |
| 358 | 367 |
| 359 // We don't try to optimize for this case at all | 368 // We don't try to optimize for this case at all |
| 360 if (NULL == inputColor) { | 369 if (NULL == inputColor) { |
| 361 builder->fsCodeAppendf("\t\tconst vec4 src = %s;\n", GrGLSLOnesVecf(4)); | 370 builder->fsCodeAppendf("\t\tconst vec4 src = %s;\n", GrGLSLOnesVecf(4)); |
| 362 } else { | 371 } else { |
| 363 builder->fsCodeAppendf("\t\tvec4 src = %s;\n", inputColor); | 372 builder->fsCodeAppendf("\t\tvec4 src = %s;\n", inputColor); |
| 364 builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\
n"); | 373 if (unpremultiply) { |
| 374 builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.
0);\n"); |
| 375 } |
| 365 } | 376 } |
| 366 | 377 |
| 367 builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor); | 378 builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor); |
| 368 builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n"); | 379 if (unpremultiply) { |
| 380 builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\
n"); |
| 381 } |
| 369 | 382 |
| 370 builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst
+ %s.w;\n", outputColor, kUni, kUni, kUni, kUni); | 383 builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst
+ %s.w;\n", outputColor, kUni, kUni, kUni, kUni); |
| 371 builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outpu
tColor); | 384 builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outpu
tColor); |
| 372 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor); | 385 if (unpremultiply) { |
| 386 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor
); |
| 387 } else { |
| 388 builder->fsCodeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor,
outputColor, outputColor); |
| 389 } |
| 373 } | 390 } |
| 374 | 391 |
| 375 void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawE
ffect& drawEffect) { | 392 void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawE
ffect& drawEffect) { |
| 376 const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>(
); | 393 const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>(
); |
| 377 uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); | 394 uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); |
| 378 GrTexture* bgTex = arith.backgroundTexture(); | 395 GrTexture* bgTex = arith.backgroundTexture(); |
| 379 if (bgTex) { | 396 if (bgTex) { |
| 380 fBackgroundEffectMatrix.setData(uman, | 397 fBackgroundEffectMatrix.setData(uman, |
| 381 GrEffect::MakeDivByTextureWHMatrix(bgTex
), | 398 GrEffect::MakeDivByTextureWHMatrix(bgTex
), |
| 382 drawEffect, | 399 drawEffect, |
| 383 bgTex); | 400 bgTex); |
| 384 } | 401 } |
| 385 } | 402 } |
| 386 | 403 |
| 387 GrGLEffect::EffectKey GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffec
t, const GrGLCaps&) { | 404 GrGLEffect::EffectKey GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffec
t, const GrGLCaps&) { |
| 388 const GrArithmeticEffect& effect = drawEffect.castEffect<GrArithmeticEffect>
(); | 405 const GrArithmeticEffect& effect = drawEffect.castEffect<GrArithmeticEffect>
(); |
| 389 GrTexture* bgTex = effect.backgroundTexture(); | 406 GrTexture* bgTex = effect.backgroundTexture(); |
| 390 EffectKey bgKey = 0; | 407 EffectKey bgKey = 0; |
| 391 if (bgTex) { | 408 if (bgTex) { |
| 392 bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(bgTe
x), | 409 bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(bgTe
x), |
| 393 drawEffect, | 410 drawEffect, |
| 394 GrGLArithmeticEffect::kCoordsType, | 411 GrGLArithmeticEffect::kCoordsType, |
| 395 bgTex); | 412 bgTex); |
| 396 } | 413 } |
| 397 return bgKey; | 414 EffectKey unpremulKey = (effect.unpremultiply() ? 0x1 : 0x0) << GrGLEffectMa
trix::kKeyBits; |
| 415 return unpremulKey | bgKey; |
| 398 } | 416 } |
| 399 | 417 |
| 400 GrEffectRef* GrArithmeticEffect::TestCreate(SkMWCRandom* rand, | 418 GrEffectRef* GrArithmeticEffect::TestCreate(SkMWCRandom* rand, |
| 401 GrContext*, | 419 GrContext*, |
| 402 const GrDrawTargetCaps&, | 420 const GrDrawTargetCaps&, |
| 403 GrTexture*[]) { | 421 GrTexture*[]) { |
| 404 float k1 = rand->nextF(); | 422 float k1 = rand->nextF(); |
| 405 float k2 = rand->nextF(); | 423 float k2 = rand->nextF(); |
| 406 float k3 = rand->nextF(); | 424 float k3 = rand->nextF(); |
| 407 float k4 = rand->nextF(); | 425 float k4 = rand->nextF(); |
| 426 bool unpremultiply = rand->nextBool(); |
| 408 | 427 |
| 409 static AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k
4, NULL))); | 428 static AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k
4, unpremultiply, NULL))); |
| 410 return CreateEffectRef(gEffect); | 429 return CreateEffectRef(gEffect); |
| 411 } | 430 } |
| 412 | 431 |
| 413 GR_DEFINE_EFFECT_TEST(GrArithmeticEffect); | 432 GR_DEFINE_EFFECT_TEST(GrArithmeticEffect); |
| 414 | 433 |
| 415 bool SkArithmeticMode_scalar::asNewEffectOrCoeff(GrContext*, | 434 bool SkArithmeticMode_scalar::asNewEffectOrCoeff(GrContext*, |
| 416 GrEffectRef** effect, | 435 GrEffectRef** effect, |
| 417 Coeff*, | 436 Coeff*, |
| 418 Coeff*, | 437 Coeff*, |
| 419 GrTexture* background) const { | 438 GrTexture* background) const { |
| 420 if (effect) { | 439 if (effect) { |
| 421 *effect = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]), | 440 *effect = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]), |
| 422 SkScalarToFloat(fK[1]), | 441 SkScalarToFloat(fK[1]), |
| 423 SkScalarToFloat(fK[2]), | 442 SkScalarToFloat(fK[2]), |
| 424 SkScalarToFloat(fK[3]), | 443 SkScalarToFloat(fK[3]), |
| 444 fUnpremultiply, |
| 425 background); | 445 background); |
| 426 } | 446 } |
| 427 return true; | 447 return true; |
| 428 } | 448 } |
| 429 | 449 |
| 430 #endif | 450 #endif |
| 431 | 451 |
| 432 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) | 452 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) |
| 433 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) | 453 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) |
| 434 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 454 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |