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

Unified Diff: src/core/SkImageFilter.cpp

Issue 920513003: Make filters use SkImage instead of SkBitmap Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkDeviceImageFilterProxy.h ('k') | src/core/SkMatrixImageFilter.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkImageFilter.cpp
diff --git a/src/core/SkImageFilter.cpp b/src/core/SkImageFilter.cpp
index fd98911ca58c705e01c11803976d66b403979d01..cde77381091107c065aea53d11f243cce3fb6163 100644
--- a/src/core/SkImageFilter.cpp
+++ b/src/core/SkImageFilter.cpp
@@ -10,11 +10,15 @@
#include "SkBitmap.h"
#include "SkChecksum.h"
#include "SkDevice.h"
+#include "SkImage.h"
+#include "SkImagePriv.h"
+#include "SkImage_Base.h"
#include "SkLazyPtr.h"
#include "SkMatrixImageFilter.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
#include "SkRect.h"
+#include "SkSurface.h"
#include "SkTDynamicHash.h"
#include "SkTInternalLList.h"
#include "SkValidationUtils.h"
@@ -165,13 +169,12 @@ void SkImageFilter::flatten(SkWriteBuffer& buffer) const {
buffer.writeUInt(fCropRect.flags());
}
-bool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src,
+bool SkImageFilter::filterImage(Proxy* proxy, const SkImage* src,
const Context& context,
- SkBitmap* result, SkIPoint* offset) const {
- SkASSERT(result);
+ SkAutoTUnref<const SkImage>& result, SkIPoint* offset) const {
SkASSERT(offset);
- uint32_t srcGenID = fUsesSrcInput ? src.getGenerationID() : 0;
- Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), srcGenID);
+ uint32_t srcUniqueID = fUsesSrcInput ? src->uniqueID() : 0;
+ Cache::Key key(fUniqueID, context.ctm(), context.clipBounds(), srcUniqueID);
if (context.cache()) {
if (context.cache()->get(key, result, offset)) {
return true;
@@ -182,9 +185,10 @@ bool SkImageFilter::filterImage(Proxy* proxy, const SkBitmap& src,
* the filter to do it.
*/
if ((proxy && proxy->filterImage(this, src, context, result, offset)) ||
- this->onFilterImage(proxy, src, context, result, offset)) {
+ (this->onFilterImage(proxy, src, context, result, offset))) {
+ SkASSERT(result);
if (context.cache()) {
- context.cache()->set(key, *result, *offset);
+ context.cache()->set(key, result, *offset);
}
return true;
}
@@ -220,8 +224,8 @@ void SkImageFilter::computeFastBounds(const SkRect& src, SkRect* dst) const {
}
}
-bool SkImageFilter::onFilterImage(Proxy*, const SkBitmap&, const Context&,
- SkBitmap*, SkIPoint*) const {
+bool SkImageFilter::onFilterImage(Proxy*, const SkImage*, const Context&,
+ SkAutoTUnref<const SkImage>&, SkIPoint*) const {
return false;
}
@@ -229,21 +233,27 @@ bool SkImageFilter::canFilterImageGPU() const {
return this->asFragmentProcessor(NULL, NULL, SkMatrix::I(), SkIRect());
}
-bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx,
- SkBitmap* result, SkIPoint* offset) const {
+bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkImage* src, const Context& ctx,
+ SkAutoTUnref<const SkImage>& result, SkIPoint* offset) const {
#if SK_SUPPORT_GPU
- SkBitmap input = src;
- SkASSERT(fInputCount == 1);
+ SkAutoTUnref<const SkImage> filtered(SkRef(src));
SkIPoint srcOffset = SkIPoint::Make(0, 0);
+
+ SkASSERT(fInputCount == 1);
if (this->getInput(0) &&
- !this->getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) {
+ !this->getInput(0)->getInputResultGPU(proxy, src, ctx, filtered, &srcOffset)) {
return false;
}
- GrTexture* srcTexture = input.getTexture();
+
+ SkAutoTUnref<const SkImage> cropped;
SkIRect bounds;
- if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) {
+ if (!this->applyCropRect(ctx, proxy, filtered, &srcOffset, &bounds, cropped)) {
return false;
}
+ filtered.reset(NULL);
+
+ GrTexture* srcTexture = cropped->getTexture();
+
SkRect srcRect = SkRect::Make(bounds);
SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
GrContext* context = srcTexture->getContext();
@@ -276,17 +286,19 @@ bool SkImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Cont
context->drawNonAARectToRect(dst->asRenderTarget(), clip, paint, SkMatrix::I(), dstRect,
srcRect);
- WrapTexture(dst, bounds.width(), bounds.height(), result);
+ if (!WrapTexture(dst, bounds.width(), bounds.height(), result)) {
+ return false;
+ }
return true;
}
#endif
return false;
}
-bool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src,
+bool SkImageFilter::applyCropRect(const Context& ctx, const SkImage* src,
const SkIPoint& srcOffset, SkIRect* bounds) const {
- SkIRect srcBounds;
- src.getBounds(&srcBounds);
+ SkIRect srcBounds = NULL == src ? SkIRect::MakeEmpty()
+ : SkIRect::MakeWH(src->width(), src->height());
srcBounds.offset(srcOffset);
SkRect cropRect;
ctx.ctm().mapRect(&cropRect, fCropRect.rect());
@@ -303,10 +315,11 @@ bool SkImageFilter::applyCropRect(const Context& ctx, const SkBitmap& src,
return true;
}
-bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitmap& src,
- SkIPoint* srcOffset, SkIRect* bounds, SkBitmap* dst) const {
- SkIRect srcBounds;
- src.getBounds(&srcBounds);
+bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkImage* src,
+ SkIPoint* srcOffset, SkIRect* bounds,
+ SkAutoTUnref<const SkImage>& dst) const {
+ SkASSERT(src);
+ SkIRect srcBounds = SkIRect::MakeWH(src->width(), src->height());
srcBounds.offset(*srcOffset);
SkRect cropRect;
ctx.ctm().mapRect(&cropRect, fCropRect.rect());
@@ -321,7 +334,7 @@ bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitm
return false;
}
if (srcBounds.contains(*bounds)) {
- *dst = src;
+ dst.reset(SkRef(src));
return true;
} else {
SkAutoTUnref<SkBaseDevice> device(proxy->createDevice(bounds->width(), bounds->height()));
@@ -330,9 +343,13 @@ bool SkImageFilter::applyCropRect(const Context& ctx, Proxy* proxy, const SkBitm
}
SkCanvas canvas(device);
canvas.clear(0x00000000);
- canvas.drawBitmap(src, srcOffset->x() - bounds->x(), srcOffset->y() - bounds->y());
+ canvas.drawImage(src, srcOffset->x() - bounds->x(), srcOffset->y() - bounds->y());
*srcOffset = SkIPoint::Make(bounds->x(), bounds->y());
- *dst = device->accessBitmap(false);
+ SkImage* image = device->newImageSnapshot();
+ if (NULL == image) {
+ return false;
+ }
+ dst.reset(image);
return true;
}
}
@@ -377,31 +394,45 @@ SkImageFilter* SkImageFilter::CreateMatrixFilter(const SkMatrix& matrix,
#if SK_SUPPORT_GPU
-void SkImageFilter::WrapTexture(GrTexture* texture, int width, int height, SkBitmap* result) {
+bool SkImageFilter::WrapTexture(GrTexture* texture, int width, int height,
+ SkAutoTUnref<const SkImage>& result) {
+ // TODO: currently we go texture->bitmap->surface, when we should go rendertarget->device.
+ SkBitmap bitmap;
SkImageInfo info = SkImageInfo::MakeN32Premul(width, height);
- result->setInfo(info);
- result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
+ bitmap.setInfo(info);
+ bitmap.setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, texture)))->unref();
+ SkImage* image = SkNewImageFromBitmapTexture(bitmap, texture->desc().fSampleCnt,
+ SkSurface::kYes_Budgeted);
+ if (NULL == image) {
+ return false;
+ }
+ result.reset(image);
+ return true;
}
bool SkImageFilter::getInputResultGPU(SkImageFilter::Proxy* proxy,
- const SkBitmap& src, const Context& ctx,
- SkBitmap* result, SkIPoint* offset) const {
+ const SkImage* src, const Context& ctx,
+ SkAutoTUnref<const SkImage>& result, SkIPoint* offset) const {
// 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();
-
+ GrContext* context = src->getTexture()->getContext();
if (this->canFilterImageGPU()) {
return this->filterImageGPU(proxy, src, ctx, result, offset);
} else {
if (this->filterImage(proxy, src, ctx, result, offset)) {
if (!result->getTexture()) {
- const SkImageInfo info = result->info();
- if (kUnknown_SkColorType == info.colorType()) {
+ SkBitmap bitmap;
+ if (!as_IB(result)->getROPixels(&bitmap)) {
+ return false;
+ }
+ if (kUnknown_SkColorType == bitmap.colorType()) {
+ return false;
+ }
+ SkAutoTUnref<GrTexture> resultTex(GrRefCachedBitmapTexture(context, bitmap, NULL));
+ if (!WrapTexture(resultTex, bitmap.width(), bitmap.height(), result)) {
return false;
}
- SkAutoTUnref<GrTexture> resultTex(GrRefCachedBitmapTexture(context, *result, NULL));
- result->setPixelRef(SkNEW_ARGS(SkGrPixelRef, (info, resultTex)))->unref();
}
return true;
} else {
@@ -427,10 +458,10 @@ public:
}
}
struct Value {
- Value(const Key& key, const SkBitmap& bitmap, const SkIPoint& offset)
- : fKey(key), fBitmap(bitmap), fOffset(offset) {}
+ Value(const Key& key, const SkImage* value, const SkIPoint& offset)
+ : fKey(key), fImage(SkRef(value)), fOffset(offset) {}
Key fKey;
- SkBitmap fBitmap;
+ SkAutoTUnref<const SkImage> fImage;
SkIPoint fOffset;
static const Key& GetKey(const Value& v) {
return v.fKey;
@@ -440,10 +471,10 @@ public:
}
SK_DECLARE_INTERNAL_LLIST_INTERFACE(Value);
};
- bool get(const Key& key, SkBitmap* result, SkIPoint* offset) const SK_OVERRIDE {
+ bool get(const Key& key, SkAutoTUnref<const SkImage>& result, SkIPoint* offset) const SK_OVERRIDE {
SkAutoMutexAcquire mutex(fMutex);
if (Value* v = fLookup.find(key)) {
- *result = v->fBitmap;
+ result.reset(SkRef(v->fImage.get()));
*offset = v->fOffset;
if (v != fLRU.head()) {
fLRU.remove(v);
@@ -453,15 +484,15 @@ public:
}
return false;
}
- void set(const Key& key, const SkBitmap& result, const SkIPoint& offset) SK_OVERRIDE {
+ void set(const Key& key, const SkImage* image, const SkIPoint& offset) SK_OVERRIDE {
SkAutoMutexAcquire mutex(fMutex);
if (Value* v = fLookup.find(key)) {
removeInternal(v);
}
- Value* v = new Value(key, result, offset);
+ Value* v = new Value(key, image, offset);
fLookup.add(v);
fLRU.addToHead(v);
- fCurrentBytes += result.getSize();
+ fCurrentBytes += as_IB(image)->getSize();
while (fCurrentBytes > fMaxBytes) {
Value* tail = fLRU.tail();
SkASSERT(tail);
@@ -473,7 +504,7 @@ public:
}
private:
void removeInternal(Value* v) {
- fCurrentBytes -= v->fBitmap.getSize();
+ fCurrentBytes -= as_IB(v->fImage)->getSize();
fLRU.remove(v);
fLookup.remove(v->fKey);
delete v;
« no previous file with comments | « src/core/SkDeviceImageFilterProxy.h ('k') | src/core/SkMatrixImageFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698