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

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: Address code review comments 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
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/GrTextureDomain.h" 18 #include "effects/GrTextureDomain.h"
19 #include "effects/GrSimpleTextureEffect.h" 19 #include "effects/GrSimpleTextureEffect.h"
20 #include "SkGr.h" 20 #include "SkGr.h"
21 #endif 21 #endif
22 22
23 /////////////////////////////////////////////////////////////////////////////// 23 ///////////////////////////////////////////////////////////////////////////////
24 24
25 SkXfermodeImageFilter::SkXfermodeImageFilter(SkXfermode* mode, 25 SkXfermodeImageFilter::SkXfermodeImageFilter(SkXfermode* mode,
26 SkImageFilter* inputs[2], 26 SkImageFilter* inputs[2],
27 const CropRect* cropRect) 27 const CropRect* cropRect)
28 : INHERITED(2, inputs, cropRect), fMode(mode) { 28 : INHERITED(2, inputs, cropRect)
29 SkSafeRef(fMode); 29 , fMode(SkSafeRef(mode)) {
30 }
31
32 SkXfermodeImageFilter::~SkXfermodeImageFilter() {
33 SkSafeUnref(fMode);
34 } 30 }
35 31
36 SkFlattenable* SkXfermodeImageFilter::CreateProc(SkReadBuffer& buffer) { 32 SkFlattenable* SkXfermodeImageFilter::CreateProc(SkReadBuffer& buffer) {
37 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); 33 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
38 SkAutoTUnref<SkXfermode> mode(buffer.readXfermode()); 34 SkAutoTUnref<SkXfermode> mode(buffer.readXfermode());
39 return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect ()); 35 return Create(mode, common.getInput(0), common.getInput(1), &common.cropRect ());
40 } 36 }
41 37
42 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const { 38 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const {
43 this->INHERITED::flatten(buffer); 39 this->INHERITED::flatten(buffer);
44 buffer.writeFlattenable(fMode); 40 buffer.writeFlattenable(fMode);
45 } 41 }
46 42
47 bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy, 43 bool SkXfermodeImageFilter::onFilterImage(Proxy* proxy,
48 const SkBitmap& src, 44 const SkBitmap& src,
49 const Context& ctx, 45 const Context& ctx,
50 SkBitmap* dst, 46 SkBitmap* dst,
51 SkIPoint* offset) const { 47 SkIPoint* offset) const {
52 SkBitmap background = src, foreground = src; 48 SkBitmap background = src, foreground = src;
53 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 49 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
54 if (!this->filterInput(0, proxy, src, ctx, &background, &backgroundOffset)) { 50 if (!this->filterInput(0, proxy, src, ctx, &background, &backgroundOffset)) {
55 background.reset(); 51 background.reset();
56 } 52 }
57 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); 53 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
58 if (!this->filterInput(1, proxy, src, ctx, &foreground, &foregroundOffset)) { 54 if (!this->filterInput(1, proxy, src, ctx, &foreground, &foregroundOffset)) {
59 foreground.reset(); 55 foreground.reset();
60 } 56 }
61 57
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
113 this->getInput(1)->toString(str); 109 this->getInput(1)->toString(str);
114 str->appendf(")"); 110 str->appendf(")");
115 } 111 }
116 str->append(")"); 112 str->append(")");
117 } 113 }
118 #endif 114 #endif
119 115
120 #if SK_SUPPORT_GPU 116 #if SK_SUPPORT_GPU
121 117
122 bool SkXfermodeImageFilter::canFilterImageGPU() const { 118 bool SkXfermodeImageFilter::canFilterImageGPU() const {
123 return fMode && fMode->asFragmentProcessor(nullptr, nullptr) && !cropRectIsS et(); 119 return !this->cropRectIsSet();
124 } 120 }
125 121
122 #include "SkXfermode_proccoeff.h"
123
126 bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy, 124 bool SkXfermodeImageFilter::filterImageGPU(Proxy* proxy,
127 const SkBitmap& src, 125 const SkBitmap& src,
128 const Context& ctx, 126 const Context& ctx,
129 SkBitmap* result, 127 SkBitmap* result,
130 SkIPoint* offset) const { 128 SkIPoint* offset) const {
131 SkBitmap background = src; 129 SkBitmap background = src;
132 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 130 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
133 if (!this->filterInputGPU(0, proxy, src, ctx, &background, &backgroundOffset )) { 131 if (!this->filterInputGPU(0, proxy, src, ctx, &background, &backgroundOffset )) {
134 return false; 132 return false;
135 } 133 }
(...skipping 10 matching lines...) Expand all
146 return false; 144 return false;
147 } 145 }
148 GrTexture* foregroundTex = foreground.getTexture(); 146 GrTexture* foregroundTex = foreground.getTexture();
149 GrContext* context = foregroundTex->getContext(); 147 GrContext* context = foregroundTex->getContext();
150 SkIRect bounds = background.bounds().makeOffset(backgroundOffset.x(), backgr oundOffset.y()); 148 SkIRect bounds = background.bounds().makeOffset(backgroundOffset.x(), backgr oundOffset.y());
151 bounds.join(foreground.bounds().makeOffset(foregroundOffset.x(), foregroundO ffset.y())); 149 bounds.join(foreground.bounds().makeOffset(foregroundOffset.x(), foregroundO ffset.y()));
152 if (bounds.isEmpty()) { 150 if (bounds.isEmpty()) {
153 return false; 151 return false;
154 } 152 }
155 153
156 const GrFragmentProcessor* xferFP = nullptr;
157
158 GrSurfaceDesc desc; 154 GrSurfaceDesc desc;
159 desc.fFlags = kRenderTarget_GrSurfaceFlag; 155 desc.fFlags = kRenderTarget_GrSurfaceFlag;
160 desc.fWidth = bounds.width(); 156 desc.fWidth = bounds.width();
161 desc.fHeight = bounds.height(); 157 desc.fHeight = bounds.height();
162 desc.fConfig = kSkia8888_GrPixelConfig; 158 desc.fConfig = kSkia8888_GrPixelConfig;
163 SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture( desc)); 159 SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture( desc));
164 if (!dst) { 160 if (!dst) {
165 return false; 161 return false;
166 } 162 }
167 163
168 GrPaint paint; 164 GrPaint paint;
169 SkMatrix backgroundMatrix; 165 SkMatrix backgroundMatrix;
170 backgroundMatrix.setIDiv(backgroundTex->width(), backgroundTex->height()); 166 backgroundMatrix.setIDiv(backgroundTex->width(), backgroundTex->height());
171 backgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX), 167 backgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX),
172 SkIntToScalar(-backgroundOffset.fY)); 168 SkIntToScalar(-backgroundOffset.fY));
173 SkAutoTUnref<const GrFragmentProcessor> bgFP(GrTextureDomainEffect::Create( 169 SkAutoTUnref<const GrFragmentProcessor> bgFP(GrTextureDomainEffect::Create(
174 backgroundTex, backgroundMatrix, 170 backgroundTex, backgroundMatrix,
175 GrTextureDomain::MakeTexelDomain(backgroundTex, background.bounds()), 171 GrTextureDomain::MakeTexelDomain(backgroundTex, background.bounds()),
176 GrTextureDomain::kDecal_Mode, 172 GrTextureDomain::kDecal_Mode,
177 GrTextureParams::kNone_FilterMode) 173 GrTextureParams::kNone_FilterMode)
178 ); 174 );
179 if (!fMode || !fMode->asFragmentProcessor(&xferFP, bgFP)) { 175
180 // canFilterImageGPU() should've taken care of this 176 // A null fMode is interpreted to mean kSrcOver_Mode (to match raster).
181 SkASSERT(false); 177 SkAutoTUnref<SkXfermode> mode(SkSafeRef(fMode.get()));
182 return false; 178 if (!mode) {
179 // It would be awesome to use SkXfermode::Create here but it knows bette r
180 // than us and won't return a kSrcOver_Mode SkXfermode. That means we
181 // have to get one the hard way.
182 struct ProcCoeff rec;
183 rec.fProc = SkXfermode::GetProc(SkXfermode::kSrcOver_Mode);
184 SkXfermode::ModeAsCoeff(SkXfermode::kSrcOver_Mode, &rec.fSC, &rec.fDC);
185
186 mode.reset(new SkProcCoeffXfermode(rec, SkXfermode::kSrcOver_Mode));
183 } 187 }
184 188
189 SkAutoTUnref<const GrFragmentProcessor> xferFP(mode->getFragmentProcessorFor ImageFilter(bgFP));
190
185 SkMatrix foregroundMatrix; 191 SkMatrix foregroundMatrix;
186 foregroundMatrix.setIDiv(foregroundTex->width(), foregroundTex->height()); 192 foregroundMatrix.setIDiv(foregroundTex->width(), foregroundTex->height());
187 foregroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX), 193 foregroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX),
188 SkIntToScalar(-foregroundOffset.fY)); 194 SkIntToScalar(-foregroundOffset.fY));
189 195
190
191 SkAutoTUnref<const GrFragmentProcessor> foregroundFP(GrTextureDomainEffect:: Create( 196 SkAutoTUnref<const GrFragmentProcessor> foregroundFP(GrTextureDomainEffect:: Create(
192 foregroundTex, foregroundMatrix, 197 foregroundTex, foregroundMatrix,
193 GrTextureDomain::MakeTexelDomain(foregroundTex, foreground.bounds()), 198 GrTextureDomain::MakeTexelDomain(foregroundTex, foreground.bounds()),
194 GrTextureDomain::kDecal_Mode, 199 GrTextureDomain::kDecal_Mode,
195 GrTextureParams::kNone_FilterMode) 200 GrTextureParams::kNone_FilterMode)
196 ); 201 );
197 202
198 paint.addColorFragmentProcessor(foregroundFP.get()); 203 paint.addColorFragmentProcessor(foregroundFP.get());
204 // A null 'xferFP' here means kSrc_Mode was used in which case we can just p roceed
199 if (xferFP) { 205 if (xferFP) {
200 paint.addColorFragmentProcessor(xferFP)->unref(); 206 paint.addColorFragmentProcessor(xferFP);
201 } 207 }
202 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 208 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
203 209
204 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTa rget())); 210 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTa rget()));
205 if (!drawContext) { 211 if (!drawContext) {
206 return false; 212 return false;
207 } 213 }
208 214
209 SkMatrix matrix; 215 SkMatrix matrix;
210 matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top ())); 216 matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top ()));
211 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(bounds )); 217 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(bounds ));
212 218
213 offset->fX = bounds.left(); 219 offset->fX = bounds.left();
214 offset->fY = bounds.top(); 220 offset->fY = bounds.top();
215 GrWrapTextureInBitmap(dst, bounds.width(), bounds.height(), false, result); 221 GrWrapTextureInBitmap(dst, bounds.width(), bounds.height(), false, result);
216 return true; 222 return true;
217 } 223 }
218 224
219 #endif 225 #endif
220 226
OLDNEW
« no previous file with comments | « src/effects/SkPixelXorXfermode.cpp ('k') | src/gpu/SkGr.cpp » ('j') | src/gpu/SkGr.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698