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

Side by Side Diff: src/effects/SkArithmeticMode.cpp

Issue 16125008: Implement SkXfermode image filter (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Add new case to xfermodeimagefilter GM; revert changes to arithmode GM Created 7 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/core/SkXfermode.cpp ('k') | src/effects/SkXfermodeImageFilter.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "GrTBackendEffectFactory.h" 17 #include "GrTBackendEffectFactory.h"
17 #include "SkImageFilterUtils.h" 18 #include "SkImageFilterUtils.h"
18 #endif 19 #endif
19 20
20 class SkArithmeticMode_scalar : public SkXfermode { 21 class SkArithmeticMode_scalar : public SkXfermode {
21 public: 22 public:
22 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) { 23 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) {
23 fK[0] = k1; 24 fK[0] = k1;
24 fK[1] = k2; 25 fK[1] = k2;
25 fK[2] = k3; 26 fK[2] = k3;
26 fK[3] = k4; 27 fK[3] = k4;
27 } 28 }
28 29
29 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, 30 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
30 const SkAlpha aa[]) const SK_OVERRIDE; 31 const SkAlpha aa[]) const SK_OVERRIDE;
31 32
32 SK_DEVELOPER_TO_STRING() 33 SK_DEVELOPER_TO_STRING()
33 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) 34 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar)
34 35
35 #if SK_SUPPORT_GPU 36 #if SK_SUPPORT_GPU
36 virtual bool asNewEffectOrCoeff(GrContext*, GrEffectRef** effect, Coeff*, Co eff*) const SK_OVERRIDE; 37 virtual bool asNewEffectOrCoeff(GrContext*, GrEffectRef** effect, Coeff*, Co eff*, GrTexture* background) const SK_OVERRIDE;
37 #endif 38 #endif
38 39
39 private: 40 private:
40 SkArithmeticMode_scalar(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { 41 SkArithmeticMode_scalar(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
41 fK[0] = buffer.readScalar(); 42 fK[0] = buffer.readScalar();
42 fK[1] = buffer.readScalar(); 43 fK[1] = buffer.readScalar();
43 fK[2] = buffer.readScalar(); 44 fK[2] = buffer.readScalar();
44 fK[3] = buffer.readScalar(); 45 fK[3] = buffer.readScalar();
45 } 46 }
46 47
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 const char* outputColor, 234 const char* outputColor,
234 const char* inputColor, 235 const char* inputColor,
235 const TextureSamplerArray&) SK_OVERRIDE; 236 const TextureSamplerArray&) SK_OVERRIDE;
236 237
237 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); 238 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
238 239
239 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE; 240 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE;
240 241
241 private: 242 private:
242 static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType; 243 static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType;
243 244 GrGLEffectMatrix fBackgroundEffectMatrix;
244 GrGLUniformManager::UniformHandle fKUni; 245 GrGLUniformManager::UniformHandle fKUni;
245 246
246 typedef GrGLEffect INHERITED; 247 typedef GrGLEffect INHERITED;
247 }; 248 };
248 249
249 /////////////////////////////////////////////////////////////////////////////// 250 ///////////////////////////////////////////////////////////////////////////////
250 251
251 class GrArithmeticEffect : public GrEffect { 252 class GrArithmeticEffect : public GrEffect {
252 public: 253 public:
253 static GrEffectRef* Create(float k1, float k2, float k3, float k4) { 254 static GrEffectRef* Create(float k1, float k2, float k3, float k4, GrTexture * background) {
254 AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4))) ; 255 AutoEffectUnref effect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, b ackground)));
255 return CreateEffectRef(effect); 256 return CreateEffectRef(effect);
256 } 257 }
257 258
258 virtual ~GrArithmeticEffect(); 259 virtual ~GrArithmeticEffect();
259 260
260 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; 261 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
261 262
262 typedef GrGLArithmeticEffect GLEffect; 263 typedef GrGLArithmeticEffect GLEffect;
263 static const char* Name() { return "Arithmetic"; } 264 static const char* Name() { return "Arithmetic"; }
265 GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture() ; }
264 266
265 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE; 267 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE;
266 268
267 float k1() const { return fK1; } 269 float k1() const { return fK1; }
268 float k2() const { return fK2; } 270 float k2() const { return fK2; }
269 float k3() const { return fK3; } 271 float k3() const { return fK3; }
270 float k4() const { return fK4; } 272 float k4() const { return fK4; }
271 273
272 private: 274 private:
273 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; 275 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
274 276
275 GrArithmeticEffect(float k1, float k2, float k3, float k4); 277 GrArithmeticEffect(float k1, float k2, float k3, float k4, GrTexture* backgr ound);
276 float fK1, fK2, fK3, fK4; 278 float fK1, fK2, fK3, fK4;
279 GrTextureAccess fBackgroundAccess;
277 280
278 GR_DECLARE_EFFECT_TEST; 281 GR_DECLARE_EFFECT_TEST;
279 typedef GrEffect INHERITED; 282 typedef GrEffect INHERITED;
280 283
281 }; 284 };
282 285
283 /////////////////////////////////////////////////////////////////////////////// 286 ///////////////////////////////////////////////////////////////////////////////
284 287
285 GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4) 288 GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4,
289 GrTexture* background)
286 : fK1(k1), fK2(k2), fK3(k3), fK4(k4) { 290 : fK1(k1), fK2(k2), fK3(k3), fK4(k4) {
287 this->setWillReadDstColor(); 291 if (background) {
292 fBackgroundAccess.reset(background);
293 this->addTextureAccess(&fBackgroundAccess);
294 } else {
295 this->setWillReadDstColor();
296 }
288 } 297 }
289 298
290 GrArithmeticEffect::~GrArithmeticEffect() { 299 GrArithmeticEffect::~GrArithmeticEffect() {
291 } 300 }
292 301
293 bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const { 302 bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const {
294 const GrArithmeticEffect& s = CastEffect<GrArithmeticEffect>(sBase); 303 const GrArithmeticEffect& s = CastEffect<GrArithmeticEffect>(sBase);
295 return fK1 == s.fK1 && 304 return fK1 == s.fK1 &&
296 fK2 == s.fK2 && 305 fK2 == s.fK2 &&
297 fK3 == s.fK3 && 306 fK3 == s.fK3 &&
298 fK4 == s.fK4; 307 fK4 == s.fK4 &&
308 backgroundTexture() == s.backgroundTexture();
299 } 309 }
300 310
301 const GrBackendEffectFactory& GrArithmeticEffect::getFactory() const { 311 const GrBackendEffectFactory& GrArithmeticEffect::getFactory() const {
302 return GrTBackendEffectFactory<GrArithmeticEffect>::getInstance(); 312 return GrTBackendEffectFactory<GrArithmeticEffect>::getInstance();
303 } 313 }
304 314
305 void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* va lidFlags) const { 315 void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* va lidFlags) const {
306 // TODO: optimize this 316 // TODO: optimize this
307 *validFlags = 0; 317 *validFlags = 0;
308 } 318 }
309 319
310 /////////////////////////////////////////////////////////////////////////////// 320 ///////////////////////////////////////////////////////////////////////////////
311 321
312 GrGLArithmeticEffect::GrGLArithmeticEffect(const GrBackendEffectFactory& factory , 322 GrGLArithmeticEffect::GrGLArithmeticEffect(const GrBackendEffectFactory& factory ,
313 const GrDrawEffect& drawEffect) : INH ERITED(factory) { 323 const GrDrawEffect& drawEffect)
324 : INHERITED(factory)
325 , fBackgroundEffectMatrix(kCoordsType) {
314 } 326 }
315 327
316 GrGLArithmeticEffect::~GrGLArithmeticEffect() { 328 GrGLArithmeticEffect::~GrGLArithmeticEffect() {
317 } 329 }
318 330
319 void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder, 331 void GrGLArithmeticEffect::emitCode(GrGLShaderBuilder* builder,
320 const GrDrawEffect&, 332 const GrDrawEffect& drawEffect,
321 EffectKey key, 333 EffectKey key,
322 const char* outputColor, 334 const char* outputColor,
323 const char* inputColor, 335 const char* inputColor,
324 const TextureSamplerArray& samplers) { 336 const TextureSamplerArray& samplers) {
325 const char* dstColor = builder->dstColor(); 337
338 GrTexture* backgroundTex = drawEffect.castEffect<GrArithmeticEffect>().backg roundTexture();
339 const char* dstColor;
340 if (backgroundTex) {
341 const char* bgCoords;
342 GrSLType bgCoordsType = fBackgroundEffectMatrix.emitCode(builder, key, & bgCoords, NULL, "BG");
343 builder->fsCodeAppend("\t\tvec4 bgColor = ");
344 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType,
345 samplers[0],
346 bgCoords,
347 bgCoordsType);
348 builder->fsCodeAppendf(";\n");
349 dstColor = "bgColor";
350 } else {
351 dstColor = builder->dstColor();
352 }
353
326 GrAssert(NULL != dstColor); 354 GrAssert(NULL != dstColor);
327 fKUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType, 355 fKUni = builder->addUniform(GrGLShaderBuilder::kFragment_ShaderType,
328 kVec4f_GrSLType, "k"); 356 kVec4f_GrSLType, "k");
329 const char* kUni = builder->getUniformCStr(fKUni); 357 const char* kUni = builder->getUniformCStr(fKUni);
330 358
331 // We don't try to optimize for this case at all 359 // We don't try to optimize for this case at all
332 if (NULL == inputColor) { 360 if (NULL == inputColor) {
333 builder->fsCodeAppendf("\t\tconst vec4 src = %s;\n", GrGLSLOnesVecf(4)); 361 builder->fsCodeAppendf("\t\tconst vec4 src = %s;\n", GrGLSLOnesVecf(4));
334 } else { 362 } else {
335 builder->fsCodeAppendf("\t\tvec4 src = %s;\n", inputColor); 363 builder->fsCodeAppendf("\t\tvec4 src = %s;\n", inputColor);
336 builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\ n"); 364 builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\ n");
337 } 365 }
338 366
339 builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor); 367 builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor);
340 builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n"); 368 builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n");
341 369
342 builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;\n", outputColor, kUni, kUni, kUni, kUni); 370 builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;\n", outputColor, kUni, kUni, kUni, kUni);
343 builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outpu tColor); 371 builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outpu tColor);
344 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor); 372 builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
345 } 373 }
346 374
347 void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawE ffect& drawEffect) { 375 void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawE ffect& drawEffect) {
348 const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>( ); 376 const GrArithmeticEffect& arith = drawEffect.castEffect<GrArithmeticEffect>( );
349 uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); 377 uman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4());
378 GrTexture* bgTex = arith.backgroundTexture();
379 if (bgTex) {
380 fBackgroundEffectMatrix.setData(uman,
381 GrEffect::MakeDivByTextureWHMatrix(bgTex ),
382 drawEffect,
383 bgTex);
384 }
350 } 385 }
351 386
352 GrGLEffect::EffectKey GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffec t, const GrGLCaps&) { 387 GrGLEffect::EffectKey GrGLArithmeticEffect::GenKey(const GrDrawEffect& drawEffec t, const GrGLCaps&) {
353 return 0; 388 const GrArithmeticEffect& effect = drawEffect.castEffect<GrArithmeticEffect> ();
389 GrTexture* bgTex = effect.backgroundTexture();
390 EffectKey bgKey = 0;
391 if (bgTex) {
392 bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatrix(bgTe x),
393 drawEffect,
394 GrGLArithmeticEffect::kCoordsType,
395 bgTex);
396 }
397 return bgKey;
354 } 398 }
355 399
356 GrEffectRef* GrArithmeticEffect::TestCreate(SkMWCRandom* rand, 400 GrEffectRef* GrArithmeticEffect::TestCreate(SkMWCRandom* rand,
357 GrContext*, 401 GrContext*,
358 const GrDrawTargetCaps&, 402 const GrDrawTargetCaps&,
359 GrTexture*[]) { 403 GrTexture*[]) {
360 float k1 = rand->nextF(); 404 float k1 = rand->nextF();
361 float k2 = rand->nextF(); 405 float k2 = rand->nextF();
362 float k3 = rand->nextF(); 406 float k3 = rand->nextF();
363 float k4 = rand->nextF(); 407 float k4 = rand->nextF();
364 408
365 static AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k 4))); 409 static AutoEffectUnref gEffect(SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k 4, NULL)));
366 return CreateEffectRef(gEffect); 410 return CreateEffectRef(gEffect);
367 } 411 }
368 412
369 GR_DEFINE_EFFECT_TEST(GrArithmeticEffect); 413 GR_DEFINE_EFFECT_TEST(GrArithmeticEffect);
370 414
371 bool SkArithmeticMode_scalar::asNewEffectOrCoeff(GrContext*, 415 bool SkArithmeticMode_scalar::asNewEffectOrCoeff(GrContext*,
372 GrEffectRef** effect, 416 GrEffectRef** effect,
373 Coeff*, 417 Coeff*,
374 Coeff*) const { 418 Coeff*,
419 GrTexture* background) const {
375 if (effect) { 420 if (effect) {
376 *effect = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]), 421 *effect = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]),
377 SkScalarToFloat(fK[1]), 422 SkScalarToFloat(fK[1]),
378 SkScalarToFloat(fK[2]), 423 SkScalarToFloat(fK[2]),
379 SkScalarToFloat(fK[3])); 424 SkScalarToFloat(fK[3]),
425 background);
380 } 426 }
381 return true; 427 return true;
382 } 428 }
383 429
384 #endif 430 #endif
385 431
386 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) 432 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode)
387 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) 433 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar)
388 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 434 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « src/core/SkXfermode.cpp ('k') | src/effects/SkXfermodeImageFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698