Image generator-backed SkPictureShader
A respin of http://crrev.com/866773002 R=reed@google.com Review URL: https://codereview.chromium.org/1323863002
This commit is contained in:
parent
dde03ff89f
commit
ddc4b46c34
@ -10,6 +10,7 @@
|
||||
#include "SkBitmap.h"
|
||||
#include "SkBitmapProcShader.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkImageGenerator.h"
|
||||
#include "SkMatrixUtils.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkReadBuffer.h"
|
||||
@ -84,26 +85,12 @@ struct BitmapShaderRec : public SkResourceCache::Rec {
|
||||
|
||||
result->reset(SkRef(rec.fShader.get()));
|
||||
|
||||
SkBitmap tile;
|
||||
if (rec.fShader.get()->isABitmap(&tile, nullptr, nullptr)) {
|
||||
// FIXME: this doesn't protect the pixels from being discarded as soon as we unlock.
|
||||
// Should be handled via a pixel ref generator instead
|
||||
// (https://code.google.com/p/skia/issues/detail?id=3220).
|
||||
SkAutoLockPixels alp(tile, true);
|
||||
return tile.getPixels() != nullptr;
|
||||
}
|
||||
return false;
|
||||
// The bitmap shader is backed by an image generator, thus it can always re-generate its
|
||||
// pixels if discarded.
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static bool cache_try_alloc_pixels(SkBitmap* bitmap) {
|
||||
SkBitmap::Allocator* allocator = SkResourceCache::GetAllocator();
|
||||
|
||||
return nullptr != allocator
|
||||
? allocator->allocPixelRef(bitmap, nullptr)
|
||||
: bitmap->tryAllocPixels();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
SkPictureShader::SkPictureShader(const SkPicture* picture, TileMode tmx, TileMode tmy,
|
||||
@ -115,10 +102,6 @@ SkPictureShader::SkPictureShader(const SkPicture* picture, TileMode tmx, TileMod
|
||||
, fTmy(tmy) {
|
||||
}
|
||||
|
||||
SkPictureShader::~SkPictureShader() {
|
||||
fPicture->unref();
|
||||
}
|
||||
|
||||
SkShader* SkPictureShader::Create(const SkPicture* picture, TileMode tmx, TileMode tmy,
|
||||
const SkMatrix* localMatrix, const SkRect* tile) {
|
||||
if (!picture || picture->cullRect().isEmpty() || (tile && tile->isEmpty())) {
|
||||
@ -232,19 +215,14 @@ SkShader* SkPictureShader::refBitmapShader(const SkMatrix& matrix, const SkMatri
|
||||
this->getLocalMatrix());
|
||||
|
||||
if (!SkResourceCache::Find(key, BitmapShaderRec::Visitor, &tileShader)) {
|
||||
SkMatrix matrix;
|
||||
matrix.setRectToRect(fTile, SkRect::MakeIWH(tileSize.width(), tileSize.height()),
|
||||
SkMatrix::kFill_ScaleToFit);
|
||||
SkBitmap bm;
|
||||
bm.setInfo(SkImageInfo::MakeN32Premul(tileSize));
|
||||
if (!cache_try_alloc_pixels(&bm)) {
|
||||
return SkShader::CreateEmptyShader();
|
||||
if (!SkInstallDiscardablePixelRef(
|
||||
SkImageGenerator::NewFromPicture(tileSize, fPicture, &matrix, nullptr), &bm)) {
|
||||
return nullptr;
|
||||
}
|
||||
bm.eraseColor(SK_ColorTRANSPARENT);
|
||||
|
||||
// Always disable LCD text, since we can't assume our image will be opaque.
|
||||
SkCanvas canvas(bm, SkSurfaceProps(0, kUnknown_SkPixelGeometry));
|
||||
|
||||
canvas.scale(tileScale.width(), tileScale.height());
|
||||
canvas.translate(-fTile.x(), -fTile.y());
|
||||
canvas.drawPicture(fPicture);
|
||||
|
||||
SkMatrix shaderMatrix = this->getLocalMatrix();
|
||||
shaderMatrix.preScale(1 / tileScale.width(), 1 / tileScale.height());
|
||||
@ -324,10 +302,10 @@ void SkPictureShader::toString(SkString* str) const {
|
||||
};
|
||||
|
||||
str->appendf("PictureShader: [%f:%f:%f:%f] ",
|
||||
fPicture ? fPicture->cullRect().fLeft : 0,
|
||||
fPicture ? fPicture->cullRect().fTop : 0,
|
||||
fPicture ? fPicture->cullRect().fRight : 0,
|
||||
fPicture ? fPicture->cullRect().fBottom : 0);
|
||||
fPicture->cullRect().fLeft,
|
||||
fPicture->cullRect().fTop,
|
||||
fPicture->cullRect().fRight,
|
||||
fPicture->cullRect().fBottom);
|
||||
|
||||
str->appendf("(%s, %s)", gTileModeName[fTmx], gTileModeName[fTmy]);
|
||||
|
||||
|
@ -24,7 +24,6 @@ class SkPictureShader : public SkShader {
|
||||
public:
|
||||
static SkShader* Create(const SkPicture*, TileMode, TileMode, const SkMatrix*,
|
||||
const SkRect*);
|
||||
virtual ~SkPictureShader();
|
||||
|
||||
size_t contextSize() const override;
|
||||
|
||||
@ -49,9 +48,9 @@ private:
|
||||
|
||||
SkShader* refBitmapShader(const SkMatrix&, const SkMatrix* localMatrix, const int maxTextureSize = 0) const;
|
||||
|
||||
const SkPicture* fPicture;
|
||||
SkRect fTile;
|
||||
TileMode fTmx, fTmy;
|
||||
SkAutoTUnref<const SkPicture> fPicture;
|
||||
SkRect fTile;
|
||||
TileMode fTmx, fTmy;
|
||||
|
||||
class PictureShaderContext : public SkShader::Context {
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user