| 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 |