OLD | NEW |
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 Loading... |
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 SkBitmap& displ, const SkIPoint& offset, |
61 SkBitmap* src, | 63 const SkBitmap& 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.getAddr32(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.getAddr32(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 SkBitmap& displ, const SkIPoint& offset, |
94 SkBitmap* src, | 94 const SkBitmap& 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 SkBitmap& displ, const SkIPoint& offset, |
124 SkBitmap* src, | 123 const SkBitmap& 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 Loading... |
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 sk_sp<SkFlattenable> SkDisplacementMapEffect::CreateProc(SkReadBuffer& buffer) { | 195 sk_sp<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 sk_sp<SkFlattenable>(Create(xsel, ysel, scale, common.getInput(0).get
(), | 200 return sk_sp<SkFlattenable>(Create(xsel, ysel, scale, common.getInput(0).get
(), |
204 common.getInput(1).get(), &common.cropRec
t())); | 201 common.getInput(1).get(), &common.cropRec
t())); |
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 #if SK_SUPPORT_GPU |
215 const SkBitmap& src, | 212 class GrDisplacementMapEffect : public GrFragmentProcessor { |
216 const Context& ctx, | 213 public: |
217 SkBitmap* dst, | 214 static GrFragmentProcessor* Create( |
218 SkIPoint* offset) const { | 215 SkDisplacementMapEffect::ChannelSelectorType xChannelSelector, |
219 SkBitmap displ = src, color = src; | 216 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector, S
kVector scale, |
220 SkIPoint colorOffset = SkIPoint::Make(0, 0), displOffset = SkIPoint::Make(0,
0); | 217 GrTexture* displacement, const SkMatrix& offsetMatrix, GrTexture
* color, |
221 if (!this->filterInputDeprecated(1, proxy, src, ctx, &color, &colorOffset) |
| | 218 const SkISize& colorDimensions) { |
222 !this->filterInputDeprecated(0, proxy, src, ctx, &displ, &displOffset))
{ | 219 return new GrDisplacementMapEffect(xChannelSelector, yChannelSelector, s
cale, displacement, |
223 return false; | 220 offsetMatrix, color, colorDimensions)
; |
224 } | |
225 if ((displ.colorType() != kN32_SkColorType) || | |
226 (color.colorType() != kN32_SkColorType)) { | |
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 } | 221 } |
248 | 222 |
249 SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds.width(), bounds
.height())); | 223 virtual ~GrDisplacementMapEffect(); |
250 if (!device) { | 224 |
251 return false; | 225 SkDisplacementMapEffect::ChannelSelectorType xChannelSelector() const { |
| 226 return fXChannelSelector; |
252 } | 227 } |
253 *dst = device->accessBitmap(false); | 228 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const { |
254 SkAutoLockPixels alp_dst(*dst); | 229 return fYChannelSelector; |
| 230 } |
| 231 const SkVector& scale() const { return fScale; } |
| 232 |
| 233 const char* name() const override { return "DisplacementMap"; } |
| 234 const GrTextureDomain& domain() const { return fDomain; } |
| 235 |
| 236 private: |
| 237 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override; |
| 238 |
| 239 void onGetGLSLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b)
const override; |
| 240 |
| 241 bool onIsEqual(const GrFragmentProcessor&) const override; |
| 242 |
| 243 void onComputeInvariantOutput(GrInvariantOutput* inout) const override; |
| 244 |
| 245 GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChanne
lSelector, |
| 246 SkDisplacementMapEffect::ChannelSelectorType yChanne
lSelector, |
| 247 const SkVector& scale, |
| 248 GrTexture* displacement, const SkMatrix& offsetMatri
x, |
| 249 GrTexture* color, |
| 250 const SkISize& colorDimensions); |
| 251 |
| 252 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
| 253 |
| 254 GrCoordTransform fDisplacementTransform; |
| 255 GrTextureAccess fDisplacementAccess; |
| 256 GrCoordTransform fColorTransform; |
| 257 GrTextureDomain fDomain; |
| 258 GrTextureAccess fColorAccess; |
| 259 SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector; |
| 260 SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector; |
| 261 SkVector fScale; |
| 262 |
| 263 typedef GrFragmentProcessor INHERITED; |
| 264 }; |
| 265 #endif |
| 266 |
| 267 sk_sp<SkSpecialImage> SkDisplacementMapEffect::onFilterImage(SkSpecialImage* sou
rce, |
| 268 const Context& ctx, |
| 269 SkIPoint* offset) c
onst { |
| 270 SkIPoint colorOffset = SkIPoint::Make(0, 0); |
| 271 sk_sp<SkSpecialImage> color(this->filterInput(1, source, ctx, &colorOffset))
; |
| 272 if (!color) { |
| 273 return nullptr; |
| 274 } |
| 275 |
| 276 SkIPoint displOffset = SkIPoint::Make(0, 0); |
| 277 sk_sp<SkSpecialImage> displ(this->filterInput(0, source, ctx, &displOffset))
; |
| 278 if (!displ) { |
| 279 return nullptr; |
| 280 } |
| 281 |
| 282 const SkIRect srcBounds = SkIRect::MakeXYWH(colorOffset.x(), colorOffset.y()
, |
| 283 color->width(), color->height())
; |
| 284 |
| 285 // Both paths do bounds checking on color pixel access, we don't need to |
| 286 // pad the color bitmap to bounds here. |
| 287 SkIRect bounds; |
| 288 if (!this->applyCropRect(ctx, srcBounds, &bounds)) { |
| 289 return nullptr; |
| 290 } |
| 291 |
| 292 SkIRect displBounds; |
| 293 displ = this->applyCropRect(ctx, displ.get(), &displOffset, &displBounds); |
| 294 if (!displ) { |
| 295 return nullptr; |
| 296 } |
| 297 |
| 298 if (!bounds.intersect(displBounds)) { |
| 299 return nullptr; |
| 300 } |
| 301 |
| 302 const SkIRect colorBounds = bounds.makeOffset(-colorOffset.x(), -colorOffset
.y()); |
255 | 303 |
256 SkVector scale = SkVector::Make(fScale, fScale); | 304 SkVector scale = SkVector::Make(fScale, fScale); |
257 ctx.ctm().mapVectors(&scale, 1); | 305 ctx.ctm().mapVectors(&scale, 1); |
258 SkIRect colorBounds = bounds; | |
259 colorBounds.offset(-colorOffset); | |
260 | 306 |
261 computeDisplacement(fXChannelSelector, fYChannelSelector, scale, dst, | 307 #if SK_SUPPORT_GPU |
262 &displ, colorOffset - displOffset, &color, colorBounds); | 308 if (source->isTextureBacked()) { |
| 309 GrContext* context = source->getContext(); |
| 310 |
| 311 sk_sp<GrTexture> colorTexture(color->asTextureRef(context)); |
| 312 sk_sp<GrTexture> displTexture(displ->asTextureRef(context)); |
| 313 if (!colorTexture || !displTexture) { |
| 314 return nullptr; |
| 315 } |
| 316 |
| 317 GrSurfaceDesc desc; |
| 318 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 319 desc.fWidth = bounds.width(); |
| 320 desc.fHeight = bounds.height(); |
| 321 desc.fConfig = kSkia8888_GrPixelConfig; |
| 322 |
| 323 SkAutoTUnref<GrTexture> dst(context->textureProvider()->createApproxText
ure(desc)); |
| 324 if (!dst) { |
| 325 return nullptr; |
| 326 } |
| 327 |
| 328 GrPaint paint; |
| 329 SkMatrix offsetMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(displ
Texture.get()); |
| 330 offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displOffset.fX)
, |
| 331 SkIntToScalar(colorOffset.fY - displOffset.fY)
); |
| 332 |
| 333 paint.addColorFragmentProcessor( |
| 334 GrDisplacementMapEffect::Create(fXChannelSelector, |
| 335 fYChannelSelector, |
| 336 scale, |
| 337 displTexture.get(), |
| 338 offsetMatrix, |
| 339 colorTexture.get(), |
| 340 SkISize::Make(color->width(), |
| 341 color->height())))->un
ref(); |
| 342 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); |
| 343 SkMatrix matrix; |
| 344 matrix.setTranslate(-SkIntToScalar(colorBounds.x()), -SkIntToScalar(colo
rBounds.y())); |
| 345 |
| 346 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRend
erTarget())); |
| 347 if (!drawContext) { |
| 348 return nullptr; |
| 349 } |
| 350 |
| 351 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(co
lorBounds)); |
| 352 |
| 353 offset->fX = bounds.left(); |
| 354 offset->fY = bounds.top(); |
| 355 return SkSpecialImage::MakeFromGpu(source->internal_getProxy(), |
| 356 SkIRect::MakeWH(bounds.width(), bound
s.height()), |
| 357 kNeedNewImageUniqueID_SpecialImage, |
| 358 dst); |
| 359 } |
| 360 #endif |
| 361 |
| 362 SkBitmap colorBM, displBM; |
| 363 |
| 364 if (!color->getROPixels(&colorBM) || !displ->getROPixels(&displBM)) { |
| 365 return nullptr; |
| 366 } |
| 367 |
| 368 if ((colorBM.colorType() != kN32_SkColorType) || |
| 369 (displBM.colorType() != kN32_SkColorType)) { |
| 370 return nullptr; |
| 371 } |
| 372 |
| 373 SkAutoLockPixels colorLock(colorBM), displLock(displBM); |
| 374 if (!colorBM.getPixels() || !displBM.getPixels()) { |
| 375 return nullptr; |
| 376 } |
| 377 |
| 378 SkImageInfo info = SkImageInfo::MakeN32(bounds.width(), bounds.height(), |
| 379 colorBM.alphaType()); |
| 380 |
| 381 SkBitmap dst; |
| 382 if (!dst.tryAllocPixels(info)) { |
| 383 return nullptr; |
| 384 } |
| 385 |
| 386 SkAutoLockPixels dstLock(dst); |
| 387 |
| 388 computeDisplacement(fXChannelSelector, fYChannelSelector, scale, &dst, |
| 389 displBM, colorOffset - displOffset, colorBM, colorBounds
); |
263 | 390 |
264 offset->fX = bounds.left(); | 391 offset->fX = bounds.left(); |
265 offset->fY = bounds.top(); | 392 offset->fY = bounds.top(); |
266 return true; | 393 return SkSpecialImage::MakeFromRaster(source->internal_getProxy(), |
| 394 SkIRect::MakeWH(bounds.width(), bounds
.height()), |
| 395 dst); |
267 } | 396 } |
268 | 397 |
269 SkRect SkDisplacementMapEffect::computeFastBounds(const SkRect& src) const { | 398 SkRect SkDisplacementMapEffect::computeFastBounds(const SkRect& src) const { |
270 SkRect bounds = this->getColorInput() ? this->getColorInput()->computeFastBo
unds(src) : src; | 399 SkRect bounds = this->getColorInput() ? this->getColorInput()->computeFastBo
unds(src) : src; |
271 bounds.outset(SkScalarAbs(fScale) * SK_ScalarHalf, SkScalarAbs(fScale) * SK_
ScalarHalf); | 400 bounds.outset(SkScalarAbs(fScale) * SK_ScalarHalf, SkScalarAbs(fScale) * SK_
ScalarHalf); |
272 return bounds; | 401 return bounds; |
273 } | 402 } |
274 | 403 |
275 SkIRect SkDisplacementMapEffect::onFilterNodeBounds(const SkIRect& src, const Sk
Matrix& ctm, | 404 SkIRect SkDisplacementMapEffect::onFilterNodeBounds(const SkIRect& src, const Sk
Matrix& ctm, |
276 MapDirection) const { | 405 MapDirection) const { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
319 | 448 |
320 private: | 449 private: |
321 GrGLSLProgramDataManager::UniformHandle fScaleUni; | 450 GrGLSLProgramDataManager::UniformHandle fScaleUni; |
322 GrTextureDomain::GLDomain fGLDomain; | 451 GrTextureDomain::GLDomain fGLDomain; |
323 | 452 |
324 typedef GrGLSLFragmentProcessor INHERITED; | 453 typedef GrGLSLFragmentProcessor INHERITED; |
325 }; | 454 }; |
326 | 455 |
327 /////////////////////////////////////////////////////////////////////////////// | 456 /////////////////////////////////////////////////////////////////////////////// |
328 | 457 |
329 class GrDisplacementMapEffect : public GrFragmentProcessor { | 458 GrGLSLFragmentProcessor* GrDisplacementMapEffect::onCreateGLSLInstance() const { |
330 public: | 459 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 // SRGBTODO: AllowSRGBInputs? | |
435 SkMatrix offsetMatrix = GrCoordTransform::MakeDivByTextureWHMatrix(displacem
ent); | |
436 offsetMatrix.preTranslate(SkIntToScalar(colorOffset.fX - displacementOffset.
fX), | |
437 SkIntToScalar(colorOffset.fY - displacementOffset.
fY)); | |
438 | |
439 paint.addColorFragmentProcessor( | |
440 GrDisplacementMapEffect::Create(fXChannelSelector, | |
441 fYChannelSelector, | |
442 scale, | |
443 displacement, | |
444 offsetMatrix, | |
445 color, | |
446 colorBM.dimensions()))->unref(); | |
447 paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode); | |
448 SkIRect colorBounds = bounds; | |
449 colorBounds.offset(-colorOffset); | |
450 SkMatrix matrix; | |
451 matrix.setTranslate(-SkIntToScalar(colorBounds.x()), | |
452 -SkIntToScalar(colorBounds.y())); | |
453 | |
454 SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(dst->asRenderTa
rget())); | |
455 if (!drawContext) { | |
456 return false; | |
457 } | |
458 | |
459 drawContext->drawRect(GrClip::WideOpen(), paint, matrix, SkRect::Make(colorB
ounds)); | |
460 offset->fX = bounds.left(); | |
461 offset->fY = bounds.top(); | |
462 GrWrapTextureInBitmap(dst, bounds.width(), bounds.height(), false, result); | |
463 return true; | |
464 } | 460 } |
465 | 461 |
466 /////////////////////////////////////////////////////////////////////////////// | 462 void GrDisplacementMapEffect::onGetGLSLProcessorKey(const GrGLSLCaps& caps, |
| 463 GrProcessorKeyBuilder* b) co
nst { |
| 464 GrGLDisplacementMapEffect::GenKey(*this, caps, b); |
| 465 } |
467 | 466 |
468 GrDisplacementMapEffect::GrDisplacementMapEffect( | 467 GrDisplacementMapEffect::GrDisplacementMapEffect( |
469 SkDisplacementMapEffect::ChannelSelectorType xChann
elSelector, | 468 SkDisplacementMapEffect::ChannelSelectorType xChann
elSelector, |
470 SkDisplacementMapEffect::ChannelSelectorType yChann
elSelector, | 469 SkDisplacementMapEffect::ChannelSelectorType yChann
elSelector, |
471 const SkVector& scale, | 470 const SkVector& scale, |
472 GrTexture* displacement, | 471 GrTexture* displacement, |
473 const SkMatrix& offsetMatrix, | 472 const SkMatrix& offsetMatrix, |
474 GrTexture* color, | 473 GrTexture* color, |
475 const SkISize& colorDimensions) | 474 const SkISize& colorDimensions) |
476 : fDisplacementTransform(kLocal_GrCoordSet, offsetMatrix, displacement, | 475 : fDisplacementTransform(kLocal_GrCoordSet, offsetMatrix, displacement, |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 void GrGLDisplacementMapEffect::GenKey(const GrProcessor& proc, | 625 void GrGLDisplacementMapEffect::GenKey(const GrProcessor& proc, |
627 const GrGLSLCaps&, GrProcessorKeyBuilder*
b) { | 626 const GrGLSLCaps&, GrProcessorKeyBuilder*
b) { |
628 const GrDisplacementMapEffect& displacementMap = proc.cast<GrDisplacementMap
Effect>(); | 627 const GrDisplacementMapEffect& displacementMap = proc.cast<GrDisplacementMap
Effect>(); |
629 | 628 |
630 uint32_t xKey = displacementMap.xChannelSelector(); | 629 uint32_t xKey = displacementMap.xChannelSelector(); |
631 uint32_t yKey = displacementMap.yChannelSelector() << kChannelSelectorKeyBit
s; | 630 uint32_t yKey = displacementMap.yChannelSelector() << kChannelSelectorKeyBit
s; |
632 | 631 |
633 b->add32(xKey | yKey); | 632 b->add32(xKey | yKey); |
634 } | 633 } |
635 #endif | 634 #endif |
OLD | NEW |