Pull texture-backed bitmap resampler out of GrTextureParamsAdjuster code into its own class.
Review URL: https://codereview.chromium.org/1420963008
This commit is contained in:
parent
05527a65e0
commit
89fe56bb98
@ -273,9 +273,9 @@ GrTexture* SkImageCacherator::lockTexture(GrContext* ctx, const GrUniqueKey& key
|
||||
|
||||
#include "GrTextureParamsAdjuster.h"
|
||||
|
||||
class Cacherator_GrTextureParamsAdjuster : public GrTextureParamsAdjuster {
|
||||
class Cacherator_GrTextureMaker : public GrTextureMaker {
|
||||
public:
|
||||
Cacherator_GrTextureParamsAdjuster(SkImageCacherator* cacher, const SkImage* client)
|
||||
Cacherator_GrTextureMaker(SkImageCacherator* cacher, const SkImage* client)
|
||||
: INHERITED(cacher->info().width(), cacher->info().height())
|
||||
, fCacher(cacher)
|
||||
, fClient(client)
|
||||
@ -312,7 +312,7 @@ private:
|
||||
const SkImage* fClient;
|
||||
GrUniqueKey fOriginalKey;
|
||||
|
||||
typedef GrTextureParamsAdjuster INHERITED;
|
||||
typedef GrTextureMaker INHERITED;
|
||||
};
|
||||
|
||||
GrTexture* SkImageCacherator::lockAsTexture(GrContext* ctx, const GrTextureParams& params,
|
||||
@ -321,7 +321,7 @@ GrTexture* SkImageCacherator::lockAsTexture(GrContext* ctx, const GrTextureParam
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return Cacherator_GrTextureParamsAdjuster(this, client).refTextureForParams(ctx, params);
|
||||
return Cacherator_GrTextureMaker(this, client).refTextureForParams(ctx, params);
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -86,7 +86,7 @@ private:
|
||||
const SkIPoint fOrigin;
|
||||
const uint32_t fUniqueID;
|
||||
|
||||
friend class Cacherator_GrTextureParamsAdjuster;
|
||||
friend class Cacherator_GrTextureMaker;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -56,7 +56,7 @@ void GrGpu::contextAbandoned() {}
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool GrGpu::makeCopyForTextureParams(int width, int height, const GrTextureParams& textureParams,
|
||||
GrTextureParamsAdjuster::CopyParams* copyParams) const {
|
||||
GrTextureProducer::CopyParams* copyParams) const {
|
||||
const GrCaps& caps = *this->caps();
|
||||
if (textureParams.isTiled() && !caps.npotTextureTileSupport() &&
|
||||
(!SkIsPow2(width) || !SkIsPow2(height))) {
|
||||
|
@ -384,7 +384,7 @@ public:
|
||||
// a given GrTextureParams. If so, the width, height and filter used for the copy are
|
||||
// output via the CopyParams.
|
||||
bool makeCopyForTextureParams(int width, int height, const GrTextureParams&,
|
||||
GrTextureParamsAdjuster::CopyParams*) const;
|
||||
GrTextureProducer::CopyParams*) const;
|
||||
|
||||
// This is only to be used in GL-specific tests.
|
||||
virtual const GrGLContext* glContextForTesting() const { return nullptr; }
|
||||
|
@ -11,24 +11,31 @@
|
||||
#include "GrContext.h"
|
||||
#include "GrDrawContext.h"
|
||||
#include "GrGpu.h"
|
||||
#include "GrGpuResourcePriv.h"
|
||||
#include "GrResourceKey.h"
|
||||
#include "GrTexture.h"
|
||||
#include "GrTextureParams.h"
|
||||
#include "GrTextureProvider.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkGr.h"
|
||||
#include "SkGrPriv.h"
|
||||
#include "effects/GrTextureDomain.h"
|
||||
|
||||
typedef GrTextureParamsAdjuster::CopyParams CopyParams;
|
||||
typedef GrTextureProducer::CopyParams CopyParams;
|
||||
|
||||
static GrTexture* copy_on_gpu(GrTexture* inputTexture, const CopyParams& copyParams) {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static GrTexture* copy_on_gpu(GrTexture* inputTexture, const SkIRect* subset,
|
||||
const CopyParams& copyParams) {
|
||||
SkASSERT(!subset || !subset->isEmpty());
|
||||
GrContext* context = inputTexture->getContext();
|
||||
SkASSERT(context);
|
||||
const GrCaps* caps = context->caps();
|
||||
|
||||
// Either it's a cache miss or the original wasn't cached to begin with.
|
||||
GrSurfaceDesc rtDesc = inputTexture->desc();
|
||||
rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
|
||||
rtDesc.fWidth = copyParams.fWidth;
|
||||
rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
|
||||
rtDesc.fWidth = copyParams.fWidth;
|
||||
rtDesc.fHeight = copyParams.fHeight;
|
||||
rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig);
|
||||
|
||||
@ -60,27 +67,107 @@ static GrTexture* copy_on_gpu(GrTexture* inputTexture, const CopyParams& copyPar
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// TODO: If no scaling is being performed then use copySurface.
|
||||
|
||||
GrPaint paint;
|
||||
|
||||
// If filtering is not desired then we want to ensure all texels in the resampled image are
|
||||
// copies of texels from the original.
|
||||
GrTextureParams params(SkShader::kClamp_TileMode, copyParams.fFilter);
|
||||
paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params);
|
||||
SkScalar sx;
|
||||
SkScalar sy;
|
||||
if (subset) {
|
||||
sx = 1.f / inputTexture->width();
|
||||
sy = 1.f / inputTexture->height();
|
||||
}
|
||||
|
||||
SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight));
|
||||
SkRect localRect = SkRect::MakeWH(1.f, 1.f);
|
||||
if (copyParams.fFilter != GrTextureParams::kNone_FilterMode && subset &&
|
||||
(subset->width() != copyParams.fWidth || subset->height() != copyParams.fHeight)) {
|
||||
SkRect domain;
|
||||
domain.fLeft = (subset->fLeft + 0.5f) * sx;
|
||||
domain.fTop = (subset->fTop + 0.5f)* sy;
|
||||
domain.fRight = (subset->fRight - 0.5f) * sx;
|
||||
domain.fBottom = (subset->fBottom - 0.5f) * sy;
|
||||
// This would cause us to read values from outside the subset. Surely, the caller knows
|
||||
// better!
|
||||
SkASSERT(copyParams.fFilter != GrTextureParams::kMipMap_FilterMode);
|
||||
paint.addColorFragmentProcessor(
|
||||
GrTextureDomainEffect::Create(inputTexture, SkMatrix::I(), domain,
|
||||
GrTextureDomain::kClamp_Mode,
|
||||
copyParams.fFilter))->unref();
|
||||
} else {
|
||||
GrTextureParams params(SkShader::kClamp_TileMode, copyParams.fFilter);
|
||||
paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params);
|
||||
}
|
||||
|
||||
SkRect localRect;
|
||||
if (subset) {
|
||||
localRect = SkRect::Make(*subset);
|
||||
localRect.fLeft *= sx;
|
||||
localRect.fTop *= sy;
|
||||
localRect.fRight *= sx;
|
||||
localRect.fBottom *= sy;
|
||||
} else {
|
||||
localRect = SkRect::MakeWH(1.f, 1.f);
|
||||
}
|
||||
|
||||
SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(copy->asRenderTarget()));
|
||||
if (!drawContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
drawContext->drawNonAARectToRect(GrClip::WideOpen(), paint, SkMatrix::I(), rect, localRect);
|
||||
SkRect dstRect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight));
|
||||
drawContext->drawNonAARectToRect(GrClip::WideOpen(), paint, SkMatrix::I(), dstRect, localRect);
|
||||
return copy.detach();
|
||||
}
|
||||
|
||||
GrTexture* GrTextureParamsAdjuster::refTextureForParams(GrContext* ctx,
|
||||
const GrTextureParams& params) {
|
||||
GrTextureAdjuster::GrTextureAdjuster(GrTexture* original, const SkIRect& subset)
|
||||
: fOriginal(original) {
|
||||
if (subset.fLeft > 0 || subset.fTop > 0 ||
|
||||
subset.fRight < original->width() || subset.fBottom < original->height()) {
|
||||
fSubset.set(subset);
|
||||
}
|
||||
}
|
||||
|
||||
GrTexture* GrTextureAdjuster::refTextureSafeForParams(const GrTextureParams& params,
|
||||
SkIPoint* outOffset) {
|
||||
GrTexture* texture = this->originalTexture();
|
||||
GrContext* context = texture->getContext();
|
||||
CopyParams copyParams;
|
||||
const SkIRect* subset = this->subset();
|
||||
|
||||
if (!context->getGpu()->makeCopyForTextureParams(texture->width(), texture->height(), params,
|
||||
©Params)) {
|
||||
if (outOffset) {
|
||||
if (subset) {
|
||||
outOffset->set(subset->fLeft, subset->fRight);
|
||||
} else {
|
||||
outOffset->set(0, 0);
|
||||
}
|
||||
}
|
||||
return SkRef(texture);
|
||||
}
|
||||
GrUniqueKey key;
|
||||
this->makeCopyKey(copyParams, &key);
|
||||
if (key.isValid()) {
|
||||
GrTexture* result = context->textureProvider()->findAndRefTextureByUniqueKey(key);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
GrTexture* result = copy_on_gpu(texture, subset, copyParams);
|
||||
if (result) {
|
||||
if (key.isValid()) {
|
||||
result->resourcePriv().setUniqueKey(key);
|
||||
this->didCacheCopy(key);
|
||||
}
|
||||
if (outOffset) {
|
||||
outOffset->set(0, 0);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
GrTexture* GrTextureMaker::refTextureForParams(GrContext* ctx, const GrTextureParams& params) {
|
||||
CopyParams copyParams;
|
||||
if (!ctx->getGpu()->makeCopyForTextureParams(this->width(), this->height(), params,
|
||||
©Params)) {
|
||||
@ -107,11 +194,10 @@ GrTexture* GrTextureParamsAdjuster::refTextureForParams(GrContext* ctx,
|
||||
return result;
|
||||
}
|
||||
|
||||
GrTexture* GrTextureParamsAdjuster::generateTextureForParams(GrContext* ctx,
|
||||
const CopyParams& copyParams) {
|
||||
GrTexture* GrTextureMaker::generateTextureForParams(GrContext* ctx, const CopyParams& copyParams) {
|
||||
SkAutoTUnref<GrTexture> original(this->refOriginalTexture(ctx));
|
||||
if (!original) {
|
||||
return nullptr;
|
||||
}
|
||||
return copy_on_gpu(original, copyParams);
|
||||
return copy_on_gpu(original, nullptr, copyParams);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "GrTextureParams.h"
|
||||
#include "GrResourceKey.h"
|
||||
#include "SkTLazy.h"
|
||||
|
||||
class GrContext;
|
||||
class GrTexture;
|
||||
@ -20,12 +21,12 @@ class SkBitmap;
|
||||
/**
|
||||
* Different GPUs and API extensions have different requirements with respect to what texture
|
||||
* sampling parameters may be used with textures of various types. This class facilitates making
|
||||
* texture compatible with a given GrTextureParams. It abstracts the source of the original data
|
||||
* which may be an already existing texture, CPU pixels, a codec, ... so that various sources can
|
||||
* be used with common code that scales or copies the data to make it compatible with a
|
||||
* GrTextureParams.
|
||||
* texture compatible with a given GrTextureParams. There are two immediate subclasses defined
|
||||
* below. One is a base class for sources that are inherently texture-backed (e.g. a texture-backed
|
||||
* SkImage). It supports subsetting the original texture. The other is for use cases where the
|
||||
* source can generate a texture that represents some content (e.g. cpu pixels, SkPicture, ...).
|
||||
*/
|
||||
class GrTextureParamsAdjuster {
|
||||
class GrTextureProducer : public SkNoncopyable {
|
||||
public:
|
||||
struct CopyParams {
|
||||
GrTextureParams::FilterMode fFilter;
|
||||
@ -33,13 +34,85 @@ public:
|
||||
int fHeight;
|
||||
};
|
||||
|
||||
GrTextureParamsAdjuster(int width, int height) : fWidth(width), fHeight(height) {}
|
||||
virtual ~GrTextureParamsAdjuster() {}
|
||||
virtual ~GrTextureProducer() {}
|
||||
|
||||
protected:
|
||||
/** Helper for creating a key for a copy from an original key. */
|
||||
static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
|
||||
const CopyParams& copyParams,
|
||||
GrUniqueKey* copyKey) {
|
||||
SkASSERT(!copyKey->isValid());
|
||||
if (origKey.isValid()) {
|
||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||
GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
|
||||
builder[0] = copyParams.fFilter;
|
||||
builder[1] = copyParams.fWidth;
|
||||
builder[2] = copyParams.fHeight;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we need to make a copy in order to be compatible with GrTextureParams producer is asked to
|
||||
* return a key that identifies its original content + the CopyParms parameter. If the producer
|
||||
* does not want to cache the stretched version (e.g. the producer is volatile), this should
|
||||
* simply return without initializing the copyKey.
|
||||
*/
|
||||
virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey) = 0;
|
||||
|
||||
/**
|
||||
* If a stretched version of the texture is generated, it may be cached (assuming that
|
||||
* makeCopyKey() returns true). In that case, the maker is notified in case it
|
||||
* wants to note that for when the maker is destroyed.
|
||||
*/
|
||||
virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
|
||||
|
||||
typedef SkNoncopyable INHERITED;
|
||||
};
|
||||
|
||||
/** Base class for sources that start out as textures */
|
||||
class GrTextureAdjuster : public GrTextureProducer {
|
||||
public:
|
||||
/** Makes the subset of the texture safe to use with the given texture parameters.
|
||||
outOffset will be the top-left corner of the subset if a copy is not made. Otherwise,
|
||||
the copy will be tight to the contents and outOffset will be (0, 0). If the copy's size
|
||||
does not match subset's dimensions then the contents are scaled to fit the copy.*/
|
||||
GrTexture* refTextureSafeForParams(const GrTextureParams&, SkIPoint* outOffset);
|
||||
|
||||
protected:
|
||||
/** No subset, use the whole texture */
|
||||
explicit GrTextureAdjuster(GrTexture* original): fOriginal(original) {}
|
||||
|
||||
GrTextureAdjuster(GrTexture* original, const SkIRect& subset);
|
||||
|
||||
GrTexture* originalTexture() { return fOriginal; }
|
||||
|
||||
/** Returns the subset or null for the whole original texture */
|
||||
const SkIRect* subset() { return fSubset.getMaybeNull(); }
|
||||
|
||||
private:
|
||||
GrTexture* internalRefTextureSafeForParams(GrTexture*, const SkIRect* subset,
|
||||
const GrTextureParams&, SkIPoint* outOffset);
|
||||
SkTLazy<SkIRect> fSubset;
|
||||
GrTexture* fOriginal;
|
||||
|
||||
typedef GrTextureProducer INHERITED;
|
||||
};
|
||||
|
||||
/**
|
||||
* Base class for sources that start out as something other than a texture (encoded image,
|
||||
* picture, ...).
|
||||
*/
|
||||
class GrTextureMaker : public GrTextureProducer {
|
||||
public:
|
||||
|
||||
GrTextureMaker(int width, int height) : fWidth(width), fHeight(height) {}
|
||||
|
||||
int width() const { return fWidth; }
|
||||
int height() const { return fHeight; }
|
||||
|
||||
/** Returns a texture that is safe for use with the params */
|
||||
/** Returns a texture that is safe for use with the params. If the size of the returned texture
|
||||
does not match width()/height() then the contents of the original must be scaled to fit
|
||||
the texture. */
|
||||
GrTexture* refTextureForParams(GrContext*, const GrTextureParams&);
|
||||
|
||||
protected:
|
||||
@ -51,9 +124,9 @@ protected:
|
||||
virtual GrTexture* refOriginalTexture(GrContext*) = 0;
|
||||
|
||||
/**
|
||||
* If we need to copy the maker's original texture, the maker is asked to return a key
|
||||
* If we need to copy the producer's original texture, the producer is asked to return a key
|
||||
* that identifies its original + the CopyParms parameter. If the maker does not want to cache
|
||||
* the stretched version (e.g. the maker is volatile), this should simply return without
|
||||
* the stretched version (e.g. the producer is volatile), this should simply return without
|
||||
* initializing the copyKey.
|
||||
*/
|
||||
virtual void makeCopyKey(const CopyParams&, GrUniqueKey* copyKey) = 0;
|
||||
@ -70,30 +143,11 @@ protected:
|
||||
*/
|
||||
virtual GrTexture* generateTextureForParams(GrContext*, const CopyParams&);
|
||||
|
||||
/**
|
||||
* If a stretched version of the texture is generated, it may be cached (assuming that
|
||||
* onMakeParamsKey() returns true). In that case, the maker is notified in case it
|
||||
* wants to note that for when the maker is destroyed.
|
||||
*/
|
||||
virtual void didCacheCopy(const GrUniqueKey& copyKey) = 0;
|
||||
|
||||
/** Helper for creating a key for a copy from an original key. */
|
||||
static void MakeCopyKeyFromOrigKey(const GrUniqueKey& origKey,
|
||||
const CopyParams& copyParams,
|
||||
GrUniqueKey* copyKey) {
|
||||
SkASSERT(!copyKey->isValid());
|
||||
if (origKey.isValid()) {
|
||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||
GrUniqueKey::Builder builder(copyKey, origKey, kDomain, 3);
|
||||
builder[0] = copyParams.fFilter;
|
||||
builder[1] = copyParams.fWidth;
|
||||
builder[2] = copyParams.fHeight;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
const int fWidth;
|
||||
const int fHeight;
|
||||
|
||||
typedef GrTextureProducer INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -271,12 +271,26 @@ GrTexture* GrUploadBitmapToTexture(GrContext* ctx, const SkBitmap& bmp) {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Bitmap_GrTextureParamsAdjuster : public GrTextureParamsAdjuster {
|
||||
static void install_bmp_key_invalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
|
||||
class Invalidator : public SkPixelRef::GenIDChangeListener {
|
||||
public:
|
||||
explicit Invalidator(const GrUniqueKey& key) : fMsg(key) {}
|
||||
private:
|
||||
GrUniqueKeyInvalidatedMessage fMsg;
|
||||
|
||||
void onChange() override { SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); }
|
||||
};
|
||||
|
||||
pixelRef->addGenIDChangeListener(new Invalidator(key));
|
||||
}
|
||||
|
||||
class RasterBitmap_GrTextureMaker : public GrTextureMaker {
|
||||
public:
|
||||
Bitmap_GrTextureParamsAdjuster(const SkBitmap& bitmap)
|
||||
RasterBitmap_GrTextureMaker(const SkBitmap& bitmap)
|
||||
: INHERITED(bitmap.width(), bitmap.height())
|
||||
, fBitmap(bitmap)
|
||||
{
|
||||
SkASSERT(!bitmap.getTexture());
|
||||
if (!bitmap.isVolatile()) {
|
||||
SkIPoint origin = bitmap.pixelRefOrigin();
|
||||
SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.width(),
|
||||
@ -287,10 +301,7 @@ public:
|
||||
|
||||
protected:
|
||||
GrTexture* refOriginalTexture(GrContext* ctx) override {
|
||||
GrTexture* tex = fBitmap.getTexture();
|
||||
if (tex) {
|
||||
return SkRef(tex);
|
||||
}
|
||||
GrTexture* tex;
|
||||
|
||||
if (fOriginalKey.isValid()) {
|
||||
tex = ctx->textureProvider()->findAndRefTextureByUniqueKey(fOriginalKey);
|
||||
@ -302,7 +313,7 @@ protected:
|
||||
tex = GrUploadBitmapToTexture(ctx, fBitmap);
|
||||
if (tex && fOriginalKey.isValid()) {
|
||||
tex->resourcePriv().setUniqueKey(fOriginalKey);
|
||||
InstallInvalidator(fOriginalKey, fBitmap.pixelRef());
|
||||
install_bmp_key_invalidator(fOriginalKey, fBitmap.pixelRef());
|
||||
}
|
||||
return tex;
|
||||
}
|
||||
@ -314,34 +325,51 @@ protected:
|
||||
}
|
||||
|
||||
void didCacheCopy(const GrUniqueKey& copyKey) override {
|
||||
InstallInvalidator(copyKey, fBitmap.pixelRef());
|
||||
install_bmp_key_invalidator(copyKey, fBitmap.pixelRef());
|
||||
}
|
||||
|
||||
private:
|
||||
static void InstallInvalidator(const GrUniqueKey& key, SkPixelRef* pixelRef) {
|
||||
class Invalidator : public SkPixelRef::GenIDChangeListener {
|
||||
public:
|
||||
explicit Invalidator(const GrUniqueKey& key) : fMsg(key) {}
|
||||
private:
|
||||
GrUniqueKeyInvalidatedMessage fMsg;
|
||||
|
||||
void onChange() override {
|
||||
SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg);
|
||||
}
|
||||
};
|
||||
Invalidator* listener = new Invalidator(key);
|
||||
pixelRef->addGenIDChangeListener(listener);
|
||||
}
|
||||
|
||||
const SkBitmap fBitmap;
|
||||
GrUniqueKey fOriginalKey;
|
||||
|
||||
typedef GrTextureParamsAdjuster INHERITED;
|
||||
typedef GrTextureMaker INHERITED;
|
||||
};
|
||||
|
||||
class TextureBitmap_GrTextureAdjuster : public GrTextureAdjuster {
|
||||
public:
|
||||
explicit TextureBitmap_GrTextureAdjuster(const SkBitmap* bmp)
|
||||
: INHERITED(bmp->getTexture(), SkIRect::MakeWH(bmp->width(), bmp->height()))
|
||||
, fBmp(bmp) {}
|
||||
|
||||
private:
|
||||
void makeCopyKey(const CopyParams& params, GrUniqueKey* copyKey) override {
|
||||
if (fBmp->isVolatile()) {
|
||||
return;
|
||||
}
|
||||
// The texture subset must represent the whole bitmap. Texture-backed bitmaps don't support
|
||||
// extractSubset(). Therefore, either the bitmap and the teture are the same size or the
|
||||
// subset's dimensions are the bitmap's dimensions.
|
||||
GrUniqueKey baseKey;
|
||||
GrMakeKeyFromImageID(&baseKey, fBmp->getGenerationID(),
|
||||
SkIRect::MakeWH(fBmp->width(), fBmp->height()));
|
||||
MakeCopyKeyFromOrigKey(baseKey, params, copyKey);
|
||||
}
|
||||
|
||||
void didCacheCopy(const GrUniqueKey& copyKey) override {
|
||||
install_bmp_key_invalidator(copyKey, fBmp->pixelRef());
|
||||
}
|
||||
|
||||
const SkBitmap* fBmp;
|
||||
|
||||
typedef GrTextureAdjuster INHERITED;
|
||||
};
|
||||
|
||||
GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
|
||||
const GrTextureParams& params) {
|
||||
return Bitmap_GrTextureParamsAdjuster(bitmap).refTextureForParams(ctx, params);
|
||||
if (bitmap.getTexture()) {
|
||||
return TextureBitmap_GrTextureAdjuster(&bitmap).refTextureSafeForParams(params, nullptr);
|
||||
}
|
||||
return RasterBitmap_GrTextureMaker(bitmap).refTextureForParams(ctx, params);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include "effects/GrYUVtoRGBEffect.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkGpuDevice.h"
|
||||
#include "SkGr.h"
|
||||
#include "SkGrPriv.h"
|
||||
#include "SkPixelRef.h"
|
||||
|
||||
SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrTexture* tex,
|
||||
@ -67,47 +67,31 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
static void make_raw_texture_stretched_key(uint32_t imageID,
|
||||
const GrTextureParamsAdjuster::CopyParams& params,
|
||||
GrUniqueKey* stretchedKey) {
|
||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||
GrUniqueKey::Builder builder(stretchedKey, kDomain, 4);
|
||||
builder[0] = imageID;
|
||||
builder[1] = params.fFilter;
|
||||
builder[2] = params.fWidth;
|
||||
builder[3] = params.fHeight;
|
||||
}
|
||||
|
||||
class Texture_GrTextureParamsAdjuster : public GrTextureParamsAdjuster {
|
||||
class GpuImage_GrTextureAdjuster : public GrTextureAdjuster {
|
||||
public:
|
||||
Texture_GrTextureParamsAdjuster(const SkImage* image, GrTexture* unstretched)
|
||||
: INHERITED(image->width(), image->height())
|
||||
GpuImage_GrTextureAdjuster(const SkImage_Gpu* image)
|
||||
: INHERITED(image->peekTexture())
|
||||
, fImage(image)
|
||||
, fOriginal(unstretched)
|
||||
{}
|
||||
|
||||
protected:
|
||||
GrTexture* refOriginalTexture(GrContext* ctx) override {
|
||||
return SkRef(fOriginal);
|
||||
void makeCopyKey(const CopyParams& params, GrUniqueKey* copyKey) override {
|
||||
GrUniqueKey baseKey;
|
||||
GrMakeKeyFromImageID(&baseKey, fImage->uniqueID(),
|
||||
SkIRect::MakeWH(fImage->width(), fImage->height()));
|
||||
MakeCopyKeyFromOrigKey(baseKey, params, copyKey);
|
||||
}
|
||||
|
||||
void makeCopyKey(const CopyParams& copyParams, GrUniqueKey* copyKey) override {
|
||||
make_raw_texture_stretched_key(fImage->uniqueID(), copyParams, copyKey);
|
||||
}
|
||||
|
||||
void didCacheCopy(const GrUniqueKey& copyKey) override {
|
||||
as_IB(fImage)->notifyAddedToCache();
|
||||
}
|
||||
void didCacheCopy(const GrUniqueKey& copyKey) override { as_IB(fImage)->notifyAddedToCache(); }
|
||||
|
||||
private:
|
||||
const SkImage* fImage;
|
||||
GrTexture* fOriginal;
|
||||
|
||||
typedef GrTextureParamsAdjuster INHERITED;
|
||||
typedef GrTextureAdjuster INHERITED;
|
||||
};
|
||||
|
||||
GrTexture* SkImage_Gpu::asTextureRef(GrContext* ctx, const GrTextureParams& params) const {
|
||||
return Texture_GrTextureParamsAdjuster(this, fTexture).refTextureForParams(ctx, params);
|
||||
return GpuImage_GrTextureAdjuster(this).refTextureSafeForParams(params, nullptr);
|
||||
}
|
||||
|
||||
bool SkImage_Gpu::isOpaque() const {
|
||||
|
Loading…
Reference in New Issue
Block a user