LEFT | RIGHT |
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 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 #include "SkBlendImageFilter.h" | 8 #include "SkBlendImageFilter.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 case SkBlendImageFilter::kScreen_Mode: | 29 case SkBlendImageFilter::kScreen_Mode: |
30 return SkXfermode::kScreen_Mode; | 30 return SkXfermode::kScreen_Mode; |
31 case SkBlendImageFilter::kDarken_Mode: | 31 case SkBlendImageFilter::kDarken_Mode: |
32 return SkXfermode::kDarken_Mode; | 32 return SkXfermode::kDarken_Mode; |
33 case SkBlendImageFilter::kLighten_Mode: | 33 case SkBlendImageFilter::kLighten_Mode: |
34 return SkXfermode::kLighten_Mode; | 34 return SkXfermode::kLighten_Mode; |
35 } | 35 } |
36 SkASSERT(0); | 36 SkASSERT(0); |
37 return SkXfermode::kSrcOver_Mode; | 37 return SkXfermode::kSrcOver_Mode; |
38 } | 38 } |
| 39 |
| 40 #ifdef SK_IGNORE_MULTIPLY_XFERMODE_OPT |
| 41 SkPMColor multiply_proc(SkPMColor src, SkPMColor dst) { |
| 42 int omsa = 255 - SkGetPackedA32(src); |
| 43 int sr = SkGetPackedR32(src), sg = SkGetPackedG32(src), sb = SkGetPackedB32(
src); |
| 44 int omda = 255 - SkGetPackedA32(dst); |
| 45 int dr = SkGetPackedR32(dst), dg = SkGetPackedG32(dst), db = SkGetPackedB32(
dst); |
| 46 int a = 255 - SkMulDiv255Round(omsa, omda); |
| 47 int r = SkMulDiv255Round(omsa, dr) + SkMulDiv255Round(omda, sr) + SkMulDiv25
5Round(sr, dr); |
| 48 int g = SkMulDiv255Round(omsa, dg) + SkMulDiv255Round(omda, sg) + SkMulDiv25
5Round(sg, dg); |
| 49 int b = SkMulDiv255Round(omsa, db) + SkMulDiv255Round(omda, sb) + SkMulDiv25
5Round(sb, db); |
| 50 return SkPackARGB32(a, r, g, b); |
| 51 } |
| 52 #endif |
| 53 |
39 }; | 54 }; |
40 | 55 |
41 /////////////////////////////////////////////////////////////////////////////// | 56 /////////////////////////////////////////////////////////////////////////////// |
42 | 57 |
43 SkBlendImageFilter::SkBlendImageFilter(SkBlendImageFilter::Mode mode, SkImageFil
ter* background, SkImageFilter* foreground) | 58 SkBlendImageFilter::SkBlendImageFilter(SkBlendImageFilter::Mode mode, SkImageFil
ter* background, SkImageFilter* foreground) |
44 : INHERITED(background, foreground), fMode(mode) | 59 : INHERITED(background, foreground), fMode(mode) |
45 { | 60 { |
46 } | 61 } |
47 | 62 |
48 SkBlendImageFilter::~SkBlendImageFilter() { | 63 SkBlendImageFilter::~SkBlendImageFilter() { |
(...skipping 28 matching lines...) Expand all Loading... |
77 SkAutoLockPixels alp_foreground(foreground), alp_background(background); | 92 SkAutoLockPixels alp_foreground(foreground), alp_background(background); |
78 if (!foreground.getPixels() || !background.getPixels()) { | 93 if (!foreground.getPixels() || !background.getPixels()) { |
79 return false; | 94 return false; |
80 } | 95 } |
81 dst->setConfig(background.config(), background.width(), background.height())
; | 96 dst->setConfig(background.config(), background.width(), background.height())
; |
82 dst->allocPixels(); | 97 dst->allocPixels(); |
83 SkCanvas canvas(*dst); | 98 SkCanvas canvas(*dst); |
84 SkPaint paint; | 99 SkPaint paint; |
85 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 100 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
86 canvas.drawBitmap(background, 0, 0, &paint); | 101 canvas.drawBitmap(background, 0, 0, &paint); |
| 102 #ifdef SK_IGNORE_MULTIPLY_XFERMODE_OPT |
| 103 // FEBlend's multiply mode is (1 - Sa) * Da + (1 - Da) * Sc + Sc * Dc |
| 104 // Skia's is just Sc * Dc. So we use a custom proc to implement FEBlend's |
| 105 // version. |
| 106 if (fMode == SkBlendImageFilter::kMultiply_Mode) { |
| 107 paint.setXfermode(new SkProcXfermode(multiply_proc))->unref(); |
| 108 } else { |
| 109 paint.setXfermodeMode(modeToXfermode(fMode)); |
| 110 } |
| 111 #else |
87 paint.setXfermodeMode(modeToXfermode(fMode)); | 112 paint.setXfermodeMode(modeToXfermode(fMode)); |
| 113 #endif |
88 canvas.drawBitmap(foreground, 0, 0, &paint); | 114 canvas.drawBitmap(foreground, 0, 0, &paint); |
89 return true; | 115 return true; |
90 } | 116 } |
91 | 117 |
92 /////////////////////////////////////////////////////////////////////////////// | 118 /////////////////////////////////////////////////////////////////////////////// |
93 | 119 |
94 #if SK_SUPPORT_GPU | 120 #if SK_SUPPORT_GPU |
95 class GrGLBlendEffect : public GrGLEffect { | 121 class GrGLBlendEffect : public GrGLEffect { |
96 public: | 122 public: |
97 GrGLBlendEffect(const GrBackendEffectFactory& factory, | 123 GrGLBlendEffect(const GrBackendEffectFactory& factory, |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 | 331 |
306 EffectKey bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatri
x(bgTex), | 332 EffectKey bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatri
x(bgTex), |
307 stage.getCoordChangeMatrix(), | 333 stage.getCoordChangeMatrix(), |
308 bgTex); | 334 bgTex); |
309 bgKey <<= GrGLEffectMatrix::kKeyBits; | 335 bgKey <<= GrGLEffectMatrix::kKeyBits; |
310 EffectKey modeKey = blend.mode() << (2 * GrGLEffectMatrix::kKeyBits); | 336 EffectKey modeKey = blend.mode() << (2 * GrGLEffectMatrix::kKeyBits); |
311 | 337 |
312 return modeKey | bgKey | fgKey; | 338 return modeKey | bgKey | fgKey; |
313 } | 339 } |
314 #endif | 340 #endif |
LEFT | RIGHT |