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

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

Issue 1846313002: Switch SkDisplacementImageFilter over to new onFilterImage interface (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: update 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/SkDisplacementMapEffect.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 Google Inc. 2 * Copyright 2013 Google Inc.
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 "SkDisplacementMapEffect.h" 8 #include "SkDisplacementMapEffect.h"
9 #include "SkDevice.h" 9
10 #include "SkBitmap.h"
10 #include "SkReadBuffer.h" 11 #include "SkReadBuffer.h"
12 #include "SkSpecialImage.h"
11 #include "SkWriteBuffer.h" 13 #include "SkWriteBuffer.h"
12 #include "SkUnPreMultiply.h" 14 #include "SkUnPreMultiply.h"
13 #include "SkColorPriv.h" 15 #include "SkColorPriv.h"
14 #if SK_SUPPORT_GPU 16 #if SK_SUPPORT_GPU
15 #include "GrContext.h" 17 #include "GrContext.h"
16 #include "GrDrawContext.h" 18 #include "GrDrawContext.h"
17 #include "GrCoordTransform.h" 19 #include "GrCoordTransform.h"
18 #include "GrInvariantOutput.h" 20 #include "GrInvariantOutput.h"
19 #include "SkGr.h" 21 #include "SkGr.h"
20 #include "effects/GrTextureDomain.h" 22 #include "effects/GrTextureDomain.h"
(...skipping 29 matching lines...) Expand all
50 } 52 }
51 53
52 template<> uint32_t getValue<SkDisplacementMapEffect::kA_ChannelSelectorType>( 54 template<> uint32_t getValue<SkDisplacementMapEffect::kA_ChannelSelectorType>(
53 SkColor l, const SkUnPreMultiply::Scale*) { 55 SkColor l, const SkUnPreMultiply::Scale*) {
54 return SkGetPackedA32(l); 56 return SkGetPackedA32(l);
55 } 57 }
56 58
57 template<SkDisplacementMapEffect::ChannelSelectorType typeX, 59 template<SkDisplacementMapEffect::ChannelSelectorType typeX,
58 SkDisplacementMapEffect::ChannelSelectorType typeY> 60 SkDisplacementMapEffect::ChannelSelectorType typeY>
59 void computeDisplacement(const SkVector& scale, SkBitmap* dst, 61 void computeDisplacement(const SkVector& scale, SkBitmap* dst,
60 SkBitmap* displ, const SkIPoint& offset, 62 const SkPixmap& displ, const SkIPoint& offset,
61 SkBitmap* src, 63 const SkPixmap& src,
62 const SkIRect& bounds) 64 const SkIRect& bounds) {
63 {
64 static const SkScalar Inv8bit = SkScalarInvert(255); 65 static const SkScalar Inv8bit = SkScalarInvert(255);
65 const int srcW = src->width(); 66 const int srcW = src.width();
66 const int srcH = src->height(); 67 const int srcH = src.height();
67 const SkVector scaleForColor = SkVector::Make(SkScalarMul(scale.fX, Inv8bit) , 68 const SkVector scaleForColor = SkVector::Make(SkScalarMul(scale.fX, Inv8bit) ,
68 SkScalarMul(scale.fY, Inv8bit) ); 69 SkScalarMul(scale.fY, Inv8bit) );
69 const SkVector scaleAdj = SkVector::Make(SK_ScalarHalf - SkScalarMul(scale.f X, SK_ScalarHalf), 70 const SkVector scaleAdj = SkVector::Make(SK_ScalarHalf - SkScalarMul(scale.f X, SK_ScalarHalf),
70 SK_ScalarHalf - SkScalarMul(scale.f Y, SK_ScalarHalf)); 71 SK_ScalarHalf - SkScalarMul(scale.f Y, SK_ScalarHalf));
71 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable(); 72 const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
72 SkPMColor* dstPtr = dst->getAddr32(0, 0); 73 SkPMColor* dstPtr = dst->getAddr32(0, 0);
73 for (int y = bounds.top(); y < bounds.bottom(); ++y) { 74 for (int y = bounds.top(); y < bounds.bottom(); ++y) {
74 const SkPMColor* displPtr = displ->getAddr32(bounds.left() + offset.fX, 75 const SkPMColor* displPtr = displ.addr32(bounds.left() + offset.fX, y + offset.fY);
75 y + offset.fY);
76 for (int x = bounds.left(); x < bounds.right(); ++x, ++displPtr) { 76 for (int x = bounds.left(); x < bounds.right(); ++x, ++displPtr) {
77 const SkScalar displX = SkScalarMul(scaleForColor.fX, 77 const SkScalar displX = SkScalarMul(scaleForColor.fX,
78 SkIntToScalar(getValue<typeX>(*displPtr, table))) + scaleAdj.fX; 78 SkIntToScalar(getValue<typeX>(*displPtr, table))) + scaleAdj.fX;
79 const SkScalar displY = SkScalarMul(scaleForColor.fY, 79 const SkScalar displY = SkScalarMul(scaleForColor.fY,
80 SkIntToScalar(getValue<typeY>(*displPtr, table))) + scaleAdj.fY; 80 SkIntToScalar(getValue<typeY>(*displPtr, table))) + scaleAdj.fY;
81 // Truncate the displacement values 81 // Truncate the displacement values
82 const int srcX = x + SkScalarTruncToInt(displX); 82 const int srcX = x + SkScalarTruncToInt(displX);
83 const int srcY = y + SkScalarTruncToInt(displY); 83 const int srcY = y + SkScalarTruncToInt(displY);
84 *dstPtr++ = ((srcX < 0) || (srcX >= srcW) || (srcY < 0) || (srcY >= srcH)) ? 84 *dstPtr++ = ((srcX < 0) || (srcX >= srcW) || (srcY < 0) || (srcY >= srcH)) ?
85 0 : *(src->getAddr32(srcX, srcY)); 85 0 : *(src.addr32(srcX, srcY));
86 } 86 }
87 } 87 }
88 } 88 }
89 89
90 template<SkDisplacementMapEffect::ChannelSelectorType typeX> 90 template<SkDisplacementMapEffect::ChannelSelectorType typeX>
91 void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType yChannelSe lector, 91 void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType yChannelSe lector,
92 const SkVector& scale, SkBitmap* dst, 92 const SkVector& scale, SkBitmap* dst,
93 SkBitmap* displ, const SkIPoint& offset, 93 const SkPixmap& displ, const SkIPoint& offset,
94 SkBitmap* src, 94 const SkPixmap& src,
95 const SkIRect& bounds) 95 const SkIRect& bounds) {
96 {
97 switch (yChannelSelector) { 96 switch (yChannelSelector) {
98 case SkDisplacementMapEffect::kR_ChannelSelectorType: 97 case SkDisplacementMapEffect::kR_ChannelSelectorType:
99 computeDisplacement<typeX, SkDisplacementMapEffect::kR_ChannelSelectorTy pe>( 98 computeDisplacement<typeX, SkDisplacementMapEffect::kR_ChannelSelectorTy pe>(
100 scale, dst, displ, offset, src, bounds); 99 scale, dst, displ, offset, src, bounds);
101 break; 100 break;
102 case SkDisplacementMapEffect::kG_ChannelSelectorType: 101 case SkDisplacementMapEffect::kG_ChannelSelectorType:
103 computeDisplacement<typeX, SkDisplacementMapEffect::kG_ChannelSelectorTy pe>( 102 computeDisplacement<typeX, SkDisplacementMapEffect::kG_ChannelSelectorTy pe>(
104 scale, dst, displ, offset, src, bounds); 103 scale, dst, displ, offset, src, bounds);
105 break; 104 break;
106 case SkDisplacementMapEffect::kB_ChannelSelectorType: 105 case SkDisplacementMapEffect::kB_ChannelSelectorType:
107 computeDisplacement<typeX, SkDisplacementMapEffect::kB_ChannelSelectorTy pe>( 106 computeDisplacement<typeX, SkDisplacementMapEffect::kB_ChannelSelectorTy pe>(
108 scale, dst, displ, offset, src, bounds); 107 scale, dst, displ, offset, src, bounds);
109 break; 108 break;
110 case SkDisplacementMapEffect::kA_ChannelSelectorType: 109 case SkDisplacementMapEffect::kA_ChannelSelectorType:
111 computeDisplacement<typeX, SkDisplacementMapEffect::kA_ChannelSelectorTy pe>( 110 computeDisplacement<typeX, SkDisplacementMapEffect::kA_ChannelSelectorTy pe>(
112 scale, dst, displ, offset, src, bounds); 111 scale, dst, displ, offset, src, bounds);
113 break; 112 break;
114 case SkDisplacementMapEffect::kUnknown_ChannelSelectorType: 113 case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
115 default: 114 default:
116 SkDEBUGFAIL("Unknown Y channel selector"); 115 SkDEBUGFAIL("Unknown Y channel selector");
117 } 116 }
118 } 117 }
119 118
120 void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType xChannelSe lector, 119 void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType xChannelSe lector,
121 SkDisplacementMapEffect::ChannelSelectorType yChannelSe lector, 120 SkDisplacementMapEffect::ChannelSelectorType yChannelSe lector,
122 const SkVector& scale, SkBitmap* dst, 121 const SkVector& scale, SkBitmap* dst,
123 SkBitmap* displ, const SkIPoint& offset, 122 const SkPixmap& displ, const SkIPoint& offset,
124 SkBitmap* src, 123 const SkPixmap& src,
125 const SkIRect& bounds) 124 const SkIRect& bounds) {
126 {
127 switch (xChannelSelector) { 125 switch (xChannelSelector) {
128 case SkDisplacementMapEffect::kR_ChannelSelectorType: 126 case SkDisplacementMapEffect::kR_ChannelSelectorType:
129 computeDisplacement<SkDisplacementMapEffect::kR_ChannelSelectorType>( 127 computeDisplacement<SkDisplacementMapEffect::kR_ChannelSelectorType>(
130 yChannelSelector, scale, dst, displ, offset, src, bounds); 128 yChannelSelector, scale, dst, displ, offset, src, bounds);
131 break; 129 break;
132 case SkDisplacementMapEffect::kG_ChannelSelectorType: 130 case SkDisplacementMapEffect::kG_ChannelSelectorType:
133 computeDisplacement<SkDisplacementMapEffect::kG_ChannelSelectorType>( 131 computeDisplacement<SkDisplacementMapEffect::kG_ChannelSelectorType>(
134 yChannelSelector, scale, dst, displ, offset, src, bounds); 132 yChannelSelector, scale, dst, displ, offset, src, bounds);
135 break; 133 break;
136 case SkDisplacementMapEffect::kB_ChannelSelectorType: 134 case SkDisplacementMapEffect::kB_ChannelSelectorType:
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 176
179 SkImageFilter* inputs[2] = { displacement, color }; 177 SkImageFilter* inputs[2] = { displacement, color };
180 return new SkDisplacementMapEffect(xChannelSelector, yChannelSelector, scale , inputs, cropRect); 178 return new SkDisplacementMapEffect(xChannelSelector, yChannelSelector, scale , inputs, cropRect);
181 } 179 }
182 180
183 SkDisplacementMapEffect::SkDisplacementMapEffect(ChannelSelectorType xChannelSel ector, 181 SkDisplacementMapEffect::SkDisplacementMapEffect(ChannelSelectorType xChannelSel ector,
184 ChannelSelectorType yChannelSel ector, 182 ChannelSelectorType yChannelSel ector,
185 SkScalar scale, 183 SkScalar scale,
186 SkImageFilter* inputs[2], 184 SkImageFilter* inputs[2],
187 const CropRect* cropRect) 185 const CropRect* cropRect)
188 : INHERITED(2, inputs, cropRect) 186 : INHERITED(2, inputs, cropRect)
189 , fXChannelSelector(xChannelSelector) 187 , fXChannelSelector(xChannelSelector)
190 , fYChannelSelector(yChannelSelector) 188 , fYChannelSelector(yChannelSelector)
191 , fScale(scale) 189 , fScale(scale) {
192 {
193 } 190 }
194 191
195 SkDisplacementMapEffect::~SkDisplacementMapEffect() { 192 SkDisplacementMapEffect::~SkDisplacementMapEffect() {
196 } 193 }
197 194
198 SkFlattenable* SkDisplacementMapEffect::CreateProc(SkReadBuffer& buffer) { 195 SkFlattenable* SkDisplacementMapEffect::CreateProc(SkReadBuffer& buffer) {
199 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2); 196 SK_IMAGEFILTER_UNFLATTEN_COMMON(common, 2);
200 ChannelSelectorType xsel = (ChannelSelectorType)buffer.readInt(); 197 ChannelSelectorType xsel = (ChannelSelectorType)buffer.readInt();
201 ChannelSelectorType ysel = (ChannelSelectorType)buffer.readInt(); 198 ChannelSelectorType ysel = (ChannelSelectorType)buffer.readInt();
202 SkScalar scale = buffer.readScalar(); 199 SkScalar scale = buffer.readScalar();
203 return Create(xsel, ysel, scale, 200 return Create(xsel, ysel, scale,
204 common.getInput(0).get(), common.getInput(1).get(), &common.cr opRect()); 201 common.getInput(0).get(), common.getInput(1).get(), &common.cr opRect());
205 } 202 }
206 203
207 void SkDisplacementMapEffect::flatten(SkWriteBuffer& buffer) const { 204 void SkDisplacementMapEffect::flatten(SkWriteBuffer& buffer) const {
208 this->INHERITED::flatten(buffer); 205 this->INHERITED::flatten(buffer);
209 buffer.writeInt((int) fXChannelSelector); 206 buffer.writeInt((int) fXChannelSelector);
210 buffer.writeInt((int) fYChannelSelector); 207 buffer.writeInt((int) fYChannelSelector);
211 buffer.writeScalar(fScale); 208 buffer.writeScalar(fScale);
212 } 209 }
213 210
214 bool SkDisplacementMapEffect::onFilterImageDeprecated(Proxy* proxy, 211 ///////////////////////////////////////////////////////////////////////////////
215 const SkBitmap& src, 212
216 const Context& ctx, 213 #if SK_SUPPORT_GPU
217 SkBitmap* dst, 214
218 SkIPoint* offset) const { 215 class GrDisplacementMapEffect : public GrFragmentProcessor {
Stephen White 2016/04/01 19:17:42 Could you move this code back to where it was for
robertphillips 2016/04/01 19:41:43 Done.
219 SkBitmap displ = src, color = src; 216 public:
220 SkIPoint colorOffset = SkIPoint::Make(0, 0), displOffset = SkIPoint::Make(0, 0); 217 static GrFragmentProcessor* Create(
221 if (!this->filterInputDeprecated(1, proxy, src, ctx, &color, &colorOffset) | | 218 SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
222 !this->filterInputDeprecated(0, proxy, src, ctx, &displ, &displOffset)) { 219 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, S kVector scale,
223 return false; 220 GrTexture* displacement, const SkMatrix& offsetMatrix, GrTexture * color,
224 } 221 const SkISize& colorDimensions) {
225 if ((displ.colorType() != kN32_SkColorType) || 222 return new GrDisplacementMapEffect(xChannelSelector, yChannelSelector, s cale, displacement,
226 (color.colorType() != kN32_SkColorType)) { 223 offsetMatrix, color, colorDimensions) ;
227 return false;
228 }
229 SkIRect bounds;
230 // Since computeDisplacement does bounds checking on color pixel access, we don't need to pad
231 // the color bitmap to bounds here.
232 SkIRect srcBounds = color.bounds();
233 srcBounds.offset(colorOffset);
234 if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
235 return false;
236 }
237 SkIRect displBounds;
238 if (!this->applyCropRectDeprecated(ctx, proxy, displ, &displOffset, &displBo unds, &displ)) {
239 return false;
240 }
241 if (!bounds.intersect(displBounds)) {
242 return false;
243 }
244 SkAutoLockPixels alp_displacement(displ), alp_color(color);
245 if (!displ.getPixels() || !color.getPixels()) {
246 return false;
247 } 224 }
248 225
249 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds .height())); 226 virtual ~GrDisplacementMapEffect();
250 if (!device) { 227
251 return false; 228 SkDisplacementMapEffect::ChannelSelectorType xChannelSelector() const {
229 return fXChannelSelector;
252 } 230 }
253 *dst = device->accessBitmap(false); 231 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const {
254 SkAutoLockPixels alp_dst(*dst); 232 return fYChannelSelector;
233 }
234 const SkVector& scale() const { return fScale; }
235
236 const char* name() const override { return "DisplacementMap"; }
237 const GrTextureDomain& domain() const { return fDomain; }
238
239 private:
240 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
241
242 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override;
243
244 bool onIsEqual(const GrFragmentProcessor&) const override;
245
246 void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
247
248 GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChanne lSelector,
249 SkDisplacementMapEffect::ChannelSelectorType yChanne lSelector,
250 const SkVector& scale,
251 GrTexture* displacement, const SkMatrix& offsetMatri x,
252 GrTexture* color,
253 const SkISize& colorDimensions);
254
255 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
256
257 GrCoordTransform fDisplacementTransform;
258 GrTextureAccess fDisplacementAccess;
259 GrCoordTransform fColorTransform;
260 GrTextureDomain fDomain;
261 GrTextureAccess fColorAccess;
262 SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector;
263 SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector;
264 SkVector fScale;
265
266 typedef GrFragmentProcessor INHERITED;
267 };
268
269 #endif
270
271 ///////////////////////////////////////////////////////////////////////////////
272
273 sk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* sou rce,
274 const Context& ctx,
275 SkIPoint* offset) c onst {
276 SkIPoint colorOffset = SkIPoint::Make(0, 0);
277 sk_sp<SkSpecialImage> color(this->filterInput(1, source, ctx, &colorOffset)) ;
278 if (!color) {
279 return nullptr;
280 }
281
282 SkIPoint displOffset = SkIPoint::Make(0, 0);
283 sk_sp<SkSpecialImage> displ(this->filterInput(0, source, ctx, &displOffset)) ;
284 if (!displ) {
285 return nullptr;
286 }
287
288 const SkIRect srcBounds = SkIRect::MakeXYWH(colorOffset.x(), colorOffset.y() ,
289 color->width(), color->height()) ;
290
291 // Both paths do bounds checking on color pixel access, we don't need to
292 // pad the color bitmap to bounds here.
293 SkIRect bounds;
294 if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
295 return nullptr;
296 }
297
298 SkIRect displBounds;
299 displ = this->applyCropRect(ctx, displ.get(), &displOffset, &displBounds);
300 if (!displ) {
301 return nullptr;
302 }
303
304 if (!bounds.intersect(displBounds)) {
305 return nullptr;
306 }
307
308 const SkIRect colorBounds = bounds.makeOffset(-colorOffset.x(), -colorOffset .y());
255 309
256 SkVector scale = SkVector::Make(fScale, fScale); 310 SkVector scale = SkVector::Make(fScale, fScale);
257 ctx.ctm().mapVectors(&scale, 1); 311 ctx.ctm().mapVectors(&scale, 1);
258 SkIRect colorBounds = bounds;
259 colorBounds.offset(-colorOffset);
260 312
261 computeDisplacement(fXChannelSelector, fYChannelSelector, scale, dst, 313 #if SK_SUPPORT_GPU
262 &displ, colorOffset - displOffset, &color, colorBounds); 314 if (color->peekTexture()) {
315 SkASSERT(displ->peekTexture());
316
317 GrTexture* colorTexture = color->peekTexture();
318 GrTexture* displacement = displ->peekTexture();
Stephen White 2016/04/01 19:17:42 Peeking usually implies that these could be null.
robertphillips 2016/04/01 19:41:43 Done. The logic is a bit circuitous. If 'source' i
Stephen White 2016/04/02 02:33:48 OK, so at this point can we assert that both color
robertphillips 2016/04/04 14:24:03 Done.
319 GrContext* context = colorTexture->getContext();
320
321 GrSurfaceDesc desc;
322 desc.fFlags = kRenderTarget_GrSurfaceFlag;
323 desc.fWidth = bounds.width();
324 desc.fHeight = bounds.height();
325 desc.fConfig = kSkia8888_GrPixelConfig;
326
327 SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxText ure(desc));
328 if (!dst) {
329 return nullptr;
330 }
331
332 GrPaint paint;
333 SkMatrix offsetMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(displ acement);
334 offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displOffset.fX) ,
335 SkIntToScalar(colorOffset.fY - displOffset.fY) );
336
337 paint.addColorFragmentProcessor(
338 GrDisplacementMapEffect::Create(fXChannelSelector,
339 fYChannelSelector,
340 scale,
341 displacement,
342 offsetMatrix,
343 colorTexture,
344 SkISize::Make(color->width(),
345 color->height())))->un ref();
346 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
347 SkMatrix matrix;
348 matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colo rBounds.y()));
349
350 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRend erTarget()));
351 if (!drawContext) {
352 return nullptr;
353 }
354
355 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(co lorBounds));
356
357 offset->fX = bounds.left();
358 offset->fY = bounds.top();
359 return SkSpecialImage::MakeFromGpu(source->internal_getProxy(),
360 SkIRect::MakeWH(bounds.width(), bound s.height()),
361 kNeedNewImageUniqueID_SpecialImage,
362 dst);
363 }
364 #endif
365
366 SkPixmap colorPixmap, displPixmap;
367
368 if (!color->peekPixels(&colorPixmap) || !displ->peekPixels(&displPixmap)) {
369 return nullptr;
370 }
371
372 if ((colorPixmap.colorType() != kN32_SkColorType) ||
373 (displPixmap.colorType() != kN32_SkColorType)) {
374 return nullptr;
375 }
376
377 SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height(),
378 colorPixmap.alphaType());
379
380 SkBitmap dst2;
Stephen White 2016/04/01 19:17:42 Nit: it looks like this could actually be called d
robertphillips 2016/04/01 19:41:43 Done.
381 if (!dst2.tryAllocPixels(info)) {
382 return nullptr;
383 }
384
385 SkAutoLockPixels dstLock(dst2);
386
387 computeDisplacement(fXChannelSelector, fYChannelSelector, scale, &dst2,
388 displPixmap, colorOffset - displOffset, colorPixmap, col orBounds);
263 389
264 offset->fX = bounds.left(); 390 offset->fX = bounds.left();
265 offset->fY = bounds.top(); 391 offset->fY = bounds.top();
266 return true; 392 return SkSpecialImage::MakeFromRaster(source->internal_getProxy(),
393 SkIRect::MakeWH(bounds.width(), bounds .height()),
394 dst2);
267 } 395 }
268 396
269 SkRect SkDisplacementMapEffect::computeFastBounds(const SkRect& src) const { 397 SkRect SkDisplacementMapEffect::computeFastBounds(const SkRect& src) const {
270 SkRect bounds = this->getColorInput() ? this->getColorInput()->computeFastBo unds(src) : src; 398 SkRect bounds = this->getColorInput() ? this->getColorInput()->computeFastBo unds(src) : src;
271 bounds.outset(SkScalarAbs(fScale) * SK_ScalarHalf, SkScalarAbs(fScale) * SK_ ScalarHalf); 399 bounds.outset(SkScalarAbs(fScale) * SK_ScalarHalf, SkScalarAbs(fScale) * SK_ ScalarHalf);
272 return bounds; 400 return bounds;
273 } 401 }
274 402
275 SkIRect SkDisplacementMapEffect::onFilterNodeBounds(const SkIRect& src, const Sk Matrix& ctm, 403 SkIRect SkDisplacementMapEffect::onFilterNodeBounds(const SkIRect& src, const Sk Matrix& ctm,
276 MapDirection) const { 404 MapDirection) const {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 447
320 private: 448 private:
321 GrGLSLProgramDataManager::UniformHandle fScaleUni; 449 GrGLSLProgramDataManager::UniformHandle fScaleUni;
322 GrTextureDomain::GLDomain fGLDomain; 450 GrTextureDomain::GLDomain fGLDomain;
323 451
324 typedef GrGLSLFragmentProcessor INHERITED; 452 typedef GrGLSLFragmentProcessor INHERITED;
325 }; 453 };
326 454
327 /////////////////////////////////////////////////////////////////////////////// 455 ///////////////////////////////////////////////////////////////////////////////
328 456
329 class GrDisplacementMapEffect : public GrFragmentProcessor { 457 GrGLSLFragmentProcessor* GrDisplacementMapEffect::onCreateGLSLInstance() const {
330 public: 458 return new GrGLDisplacementMapEffect;
331 static GrFragmentProcessor* Create(
332 SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
333 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, SkVec tor scale,
334 GrTexture* displacement, const SkMatrix& offsetMatrix, GrTexture* co lor,
335 const SkISize& colorDimensions) {
336 return new GrDisplacementMapEffect(xChannelSelector, yChannelSelector, s cale, displacement,
337 offsetMatrix, color, colorDimensions) ;
338 }
339
340 virtual ~GrDisplacementMapEffect();
341
342 SkDisplacementMapEffect::ChannelSelectorType xChannelSelector() const
343 { return fXChannelSelector; }
344 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const
345 { return fYChannelSelector; }
346 const SkVector& scale() const { return fScale; }
347
348 const char* name() const override { return "DisplacementMap"; }
349 const GrTextureDomain& domain() const { return fDomain; }
350
351 private:
352 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
353 return new GrGLDisplacementMapEffect;
354 }
355
356 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) const override {
357 GrGLDisplacementMapEffect::GenKey(*this, caps, b);
358 }
359
360 bool onIsEqual(const GrFragmentProcessor&) const override;
361
362 void onComputeInvariantOutput(GrInvariantOutput* inout) const override;
363
364 GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChanne lSelector,
365 SkDisplacementMapEffect::ChannelSelectorType yChanne lSelector,
366 const SkVector& scale,
367 GrTexture* displacement, const SkMatrix& offsetMatri x,
368 GrTexture* color,
369 const SkISize& colorDimensions);
370
371 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
372
373 GrCoordTransform fDisplacementTransform;
374 GrTextureAccess fDisplacementAccess;
375 GrCoordTransform fColorTransform;
376 GrTextureDomain fDomain;
377 GrTextureAccess fColorAccess;
378 SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector;
379 SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector;
380 SkVector fScale;
381
382 typedef GrFragmentProcessor INHERITED;
383 };
384
385 bool SkDisplacementMapEffect::filterImageGPUDeprecated(Proxy* proxy, const SkBit map& src,
386 const Context& ctx,
387 SkBitmap* result, SkIPoin t* offset) const {
388 SkBitmap colorBM = src;
389 SkIPoint colorOffset = SkIPoint::Make(0, 0);
390 if (!this->filterInputGPUDeprecated(1, proxy, src, ctx, &colorBM, &colorOffs et)) {
391 return false;
392 }
393 SkBitmap displacementBM = src;
394 SkIPoint displacementOffset = SkIPoint::Make(0, 0);
395 if (!this->filterInputGPUDeprecated(0, proxy, src, ctx, &displacementBM, &di splacementOffset)) {
396 return false;
397 }
398 SkIRect srcBounds = colorBM.bounds();
399 srcBounds.offset(colorOffset);
400 SkIRect bounds;
401 // Since GrDisplacementMapEffect does bounds checking on color pixel access, we don't need to
402 // pad the color bitmap to bounds here.
403 if (!this->applyCropRect(ctx, srcBounds, &bounds)) {
404 return false;
405 }
406 SkIRect displBounds;
407 if (!this->applyCropRectDeprecated(ctx, proxy, displacementBM,
408 &displacementOffset, &displBounds, &displ acementBM)) {
409 return false;
410 }
411 if (!bounds.intersect(displBounds)) {
412 return false;
413 }
414 GrTexture* color = colorBM.getTexture();
415 GrTexture* displacement = displacementBM.getTexture();
416 GrContext* context = color->getContext();
417
418 GrSurfaceDesc desc;
419 desc.fFlags = kRenderTarget_GrSurfaceFlag;
420 desc.fWidth = bounds.width();
421 desc.fHeight = bounds.height();
422 desc.fConfig = kSkia8888_GrPixelConfig;
423
424 SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxTexture( desc));
425
426 if (!dst) {
427 return false;
428 }
429
430 SkVector scale = SkVector::Make(fScale, fScale);
431 ctx.ctm().mapVectors(&scale, 1);
432
433 GrPaint paint;
434 SkMatrix offsetMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(displacem ent);
435 offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displacementOffset. fX),
436 SkIntToScalar(colorOffset.fY - displacementOffset. fY));
437
438 paint.addColorFragmentProcessor(
439 GrDisplacementMapEffect::Create(fXChannelSelector,
440 fYChannelSelector,
441 scale,
442 displacement,
443 offsetMatrix,
444 color,
445 colorBM.dimensions()))->unref();
446 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
447 SkIRect colorBounds = bounds;
448 colorBounds.offset(-colorOffset);
449 SkMatrix matrix;
450 matrix.setTranslate(-SkIntToScalar(colorBounds.x()),
451 -SkIntToScalar(colorBounds.y()));
452
453 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTa rget()));
454 if (!drawContext) {
455 return false;
456 }
457
458 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(colorB ounds));
459 offset->fX = bounds.left();
460 offset->fY = bounds.top();
461 GrWrapTextureInBitmap(dst, bounds.width(), bounds.height(), false, result);
462 return true;
463 } 459 }
464 460
465 /////////////////////////////////////////////////////////////////////////////// 461 void GrDisplacementMapEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps,
462 GrProcessorKeyBuilder* b) co nst {
463 GrGLDisplacementMapEffect::GenKey(*this, caps, b);
464 }
466 465
467 GrDisplacementMapEffect::GrDisplacementMapEffect( 466 GrDisplacementMapEffect::GrDisplacementMapEffect(
468 SkDisplacementMapEffect::ChannelSelectorType xChann elSelector, 467 SkDisplacementMapEffect::ChannelSelectorType xChann elSelector,
469 SkDisplacementMapEffect::ChannelSelectorType yChann elSelector, 468 SkDisplacementMapEffect::ChannelSelectorType yChann elSelector,
470 const SkVector& scale, 469 const SkVector& scale,
471 GrTexture* displacement, 470 GrTexture* displacement,
472 const SkMatrix& offsetMatrix, 471 const SkMatrix& offsetMatrix,
473 GrTexture* color, 472 GrTexture* color,
474 const SkISize& colorDimensions) 473 const SkISize& colorDimensions)
475 : fDisplacementTransform(kLocal_GrCoordSet, offsetMatrix, displacement, 474 : fDisplacementTransform(kLocal_GrCoordSet, offsetMatrix, displacement,
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
625 void GrGLDisplacementMapEffect::GenKey(const GrProcessor& proc, 624 void GrGLDisplacementMapEffect::GenKey(const GrProcessor& proc,
626 const GrGLSLCaps&, GrProcessorKeyBuilder* b) { 625 const GrGLSLCaps&, GrProcessorKeyBuilder* b) {
627 const GrDisplacementMapEffect& displacementMap = proc.cast<GrDisplacementMap Effect>(); 626 const GrDisplacementMapEffect& displacementMap = proc.cast<GrDisplacementMap Effect>();
628 627
629 uint32_t xKey = displacementMap.xChannelSelector(); 628 uint32_t xKey = displacementMap.xChannelSelector();
630 uint32_t yKey = displacementMap.yChannelSelector() << kChannelSelectorKeyBit s; 629 uint32_t yKey = displacementMap.yChannelSelector() << kChannelSelectorKeyBit s;
631 630
632 b->add32(xKey | yKey); 631 b->add32(xKey | yKey);
633 } 632 }
634 #endif 633 #endif
OLDNEW
« no previous file with comments | « include/effects/SkDisplacementMapEffect.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698