OLD | NEW |
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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 | 61 |
62 bool SkBlendImageFilter::onFilterImage(Proxy* proxy, | 62 bool SkBlendImageFilter::onFilterImage(Proxy* proxy, |
63 const SkBitmap& src, | 63 const SkBitmap& src, |
64 const SkMatrix& ctm, | 64 const SkMatrix& ctm, |
65 SkBitmap* dst, | 65 SkBitmap* dst, |
66 SkIPoint* offset) { | 66 SkIPoint* offset) { |
67 SkBitmap background, foreground = src; | 67 SkBitmap background, foreground = src; |
68 SkImageFilter* backgroundInput = getBackgroundInput(); | 68 SkImageFilter* backgroundInput = getBackgroundInput(); |
69 SkImageFilter* foregroundInput = getForegroundInput(); | 69 SkImageFilter* foregroundInput = getForegroundInput(); |
70 SkASSERT(NULL != backgroundInput); | 70 SkASSERT(NULL != backgroundInput); |
71 if (!backgroundInput->filterImage(proxy, src, ctm, &background, offset)) { | 71 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); |
| 72 if (!backgroundInput->filterImage(proxy, src, ctm, &background, &backgroundO
ffset)) { |
72 return false; | 73 return false; |
73 } | 74 } |
74 if (foregroundInput && !foregroundInput->filterImage(proxy, src, ctm, &foreg
round, offset)) { | 75 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); |
| 76 if (foregroundInput && |
| 77 !foregroundInput->filterImage(proxy, src, ctm, &foreground, &foregroundO
ffset)) { |
75 return false; | 78 return false; |
76 } | 79 } |
77 SkAutoLockPixels alp_foreground(foreground), alp_background(background); | 80 SkAutoLockPixels alp_foreground(foreground), alp_background(background); |
78 if (!foreground.getPixels() || !background.getPixels()) { | 81 if (!foreground.getPixels() || !background.getPixels()) { |
79 return false; | 82 return false; |
80 } | 83 } |
81 dst->setConfig(background.config(), background.width(), background.height())
; | 84 dst->setConfig(background.config(), background.width(), background.height())
; |
82 dst->allocPixels(); | 85 dst->allocPixels(); |
83 SkCanvas canvas(*dst); | 86 SkCanvas canvas(*dst); |
84 SkPaint paint; | 87 SkPaint paint; |
85 paint.setXfermodeMode(SkXfermode::kSrc_Mode); | 88 paint.setXfermodeMode(SkXfermode::kSrc_Mode); |
86 canvas.drawBitmap(background, 0, 0, &paint); | 89 canvas.drawBitmap(background, backgroundOffset.fX, backgroundOffset.fY, &pai
nt); |
87 paint.setXfermodeMode(modeToXfermode(fMode)); | 90 paint.setXfermodeMode(modeToXfermode(fMode)); |
88 canvas.drawBitmap(foreground, 0, 0, &paint); | 91 canvas.drawBitmap(foreground, foregroundOffset.fX, foregroundOffset.fY, &pai
nt); |
89 return true; | 92 return true; |
90 } | 93 } |
91 | 94 |
92 /////////////////////////////////////////////////////////////////////////////// | 95 /////////////////////////////////////////////////////////////////////////////// |
93 | 96 |
94 #if SK_SUPPORT_GPU | 97 #if SK_SUPPORT_GPU |
95 class GrGLBlendEffect : public GrGLEffect { | 98 class GrGLBlendEffect : public GrGLEffect { |
96 public: | 99 public: |
97 GrGLBlendEffect(const GrBackendEffectFactory&, const GrDrawEffect&); | 100 GrGLBlendEffect(const GrBackendEffectFactory&, const GrDrawEffect&); |
98 virtual ~GrGLBlendEffect(); | 101 virtual ~GrGLBlendEffect(); |
(...skipping 18 matching lines...) Expand all Loading... |
117 | 120 |
118 typedef GrGLEffect INHERITED; | 121 typedef GrGLEffect INHERITED; |
119 }; | 122 }; |
120 | 123 |
121 /////////////////////////////////////////////////////////////////////////////// | 124 /////////////////////////////////////////////////////////////////////////////// |
122 | 125 |
123 class GrBlendEffect : public GrEffect { | 126 class GrBlendEffect : public GrEffect { |
124 public: | 127 public: |
125 static GrEffectRef* Create(SkBlendImageFilter::Mode mode, | 128 static GrEffectRef* Create(SkBlendImageFilter::Mode mode, |
126 GrTexture* foreground, | 129 GrTexture* foreground, |
127 GrTexture* background) { | 130 const SkIPoint& foregroundOffset, |
128 AutoEffectUnref effect(SkNEW_ARGS(GrBlendEffect, (mode, foreground, back
ground))); | 131 GrTexture* background, |
| 132 const SkIPoint& backgroundOffset) { |
| 133 AutoEffectUnref effect(SkNEW_ARGS(GrBlendEffect, (mode, foreground, fore
groundOffset, |
| 134 background, background
Offset))); |
129 return CreateEffectRef(effect); | 135 return CreateEffectRef(effect); |
130 } | 136 } |
131 | 137 |
132 virtual ~GrBlendEffect(); | 138 virtual ~GrBlendEffect(); |
133 | 139 |
134 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 140 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
135 SkBlendImageFilter::Mode mode() const { return fMode; } | 141 SkBlendImageFilter::Mode mode() const { return fMode; } |
| 142 const SkMatrix& foregroundMatrix() const { return fForegroundMatrix; } |
| 143 const SkMatrix& backgroundMatrix() const { return fBackgroundMatrix; } |
136 | 144 |
137 typedef GrGLBlendEffect GLEffect; | 145 typedef GrGLBlendEffect GLEffect; |
138 static const char* Name() { return "Blend"; } | 146 static const char* Name() { return "Blend"; } |
139 | 147 |
140 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 148 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
141 | 149 |
142 private: | 150 private: |
143 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; | 151 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; |
144 | 152 |
145 GrBlendEffect(SkBlendImageFilter::Mode mode, GrTexture* foreground, GrTextur
e* background); | 153 GrBlendEffect(SkBlendImageFilter::Mode mode, |
| 154 GrTexture* foreground, const SkIPoint& foregroundOffset, |
| 155 GrTexture* background, const SkIPoint& backgroundOffset); |
146 GrTextureAccess fForegroundAccess; | 156 GrTextureAccess fForegroundAccess; |
| 157 SkMatrix fForegroundMatrix; |
147 GrTextureAccess fBackgroundAccess; | 158 GrTextureAccess fBackgroundAccess; |
| 159 SkMatrix fBackgroundMatrix; |
148 SkBlendImageFilter::Mode fMode; | 160 SkBlendImageFilter::Mode fMode; |
149 | 161 |
150 typedef GrEffect INHERITED; | 162 typedef GrEffect INHERITED; |
151 }; | 163 }; |
152 | 164 |
153 bool SkBlendImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkBit
map* result) { | 165 bool SkBlendImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkBit
map* result, |
| 166 SkIPoint* offset) { |
154 SkBitmap backgroundBM; | 167 SkBitmap backgroundBM; |
155 if (!SkImageFilterUtils::GetInputResultGPU(getBackgroundInput(), proxy, src,
&backgroundBM)) { | 168 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); |
| 169 if (!SkImageFilterUtils::GetInputResultGPU(getBackgroundInput(), proxy, src,
&backgroundBM, |
| 170 &backgroundOffset)) { |
156 return false; | 171 return false; |
157 } | 172 } |
158 GrTexture* background = backgroundBM.getTexture(); | 173 GrTexture* background = backgroundBM.getTexture(); |
159 SkBitmap foregroundBM; | 174 SkBitmap foregroundBM; |
160 if (!SkImageFilterUtils::GetInputResultGPU(getForegroundInput(), proxy, src,
&foregroundBM)) { | 175 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); |
| 176 if (!SkImageFilterUtils::GetInputResultGPU(getForegroundInput(), proxy, src,
&foregroundBM, |
| 177 &foregroundOffset)) { |
161 return false; | 178 return false; |
162 } | 179 } |
163 GrTexture* foreground = foregroundBM.getTexture(); | 180 GrTexture* foreground = foregroundBM.getTexture(); |
164 GrContext* context = foreground->getContext(); | 181 GrContext* context = foreground->getContext(); |
165 | 182 |
166 GrTextureDesc desc; | 183 GrTextureDesc desc; |
167 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; | 184 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; |
168 desc.fWidth = src.width(); | 185 desc.fWidth = src.width(); |
169 desc.fHeight = src.height(); | 186 desc.fHeight = src.height(); |
170 desc.fConfig = kSkia8888_GrPixelConfig; | 187 desc.fConfig = kSkia8888_GrPixelConfig; |
171 | 188 |
172 GrAutoScratchTexture ast(context, desc); | 189 GrAutoScratchTexture ast(context, desc); |
173 SkAutoTUnref<GrTexture> dst(ast.detach()); | 190 SkAutoTUnref<GrTexture> dst(ast.detach()); |
174 | 191 |
175 GrContext::AutoRenderTarget art(context, dst->asRenderTarget()); | 192 GrContext::AutoRenderTarget art(context, dst->asRenderTarget()); |
176 | 193 |
177 GrPaint paint; | 194 GrPaint paint; |
178 paint.colorStage(0)->setEffect( | 195 paint.colorStage(0)->setEffect( |
179 GrBlendEffect::Create(fMode, foreground, background))->unref(); | 196 GrBlendEffect::Create(fMode, foreground, foregroundOffset, background, b
ackgroundOffset))->unref(); |
180 SkRect srcRect; | 197 SkRect srcRect; |
181 src.getBounds(&srcRect); | 198 src.getBounds(&srcRect); |
182 context->drawRect(paint, srcRect); | 199 context->drawRect(paint, srcRect); |
183 return SkImageFilterUtils::WrapTexture(dst, src.width(), src.height(), resul
t); | 200 return SkImageFilterUtils::WrapTexture(dst, src.width(), src.height(), resul
t); |
184 } | 201 } |
185 | 202 |
186 /////////////////////////////////////////////////////////////////////////////// | 203 /////////////////////////////////////////////////////////////////////////////// |
187 | 204 |
188 GrBlendEffect::GrBlendEffect(SkBlendImageFilter::Mode mode, | 205 GrBlendEffect::GrBlendEffect(SkBlendImageFilter::Mode mode, |
189 GrTexture* foreground, | 206 GrTexture* foreground, |
190 GrTexture* background) | 207 const SkIPoint& foregroundOffset, |
| 208 GrTexture* background, |
| 209 const SkIPoint& backgroundOffset) |
191 : fForegroundAccess(foreground) | 210 : fForegroundAccess(foreground) |
192 , fBackgroundAccess(background) | 211 , fBackgroundAccess(background) |
193 , fMode(mode) { | 212 , fMode(mode) { |
194 this->addTextureAccess(&fForegroundAccess); | 213 this->addTextureAccess(&fForegroundAccess); |
195 this->addTextureAccess(&fBackgroundAccess); | 214 this->addTextureAccess(&fBackgroundAccess); |
| 215 fForegroundMatrix = GrEffect::MakeDivByTextureWHMatrix(foreground); |
| 216 fForegroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX), |
| 217 SkIntToScalar(-foregroundOffset.fY)); |
| 218 fBackgroundMatrix = GrEffect::MakeDivByTextureWHMatrix(background); |
| 219 fBackgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX), |
| 220 SkIntToScalar(-backgroundOffset.fY)); |
196 } | 221 } |
197 | 222 |
198 GrBlendEffect::~GrBlendEffect() { | 223 GrBlendEffect::~GrBlendEffect() { |
199 } | 224 } |
200 | 225 |
201 bool GrBlendEffect::onIsEqual(const GrEffect& sBase) const { | 226 bool GrBlendEffect::onIsEqual(const GrEffect& sBase) const { |
202 const GrBlendEffect& s = CastEffect<GrBlendEffect>(sBase); | 227 const GrBlendEffect& s = CastEffect<GrBlendEffect>(sBase); |
203 return fForegroundAccess.getTexture() == s.fForegroundAccess.getTexture() && | 228 return fForegroundAccess.getTexture() == s.fForegroundAccess.getTexture() && |
204 fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture() && | 229 fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture() && |
205 fMode == s.fMode; | 230 fMode == s.fMode; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
281 builder->fsCodeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb,
(1.0 - %s.a) * %s.rgb + %s.rgb);\n", outputColor, fgColor, bgColor, fgColor, bg
Color, fgColor, bgColor); | 306 builder->fsCodeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb,
(1.0 - %s.a) * %s.rgb + %s.rgb);\n", outputColor, fgColor, bgColor, fgColor, bg
Color, fgColor, bgColor); |
282 break; | 307 break; |
283 } | 308 } |
284 } | 309 } |
285 | 310 |
286 void GrGLBlendEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect
& drawEffect) { | 311 void GrGLBlendEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect
& drawEffect) { |
287 const GrBlendEffect& blend = drawEffect.castEffect<GrBlendEffect>(); | 312 const GrBlendEffect& blend = drawEffect.castEffect<GrBlendEffect>(); |
288 GrTexture* fgTex = blend.texture(0); | 313 GrTexture* fgTex = blend.texture(0); |
289 GrTexture* bgTex = blend.texture(1); | 314 GrTexture* bgTex = blend.texture(1); |
290 fForegroundEffectMatrix.setData(uman, | 315 fForegroundEffectMatrix.setData(uman, |
291 GrEffect::MakeDivByTextureWHMatrix(fgTex), | 316 blend.foregroundMatrix(), |
292 drawEffect, | 317 drawEffect, |
293 fgTex); | 318 fgTex); |
294 fBackgroundEffectMatrix.setData(uman, | 319 fBackgroundEffectMatrix.setData(uman, |
295 GrEffect::MakeDivByTextureWHMatrix(bgTex), | 320 blend.backgroundMatrix(), |
296 drawEffect, | 321 drawEffect, |
297 bgTex); | 322 bgTex); |
298 | 323 |
299 } | 324 } |
300 | 325 |
301 GrGLEffect::EffectKey GrGLBlendEffect::GenKey(const GrDrawEffect& drawEffect, co
nst GrGLCaps&) { | 326 GrGLEffect::EffectKey GrGLBlendEffect::GenKey(const GrDrawEffect& drawEffect, co
nst GrGLCaps&) { |
302 const GrBlendEffect& blend = drawEffect.castEffect<GrBlendEffect>(); | 327 const GrBlendEffect& blend = drawEffect.castEffect<GrBlendEffect>(); |
303 | 328 |
304 GrTexture* fgTex = blend.texture(0); | 329 GrTexture* fgTex = blend.texture(0); |
305 GrTexture* bgTex = blend.texture(1); | 330 GrTexture* bgTex = blend.texture(1); |
306 | 331 |
307 EffectKey fgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatri
x(fgTex), | 332 EffectKey fgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatri
x(fgTex), |
308 drawEffect, | 333 drawEffect, |
309 kCoordsType, | 334 kCoordsType, |
310 fgTex); | 335 fgTex); |
311 | 336 |
312 EffectKey bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatri
x(bgTex), | 337 EffectKey bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatri
x(bgTex), |
313 drawEffect, | 338 drawEffect, |
314 kCoordsType, | 339 kCoordsType, |
315 bgTex); | 340 bgTex); |
316 bgKey <<= GrGLEffectMatrix::kKeyBits; | 341 bgKey <<= GrGLEffectMatrix::kKeyBits; |
317 EffectKey modeKey = blend.mode() << (2 * GrGLEffectMatrix::kKeyBits); | 342 EffectKey modeKey = blend.mode() << (2 * GrGLEffectMatrix::kKeyBits); |
318 | 343 |
319 return modeKey | bgKey | fgKey; | 344 return modeKey | bgKey | fgKey; |
320 } | 345 } |
321 #endif | 346 #endif |
OLD | NEW |