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

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

Issue 1894643002: Switch SkXfermodeImagerFilter over to new onFilterImage interface (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix return values Created 4 years, 8 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 | « include/effects/SkXfermodeImageFilter.h ('k') | no next file » | 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
9 #include "SkCanvas.h" 10 #include "SkCanvas.h"
10 #include "SkDevice.h"
11 #include "SkColorPriv.h" 11 #include "SkColorPriv.h"
12 #include "SkReadBuffer.h" 12 #include "SkReadBuffer.h"
13 #include "SkSpecialImage.h"
14 #include "SkSpecialSurface.h"
13 #include "SkWriteBuffer.h" 15 #include "SkWriteBuffer.h"
14 #include "SkXfermode.h" 16 #include "SkXfermode.h"
15 #if SK_SUPPORT_GPU 17 #if SK_SUPPORT_GPU
16 #include "GrContext.h" 18 #include "GrContext.h"
17 #include "GrDrawContext.h" 19 #include "GrDrawContext.h"
18 #include "effects/GrConstColorProcessor.h" 20 #include "effects/GrConstColorProcessor.h"
19 #include "effects/GrTextureDomain.h" 21 #include "effects/GrTextureDomain.h"
20 #include "effects/GrSimpleTextureEffect.h" 22 #include "effects/GrSimpleTextureEffect.h"
21 #include "SkGr.h" 23 #include "SkGr.h"
22 #endif 24 #endif
23 25
24 /////////////////////////////////////////////////////////////////////////////// 26 ///////////////////////////////////////////////////////////////////////////////
25 27
26 sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(sk_sp<SkXfermode> mode, 28 sk_sp<SkImageFilter> SkXfermodeImageFilter::Make(sk_sp<SkXfermode> mode,
27 sk_sp<SkImageFilter> background , 29 sk_sp<SkImageFilter> background ,
28 sk_sp<SkImageFilter> foreground , 30 sk_sp<SkImageFilter> foreground ,
29 const CropRect* cropRect) { 31 const CropRect* cropRect) {
30 sk_sp<SkImageFilter> inputs[2] = { std::move(background), std::move(foregrou nd) }; 32 sk_sp<SkImageFilter> inputs[2] = { std::move(background), std::move(foregrou nd) };
31 return sk_sp<SkImageFilter>(new SkXfermodeImageFilter(mode, inputs, cropRect )); 33 return sk_sp<SkImageFilter>(new SkXfermodeImageFilter(mode, inputs, cropRect ));
32 } 34 }
33 35
34 SkXfermodeImageFilter::SkXfermodeImageFilter(sk_sp<SkXfermode> mode, 36 SkXfermodeImageFilter::SkXfermodeImageFilter(sk_sp<SkXfermode> mode,
35 sk_sp<SkImageFilter> inputs[2], 37 sk_sp<SkImageFilter> inputs[2],
36 const CropRect* cropRect) 38 const CropRect* cropRect)
37 : INHERITED(inputs, 2, cropRect) 39 : INHERITED(inputs, 2, cropRect)
38 , fMode(std::move(mode)) 40 , fMode(std::move(mode)) {
39 {} 41 }
40 42
41 sk_sp<SkFlattenable> SkXfermodeImageFilter::CreateProc(SkReadBuffer& buffer) { 43 sk_sp<SkFlattenable> SkXfermodeImageFilter::CreateProc(SkReadBuffer& buffer) {
42 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); 44 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
43 sk_sp<SkXfermode> mode(buffer.readXfermode()); 45 sk_sp<SkXfermode> mode(buffer.readXfermode());
44 return Make(std::move(mode), common.getInput(0), common.getInput(1), 46 return Make(std::move(mode), common.getInput(0), common.getInput(1), &common .cropRect());
45 &common.cropRect());
46 } 47 }
47 48
48 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const { 49 void SkXfermodeImageFilter::flatten(SkWriteBuffer& buffer) const {
49 this->INHERITED::flatten(buffer); 50 this->INHERITED::flatten(buffer);
50 buffer.writeFlattenable(fMode.get()); 51 buffer.writeFlattenable(fMode.get());
51 } 52 }
52 53
53 bool SkXfermodeImageFilter::onFilterImageDeprecated(Proxy* proxy, 54 sk_sp<SkSpecialImage> SkXfermodeImageFilter::onFilterImage(SkSpecialImage* sourc e,
54 const SkBitmap& src, 55 const Context& ctx,
55 const Context& ctx, 56 SkIPoint* offset) con st {
56 SkBitmap* dst,
57 SkIPoint* offset) const {
58 SkBitmap background = src, foreground = src;
59 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 57 SkIPoint backgroundOffset = SkIPoint::Make(0, 0);
60 if (!this->filterInputDeprecated(0, proxy, src, ctx, &background, &backgroun dOffset)) { 58 sk_sp<SkSpecialImage> background(this->filterInput(0, source, ctx, &backgrou ndOffset));
61 background.reset(); 59
62 }
63 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); 60 SkIPoint foregroundOffset = SkIPoint::Make(0, 0);
64 if (!this->filterInputDeprecated(1, proxy, src, ctx, &foreground, &foregroun dOffset)) { 61 sk_sp<SkSpecialImage> foreground(this->filterInput(1, source, ctx, &foregrou ndOffset));
65 foreground.reset(); 62
63 SkIRect foregroundBounds = SkIRect::EmptyIRect();
64 if (foreground) {
65 foregroundBounds = SkIRect::MakeXYWH(foregroundOffset.x(), foregroundOff set.y(),
66 foreground->width(), foreground->he ight());
66 } 67 }
67 68
68 SkIRect foregroundBounds = foreground.bounds(); 69 SkIRect srcBounds = SkIRect::EmptyIRect();
69 foregroundBounds.offset(foregroundOffset); 70 if (background) {
70 SkIRect srcBounds = background.bounds(); 71 srcBounds = SkIRect::MakeXYWH(backgroundOffset.x(), backgroundOffset.y() ,
71 srcBounds.offset(backgroundOffset); 72 background->width(), background->height() );
73 }
74
72 srcBounds.join(foregroundBounds); 75 srcBounds.join(foregroundBounds);
76 if (srcBounds.isEmpty()) {
77 return nullptr;
78 }
79
73 SkIRect bounds; 80 SkIRect bounds;
74 if (!this->applyCropRect(ctx, srcBounds, &bounds)) { 81 if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
75 return false; 82 return nullptr;
76 } 83 }
77 84
78 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds .height())); 85 offset->fX = bounds.left();
79 if (nullptr == device.get()) { 86 offset->fY = bounds.top();
80 return false; 87
88 #if SK_SUPPORT_GPU
89 if (source->isTextureBacked()) {
90 return this->filterImageGPU(source,
91 background, backgroundOffset,
92 foreground, foregroundOffset,
93 bounds);
81 } 94 }
82 SkCanvas canvas(device); 95 #endif
83 canvas.translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top()) ); 96
97 const SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height( ),
98 kPremul_SkAlphaType);
99 sk_sp<SkSpecialSurface> surf(source->makeSurface(info));
100 if (!surf) {
101 return nullptr;
102 }
103
104 SkCanvas* canvas = surf->getCanvas();
105 SkASSERT(canvas);
106
107 canvas->translate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top() ));
108
84 SkPaint paint; 109 SkPaint paint;
85 paint.setXfermodeMode(SkXfermode::kSrc_Mode); 110 paint.setXfermodeMode(SkXfermode::kSrc_Mode);
86 canvas.drawBitmap(background, SkIntToScalar(backgroundOffset.fX), 111
87 SkIntToScalar(backgroundOffset.fY), &paint); 112 if (background) {
113 background->draw(canvas,
114 SkIntToScalar(backgroundOffset.fX), SkIntToScalar(backg roundOffset.fY),
115 &paint);
116 }
117
88 paint.setXfermode(fMode); 118 paint.setXfermode(fMode);
89 canvas.drawBitmap(foreground, SkIntToScalar(foregroundOffset.fX), 119
90 SkIntToScalar(foregroundOffset.fY), &paint); 120 if (foreground) {
91 canvas.clipRect(SkRect::Make(foregroundBounds), SkRegion::kDifference_Op); 121 foreground->draw(canvas,
122 SkIntToScalar(foregroundOffset.fX), SkIntToScalar(foreg roundOffset.fY),
123 &paint);
124 }
125
126 canvas->clipRect(SkRect::Make(foregroundBounds), SkRegion::kDifference_Op);
92 paint.setColor(SK_ColorTRANSPARENT); 127 paint.setColor(SK_ColorTRANSPARENT);
93 canvas.drawPaint(paint); 128 canvas->drawPaint(paint);
94 *dst = device->accessBitmap(false); 129
95 offset->fX = bounds.left(); 130 return surf->makeImageSnapshot();
96 offset->fY = bounds.top();
97 return true;
98 } 131 }
99 132
100 #ifndef SK_IGNORE_TO_STRING 133 #ifndef SK_IGNORE_TO_STRING
101 void SkXfermodeImageFilter::toString(SkString* str) const { 134 void SkXfermodeImageFilter::toString(SkString* str) const {
102 str->appendf("SkXfermodeImageFilter: ("); 135 str->appendf("SkXfermodeImageFilter: (");
103 str->appendf("xfermode: ("); 136 str->appendf("xfermode: (");
104 if (fMode) { 137 if (fMode) {
105 fMode->toString(str); 138 fMode->toString(str);
106 } 139 }
107 str->append(")"); 140 str->append(")");
108 if (this->getInput(0)) { 141 if (this->getInput(0)) {
109 str->appendf("foreground: ("); 142 str->appendf("foreground: (");
110 this->getInput(0)->toString(str); 143 this->getInput(0)->toString(str);
111 str->appendf(")"); 144 str->appendf(")");
112 } 145 }
113 if (this->getInput(1)) { 146 if (this->getInput(1)) {
114 str->appendf("background: ("); 147 str->appendf("background: (");
115 this->getInput(1)->toString(str); 148 this->getInput(1)->toString(str);
116 str->appendf(")"); 149 str->appendf(")");
117 } 150 }
118 str->append(")"); 151 str->append(")");
119 } 152 }
120 #endif 153 #endif
121 154
122 #if SK_SUPPORT_GPU 155 #if SK_SUPPORT_GPU
123 156
124 bool SkXfermodeImageFilter::canFilterImageGPU() const {
125 return !this->cropRectIsSet();
126 }
127
128 #include "SkXfermode_proccoeff.h" 157 #include "SkXfermode_proccoeff.h"
129 158
130 bool SkXfermodeImageFilter::filterImageGPUDeprecated(Proxy* proxy, 159 sk_sp<SkSpecialImage> SkXfermodeImageFilter::filterImageGPU(SkSpecialImage* sour ce,
131 const SkBitmap& src, 160 sk_sp<SkSpecialImage > background,
132 const Context& ctx, 161 const SkIPoint& back groundOffset,
133 SkBitmap* result, 162 sk_sp<SkSpecialImage > foreground,
134 SkIPoint* offset) const { 163 const SkIPoint& fore groundOffset,
135 GrContext* context = nullptr; 164 const SkIRect& bound s) const {
136 SkBitmap background = src; 165 SkASSERT(source->isTextureBacked());
137 SkIPoint backgroundOffset = SkIPoint::Make(0, 0); 166
138 if (!this->filterInputGPUDeprecated(0, proxy, src, ctx, &background, &backgr oundOffset)) { 167 GrContext* context = source->getContext();
139 background.reset(); 168
140 } 169 sk_sp<GrTexture> backgroundTex, foregroundTex;
141 GrTexture* backgroundTex = background.getTexture(); 170
142 if (backgroundTex) { 171 if (background) {
143 context = backgroundTex->getContext(); 172 backgroundTex.reset(background->asTextureRef(context));
144 } 173 }
145 174
146 SkBitmap foreground = src; 175 if (foreground) {
147 SkIPoint foregroundOffset = SkIPoint::Make(0, 0); 176 foregroundTex.reset(foreground->asTextureRef(context));
148 if (!this->filterInputGPUDeprecated(1, proxy, src, ctx, &foreground, &foregr oundOffset)) {
149 foreground.reset();
150 }
151 GrTexture* foregroundTex = foreground.getTexture();
152 if (foregroundTex) {
153 context = foregroundTex->getContext();
154 }
155
156 if (!context) {
157 return false;
158 }
159
160 SkIRect bounds = background.bounds().makeOffset(backgroundOffset.x(), backgr oundOffset.y());
161 bounds.join(foreground.bounds().makeOffset(foregroundOffset.x(), foregroundO ffset.y()));
162 if (bounds.isEmpty()) {
163 return false;
164 } 177 }
165 178
166 GrSurfaceDesc desc; 179 GrSurfaceDesc desc;
167 desc.fFlags = kRenderTarget_GrSurfaceFlag; 180 desc.fFlags = kRenderTarget_GrSurfaceFlag;
168 desc.fWidth = bounds.width(); 181 desc.fWidth = bounds.width();
169 desc.fHeight = bounds.height(); 182 desc.fHeight = bounds.height();
170 desc.fConfig = kSkia8888_GrPixelConfig; 183 desc.fConfig = kSkia8888_GrPixelConfig;
171 SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture( desc)); 184 SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture( desc));
172 if (!dst) { 185 if (!dst) {
173 return false; 186 return nullptr;
174 } 187 }
175 188
176 GrPaint paint; 189 GrPaint paint;
177 // SRGBTODO: AllowSRGBInputs? 190 // SRGBTODO: AllowSRGBInputs?
178 SkAutoTUnref<const GrFragmentProcessor> bgFP; 191 SkAutoTUnref<const GrFragmentProcessor> bgFP;
179 192
180 if (backgroundTex) { 193 if (backgroundTex) {
181 SkMatrix backgroundMatrix; 194 SkMatrix backgroundMatrix;
182 backgroundMatrix.setIDiv(backgroundTex->width(), backgroundTex->height() ); 195 backgroundMatrix.setIDiv(backgroundTex->width(), backgroundTex->height() );
183 backgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX), 196 backgroundMatrix.preTranslate(SkIntToScalar(-backgroundOffset.fX),
184 SkIntToScalar(-backgroundOffset.fY)); 197 SkIntToScalar(-backgroundOffset.fY));
185 bgFP.reset(GrTextureDomainEffect::Create( 198 bgFP.reset(GrTextureDomainEffect::Create(
186 backgroundTex, backgroundMatrix, 199 backgroundTex.get(), backgroundMatrix,
187 GrTextureDomain::MakeTexelDomain(backgroundTex, back ground.bounds()), 200 GrTextureDomain::MakeTexelDomain(backgroundTex.get() ,
201 background->subset( )),
188 GrTextureDomain::kDecal_Mode, 202 GrTextureDomain::kDecal_Mode,
189 GrTextureParams::kNone_FilterMode)); 203 GrTextureParams::kNone_FilterMode));
190 } else { 204 } else {
191 bgFP.reset(GrConstColorProcessor::Create(GrColor_TRANSPARENT_BLACK, 205 bgFP.reset(GrConstColorProcessor::Create(GrColor_TRANSPARENT_BLACK,
192 GrConstColorProcessor::kIgnore_ InputMode)); 206 GrConstColorProcessor::kIgnore_ InputMode));
193 } 207 }
194 208
195 if (foregroundTex) { 209 if (foregroundTex) {
196 SkMatrix foregroundMatrix; 210 SkMatrix foregroundMatrix;
197 foregroundMatrix.setIDiv(foregroundTex->width(), foregroundTex->height() ); 211 foregroundMatrix.setIDiv(foregroundTex->width(), foregroundTex->height() );
198 foregroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX), 212 foregroundMatrix.preTranslate(SkIntToScalar(-foregroundOffset.fX),
199 SkIntToScalar(-foregroundOffset.fY)); 213 SkIntToScalar(-foregroundOffset.fY));
200 214
201 SkAutoTUnref<const GrFragmentProcessor> foregroundFP; 215 SkAutoTUnref<const GrFragmentProcessor> foregroundFP;
202 216
203 foregroundFP.reset(GrTextureDomainEffect::Create( 217 foregroundFP.reset(GrTextureDomainEffect::Create(
204 foregroundTex, foregroundMatrix, 218 foregroundTex.get(), foregroundMatrix,
205 GrTextureDomain::MakeTexelDomain(foregroundTex, fore ground.bounds()), 219 GrTextureDomain::MakeTexelDomain(foregroundTex.get() ,
220 foreground->subset( )),
206 GrTextureDomain::kDecal_Mode, 221 GrTextureDomain::kDecal_Mode,
207 GrTextureParams::kNone_FilterMode)); 222 GrTextureParams::kNone_FilterMode));
208 223
209 paint.addColorFragmentProcessor(foregroundFP.get()); 224 paint.addColorFragmentProcessor(foregroundFP.get());
210 225
211 // A null fMode is interpreted to mean kSrcOver_Mode (to match raster). 226 // A null fMode is interpreted to mean kSrcOver_Mode (to match raster).
212 SkAutoTUnref<SkXfermode> mode(SkSafeRef(fMode.get())); 227 SkAutoTUnref<SkXfermode> mode(SkSafeRef(fMode.get()));
213 if (!mode) { 228 if (!mode) {
214 // It would be awesome to use SkXfermode::Create here but it knows b etter 229 // It would be awesome to use SkXfermode::Create here but it knows b etter
215 // than us and won't return a kSrcOver_Mode SkXfermode. That means w e 230 // than us and won't return a kSrcOver_Mode SkXfermode. That means w e
(...skipping 12 matching lines...) Expand all
228 paint.addColorFragmentProcessor(xferFP); 243 paint.addColorFragmentProcessor(xferFP);
229 } 244 }
230 } else { 245 } else {
231 paint.addColorFragmentProcessor(bgFP); 246 paint.addColorFragmentProcessor(bgFP);
232 } 247 }
233 248
234 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); 249 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
235 250
236 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTa rget())); 251 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTa rget()));
237 if (!drawContext) { 252 if (!drawContext) {
238 return false; 253 return nullptr;
239 } 254 }
240 255
241 SkMatrix matrix; 256 SkMatrix matrix;
242 matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top ())); 257 matrix.setTranslate(SkIntToScalar(-bounds.left()), SkIntToScalar(-bounds.top ()));
243 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(bounds )); 258 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(bounds ));
244 259
245 offset->fX = bounds.left(); 260 return SkSpecialImage::MakeFromGpu(source->internal_getProxy(),
246 offset->fY = bounds.top(); 261 SkIRect::MakeWH(bounds.width(), bounds.he ight()),
247 GrWrapTextureInBitmap(dst, bounds.width(), bounds.height(), false, result); 262 kNeedNewImageUniqueID_SpecialImage,
248 return true; 263 dst.get());
249 } 264 }
250 265
251 #endif 266 #endif
OLDNEW
« no previous file with comments | « include/effects/SkXfermodeImageFilter.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698