Chromium Code Reviews| 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 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 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 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |