aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2016-03-07 12:45:14 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2016-03-07 12:45:14 -0800
commit4418dbac3386f26c8da62ab242be9c178961eb18 (patch)
treed94be5d8f77cb85fd6bc908ef7ebc93357ce4908 /src/core
parent19de504eaee0c18cac4f840e0ca336a1e41b65eb (diff)
Swap over to using SkImageFilter::filterImage instead of filterImageDeprecated
This CL relies on https://codereview.chromium.org/1757983002/ (Add SkSpecialImage-based methods to SkImageFilter) GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1762013002 TBR=bsalomon@google.com Review URL: https://codereview.chromium.org/1762013002
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkCanvas.cpp23
-rw-r--r--src/core/SkDevice.cpp17
-rw-r--r--src/core/SkImageFilter.cpp72
-rw-r--r--src/core/SkSpecialImage.cpp51
-rw-r--r--src/core/SkSpecialImage.h17
5 files changed, 139 insertions, 41 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index f3f38386bd..35710fb317 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -28,6 +28,7 @@
#include "SkReadPixelsRec.h"
#include "SkRRect.h"
#include "SkSmallAllocator.h"
+#include "SkSpecialImage.h"
#include "SkSurface_Base.h"
#include "SkTextBlob.h"
#include "SkTextFormatParams.h"
@@ -1392,19 +1393,29 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y,
SkIPoint pos = { x - iter.getX(), y - iter.getY() };
if (filter && !dstDev->canHandleImageFilter(filter)) {
SkImageFilter::DeviceProxy proxy(dstDev);
- SkBitmap dst;
SkIPoint offset = SkIPoint::Make(0, 0);
- const SkBitmap& src = srcDev->accessBitmap(false);
+ const SkBitmap& srcBM = srcDev->accessBitmap(false);
SkMatrix matrix = *iter.fMatrix;
matrix.postTranslate(SkIntToScalar(-pos.x()), SkIntToScalar(-pos.y()));
- SkIRect clipBounds = iter.fClip->getBounds().makeOffset(-pos.x(), -pos.y());
+ const SkIRect clipBounds = iter.fClip->getBounds().makeOffset(-pos.x(), -pos.y());
SkAutoTUnref<SkImageFilter::Cache> cache(dstDev->getImageFilterCache());
SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
- if (filter->filterImageDeprecated(&proxy, src, ctx, &dst, &offset)) {
+
+ SkAutoTUnref<SkSpecialImage> srcImg(SkSpecialImage::internal_fromBM(&proxy, srcBM));
+ if (!srcImg) {
+ continue; // something disastrous happened
+ }
+
+ SkAutoTUnref<SkSpecialImage> resultImg(filter->filterImage(srcImg, ctx, &offset));
+ if (resultImg) {
SkPaint tmpUnfiltered(*paint);
tmpUnfiltered.setImageFilter(nullptr);
- dstDev->drawSprite(iter, dst, pos.x() + offset.x(), pos.y() + offset.y(),
- tmpUnfiltered);
+ SkBitmap resultBM;
+ if (resultImg->internal_getBM(&resultBM)) {
+ // TODO: add drawSprite(SkSpecialImage) to SkDevice? (see skbug.com/5073)
+ dstDev->drawSprite(iter, resultBM, pos.x() + offset.x(), pos.y() + offset.y(),
+ tmpUnfiltered);
+ }
}
} else if (deviceIsBitmapDevice) {
const SkBitmap& src = static_cast<SkBitmapDevice*>(srcDev)->fBitmap;
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 7adb0f4b3c..fa4a4b8fd1 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -17,6 +17,7 @@
#include "SkRasterClip.h"
#include "SkRSXform.h"
#include "SkShader.h"
+#include "SkSpecialImage.h"
#include "SkTextBlobRunIterator.h"
#include "SkTextToPathIter.h"
@@ -408,17 +409,27 @@ void SkBaseDevice::drawBitmapAsSprite(const SkDraw& draw, const SkBitmap& bitmap
SkImageFilter* filter = paint.getImageFilter();
if (filter && !this->canHandleImageFilter(filter)) {
SkImageFilter::DeviceProxy proxy(this);
- SkBitmap dst;
SkIPoint offset = SkIPoint::Make(0, 0);
SkMatrix matrix = *draw.fMatrix;
matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
const SkIRect clipBounds = draw.fClip->getBounds().makeOffset(-x, -y);
SkAutoTUnref<SkImageFilter::Cache> cache(this->getImageFilterCache());
SkImageFilter::Context ctx(matrix, clipBounds, cache.get());
- if (filter->filterImageDeprecated(&proxy, bitmap, ctx, &dst, &offset)) {
+
+ SkAutoTUnref<SkSpecialImage> srcImg(SkSpecialImage::internal_fromBM(&proxy, bitmap));
+ if (!srcImg) {
+ return; // something disastrous happened
+ }
+
+ SkAutoTUnref<SkSpecialImage> resultImg(filter->filterImage(srcImg, ctx, &offset));
+ if (resultImg) {
SkPaint tmpUnfiltered(paint);
tmpUnfiltered.setImageFilter(nullptr);
- this->drawSprite(draw, dst, x + offset.x(), y + offset.y(), tmpUnfiltered);
+ SkBitmap resultBM;
+ if (resultImg->internal_getBM(&resultBM)) {
+ // TODO: add drawSprite(SkSpecialImage) to SkDevice? (see skbug.com/5073)
+ this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
+ }
}
} else {
this->drawSprite(draw, bitmap, x, y, paint);
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index 5f905285bb..a233871bff 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -272,7 +272,20 @@ bool SkImageFilter::filterInputDeprecated(int index, Proxy* proxy, const SkBitma
if (!input) {
return true;
}
- return input->filterImageDeprecated(proxy, src, this->mapContext(ctx), result, offset);
+
+ SkAutoTUnref<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src));
+ if (!specialSrc) {
+ return false;
+ }
+
+ SkAutoTUnref<SkSpecialImage> tmp(input->onFilterImage(specialSrc,
+ this->mapContext(ctx),
+ offset));
+ if (!tmp) {
+ return false;
+ }
+
+ return tmp->internal_getBM(result);
}
bool SkImageFilter::filterBounds(const SkIRect& src, const SkMatrix& ctm, SkIRect* dst,
@@ -327,9 +340,15 @@ bool SkImageFilter::canComputeFastBounds() const {
bool SkImageFilter::onFilterImageDeprecated(Proxy*, const SkBitmap&, const Context&,
SkBitmap*, SkIPoint*) const {
+ // Only classes that now use the new SkSpecialImage-based path will not have
+ // onFilterImageDeprecated methods. For those classes we should never be
+ // calling this method.
+ SkASSERT(0);
return false;
}
+// SkImageFilter-derived classes that do not yet have their own onFilterImage
+// implementation convert back to calling the deprecated filterImage method
SkSpecialImage* SkImageFilter::onFilterImage(SkSpecialImage* src, const Context& ctx,
SkIPoint* offset) const {
SkBitmap srcBM, resultBM;
@@ -338,6 +357,7 @@ SkSpecialImage* SkImageFilter::onFilterImage(SkSpecialImage* src, const Context&
return nullptr;
}
+ // This is the only valid call to the old filterImage path
if (!this->filterImageDeprecated(src->internal_getProxy(), srcBM, ctx, &resultBM, offset)) {
return nullptr;
}
@@ -583,27 +603,39 @@ bool SkImageFilter::filterInputGPUDeprecated(int index, SkImageFilter::Proxy* pr
if (!input) {
return true;
}
- // Ensure that GrContext calls under filterImage and filterImageGPU below will see an identity
- // matrix with no clip and that the matrix, clip, and render target set before this function was
- // called are restored before we return to the caller.
- GrContext* context = src.getTexture()->getContext();
- if (input->filterImageDeprecated(proxy, src, this->mapContext(ctx), result, offset)) {
- if (!result->getTexture()) {
- const SkImageInfo info = result->info();
- if (kUnknown_SkColorType == info.colorType()) {
- return false;
- }
- SkAutoTUnref<GrTexture> resultTex(
- GrRefCachedBitmapTexture(context, *result, GrTextureParams::ClampNoFilter()));
- if (!resultTex) {
- return false;
- }
- result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref();
- }
- return true;
- } else {
+
+ SkAutoTUnref<SkSpecialImage> specialSrc(SkSpecialImage::internal_fromBM(proxy, src));
+ if (!specialSrc) {
+ return false;
+ }
+
+ SkAutoTUnref<SkSpecialImage> tmp(input->onFilterImage(specialSrc,
+ this->mapContext(ctx),
+ offset));
+ if (!tmp) {
return false;
}
+
+ if (!tmp->internal_getBM(result)) {
+ return false;
+ }
+
+ if (!result->getTexture()) {
+ GrContext* context = src.getTexture()->getContext();
+
+ const SkImageInfo info = result->info();
+ if (kUnknown_SkColorType == info.colorType()) {
+ return false;
+ }
+ SkAutoTUnref<GrTexture> resultTex(
+ GrRefCachedBitmapTexture(context, *result, GrTextureParams::ClampNoFilter()));
+ if (!resultTex) {
+ return false;
+ }
+ result->setPixelRef(new SkGrPixelRef(info, resultTex))->unref();
+ }
+
+ return true;
}
#endif
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index 88d90b8602..0bbe50a688 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -20,10 +20,12 @@ public:
virtual void onDraw(SkCanvas*, SkScalar x, SkScalar y, const SkPaint*) const = 0;
- virtual bool onPeekPixels(SkPixmap*) const { return false; }
+ virtual bool testingOnlyOnPeekPixels(SkPixmap*) const { return false; }
virtual GrTexture* onPeekTexture() const { return nullptr; }
+ virtual bool testingOnlyOnGetROPixels(SkBitmap*) const = 0;
+
// Delete this entry point ASAP (see skbug.com/4965)
virtual bool getBitmap(SkBitmap* result) const = 0;
@@ -42,14 +44,18 @@ void SkSpecialImage::draw(SkCanvas* canvas, SkScalar x, SkScalar y, const SkPain
return as_SIB(this)->onDraw(canvas, x, y, paint);
}
-bool SkSpecialImage::peekPixels(SkPixmap* pixmap) const {
- return as_SIB(this)->onPeekPixels(pixmap);
+bool SkSpecialImage::testingOnlyPeekPixels(SkPixmap* pixmap) const {
+ return as_SIB(this)->testingOnlyOnPeekPixels(pixmap);
}
GrTexture* SkSpecialImage::peekTexture() const {
return as_SIB(this)->onPeekTexture();
}
+bool SkSpecialImage::testingOnlyGetROPixels(SkBitmap* result) const {
+ return as_SIB(this)->testingOnlyOnGetROPixels(result);
+}
+
SkSpecialSurface* SkSpecialImage::newSurface(const SkImageInfo& info) const {
return as_SIB(this)->onNewSurface(info);
}
@@ -125,7 +131,7 @@ public:
dst, paint, SkCanvas::kStrict_SrcRectConstraint);
}
- bool onPeekPixels(SkPixmap* pixmap) const override {
+ bool testingOnlyOnPeekPixels(SkPixmap* pixmap) const override {
return fImage->peekPixels(pixmap);
}
@@ -135,6 +141,10 @@ public:
return false;
}
+ bool testingOnlyOnGetROPixels(SkBitmap* result) const override {
+ return false;
+ }
+
SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override {
#if SK_SUPPORT_GPU
GrTexture* texture = as_IB(fImage.get())->peekTexture();
@@ -156,6 +166,11 @@ private:
#ifdef SK_DEBUG
static bool rect_fits(const SkIRect& rect, int width, int height) {
+ if (0 == width && 0 == height) {
+ SkASSERT(0 == rect.fLeft && 0 == rect.fRight && 0 == rect.fTop && 0 == rect.fBottom);
+ return true;
+ }
+
return rect.fLeft >= 0 && rect.fLeft < width && rect.fLeft < rect.fRight &&
rect.fRight >= 0 && rect.fRight <= width &&
rect.fTop >= 0 && rect.fTop < height && rect.fTop < rect.fBottom &&
@@ -178,7 +193,7 @@ public:
SkSpecialImage_Raster(SkImageFilter::Proxy* proxy, const SkIRect& subset, const SkBitmap& bm)
: INHERITED(proxy, subset, bm.getGenerationID())
, fBitmap(bm) {
- if (bm.pixelRef()->isPreLocked()) {
+ if (bm.pixelRef() && bm.pixelRef()->isPreLocked()) {
// we only preemptively lock if there is no chance of triggering something expensive
// like a lazy decode or imagegenerator. PreLocked means it is flat pixels already.
fBitmap.lockPixels();
@@ -199,7 +214,7 @@ public:
dst, paint, SkCanvas::kStrict_SrcRectConstraint);
}
- bool onPeekPixels(SkPixmap* pixmap) const override {
+ bool testingOnlyOnPeekPixels(SkPixmap* pixmap) const override {
const SkImageInfo info = fBitmap.info();
if ((kUnknown_SkColorType == info.colorType()) || !fBitmap.getPixels()) {
return false;
@@ -219,6 +234,11 @@ public:
return true;
}
+ bool testingOnlyOnGetROPixels(SkBitmap* result) const override {
+ *result = fBitmap;
+ return true;
+ }
+
SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override {
return SkSpecialSurface::NewRaster(this->proxy(), info, nullptr);
}
@@ -285,6 +305,25 @@ public:
return true;
}
+ bool testingOnlyOnGetROPixels(SkBitmap* result) const override {
+
+ const SkImageInfo info = SkImageInfo::MakeN32(this->width(),
+ this->height(),
+ this->isOpaque() ? kOpaque_SkAlphaType
+ : kPremul_SkAlphaType);
+ if (!result->tryAllocPixels(info)) {
+ return false;
+ }
+
+ if (!fTexture->readPixels(0, 0, result->width(), result->height(), kSkia8888_GrPixelConfig,
+ result->getPixels(), result->rowBytes())) {
+ return false;
+ }
+
+ result->pixelRef()->setImmutable();
+ return true;
+ }
+
SkSpecialSurface* onNewSurface(const SkImageInfo& info) const override {
GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(info);
desc.fFlags = kRenderTarget_GrSurfaceFlag;
diff --git a/src/core/SkSpecialImage.h b/src/core/SkSpecialImage.h
index 79fceeba6f..e80f82be96 100644
--- a/src/core/SkSpecialImage.h
+++ b/src/core/SkSpecialImage.h
@@ -72,6 +72,13 @@ public:
static SkSpecialImage* internal_fromBM(SkImageFilter::Proxy*, const SkBitmap&);
SkImageFilter::Proxy* internal_getProxy();
+ // TODO: hide this when GrLayerHoister uses SkSpecialImages more fully (see skbug.com/5063)
+ /**
+ * If the SpecialImage is backed by a gpu texture, return that texture.
+ * The active portion of the texture can be retrieved via 'subset'.
+ */
+ GrTexture* peekTexture() const;
+
protected:
SkSpecialImage(SkImageFilter::Proxy* proxy, const SkIRect& subset, uint32_t uniqueID)
: fSubset(subset)
@@ -94,13 +101,11 @@ protected:
*
* On failure, return false and ignore the pixmap parameter.
*/
- bool peekPixels(SkPixmap*) const;
+ bool testingOnlyPeekPixels(SkPixmap*) const;
- /**
- * If the SpecialImage is backed by a gpu texture, return that texture.
- * The active portion of the texture can be retrieved via 'subset'.
- */
- GrTexture* peekTexture() const;
+ // This entry point is for testing only. It does a readback from VRAM for
+ // GPU-backed special images.
+ bool testingOnlyGetROPixels(SkBitmap*) const;
// TODO: remove this ASAP (see skbug.com/4965)
SkImageFilter::Proxy* proxy() const { return fProxy; }