GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap, const GrTextureParams* params) { Stretch stretch; get_stretch(ctx, bitmap.width(), bitmap.height(), params, &stretch); GrTexture* result = bitmap.getTexture(); if (result) { if (Stretch::kNone_Type == stretch.fType) { return SkRef(result); } GrUniqueKey stretchedKey; // Don't create a key for the resized version if the bmp is volatile. if (!bitmap.isVolatile()) { const GrUniqueKey& key = result->getUniqueKey(); if (key.isValid()) { make_stretched_key(key, stretch, &stretchedKey); GrTexture* stretched = ctx->textureProvider()->findAndRefTextureByUniqueKey(stretchedKey); if (stretched) { return stretched; } } } return stretch_texture(result, stretch, bitmap.pixelRef(), stretchedKey); } GrUniqueKey key, resizedKey; if (!bitmap.isVolatile()) { // If the bitmap isn't changing try to find a cached copy first. make_bitmap_keys(bitmap, stretch, &key, &resizedKey); result = ctx->textureProvider()->findAndRefTextureByUniqueKey( resizedKey.isValid() ? resizedKey : key); if (result) { return result; } } result = create_bitmap_texture(ctx, bitmap, stretch, key, resizedKey); if (result) { return result; } SkErrorInternals::SetError( kInternalError_SkError, "---- failed to create texture for cache [%d %d]\n", bitmap.width(), bitmap.height()); return NULL; }
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()); } }
static GrTexture* create_bitmap_texture(GrContext* ctx, const SkBitmap& bmp, const Stretch& stretch, const GrUniqueKey& unstretchedKey, const GrUniqueKey& stretchedKey) { if (Stretch::kNone_Type != stretch.fType) { SkAutoTUnref<GrTexture> unstretched; // Check if we have the unstretched version in the cache, if not create it. if (unstretchedKey.isValid()) { unstretched.reset(ctx->textureProvider()->findAndRefTextureByUniqueKey(unstretchedKey)); } if (!unstretched) { unstretched.reset(create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey)); if (!unstretched) { // We might not have been able to create a unstrecthed texture because it is smaller // than the min texture size. In that case do cpu stretching. SkBitmap stretchedBmp = stretch_on_cpu(bmp, stretch); return create_unstretched_bitmap_texture(ctx, stretchedBmp, stretchedKey); } } return stretch_texture(unstretched, stretch, bmp.pixelRef(), stretchedKey); } return create_unstretched_bitmap_texture(ctx, bmp, unstretchedKey); }