aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Herb Derby <herb@google.com>2017-02-13 20:04:00 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-02-13 20:04:16 +0000
commit07f665efb918f68e406b76a78d0b76d5c714f16c (patch)
treed58a5d4849f779e9504aa69dda0414777770eafb
parentd2d6d726fa3e401da73befa649266bc5589da7e5 (diff)
Revert "Always make SkImageShaders in heap."
This reverts commit ff590a12441002d281254ec6a86070ac0a19263f. Reason for revert: This breaks the android roll because they are using a private call. Updating android tests to use new api. Original change's description: > Always make SkImageShaders in heap. > > I made a couple of measurments, and it looks like any differences is > well below the noise threshold. > > Just for the record run1: .9991 of baseline and run2 .9988 of baseline. > I was using top25 .skps as workload. > > TBR=mtklein@google.com > > Change-Id: If4fa06e5d5df72fb67dbb4bbb99c926f05765897 > Reviewed-on: https://skia-review.googlesource.com/8341 > Reviewed-by: Herb Derby <herb@google.com> > Commit-Queue: Herb Derby <herb@google.com> > TBR=mtklein@chromium.org,mtklein@google.com,herb@google.com,reviews@skia.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true Change-Id: Ibdaafc796702e250933b62e5f4abb5e2ce8d40c0 Reviewed-on: https://skia-review.googlesource.com/8393 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Herb Derby <herb@google.com>
-rw-r--r--src/core/SkBitmapDevice.cpp6
-rw-r--r--src/core/SkDraw.cpp19
-rw-r--r--src/core/SkImagePriv.h6
-rw-r--r--src/core/SkShader.cpp2
-rw-r--r--src/image/SkImageShader.cpp29
-rw-r--r--src/image/SkImageShader.h2
-rw-r--r--src/image/SkImage_Raster.cpp15
-rw-r--r--src/xps/SkXPSDevice.cpp2
8 files changed, 62 insertions, 19 deletions
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 45ec2b70ae..2b5c37fa2e 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -334,13 +334,15 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
// Since the shader need only live for our stack-frame, pass in a custom allocator. This
// can save malloc calls, and signals to SkMakeBitmapShader to not try to copy the bitmap
// if its mutable, since that precaution is not needed (give the short lifetime of the shader).
-
+ SkTBlitterAllocator allocator;
// construct a shader, so we can call drawRect with the dst
auto s = SkMakeBitmapShader(*bitmapPtr, SkShader::kClamp_TileMode, SkShader::kClamp_TileMode,
- &matrix, kNever_SkCopyPixelsMode);
+ &matrix, kNever_SkCopyPixelsMode, &allocator);
if (!s) {
return;
}
+ // we deliberately add a ref, since the allocator wants to be the last owner
+ s.get()->ref();
SkPaint paintWithShader(paint);
paintWithShader.setStyle(SkPaint::kFill_Style);
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 4d1c5a4998..4308000457 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -85,10 +85,23 @@ public:
SkAutoBitmapShaderInstall(const SkBitmap& src, const SkPaint& paint,
const SkMatrix* localMatrix = nullptr)
: fPaint(paint) /* makes a copy of the paint */ {
-
+ // TODO(herb): Move this over to SkArenaAlloc when arena alloc has a
+ // facility to return sk_sps.
fPaint.setShader(SkMakeBitmapShader(src, SkShader::kClamp_TileMode,
SkShader::kClamp_TileMode, localMatrix,
- kNever_SkCopyPixelsMode));
+ kNever_SkCopyPixelsMode,
+ &fAllocator));
+ // we deliberately left the shader with an owner-count of 2
+ fPaint.getShader()->ref();
+ SkASSERT(2 == fPaint.getShader()->getRefCnt());
+ }
+
+ ~SkAutoBitmapShaderInstall() {
+ // since fAllocator will destroy shader, we insist that owners == 2
+ SkASSERT(2 == fPaint.getShader()->getRefCnt());
+
+ fPaint.setShader(nullptr); // unref the shader by 1
+
}
// return the new paint that has the shader applied
@@ -97,6 +110,8 @@ public:
private:
// copy of caller's paint (which we then modify)
SkPaint fPaint;
+ // Stores the shader.
+ SkTBlitterAllocator fAllocator;
};
#define SkAutoBitmapShaderInstall(...) SK_REQUIRE_LOCAL_VAR(SkAutoBitmapShaderInstall)
diff --git a/src/core/SkImagePriv.h b/src/core/SkImagePriv.h
index d6e58d3c11..601108665d 100644
--- a/src/core/SkImagePriv.h
+++ b/src/core/SkImagePriv.h
@@ -30,7 +30,8 @@ typedef SkSmallAllocator<3, kSkBlitterContextSize> SkTBlitterAllocator;
// If alloc is non-nullptr, it will be used to allocate the returned SkShader, and MUST outlive
// the SkShader.
sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkShader::TileMode, SkShader::TileMode,
- const SkMatrix* localMatrix, SkCopyPixelsMode);
+ const SkMatrix* localMatrix, SkCopyPixelsMode,
+ SkTBlitterAllocator* alloc);
/**
* Examines the bitmap to decide if it can share the existing pixelRef, or
@@ -50,7 +51,8 @@ sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkShader::TileMode, SkSh
* SkImageInfo, or the bitmap's pixels cannot be accessed, this will return
* nullptr.
*/
-extern sk_sp<SkImage> SkMakeImageFromRasterBitmap(const SkBitmap&, SkCopyPixelsMode);
+extern sk_sp<SkImage> SkMakeImageFromRasterBitmap(const SkBitmap&, SkCopyPixelsMode,
+ SkTBlitterAllocator* = nullptr);
// Given an image created from SkNewImageFromBitmap, return its pixelref. This
// may be called to see if the surface and the image share the same pixelref,
diff --git a/src/core/SkShader.cpp b/src/core/SkShader.cpp
index cfdd8b946e..81aae116d5 100644
--- a/src/core/SkShader.cpp
+++ b/src/core/SkShader.cpp
@@ -232,7 +232,7 @@ sk_sp<SkShader> SkShader::MakeBitmapShader(const SkBitmap& src, TileMode tmx, Ti
if (localMatrix && !localMatrix->invert(nullptr)) {
return nullptr;
}
- return SkMakeBitmapShader(src, tmx, tmy, localMatrix, kIfMutable_SkCopyPixelsMode);
+ return SkMakeBitmapShader(src, tmx, tmy, localMatrix, kIfMutable_SkCopyPixelsMode, nullptr);
}
sk_sp<SkShader> SkShader::MakePictureShader(sk_sp<SkPicture> src, TileMode tmx, TileMode tmy,
diff --git a/src/image/SkImageShader.cpp b/src/image/SkImageShader.cpp
index 7e3874891c..64a09dd2dc 100644
--- a/src/image/SkImageShader.cpp
+++ b/src/image/SkImageShader.cpp
@@ -97,12 +97,23 @@ static bool bitmap_is_too_big(int w, int h) {
}
sk_sp<SkShader> SkImageShader::Make(sk_sp<SkImage> image, TileMode tx, TileMode ty,
- const SkMatrix* localMatrix) {
+ const SkMatrix* localMatrix,
+ SkTBlitterAllocator* allocator) {
+ SkShader* shader;
if (!image || bitmap_is_too_big(image->width(), image->height())) {
- return sk_make_sp<SkEmptyShader>();
+ if (nullptr == allocator) {
+ shader = new SkEmptyShader;
+ } else {
+ shader = allocator->createT<SkEmptyShader>();
+ }
} else {
- return sk_make_sp<SkImageShader>(image, tx, ty, localMatrix);
+ if (nullptr == allocator) {
+ shader = new SkImageShader(image, tx, ty, localMatrix);
+ } else {
+ shader = allocator->createT<SkImageShader>(image, tx, ty, localMatrix);
+ }
}
+ return sk_sp<SkShader>(shader);
}
#ifndef SK_IGNORE_TO_STRING
@@ -186,9 +197,15 @@ sk_sp<GrFragmentProcessor> SkImageShader::asFragmentProcessor(const AsFPArgs& ar
sk_sp<SkShader> SkMakeBitmapShader(const SkBitmap& src, SkShader::TileMode tmx,
SkShader::TileMode tmy, const SkMatrix* localMatrix,
- SkCopyPixelsMode cpm) {
- return SkImageShader::Make(SkMakeImageFromRasterBitmap(src, cpm),
- tmx, tmy, localMatrix);
+ SkCopyPixelsMode cpm, SkTBlitterAllocator* allocator) {
+ // Until we learn otherwise, it seems that any caller that is passing an allocator must be
+ // assuming that the returned shader will have a stack-frame lifetime, so we assert that
+ // they are also asking for kNever_SkCopyPixelsMode. If that proves otherwise, we can remove
+ // or modify this assert.
+ SkASSERT(!allocator || (kNever_SkCopyPixelsMode == cpm));
+
+ return SkImageShader::Make(SkMakeImageFromRasterBitmap(src, cpm, allocator),
+ tmx, tmy, localMatrix, allocator);
}
static sk_sp<SkFlattenable> SkBitmapProcShader_CreateProc(SkReadBuffer& buffer) {
diff --git a/src/image/SkImageShader.h b/src/image/SkImageShader.h
index 8960812a06..ef5e87c66d 100644
--- a/src/image/SkImageShader.h
+++ b/src/image/SkImageShader.h
@@ -15,7 +15,7 @@
class SkImageShader : public SkShader {
public:
static sk_sp<SkShader> Make(sk_sp<SkImage>, TileMode tx, TileMode ty,
- const SkMatrix* localMatrix);
+ const SkMatrix* localMatrix, SkTBlitterAllocator* = nullptr);
bool isOpaque() const override;
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 0364fc6b2a..b287789ea8 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -301,7 +301,8 @@ sk_sp<SkImage> SkImage::MakeFromRaster(const SkPixmap& pmap, RasterReleaseProc p
return sk_make_sp<SkImage_Raster>(pmap.info(), std::move(data), pmap.rowBytes(), pmap.ctable());
}
-sk_sp<SkImage> SkMakeImageFromRasterBitmap(const SkBitmap& bm, SkCopyPixelsMode cpm) {
+sk_sp<SkImage> SkMakeImageFromRasterBitmap(const SkBitmap& bm, SkCopyPixelsMode cpm,
+ SkTBlitterAllocator* allocator) {
bool hasColorTable = false;
if (kIndex_8_SkColorType == bm.colorType()) {
SkAutoLockPixels autoLockPixels(bm);
@@ -312,17 +313,23 @@ sk_sp<SkImage> SkMakeImageFromRasterBitmap(const SkBitmap& bm, SkCopyPixelsMode
return nullptr;
}
+ sk_sp<SkImage> image;
if (kAlways_SkCopyPixelsMode == cpm || (!bm.isImmutable() && kNever_SkCopyPixelsMode != cpm)) {
SkBitmap tmp(bm);
tmp.lockPixels();
SkPixmap pmap;
if (tmp.getPixels() && tmp.peekPixels(&pmap)) {
- return SkImage::MakeRasterCopy(pmap);
+ image = SkImage::MakeRasterCopy(pmap);
}
} else {
- return sk_make_sp<SkImage_Raster>(bm, kNever_SkCopyPixelsMode == cpm);
+ if (allocator) {
+ image.reset(allocator->createT<SkImage_Raster>(bm, kNever_SkCopyPixelsMode == cpm));
+ image.get()->ref(); // account for the allocator being an owner
+ } else {
+ image = sk_make_sp<SkImage_Raster>(bm, kNever_SkCopyPixelsMode == cpm);
+ }
}
- return sk_sp<SkImage>();
+ return image;
}
const SkPixelRef* SkBitmapImageGetPixelRef(const SkImage* image) {
diff --git a/src/xps/SkXPSDevice.cpp b/src/xps/SkXPSDevice.cpp
index f32ca86d92..8dca7f0156 100644
--- a/src/xps/SkXPSDevice.cpp
+++ b/src/xps/SkXPSDevice.cpp
@@ -2274,7 +2274,7 @@ void SkXPSDevice::drawBitmapRect(const SkDraw& draw,
auto bitmapShader = SkMakeBitmapShader(bitmap, SkShader::kClamp_TileMode,
SkShader::kClamp_TileMode, &matrix,
- kNever_SkCopyPixelsMode);
+ kNever_SkCopyPixelsMode, nullptr);
SkASSERT(bitmapShader);
if (!bitmapShader) { return; }
SkPaint paintWithShader(paint);