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

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

Issue 1674673002: Alter SkXfermode's asFragmentProcessor & asXPFactory contracts (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix unit test bug Created 4 years, 10 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
« no previous file with comments | « src/effects/SkPixelXorXfermode.cpp ('k') | src/gpu/SkGr.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 The Android Open Source Project 2 * Copyright 2013 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 "SkXfermodeImageFilter.h" 8 #include "SkXfermodeImageFilter.h"
9 #include "SkCanvas.h" 9 #include "SkCanvas.h"
10 #include "SkDevice.h" 10 #include "SkDevice.h"
11 #include "SkColorPriv.h" 11 #include "SkColorPriv.h"
12 #include "SkReadBuffer.h" 12 #include "SkReadBuffer.h"
13 #include "SkWriteBuffer.h" 13 #include "SkWriteBuffer.h"
14 #include "SkXfermode.h" 14 #include "SkXfermode.h"
15 #if SK_SUPPORT_GPU 15 #if SK_SUPPORT_GPU
16 #include "GrContext.h" 16 #include "GrContext.h"
17 #include "GrDrawContext.h" 17 #include "GrDrawContext.h"
18 #include "effects/GrConstColorProcessor.h"
18 #include "effects/GrTextureDomain.h" 19 #include "effects/GrTextureDomain.h"
19 #include "effects/GrSimpleTextureEffect.h" 20 #include "effects/GrSimpleTextureEffect.h"
20 #include "SkGr.h" 21 #include "SkGr.h"
21 #endif 22 #endif
22 23
23 /////////////////////////////////////////////////////////////////////////////// 24 ///////////////////////////////////////////////////////////////////////////////
24 25
25 SkXfermodeImageFilter::SkXfermodeImageFilter(SkXfermode* mode, 26 SkXfermodeImageFilter::SkXfermodeImageFilter(SkXfermode* mode,
26 SkImageFilter* inputs[2], 27 SkImageFilter* inputs[2],
27 const CropRect* cropRect) 28 const CropRect* cropRect)
28 : INHERITED(2, inputs, cropRect), fMode(mode) { 29 : INHERITED(2, inputs, cropRect)
29 SkSafeRef(fMode); 30 , fMode(SkSafeRef(mode)) {
30 }
31
32 SkXfermodeImageFilter::~SkXfermodeImageFilter() {
33 SkSafeUnref(fMode);
34 } 31 }
35 32
36 SkFlattenable* SkXfermodeImageFilter::CreateProc(SkReadBuffer& buffer) { 33 SkFlattenable* SkXfermodeImageFilter::CreateProc(SkReadBuffer& buffer) {
37 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); 34 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
38 SkAutoTUnref<SkXfermode> mode(buffer.readXfermode()); 35 SkAutoTUnref<SkXfermode> mode(buffer.readXfermode());
39 return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect ()); 36 return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect ());
40 } 37 }
41 38
42 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const { 39 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const {
43 this->INHERITED::flatten(buffer); 40 this->INHERITED::flatten(buffer);
44 buffer.writeFlattenable(fMode); 41 buffer.writeFlattenable(fMode);
45 } 42 }
46 43
47 bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy, 44 bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy,
48 const SkBitmap& src, 45 const SkBitmap& src,
49 const Context& ctx, 46 const Context& ctx,
50 SkBitmap* dst, 47 SkBitmap* dst,
51 SkIPoint* offset) const { 48 SkIPoint* offset) const {
52 SkBitmap background = src, foreground = src; 49 SkBitmap background = src, foreground = src;
53 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 50 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
54 if (!this->filterInput(0, proxy, src, ctx, &background, &backgroundOffset)) { 51 if (!this->filterInput(0, proxy, src, ctx, &background, &backgroundOffset)) {
55 background.reset(); 52 background.reset();
56 } 53 }
57 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); 54 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
58 if (!this->filterInput(1, proxy, src, ctx, &foreground, &foregroundOffset)) { 55 if (!this->filterInput(1, proxy, src, ctx, &foreground, &foregroundOffset)) {
59 foreground.reset(); 56 foreground.reset();
60 } 57 }
61 58
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 this->getInput(1)->toString(str); 110 this->getInput(1)->toString(str);
114 str->appendf(")"); 111 str->appendf(")");
115 } 112 }
116 str->append(")"); 113 str->append(")");
117 } 114 }
118 #endif 115 #endif
119 116
120 #if SK_SUPPORT_GPU 117 #if SK_SUPPORT_GPU
121 118
122 bool SkXfermodeImageFilter::canFilterImageGPU() const { 119 bool SkXfermodeImageFilter::canFilterImageGPU() const {
123 return fMode && fMode->asFragmentProcessor(nullptr, nullptr) && !cropRectIsS et(); 120 return !this->cropRectIsSet();
124 } 121 }
125 122
123 #include "SkXfermode_proccoeff.h"
124
126 bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, 125 bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
127 const SkBitmap& src, 126 const SkBitmap& src,
128 const Context& ctx, 127 const Context& ctx,
129 SkBitmap* result, 128 SkBitmap* result,
130 SkIPoint* offset) const { 129 SkIPoint* offset) const {
130 GrContext* context = nullptr;
131 SkBitmap background = src; 131 SkBitmap background = src;
132 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 132 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
133 if (!this->filterInputGPU(0, proxy, src, ctx, &background, &backgroundOffset )) { 133 if (!this->filterInputGPU(0, proxy, src, ctx, &background, &backgroundOffset )) {
134 return false; 134 background.reset();
135 } 135 }
136
137 GrTexture* backgroundTex = background.getTexture(); 136 GrTexture* backgroundTex = background.getTexture();
138 if (nullptr == backgroundTex) { 137 if (backgroundTex) {
139 SkASSERT(false); 138 context = backgroundTex->getContext();
140 return false;
141 } 139 }
142 140
143 SkBitmap foreground = src; 141 SkBitmap foreground = src;
144 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); 142 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
145 if (!this->filterInputGPU(1, proxy, src, ctx, &foreground, &foregroundOffset )) { 143 if (!this->filterInputGPU(1, proxy, src, ctx, &foreground, &foregroundOffset )) {
144 foreground.reset();
145 }
146 GrTexture* foregroundTex = foreground.getTexture();
147 if (foregroundTex) {
148 context = foregroundTex->getContext();
149 }
150
151 if (!context) {
146 return false; 152 return false;
147 } 153 }
148 GrTexture* foregroundTex = foreground.getTexture(); 154
149 GrContext* context = foregroundTex->getContext();
150 SkIRect bounds = background.bounds().makeOffset(backgroundOffset.x(), backgr oundOffset.y()); 155 SkIRect bounds = background.bounds().makeOffset(backgroundOffset.x(), backgr oundOffset.y());
151 bounds.join(foreground.bounds().makeOffset(foregroundOffset.x(), foregroundO ffset.y())); 156 bounds.join(foreground.bounds().makeOffset(foregroundOffset.x(), foregroundO ffset.y()));
152 if (bounds.isEmpty()) { 157 if (bounds.isEmpty()) {
153 return false; 158 return false;
154 } 159 }
155 160
156 const GrFragmentProcessor* xferFP = nullptr;
157
158 GrSurfaceDesc desc; 161 GrSurfaceDesc desc;
159 desc.fFlags = kRenderTarget_GrSurfaceFlag; 162 desc.fFlags = kRenderTarget_GrSurfaceFlag;
160 desc.fWidth = bounds.width(); 163 desc.fWidth = bounds.width();
161 desc.fHeight = bounds.height(); 164 desc.fHeight = bounds.height();
162 desc.fConfig = kSkia8888_GrPixelConfig; 165 desc.fConfig = kSkia8888_GrPixelConfig;
163 SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture( desc)); 166 SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture( desc));
164 if (!dst) { 167 if (!dst) {
165 return false; 168 return false;
166 } 169 }
167 170
168 GrPaint paint; 171 GrPaint paint;
169 SkMatrix backgroundMatrix; 172 SkAutoTUnref<const GrFragmentProcessor> bgFP;
170 backgroundMatrix.setIDiv(backgroundTex->width(), backgroundTex->height()); 173
171 backgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX), 174 if (backgroundTex) {
172 SkIntToScalar(-backgroundOffset.fY)); 175 SkMatrix backgroundMatrix;
173 SkAutoTUnref<const GrFragmentProcessor> bgFP(GrTextureDomainEffect::Create( 176 backgroundMatrix.setIDiv(backgroundTex->width(), backgroundTex->height() );
174 backgroundTex, backgroundMatrix, 177 backgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX),
175 GrTextureDomain::MakeTexelDomain(backgroundTex, background.bounds()), 178 SkIntToScalar(-backgroundOffset.fY));
176 GrTextureDomain::kDecal_Mode, 179 bgFP.reset(GrTextureDomainEffect::Create(
177 GrTextureParams::kNone_FilterMode) 180 backgroundTex, backgroundMatrix,
178 ); 181 GrTextureDomain::MakeTexelDomain(backgroundTex, back ground.bounds()),
179 if (!fMode || !fMode->asFragmentProcessor(&xferFP, bgFP)) { 182 GrTextureDomain::kDecal_Mode,
180 // canFilterImageGPU() should've taken care of this 183 GrTextureParams::kNone_FilterMode));
181 SkASSERT(false); 184 } else {
182 return false; 185 bgFP.reset(GrConstColorProcessor::Create(GrColor_TRANSPARENT_BLACK,
186 GrConstColorProcessor::kIgnore_ InputMode));
183 } 187 }
184 188
185 SkMatrix foregroundMatrix; 189 if (foregroundTex) {
186 foregroundMatrix.setIDiv(foregroundTex->width(), foregroundTex->height()); 190 SkMatrix foregroundMatrix;
187 foregroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX), 191 foregroundMatrix.setIDiv(foregroundTex->width(), foregroundTex->height() );
188 SkIntToScalar(-foregroundOffset.fY)); 192 foregroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX),
193 SkIntToScalar(-foregroundOffset.fY));
189 194
195 SkAutoTUnref<const GrFragmentProcessor> foregroundFP;
190 196
191 SkAutoTUnref<const GrFragmentProcessor> foregroundFP(GrTextureDomainEffect:: Create( 197 foregroundFP.reset(GrTextureDomainEffect::Create(
192 foregroundTex, foregroundMatrix, 198 foregroundTex, foregroundMatrix,
193 GrTextureDomain::MakeTexelDomain(foregroundTex, foreground.bounds()), 199 GrTextureDomain::MakeTexelDomain(foregroundTex, fore ground.bounds()),
194 GrTextureDomain::kDecal_Mode, 200 GrTextureDomain::kDecal_Mode,
195 GrTextureParams::kNone_FilterMode) 201 GrTextureParams::kNone_FilterMode));
196 );
197 202
198 paint.addColorFragmentProcessor(foregroundFP.get()); 203 paint.addColorFragmentProcessor(foregroundFP.get());
199 if (xferFP) { 204
200 paint.addColorFragmentProcessor(xferFP)->unref(); 205 // A null fMode is interpreted to mean kSrcOver_Mode (to match raster).
206 SkAutoTUnref<SkXfermode> mode(SkSafeRef(fMode.get()));
207 if (!mode) {
208 // It would be awesome to use SkXfermode::Create here but it knows b etter
209 // than us and won't return a kSrcOver_Mode SkXfermode. That means w e
210 // have to get one the hard way.
211 struct ProcCoeff rec;
212 rec.fProc = SkXfermode::GetProc(SkXfermode::kSrcOver_Mode);
213 SkXfermode::ModeAsCoeff(SkXfermode::kSrcOver_Mode, &rec.fSC, &rec.fD C);
214
215 mode.reset(new SkProcCoeffXfermode(rec, SkXfermode::kSrcOver_Mode));
216 }
217
218 SkAutoTUnref<const GrFragmentProcessor> xferFP(mode->getFragmentProcesso rForImageFilter(bgFP));
219
220 // A null 'xferFP' here means kSrc_Mode was used in which case we can ju st proceed
221 if (xferFP) {
222 paint.addColorFragmentProcessor(xferFP);
223 }
224 } else {
225 paint.addColorFragmentProcessor(bgFP);
201 } 226 }
227
202 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 228 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
203 229
204 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTa rget())); 230 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTa rget()));
205 if (!drawContext) { 231 if (!drawContext) {
206 return false; 232 return false;
207 } 233 }
208 234
209 SkMatrix matrix; 235 SkMatrix matrix;
210 matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top ())); 236 matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top ()));
211 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(bounds )); 237 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(bounds ));
212 238
213 offset->fX = bounds.left(); 239 offset->fX = bounds.left();
214 offset->fY = bounds.top(); 240 offset->fY = bounds.top();
215 GrWrapTextureInBitmap(dst, bounds.width(), bounds.height(), false, result); 241 GrWrapTextureInBitmap(dst, bounds.width(), bounds.height(), false, result);
216 return true; 242 return true;
217 } 243 }
218 244
219 #endif 245 #endif
220 246
OLDNEW
« no previous file with comments | « src/effects/SkPixelXorXfermode.cpp ('k') | src/gpu/SkGr.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698