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

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

Issue 21404002: Remove SkBlendImageFilter, and all tests. Its functionality has been subsumed by SkXfermodeImageFil… (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 4 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 | « include/effects/SkBlendImageFilter.h ('k') | src/ports/SkGlobalInitialization_default.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 2012 The Android Open Source Project
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkBlendImageFilter.h"
9 #include "SkCanvas.h"
10 #include "SkColorPriv.h"
11 #include "SkFlattenableBuffers.h"
12 #if SK_SUPPORT_GPU
13 #include "GrContext.h"
14 #include "gl/GrGLEffect.h"
15 #include "gl/GrGLEffectMatrix.h"
16 #include "GrTBackendEffectFactory.h"
17 #include "SkImageFilterUtils.h"
18 #endif
19
20 namespace {
21
22 SkXfermode::Mode modeToXfermode(SkBlendImageFilter::Mode mode) {
23 switch (mode) {
24 case SkBlendImageFilter::kNormal_Mode:
25 return SkXfermode::kSrcOver_Mode;
26 case SkBlendImageFilter::kMultiply_Mode:
27 return SkXfermode::kMultiply_Mode;
28 case SkBlendImageFilter::kScreen_Mode:
29 return SkXfermode::kScreen_Mode;
30 case SkBlendImageFilter::kDarken_Mode:
31 return SkXfermode::kDarken_Mode;
32 case SkBlendImageFilter::kLighten_Mode:
33 return SkXfermode::kLighten_Mode;
34 }
35 SkASSERT(0);
36 return SkXfermode::kSrcOver_Mode;
37 }
38
39 };
40
41 ///////////////////////////////////////////////////////////////////////////////
42
43 SkBlendImageFilter::SkBlendImageFilter(SkBlendImageFilter::Mode mode, SkImageFil ter* background, SkImageFilter* foreground)
44 : INHERITED(background, foreground), fMode(mode)
45 {
46 }
47
48 SkBlendImageFilter::~SkBlendImageFilter() {
49 }
50
51 SkBlendImageFilter::SkBlendImageFilter(SkFlattenableReadBuffer& buffer)
52 : INHERITED(buffer)
53 {
54 fMode = (SkBlendImageFilter::Mode) buffer.readInt();
55 }
56
57 void SkBlendImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const {
58 this->INHERITED::flatten(buffer);
59 buffer.writeInt((int) fMode);
60 }
61
62 bool SkBlendImageFilter::onFilterImage(Proxy* proxy,
63 const SkBitmap& src,
64 const SkMatrix& ctm,
65 SkBitmap* dst,
66 SkIPoint* offset) {
67 SkBitmap background, foreground = src;
68 SkImageFilter* backgroundInput = getBackgroundInput();
69 SkImageFilter* foregroundInput = getForegroundInput();
70 SkASSERT(NULL != backgroundInput);
71 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
72 if (!backgroundInput->filterImage(proxy, src, ctm, &background, &backgroundO ffset)) {
73 return false;
74 }
75 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
76 if (foregroundInput &&
77 !foregroundInput->filterImage(proxy, src, ctm, &foreground, &foregroundO ffset)) {
78 return false;
79 }
80 SkAutoLockPixels alp_foreground(foreground), alp_background(background);
81 if (!foreground.getPixels() || !background.getPixels()) {
82 return false;
83 }
84 dst->setConfig(background.config(), background.width(), background.height()) ;
85 dst->allocPixels();
86 SkCanvas canvas(*dst);
87 SkPaint paint;
88 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
89 canvas.drawBitmap(background, SkIntToScalar(backgroundOffset.fX),
90 SkIntToScalar(backgroundOffset.fY), &paint);
91 paint.setXfermodeMode(modeToXfermode(fMode));
92 canvas.drawBitmap(foreground, SkIntToScalar(foregroundOffset.fX),
93 SkIntToScalar(foregroundOffset.fY), &paint);
94 return true;
95 }
96
97 ///////////////////////////////////////////////////////////////////////////////
98
99 #if SK_SUPPORT_GPU
100 class GrGLBlendEffect : public GrGLEffect {
101 public:
102 GrGLBlendEffect(const GrBackendEffectFactory&, const GrDrawEffect&);
103 virtual ~GrGLBlendEffect();
104
105 virtual void emitCode(GrGLShaderBuilder*,
106 const GrDrawEffect&,
107 EffectKey,
108 const char* outputColor,
109 const char* inputColor,
110 const TextureSamplerArray&) SK_OVERRIDE;
111
112 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&);
113
114 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER RIDE;
115
116 private:
117 static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType;
118
119 SkBlendImageFilter::Mode fMode;
120 GrGLEffectMatrix fForegroundEffectMatrix;
121 GrGLEffectMatrix fBackgroundEffectMatrix;
122
123 typedef GrGLEffect INHERITED;
124 };
125
126 ///////////////////////////////////////////////////////////////////////////////
127
128 class GrBlendEffect : public GrEffect {
129 public:
130 static GrEffectRef* Create(SkBlendImageFilter::Mode mode,
131 GrTexture* foreground,
132 const SkIPoint& foregroundOffset,
133 GrTexture* background,
134 const SkIPoint& backgroundOffset) {
135 AutoEffectUnref effect(SkNEW_ARGS(GrBlendEffect, (mode, foreground, fore groundOffset,
136 background, background Offset)));
137 return CreateEffectRef(effect);
138 }
139
140 virtual ~GrBlendEffect();
141
142 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
143 SkBlendImageFilter::Mode mode() const { return fMode; }
144 const SkMatrix& foregroundMatrix() const { return fForegroundMatrix; }
145 const SkMatrix& backgroundMatrix() const { return fBackgroundMatrix; }
146
147 typedef GrGLBlendEffect GLEffect;
148 static const char* Name() { return "Blend"; }
149
150 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE;
151
152 private:
153 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE;
154
155 GrBlendEffect(SkBlendImageFilter::Mode mode,
156 GrTexture* foreground, const SkIPoint& foregroundOffset,
157 GrTexture* background, const SkIPoint& backgroundOffset);
158 GrTextureAccess fForegroundAccess;
159 SkMatrix fForegroundMatrix;
160 GrTextureAccess fBackgroundAccess;
161 SkMatrix fBackgroundMatrix;
162 SkBlendImageFilter::Mode fMode;
163
164 typedef GrEffect INHERITED;
165 };
166
167 bool SkBlendImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, SkBit map* result,
168 SkIPoint* offset) {
169 SkBitmap backgroundBM;
170 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
171 if (!SkImageFilterUtils::GetInputResultGPU(getBackgroundInput(), proxy, src, &backgroundBM,
172 &backgroundOffset)) {
173 return false;
174 }
175 GrTexture* background = backgroundBM.getTexture();
176 SkBitmap foregroundBM;
177 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
178 if (!SkImageFilterUtils::GetInputResultGPU(getForegroundInput(), proxy, src, &foregroundBM,
179 &foregroundOffset)) {
180 return false;
181 }
182 GrTexture* foreground = foregroundBM.getTexture();
183 GrContext* context = foreground->getContext();
184
185 GrTextureDesc desc;
186 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
187 desc.fWidth = src.width();
188 desc.fHeight = src.height();
189 desc.fConfig = kSkia8888_GrPixelConfig;
190
191 GrAutoScratchTexture ast(context, desc);
192 SkAutoTUnref<GrTexture> dst(ast.detach());
193
194 GrContext::AutoRenderTarget art(context, dst->asRenderTarget());
195
196 GrPaint paint;
197 paint.addColorEffect(GrBlendEffect::Create(fMode,
198 foreground, foregroundOffset,
199 background, backgroundOffset))->u nref();
200 SkRect srcRect;
201 src.getBounds(&srcRect);
202 context->drawRect(paint, srcRect);
203 return SkImageFilterUtils::WrapTexture(dst, src.width(), src.height(), resul t);
204 }
205
206 ///////////////////////////////////////////////////////////////////////////////
207
208 GrBlendEffect::GrBlendEffect(SkBlendImageFilter::Mode mode,
209 GrTexture* foreground,
210 const SkIPoint& foregroundOffset,
211 GrTexture* background,
212 const SkIPoint& backgroundOffset)
213 : fForegroundAccess(foreground)
214 , fBackgroundAccess(background)
215 , fMode(mode) {
216 this->addTextureAccess(&fForegroundAccess);
217 this->addTextureAccess(&fBackgroundAccess);
218 fForegroundMatrix = GrEffect::MakeDivByTextureWHMatrix(foreground);
219 fForegroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX),
220 SkIntToScalar(-foregroundOffset.fY));
221 fBackgroundMatrix = GrEffect::MakeDivByTextureWHMatrix(background);
222 fBackgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX),
223 SkIntToScalar(-backgroundOffset.fY));
224 }
225
226 GrBlendEffect::~GrBlendEffect() {
227 }
228
229 bool GrBlendEffect::onIsEqual(const GrEffect& sBase) const {
230 const GrBlendEffect& s = CastEffect<GrBlendEffect>(sBase);
231 return fForegroundAccess.getTexture() == s.fForegroundAccess.getTexture() &&
232 fBackgroundAccess.getTexture() == s.fBackgroundAccess.getTexture() &&
233 fMode == s.fMode;
234 }
235
236 const GrBackendEffectFactory& GrBlendEffect::getFactory() const {
237 return GrTBackendEffectFactory<GrBlendEffect>::getInstance();
238 }
239
240 void GrBlendEffect::getConstantColorComponents(GrColor* color, uint32_t* validFl ags) const {
241 // The output alpha is always 1 - (1 - FGa) * (1 - BGa). So if either FGa or BGa is known to
242 // be one then the output alpha is one. (This effect ignores its input. We s hould have a way to
243 // communicate this.)
244 if (GrPixelConfigIsOpaque(fForegroundAccess.getTexture()->config()) ||
245 GrPixelConfigIsOpaque(fBackgroundAccess.getTexture()->config())) {
246 *validFlags = kA_GrColorComponentFlag;
247 *color = GrColorPackRGBA(0, 0, 0, 0xff);
248 } else {
249 *validFlags = 0;
250 }
251 }
252
253 ///////////////////////////////////////////////////////////////////////////////
254
255 GrGLBlendEffect::GrGLBlendEffect(const GrBackendEffectFactory& factory,
256 const GrDrawEffect& drawEffect)
257 : INHERITED(factory)
258 , fMode(drawEffect.castEffect<GrBlendEffect>().mode())
259 , fForegroundEffectMatrix(kCoordsType)
260 , fBackgroundEffectMatrix(kCoordsType) {
261 }
262
263 GrGLBlendEffect::~GrGLBlendEffect() {
264 }
265
266 void GrGLBlendEffect::emitCode(GrGLShaderBuilder* builder,
267 const GrDrawEffect&,
268 EffectKey key,
269 const char* outputColor,
270 const char* inputColor,
271 const TextureSamplerArray& samplers) {
272 const char* fgCoords;
273 const char* bgCoords;
274 GrSLType fgCoordsType = fForegroundEffectMatrix.emitCode(builder, key, &fgCo ords, NULL, "FG");
275 GrSLType bgCoordsType = fBackgroundEffectMatrix.emitCode(builder, key, &bgCo ords, NULL, "BG");
276
277 const char* bgColor = "bgColor";
278 const char* fgColor = "fgColor";
279
280 builder->fsCodeAppendf("\t\tvec4 %s = ", fgColor);
281 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType,
282 samplers[0],
283 fgCoords,
284 fgCoordsType);
285 builder->fsCodeAppend(";\n");
286
287 builder->fsCodeAppendf("\t\tvec4 %s = ", bgColor);
288 builder->appendTextureLookup(GrGLShaderBuilder::kFragment_ShaderType,
289 samplers[1],
290 bgCoords,
291 bgCoordsType);
292 builder->fsCodeAppendf(";\n");
293
294 builder->fsCodeAppendf("\t\t%s.a = 1.0 - (1.0 - %s.a) * (1.0 - %s.b);\n", ou tputColor, bgColor, fgColor);
295 switch (fMode) {
296 case SkBlendImageFilter::kNormal_Mode:
297 builder->fsCodeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + %s.rgb;\n", outputColor, fgColor, bgColor, fgColor);
298 break;
299 case SkBlendImageFilter::kMultiply_Mode:
300 builder->fsCodeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + (1.0 - %s.a ) * %s.rgb + %s.rgb * %s.rgb;\n", outputColor, fgColor, bgColor, bgColor, fgColo r, fgColor, bgColor);
301 break;
302 case SkBlendImageFilter::kScreen_Mode:
303 builder->fsCodeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb - %s.rgb * %s.rgb;\ n", outputColor, bgColor, fgColor, fgColor, bgColor);
304 break;
305 case SkBlendImageFilter::kDarken_Mode:
306 builder->fsCodeAppendf("\t\t%s.rgb = min((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);
307 break;
308 case SkBlendImageFilter::kLighten_Mode:
309 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);
310 break;
311 }
312 }
313
314 void GrGLBlendEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect & drawEffect) {
315 const GrBlendEffect& blend = drawEffect.castEffect<GrBlendEffect>();
316 GrTexture* fgTex = blend.texture(0);
317 GrTexture* bgTex = blend.texture(1);
318 fForegroundEffectMatrix.setData(uman,
319 blend.foregroundMatrix(),
320 drawEffect,
321 fgTex);
322 fBackgroundEffectMatrix.setData(uman,
323 blend.backgroundMatrix(),
324 drawEffect,
325 bgTex);
326
327 }
328
329 GrGLEffect::EffectKey GrGLBlendEffect::GenKey(const GrDrawEffect& drawEffect, co nst GrGLCaps&) {
330 const GrBlendEffect& blend = drawEffect.castEffect<GrBlendEffect>();
331
332 GrTexture* fgTex = blend.texture(0);
333 GrTexture* bgTex = blend.texture(1);
334
335 EffectKey fgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatri x(fgTex),
336 drawEffect,
337 kCoordsType,
338 fgTex);
339
340 EffectKey bgKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMatri x(bgTex),
341 drawEffect,
342 kCoordsType,
343 bgTex);
344 bgKey <<= GrGLEffectMatrix::kKeyBits;
345 EffectKey modeKey = blend.mode() << (2 * GrGLEffectMatrix::kKeyBits);
346
347 return modeKey | bgKey | fgKey;
348 }
349 #endif
OLDNEW
« no previous file with comments | « include/effects/SkBlendImageFilter.h ('k') | src/ports/SkGlobalInitialization_default.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698