Index: src/gpu/SkGr.cpp |
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp |
index d8444968da6ea2e788b16900fc80af3e314a1243..3c3f3e8fab99e9836564c571d912003901991c2e 100644 |
--- a/src/gpu/SkGr.cpp |
+++ b/src/gpu/SkGr.cpp |
@@ -5,13 +5,13 @@ |
* found in the LICENSE file. |
*/ |
-#include "GrTextureMaker.h" |
#include "SkGr.h" |
#include "GrCaps.h" |
#include "GrContext.h" |
-#include "GrDrawContext.h" |
+#include "GrTextureParamsAdjuster.h" |
+#include "GrGpuResourcePriv.h" |
#include "GrXferProcessor.h" |
#include "GrYUVProvider.h" |
@@ -48,64 +48,17 @@ GrSurfaceDesc GrImageInfoToSurfaceDesc(const SkImageInfo& info) { |
return desc; |
} |
-static void get_stretch(const GrCaps& caps, int width, int height, |
- const GrTextureParams& params, SkGrStretch* stretch) { |
- stretch->fType = SkGrStretch::kNone_Type; |
- bool doStretch = false; |
- if (params.isTiled() && !caps.npotTextureTileSupport() && |
- (!SkIsPow2(width) || !SkIsPow2(height))) { |
- doStretch = true; |
- stretch->fWidth = GrNextPow2(SkTMax(width, caps.minTextureSize())); |
- stretch->fHeight = GrNextPow2(SkTMax(height, caps.minTextureSize())); |
- } else if (width < caps.minTextureSize() || height < caps.minTextureSize()) { |
- // The small texture issues appear to be with tiling. Hence it seems ok to scale them |
- // up using the GPU. If issues persist we may need to CPU-stretch. |
- doStretch = true; |
- stretch->fWidth = SkTMax(width, caps.minTextureSize()); |
- stretch->fHeight = SkTMax(height, caps.minTextureSize()); |
- } |
- if (doStretch) { |
- switch (params.filterMode()) { |
- case GrTextureParams::kNone_FilterMode: |
- stretch->fType = SkGrStretch::kNearest_Type; |
- break; |
- case GrTextureParams::kBilerp_FilterMode: |
- case GrTextureParams::kMipMap_FilterMode: |
- stretch->fType = SkGrStretch::kBilerp_Type; |
- break; |
- } |
- } else { |
- stretch->fWidth = -1; |
- stretch->fHeight = -1; |
- stretch->fType = SkGrStretch::kNone_Type; |
- } |
-} |
- |
-static void make_unstretched_key(GrUniqueKey* key, uint32_t imageID, const SkIRect& subset) { |
- SkASSERT(SkIsU16(subset.width())); |
- SkASSERT(SkIsU16(subset.height())); |
- |
- static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
- GrUniqueKey::Builder builder(key, kDomain, 4); |
+void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& imageBounds) { |
+ SkASSERT(key); |
+ SkASSERT(imageID); |
+ SkASSERT(!imageBounds.isEmpty()); |
+ static const GrUniqueKey::Domain kImageIDDomain = GrUniqueKey::GenerateDomain(); |
+ GrUniqueKey::Builder builder(key, kImageIDDomain, 5); |
builder[0] = imageID; |
- builder[1] = subset.x(); |
- builder[2] = subset.y(); |
- builder[3] = subset.width() | (subset.height() << 16); |
-} |
- |
-void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& subset, |
- const GrCaps& caps, const GrTextureParams& params) { |
- SkGrStretch stretch; |
- get_stretch(caps, subset.width(), subset.height(), params, &stretch); |
- if (SkGrStretch::kNone_Type != stretch.fType) { |
- GrUniqueKey tmpKey; |
- make_unstretched_key(&tmpKey, imageID, subset); |
- if (!GrMakeStretchedKey(tmpKey, stretch, key)) { |
- *key = tmpKey; |
- } |
- } else { |
- make_unstretched_key(key, imageID, subset); |
- } |
+ builder[1] = imageBounds.fLeft; |
+ builder[2] = imageBounds.fTop; |
+ builder[3] = imageBounds.fRight; |
+ builder[4] = imageBounds.fBottom; |
} |
GrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data, |
@@ -150,16 +103,19 @@ GrPixelConfig GrIsCompressedTextureDataSupported(GrContext* ctx, SkData* data, |
return kUnknown_GrPixelConfig; |
} |
-/* Fill out buffer with the compressed format Ganesh expects from a colortable |
- based bitmap. [palette (colortable) + indices]. |
- |
- At the moment Ganesh only supports 8bit version. If Ganesh allowed we others |
- we could detect that the colortable.count is <= 16, and then repack the |
- indices as nibbles to save RAM, but it would take more time (i.e. a lot |
- slower than memcpy), so skipping that for now. |
+////////////////////////////////////////////////////////////////////////////// |
- Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big |
- as the colortable.count says it is. |
+/** |
+ * Fill out buffer with the compressed format Ganesh expects from a colortable |
+ * based bitmap. [palette (colortable) + indices]. |
+ * |
+ * At the moment Ganesh only supports 8bit version. If Ganesh allowed we others |
+ * we could detect that the colortable.count is <= 16, and then repack the |
+ * indices as nibbles to save RAM, but it would take more time (i.e. a lot |
+ * slower than memcpy), so skipping that for now. |
+ * |
+ * Ganesh wants a full 256 palette entry, even though Skia's ctable is only as big |
+ * as the colortable.count says it is. |
*/ |
static void build_index8_data(void* buffer, const SkBitmap& bitmap) { |
SkASSERT(kIndex_8_SkColorType == bitmap.colorType()); |
@@ -207,130 +163,7 @@ static void build_index8_data(void* buffer, const SkBitmap& bitmap) { |
} |
} |
-//////////////////////////////////////////////////////////////////////////////// |
- |
- |
-bool GrMakeStretchedKey(const GrUniqueKey& origKey, const SkGrStretch& stretch, |
- GrUniqueKey* stretchedKey) { |
- if (origKey.isValid() && SkGrStretch::kNone_Type != stretch.fType) { |
- uint32_t width = SkToU16(stretch.fWidth); |
- uint32_t height = SkToU16(stretch.fHeight); |
- static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain(); |
- GrUniqueKey::Builder builder(stretchedKey, origKey, kDomain, 2); |
- builder[0] = stretch.fType; |
- builder[1] = width | (height << 16); |
- builder.finish(); |
- return true; |
- } |
- SkASSERT(!stretchedKey->isValid()); |
- return false; |
-} |
- |
-namespace { |
- |
-// When the SkPixelRef genID changes, invalidate a corresponding GrResource described by key. |
-class BitmapInvalidator : public SkPixelRef::GenIDChangeListener { |
-public: |
- explicit BitmapInvalidator(const GrUniqueKey& key) : fMsg(key) {} |
-private: |
- GrUniqueKeyInvalidatedMessage fMsg; |
- |
- void onChange() override { |
- SkMessageBus<GrUniqueKeyInvalidatedMessage>::Post(fMsg); |
- } |
-}; |
- |
-} // namespace |
- |
- |
-GrTexture* GrCreateTextureForPixels(GrContext* ctx, |
- const GrUniqueKey& optionalKey, |
- GrSurfaceDesc desc, |
- SkPixelRef* pixelRefForInvalidationNotification, |
- const void* pixels, |
- size_t rowBytes) { |
- GrTexture* result = ctx->textureProvider()->createTexture(desc, true, pixels, rowBytes); |
- if (result && optionalKey.isValid()) { |
- if (pixelRefForInvalidationNotification) { |
- BitmapInvalidator* listener = new BitmapInvalidator(optionalKey); |
- pixelRefForInvalidationNotification->addGenIDChangeListener(listener); |
- } |
- ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, result); |
- } |
- return result; |
-} |
- |
-// creates a new texture that is the input texture scaled up. If optionalKey is valid it will be |
-// set on the new texture. stretch controls whether the scaling is done using nearest or bilerp |
-// filtering and the size to stretch the texture to. |
-GrTexture* stretch_texture(GrTexture* inputTexture, const SkGrStretch& stretch, |
- SkPixelRef* pixelRef, |
- const GrUniqueKey& optionalKey) { |
- SkASSERT(SkGrStretch::kNone_Type != stretch.fType); |
- |
- 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 = stretch.fWidth; |
- rtDesc.fHeight = stretch.fHeight; |
- rtDesc.fConfig = GrMakePixelConfigUncompressed(rtDesc.fConfig); |
- |
- // If the config isn't renderable try converting to either A8 or an 32 bit config. Otherwise, |
- // fail. |
- if (!caps->isConfigRenderable(rtDesc.fConfig, false)) { |
- if (GrPixelConfigIsAlphaOnly(rtDesc.fConfig)) { |
- if (caps->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { |
- rtDesc.fConfig = kAlpha_8_GrPixelConfig; |
- } else if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) { |
- rtDesc.fConfig = kSkia8888_GrPixelConfig; |
- } else { |
- return nullptr; |
- } |
- } else if (kRGB_GrColorComponentFlags == |
- (kRGB_GrColorComponentFlags & GrPixelConfigComponentMask(rtDesc.fConfig))) { |
- if (caps->isConfigRenderable(kSkia8888_GrPixelConfig, false)) { |
- rtDesc.fConfig = kSkia8888_GrPixelConfig; |
- } else { |
- return nullptr; |
- } |
- } else { |
- return nullptr; |
- } |
- } |
- |
- SkAutoTUnref<GrTexture> stretched(GrCreateTextureForPixels(context, optionalKey, rtDesc, |
- pixelRef, nullptr,0)); |
- if (!stretched) { |
- return nullptr; |
- } |
- 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, |
- SkGrStretch::kBilerp_Type == stretch.fType ? |
- GrTextureParams::kBilerp_FilterMode : |
- GrTextureParams::kNone_FilterMode); |
- paint.addColorTextureProcessor(inputTexture, SkMatrix::I(), params); |
- |
- SkRect rect = SkRect::MakeWH(SkIntToScalar(rtDesc.fWidth), SkIntToScalar(rtDesc.fHeight)); |
- SkRect localRect = SkRect::MakeWH(1.f, 1.f); |
- |
- SkAutoTUnref<GrDrawContext> drawContext(context->drawContext(stretched->asRenderTarget())); |
- if (!drawContext) { |
- return nullptr; |
- } |
- |
- drawContext->drawNonAARectToRect(GrClip::WideOpen(), paint, SkMatrix::I(), rect, localRect); |
- |
- return stretched.detach(); |
-} |
- |
-/* |
+/** |
* Once we have made SkImages handle all lazy/deferred/generated content, the YUV apis will |
* be gone from SkPixelRef, and we can remove this subclass entirely. |
*/ |
@@ -350,33 +183,22 @@ public: |
} |
}; |
-static GrTexture* load_yuv_texture(GrContext* ctx, const GrUniqueKey& optionalKey, |
- const SkBitmap& bm, const GrSurfaceDesc& desc) { |
+static GrTexture* create_texture_from_yuv(GrContext* ctx, const SkBitmap& bm, |
+ const GrSurfaceDesc& desc) { |
// Subsets are not supported, the whole pixelRef is loaded when using YUV decoding |
SkPixelRef* pixelRef = bm.pixelRef(); |
if ((nullptr == pixelRef) || |
- (pixelRef->info().width() != bm.info().width()) || |
+ (pixelRef->info().width() != bm.info().width()) || |
(pixelRef->info().height() != bm.info().height())) { |
return nullptr; |
} |
- const bool useCache = optionalKey.isValid(); |
PixelRef_GrYUVProvider provider(pixelRef); |
- GrTexture* texture = provider.refAsTexture(ctx, desc, useCache); |
- if (!texture) { |
- return nullptr; |
- } |
- if (useCache) { |
- BitmapInvalidator* listener = new BitmapInvalidator(optionalKey); |
- pixelRef->addGenIDChangeListener(listener); |
- ctx->textureProvider()->assignUniqueKeyToTexture(optionalKey, texture); |
- } |
- return texture; |
+ return provider.refAsTexture(ctx, desc, !bm.isVolatile()); |
} |
-static GrTexture* load_etc1_texture(GrContext* ctx, const GrUniqueKey& optionalKey, |
- const SkBitmap &bm, GrSurfaceDesc desc) { |
+static GrTexture* load_etc1_texture(GrContext* ctx, const SkBitmap &bm, GrSurfaceDesc desc) { |
SkAutoTUnref<SkData> data(bm.pixelRef()->refEncodedData()); |
if (!data) { |
return nullptr; |
@@ -389,19 +211,19 @@ static GrTexture* load_etc1_texture(GrContext* ctx, const GrUniqueKey& optionalK |
return nullptr; |
} |
- return GrCreateTextureForPixels(ctx, optionalKey, desc, bm.pixelRef(), startOfTexData, 0); |
+ return ctx->textureProvider()->createTexture(desc, true, startOfTexData, 0); |
} |
-static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, |
- const SkBitmap& origBitmap, |
- const GrUniqueKey& optionalKey) { |
- if (origBitmap.width() < ctx->caps()->minTextureSize() || |
- origBitmap.height() < ctx->caps()->minTextureSize()) { |
+GrTexture* GrUploadBitmapToTexture(GrContext* ctx, const SkBitmap& bmp) { |
+ SkASSERT(!bmp.getTexture()); |
+ |
+ if (bmp.width() < ctx->caps()->minTextureSize() || |
+ bmp.height() < ctx->caps()->minTextureSize()) { |
return nullptr; |
} |
- SkBitmap tmpBitmap; |
- const SkBitmap* bitmap = &origBitmap; |
+ SkBitmap tmpBitmap; |
+ const SkBitmap* bitmap = &bmp; |
GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap->info()); |
const GrCaps* caps = ctx->caps(); |
@@ -411,14 +233,14 @@ static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, |
size_t imageSize = GrCompressedFormatDataSize(kIndex_8_GrPixelConfig, |
bitmap->width(), bitmap->height()); |
SkAutoMalloc storage(imageSize); |
- build_index8_data(storage.get(), origBitmap); |
+ build_index8_data(storage.get(), bmp); |
// our compressed data will be trimmed, so pass width() for its |
// "rowBytes", since they are the same now. |
- return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.pixelRef(), |
- storage.get(), bitmap->width()); |
+ return ctx->textureProvider()->createTexture(desc, true, storage.get(), |
+ bitmap->width()); |
} else { |
- origBitmap.copyTo(&tmpBitmap, kN32_SkColorType); |
+ bmp.copyTo(&tmpBitmap, kN32_SkColorType); |
// now bitmap points to our temp, which has been promoted to 32bits |
bitmap = &tmpBitmap; |
desc.fConfig = SkImageInfo2GrPixelConfig(bitmap->info()); |
@@ -428,13 +250,16 @@ static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, |
// compressed data on 'refEncodedData' and upload it. Probably not good, since if |
// the bitmap has available pixels, then they might not be what the decompressed |
// data is. |
- GrTexture *texture = load_etc1_texture(ctx, optionalKey, *bitmap, desc); |
+ |
+ // Really?? We aren't doing this with YUV. |
+ |
+ GrTexture *texture = load_etc1_texture(ctx, *bitmap, desc); |
if (texture) { |
return texture; |
} |
} |
- GrTexture *texture = load_yuv_texture(ctx, optionalKey, *bitmap, desc); |
+ GrTexture *texture = create_texture_from_yuv(ctx, *bitmap, desc); |
if (texture) { |
return texture; |
} |
@@ -444,83 +269,92 @@ static GrTexture* create_unstretched_bitmap_texture(GrContext* ctx, |
return nullptr; |
} |
- return GrCreateTextureForPixels(ctx, optionalKey, desc, origBitmap.pixelRef(), |
- bitmap->getPixels(), bitmap->rowBytes()); |
+ return ctx->textureProvider()->createTexture(desc, true, bitmap->getPixels(), |
+ bitmap->rowBytes()); |
} |
-static SkBitmap stretch_on_cpu(const SkBitmap& bmp, const SkGrStretch& stretch) { |
- SkBitmap stretched; |
- stretched.allocN32Pixels(stretch.fWidth, stretch.fHeight); |
- SkCanvas canvas(stretched); |
- SkPaint paint; |
- switch (stretch.fType) { |
- case SkGrStretch::kNearest_Type: |
- paint.setFilterQuality(kNone_SkFilterQuality); |
- break; |
- case SkGrStretch::kBilerp_Type: |
- paint.setFilterQuality(kLow_SkFilterQuality); |
- break; |
- case SkGrStretch::kNone_Type: |
- SkDEBUGFAIL("Shouldn't get here."); |
- break; |
- } |
- SkRect dstRect = SkRect::MakeWH(SkIntToScalar(stretch.fWidth), SkIntToScalar(stretch.fHeight)); |
- canvas.drawBitmapRect(bmp, dstRect, &paint); |
- return stretched; |
-} |
-class Bitmap_GrTextureMaker : public GrTextureMaker { |
+//////////////////////////////////////////////////////////////////////////////// |
+ |
+class Bitmap_GrTextureParamsAdjuster : public GrTextureParamsAdjuster { |
public: |
- Bitmap_GrTextureMaker(const SkBitmap& bitmap) |
+ Bitmap_GrTextureParamsAdjuster(const SkBitmap& bitmap) |
: INHERITED(bitmap.width(), bitmap.height()) |
, fBitmap(bitmap) |
- {} |
+ { |
+ if (!bitmap.isVolatile()) { |
+ SkIPoint origin = bitmap.pixelRefOrigin(); |
+ SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.width(), |
+ bitmap.height()); |
+ GrMakeKeyFromImageID(&fOriginalKey, bitmap.pixelRef()->getGenerationID(), subset); |
+ } |
+ } |
protected: |
- GrTexture* onRefUnstretchedTexture(GrContext* ctx) override { |
+ GrTexture* peekOriginalTexture() override { return fBitmap.getTexture(); } |
+ |
+ GrTexture* refOriginalTexture(GrContext* ctx) override { |
GrTexture* tex = fBitmap.getTexture(); |
if (tex) { |
return SkRef(tex); |
} |
- GrUniqueKey unstretchedKey; |
- make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap.getSubset()); |
+ if (fOriginalKey.isValid()) { |
+ tex = ctx->textureProvider()->findAndRefTextureByUniqueKey(fOriginalKey); |
+ if (tex) { |
+ return tex; |
+ } |
+ } |
- GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey(unstretchedKey); |
- if (result) { |
- return result; |
+ tex = GrUploadBitmapToTexture(ctx, fBitmap); |
+ if (tex && fOriginalKey.isValid()) { |
+ tex->resourcePriv().setUniqueKey(fOriginalKey); |
+ InstallInvalidator(fOriginalKey, fBitmap.pixelRef()); |
} |
- return create_unstretched_bitmap_texture(ctx, fBitmap, unstretchedKey); |
+ return tex; |
} |
- bool onMakeStretchedKey(const SkGrStretch& stretch, GrUniqueKey* stretchedKey) override { |
- if (fBitmap.isVolatile()) { |
- return false; |
+ void makeCopyKey(const CopyParams& copyParams, GrUniqueKey* copyKey) override { |
+ if (fOriginalKey.isValid()) { |
+ MakeCopyKeyFromOrigKey(fOriginalKey, copyParams, copyKey); |
} |
- |
- GrUniqueKey unstretchedKey; |
- make_unstretched_key(&unstretchedKey, fBitmap.getGenerationID(), fBitmap.getSubset()); |
- return GrMakeStretchedKey(unstretchedKey, stretch, stretchedKey); |
} |
- void onNotifyStretchCached(const GrUniqueKey& stretchedKey) override { |
- fBitmap.pixelRef()->addGenIDChangeListener(new BitmapInvalidator(stretchedKey)); |
+ void didCacheCopy(const GrUniqueKey& copyKey) override { |
+ InstallInvalidator(copyKey, fBitmap.pixelRef()); |
} |
- bool onGetROBitmap(SkBitmap* bitmap) override { |
+ bool getROBitmap(SkBitmap* bitmap) override { |
+ SkASSERT(!fBitmap.getTexture()); |
*bitmap = fBitmap; |
return true; |
} |
private: |
- const SkBitmap fBitmap; |
+ 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 GrTextureMaker INHERITED; |
+ typedef GrTextureParamsAdjuster INHERITED; |
}; |
GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, |
const GrTextureParams& params) { |
- return Bitmap_GrTextureMaker(bitmap).refCachedTexture(ctx, params); |
+ return Bitmap_GrTextureParamsAdjuster(bitmap).refTextureForParams(ctx, params); |
} |
/////////////////////////////////////////////////////////////////////////////// |
@@ -592,7 +426,6 @@ bool GrPixelConfig2ColorAndProfileType(GrPixelConfig config, SkColorType* ctOut, |
return true; |
} |
- |
//////////////////////////////////////////////////////////////////////////////////////////////// |
static inline bool blend_requires_shader(const SkXfermode::Mode mode, bool primitiveIsSrc) { |
@@ -842,54 +675,3 @@ GrTextureParams::FilterMode GrSkFilterQualityToGrFilterMode(SkFilterQuality pain |
} |
return textureFilterMode; |
} |
- |
-//////////////////////////////////////////////////////////////////////////////////////////////// |
- |
-GrTexture* GrTextureMaker::refCachedTexture(GrContext* ctx, const GrTextureParams& params) { |
- SkGrStretch stretch; |
- get_stretch(*ctx->caps(), this->width(), this->height(), params, &stretch); |
- |
- if (SkGrStretch::kNone_Type == stretch.fType) { |
- return this->onRefUnstretchedTexture(ctx); |
- } |
- |
- GrUniqueKey stretchedKey; |
- if (this->onMakeStretchedKey(stretch, &stretchedKey)) { |
- GrTexture* result = ctx->textureProvider()->findAndRefTextureByUniqueKey(stretchedKey); |
- if (result) { |
- return result; |
- } |
- } |
- |
- GrTexture* result = this->onGenerateStretchedTexture(ctx, stretch); |
- if (!result) { |
- return nullptr; |
- } |
- |
- if (stretchedKey.isValid()) { |
- ctx->textureProvider()->assignUniqueKeyToTexture(stretchedKey, result); |
- this->onNotifyStretchCached(stretchedKey); |
- } |
- return result; |
-} |
- |
-GrTexture* GrTextureMaker::onGenerateStretchedTexture(GrContext* ctx, const SkGrStretch& stretch) { |
- if (this->width() < ctx->caps()->minTextureSize() || |
- this->height() < ctx->caps()->minTextureSize()) |
- { |
- // we can't trust our ability to use HW to perform the stretch, so we request |
- // a raster instead, and perform the stretch on the CPU. |
- SkBitmap bitmap; |
- if (!this->onGetROBitmap(&bitmap)) { |
- return nullptr; |
- } |
- SkBitmap stretchedBmp = stretch_on_cpu(bitmap, stretch); |
- return create_unstretched_bitmap_texture(ctx, stretchedBmp, GrUniqueKey()); |
- } else { |
- SkAutoTUnref<GrTexture> unstretched(this->onRefUnstretchedTexture(ctx)); |
- if (!unstretched) { |
- return nullptr; |
- } |
- return stretch_texture(unstretched, stretch, nullptr, GrUniqueKey()); |
- } |
-} |