Index: src/effects/SkDisplacementMapEffect.cpp |
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp |
index 263ac8c69c601b4d83cfe44f577b6aff9357d0c7..5cd5e0128b4c62eceb5f3d7bd61e39c0cea4e12f 100644 |
--- a/src/effects/SkDisplacementMapEffect.cpp |
+++ b/src/effects/SkDisplacementMapEffect.cpp |
@@ -6,10 +6,12 @@ |
*/ |
#include "SkDisplacementMapEffect.h" |
+#include "SkColorPriv.h" |
+#include "SkImagePriv.h" |
+#include "SkImage_Base.h" |
#include "SkReadBuffer.h" |
-#include "SkWriteBuffer.h" |
#include "SkUnPreMultiply.h" |
-#include "SkColorPriv.h" |
+#include "SkWriteBuffer.h" |
#if SK_SUPPORT_GPU |
#include "GrContext.h" |
#include "GrCoordTransform.h" |
@@ -207,52 +209,82 @@ void SkDisplacementMapEffect::flatten(SkWriteBuffer& buffer) const { |
} |
bool SkDisplacementMapEffect::onFilterImage(Proxy* proxy, |
- const SkBitmap& src, |
+ SkImage& src, |
const Context& ctx, |
- SkBitmap* dst, |
+ SkAutoTUnref<SkImage>& dst, |
SkIPoint* offset) const { |
- SkBitmap displ = src, color = src; |
- const SkImageFilter* colorInput = getColorInput(); |
- const SkImageFilter* displInput = getDisplacementInput(); |
- SkIPoint colorOffset = SkIPoint::Make(0, 0), displOffset = SkIPoint::Make(0, 0); |
- if ((colorInput && !colorInput->filterImage(proxy, src, ctx, &color, &colorOffset)) || |
- (displInput && !displInput->filterImage(proxy, src, ctx, &displ, &displOffset))) { |
- return false; |
- } |
- if ((displ.colorType() != kN32_SkColorType) || |
- (color.colorType() != kN32_SkColorType)) { |
- return false; |
- } |
+ SkBitmap dstBitmap; |
+ SkBitmap displacementBitmap; |
+ SkBitmap colorBitmap; |
SkIRect bounds; |
- // Since computeDisplacement does bounds checking on color pixel access, we don't need to pad |
- // the color bitmap to bounds here. |
- if (!this->applyCropRect(ctx, color, colorOffset, &bounds)) { |
- return false; |
- } |
- SkIRect displBounds; |
- if (!this->applyCropRect(ctx, proxy, displ, &displOffset, &displBounds, &displ)) { |
- return false; |
- } |
- if (!bounds.intersect(displBounds)) { |
- return false; |
- } |
- SkAutoLockPixels alp_displacement(displ), alp_color(color); |
- if (!displ.getPixels() || !color.getPixels()) { |
- return false; |
- } |
+ SkIPoint colorOffset = SkIPoint::Make(0, 0), displOffset = SkIPoint::Make(0, 0); |
+ { |
+ SkAutoTUnref<SkImage> displ(SkRef(&src)); |
+ SkAutoTUnref<SkImage> color(SkRef(&src)); |
+ const SkImageFilter* colorInput = getColorInput(); |
+ const SkImageFilter* displInput = getDisplacementInput(); |
+ |
+ if ((colorInput && !colorInput->filterImage(proxy, src, ctx, color, &colorOffset)) || |
+ (displInput && !displInput->filterImage(proxy, src, ctx, displ, &displOffset))) { |
+ return false; |
+ } |
+#if 0 // TODO COLORTYPE |
+ if ((displ.colorType() != kN32_SkColorType) || |
+ (color.colorType() != kN32_SkColorType)) { |
+ return false; |
+ } |
+#endif |
+ // Since computeDisplacement does bounds checking on color pixel access, we don't need to pad |
+ // the color bitmap to bounds here. |
+ if (!this->applyCropRect(ctx, *color, colorOffset, &bounds)) { |
+ return false; |
+ } |
+ SkIRect displBounds; |
+ if (!this->applyCropRect(ctx, proxy, *displ, &displOffset, &displBounds, displ)) { |
+ return false; |
+ } |
+ if (!bounds.intersect(displBounds)) { |
+ return false; |
+ } |
- if (!dst->tryAllocPixels(color.info().makeWH(bounds.width(), bounds.height()))) { |
- return false; |
+ |
+ if (!as_IB(displ)->getROPixels(&displacementBitmap)) { |
+ return false; |
+ } |
+ |
+ if (!as_IB(color)->getROPixels(&colorBitmap)) { |
+ return false; |
+ } |
} |
+ { |
+ SkAutoLockPixels alp_displacement(displacementBitmap); |
+ SkAutoLockPixels alp_color(colorBitmap); |
+ if (!displacementBitmap.getPixels() || !colorBitmap.getPixels()) { |
+ return false; |
+ } |
- SkVector scale = SkVector::Make(fScale, fScale); |
- ctx.ctm().mapVectors(&scale, 1); |
- SkIRect colorBounds = bounds; |
- colorBounds.offset(-colorOffset); |
+ if (!dstBitmap.tryAllocPixels(colorBitmap.info().makeWH(bounds.width(), bounds.height()))) { |
+ return false; |
+ } |
+ |
+ SkVector scale = SkVector::Make(fScale, fScale); |
+ ctx.ctm().mapVectors(&scale, 1); |
+ SkIRect colorBounds = bounds; |
+ colorBounds.offset(-colorOffset); |
- computeDisplacement(fXChannelSelector, fYChannelSelector, scale, dst, |
- &displ, colorOffset - displOffset, &color, colorBounds); |
+ computeDisplacement(fXChannelSelector, fYChannelSelector, scale, &dstBitmap, |
+ &displacementBitmap, colorOffset - displOffset, |
+ &colorBitmap, colorBounds); |
+ } |
+ displacementBitmap = SkBitmap(); |
+ colorBitmap = SkBitmap(); |
+ |
+ SkImage* image = SkNewImageFromBitmap(dstBitmap, true, NULL); |
+ if (NULL == image) { |
+ return false; |
+ } |
+ dst.reset(image); |
offset->fX = bounds.left(); |
offset->fY = bounds.top(); |
return true; |
@@ -383,37 +415,37 @@ private: |
typedef GrFragmentProcessor INHERITED; |
}; |
-bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, |
- SkBitmap* result, SkIPoint* offset) const { |
- SkBitmap colorBM = src; |
+bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, SkImage& src, const Context& ctx, |
+ SkAutoTUnref<SkImage>& result, SkIPoint* offset) const { |
+ SkAutoTUnref<SkImage> colorBM(SkRef(&src)); |
SkIPoint colorOffset = SkIPoint::Make(0, 0); |
- if (getColorInput() && !getColorInput()->getInputResultGPU(proxy, src, ctx, &colorBM, |
+ if (getColorInput() && !getColorInput()->getInputResultGPU(proxy, src, ctx, colorBM, |
&colorOffset)) { |
return false; |
} |
- SkBitmap displacementBM = src; |
+ SkAutoTUnref<SkImage> displacementBM(SkRef(&src)); |
SkIPoint displacementOffset = SkIPoint::Make(0, 0); |
if (getDisplacementInput() && |
- !getDisplacementInput()->getInputResultGPU(proxy, src, ctx, &displacementBM, |
+ !getDisplacementInput()->getInputResultGPU(proxy, src, ctx, displacementBM, |
&displacementOffset)) { |
return false; |
} |
SkIRect bounds; |
// Since GrDisplacementMapEffect does bounds checking on color pixel access, we don't need to |
// pad the color bitmap to bounds here. |
- if (!this->applyCropRect(ctx, colorBM, colorOffset, &bounds)) { |
+ if (!this->applyCropRect(ctx, *colorBM, colorOffset, &bounds)) { |
return false; |
} |
SkIRect displBounds; |
- if (!this->applyCropRect(ctx, proxy, displacementBM, |
- &displacementOffset, &displBounds, &displacementBM)) { |
+ if (!this->applyCropRect(ctx, proxy, *displacementBM, |
+ &displacementOffset, &displBounds, displacementBM)) { |
return false; |
} |
if (!bounds.intersect(displBounds)) { |
return false; |
} |
- GrTexture* color = colorBM.getTexture(); |
- GrTexture* displacement = displacementBM.getTexture(); |
+ GrTexture* color = colorBM->getTexture(); |
+ GrTexture* displacement = displacementBM->getTexture(); |
GrContext* context = color->getContext(); |
GrSurfaceDesc desc; |
@@ -452,9 +484,11 @@ bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src, |
matrix.setTranslate(-SkIntToScalar(colorBounds.x()), |
-SkIntToScalar(colorBounds.y())); |
context->drawRect(paint, matrix, SkRect::Make(colorBounds)); |
+ if (!WrapTexture(dst, bounds.width(), bounds.height(), result)) { |
+ return false; |
+ } |
offset->fX = bounds.left(); |
offset->fY = bounds.top(); |
- WrapTexture(dst, bounds.width(), bounds.height(), result); |
return true; |
} |