Move GrMakeCachedBitmapProxy work in lazy mode

This basically wraps the bitmap in an SkImage and uses the GrMakeCachedImageProxy
call to create the proxy.

Bug: skia:
Change-Id: I648a9cac3a316231bfb1bcedaae2009b7de0356c
Reviewed-on: https://skia-review.googlesource.com/105360
Commit-Queue: Greg Daniel <egdaniel@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
This commit is contained in:
Greg Daniel 2018-02-08 09:15:33 -05:00 committed by Skia Commit-Bot
parent aee01c2985
commit 7e1912a8ab
5 changed files with 80 additions and 72 deletions

View File

@ -341,8 +341,8 @@ sk_sp<GrTextureProxy> GrProxyProvider::createMipMapProxyFromBitmap(const SkBitma
// In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap
// even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the
// upload of the data to the gpu can happen at anytime and the bitmap may change by then.
SkCopyPixelsMode copyMode = fResourceProvider ? kNever_SkCopyPixelsMode
: kIfMutable_SkCopyPixelsMode;
SkCopyPixelsMode copyMode = this->mutableBitmapsNeedCopy() ? kIfMutable_SkCopyPixelsMode
: kNever_SkCopyPixelsMode;
sk_sp<SkImage> baseLevel = SkMakeImageFromRasterBitmap(bitmap, copyMode);
if (!baseLevel) {

View File

@ -228,6 +228,12 @@ public:
void removeAllUniqueKeys();
/**
* Helper function for callers who are wrapping a bitmap into an SkImage so they know whether or
* not that bitmap should be copied or not.
*/
bool mutableBitmapsNeedCopy() const { return !SkToBool(fResourceProvider); }
private:
friend class GrAHardwareBufferImageGenerator; // for createWrapped

View File

@ -25,6 +25,7 @@
#include "SkData.h"
#include "SkImage_Base.h"
#include "SkImageInfoPriv.h"
#include "SkImagePriv.h"
#include "SkMaskFilterBase.h"
#include "SkMessageBus.h"
#include "SkMipMap.h"
@ -167,33 +168,24 @@ sk_sp<GrTextureProxy> GrRefCachedBitmapTextureProxy(GrContext* ctx,
}
sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider* proxyProvider,
const SkBitmap& bitmap) {
GrUniqueKey originalKey;
if (!bitmap.isVolatile()) {
SkIPoint origin = bitmap.pixelRefOrigin();
SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.width(), bitmap.height());
GrMakeKeyFromImageID(&originalKey, bitmap.pixelRef()->getGenerationID(), subset);
const SkBitmap& bitmap,
SkBackingFit fit) {
if (!bitmap.peekPixels(nullptr)) {
return nullptr;
}
sk_sp<GrTextureProxy> proxy;
// In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap
// even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the
// upload of the data to the gpu can happen at anytime and the bitmap may change by then.
SkCopyPixelsMode cpyMode = proxyProvider->mutableBitmapsNeedCopy() ? kIfMutable_SkCopyPixelsMode
: kNever_SkCopyPixelsMode;
sk_sp<SkImage> image = SkMakeImageFromRasterBitmap(bitmap, cpyMode);
if (originalKey.isValid()) {
proxy = proxyProvider->findOrCreateProxyByUniqueKey(originalKey, kTopLeft_GrSurfaceOrigin);
}
if (!proxy) {
// Pass nullptr for |dstColorSpace|. This is lenient - we allow a wider range of
// color spaces in legacy mode. Unfortunately, we have to be lenient here, since
// we can't necessarily know the |dstColorSpace| at this time.
proxy = GrUploadBitmapToTextureProxy(proxyProvider, bitmap, nullptr);
if (proxy && originalKey.isValid()) {
SkASSERT(proxy->origin() == kTopLeft_GrSurfaceOrigin);
proxyProvider->assignUniqueKeyToProxy(originalKey, proxy.get());
GrInstallBitmapUniqueKeyInvalidator(originalKey, bitmap.pixelRef());
}
if (!image) {
return nullptr;
}
return proxy;
return GrMakeCachedImageProxy(proxyProvider, std::move(image), fit);
}
static void create_unique_key_for_image(const SkImage* image, GrUniqueKey* result) {

View File

@ -228,18 +228,12 @@ sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrProxyProvider*, const SkIma
int mipLevelCount,
SkDestinationSurfaceColorMode colorMode);
// This is intended to replace:
// SkAutoLockPixels alp(bitmap, true);
// if (!bitmap.readyToDraw()) {
// return nullptr;
// }
// sk_sp<GrTexture> texture = GrMakeCachedBitmapTexture(fContext.get(), bitmap,
// GrSamplerState::ClampNearest(),
// nullptr);
// if (!texture) {
// return nullptr;
// }
sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider*, const SkBitmap& bitmap);
/*
* Create a texture proxy from the provided bitmap by wrapping it in an image and calling
* GrMakeCachedImageProxy.
*/
sk_sp<GrTextureProxy> GrMakeCachedBitmapProxy(GrProxyProvider*, const SkBitmap& bitmap,
SkBackingFit fit = SkBackingFit::kExact);
/*
* Create a texture proxy from the provided 'srcImage' and add it to the texture cache

View File

@ -12,10 +12,10 @@
#include "SkColorFilter.h"
#include "SkMakeUnique.h"
#include "SkReadBuffer.h"
#include "SkWriteBuffer.h"
#include "SkShader.h"
#include "SkUnPreMultiply.h"
#include "SkString.h"
#include "SkUnPreMultiply.h"
#include "SkWriteBuffer.h"
#if SK_SUPPORT_GPU
#include "GrContext.h"
@ -107,16 +107,19 @@ public:
}
#if SK_SUPPORT_GPU
fPermutationsBitmap.setInfo(SkImageInfo::MakeA8(kBlockSize, 1));
fPermutationsBitmap.setPixels(fLatticeSelector);
SkImageInfo info = SkImageInfo::MakeA8(kBlockSize, 1);
SkPixmap permutationsPixmap(info, fLatticeSelector, info.minRowBytes());
fPermutationsImage = SkImage::MakeFromRaster(permutationsPixmap, nullptr, nullptr);
fNoiseBitmap.setInfo(SkImageInfo::MakeN32Premul(kBlockSize, 4));
fNoiseBitmap.setPixels(fNoise[0][0]);
info = SkImageInfo::MakeN32Premul(kBlockSize, 4);
SkPixmap noisePixmap(info, fNoise[0][0], info.minRowBytes());
fNoiseImage = SkImage::MakeFromRaster(noisePixmap, nullptr, nullptr);
fImprovedPermutationsBitmap.setInfo(SkImageInfo::MakeA8(256, 1));
fImprovedPermutationsBitmap.setPixels(improved_noise_permutations);
info = SkImageInfo::MakeA8(256, 1);
SkPixmap impPermutationsPixmap(info, improved_noise_permutations, info.minRowBytes());
fImprovedPermutationsImage = SkImage::MakeFromRaster(impPermutationsPixmap, nullptr,
nullptr);
fGradientBitmap.setInfo(SkImageInfo::MakeN32Premul(16, 1));
static uint8_t gradients[] = { 2, 2, 1, 0,
0, 2, 1, 0,
2, 0, 1, 0,
@ -133,7 +136,9 @@ public:
1, 0, 2, 0,
0, 2, 1, 0,
1, 0, 0, 0 };
fGradientBitmap.setPixels(gradients);
info = SkImageInfo::MakeN32Premul(16, 1);
SkPixmap gradPixmap(info, gradients, info.minRowBytes());
fGradientImage = SkImage::MakeFromRaster(gradPixmap, nullptr, nullptr);
#endif
}
@ -143,10 +148,10 @@ public:
, fTileSize(that.fTileSize)
, fBaseFrequency(that.fBaseFrequency)
, fStitchDataInit(that.fStitchDataInit)
, fPermutationsBitmap(that.fPermutationsBitmap)
, fNoiseBitmap(that.fNoiseBitmap)
, fImprovedPermutationsBitmap(that.fImprovedPermutationsBitmap)
, fGradientBitmap(that.fGradientBitmap) {
, fPermutationsImage(that.fPermutationsImage)
, fNoiseImage(that.fNoiseImage)
, fImprovedPermutationsImage(that.fImprovedPermutationsImage)
, fGradientImage(that.fGradientImage) {
memcpy(fLatticeSelector, that.fLatticeSelector, sizeof(fLatticeSelector));
memcpy(fNoise, that.fNoise, sizeof(fNoise));
memcpy(fGradient, that.fGradient, sizeof(fGradient));
@ -164,10 +169,10 @@ public:
private:
#if SK_SUPPORT_GPU
SkBitmap fPermutationsBitmap;
SkBitmap fNoiseBitmap;
SkBitmap fImprovedPermutationsBitmap;
SkBitmap fGradientBitmap;
sk_sp<SkImage> fPermutationsImage;
sk_sp<SkImage> fNoiseImage;
sk_sp<SkImage> fImprovedPermutationsImage;
sk_sp<SkImage> fGradientImage;
#endif
inline int random() {
@ -294,13 +299,15 @@ public:
public:
#if SK_SUPPORT_GPU
const SkBitmap& getPermutationsBitmap() const { return fPermutationsBitmap; }
const sk_sp<SkImage> getPermutationsImage() const { return fPermutationsImage; }
const SkBitmap& getNoiseBitmap() const { return fNoiseBitmap; }
const sk_sp<SkImage> getNoiseImage() const { return fNoiseImage; }
const SkBitmap& getImprovedPermutationsBitmap() const { return fImprovedPermutationsBitmap; }
const sk_sp<SkImage> getImprovedPermutationsImage() const {
return fImprovedPermutationsImage;
}
const SkBitmap& getGradientBitmap() const { return fGradientBitmap; }
const sk_sp<SkImage> getGradientImage() const { return fGradientImage; }
#endif
};
@ -1409,17 +1416,20 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso
m.setTranslateX(-localMatrix.getTranslateX() + SK_Scalar1);
m.setTranslateY(-localMatrix.getTranslateY() + SK_Scalar1);
auto proxyProvider = args.fContext->contextPriv().proxyProvider();
if (fType == kImprovedNoise_Type) {
GrSamplerState textureParams(GrSamplerState::WrapMode::kRepeat,
GrSamplerState::Filter::kNearest);
// Need to assert that the textures we'll create are power of 2 so a copy isn't needed.
// We also know that we will not be using mipmaps. If things things weren't true we should
// go through GrBitmapTextureMaker to handle needed copies.
const sk_sp<SkImage> permutationsImage = paintingData->getImprovedPermutationsImage();
SkASSERT(SkIsPow2(permutationsImage->width()) && SkIsPow2(permutationsImage->height()));
sk_sp<GrTextureProxy> permutationsTexture(
GrRefCachedBitmapTextureProxy(args.fContext,
paintingData->getImprovedPermutationsBitmap(),
textureParams, nullptr));
GrMakeCachedImageProxy(proxyProvider, std::move(permutationsImage)));
const sk_sp<SkImage> gradientImage = paintingData->getGradientImage();
SkASSERT(SkIsPow2(gradientImage->width()) && SkIsPow2(gradientImage->height()));
sk_sp<GrTextureProxy> gradientTexture(
GrRefCachedBitmapTextureProxy(args.fContext,
paintingData->getGradientBitmap(),
textureParams, nullptr));
GrMakeCachedImageProxy(proxyProvider, std::move(gradientImage)));
return GrImprovedPerlinNoiseEffect::Make(fNumOctaves, fSeed, std::move(paintingData),
std::move(permutationsTexture),
std::move(gradientTexture), m);
@ -1441,12 +1451,18 @@ std::unique_ptr<GrFragmentProcessor> SkPerlinNoiseShaderImpl::asFragmentProcesso
GrConstColorProcessor::InputMode::kIgnore);
}
sk_sp<GrTextureProxy> permutationsProxy = GrMakeCachedBitmapProxy(
args.fContext->contextPriv().proxyProvider(),
paintingData->getPermutationsBitmap());
sk_sp<GrTextureProxy> noiseProxy = GrMakeCachedBitmapProxy(
args.fContext->contextPriv().proxyProvider(),
paintingData->getNoiseBitmap());
// Need to assert that the textures we'll create are power of 2 so that now copy is needed. We
// also know that we will not be using mipmaps. If things things weren't true we should go
// through GrBitmapTextureMaker to handle needed copies.
const sk_sp<SkImage> permutationsImage = paintingData->getPermutationsImage();
SkASSERT(SkIsPow2(permutationsImage->width()) && SkIsPow2(permutationsImage->height()));
sk_sp<GrTextureProxy> permutationsProxy = GrMakeCachedImageProxy(proxyProvider,
std::move(permutationsImage));
const sk_sp<SkImage> noiseImage = paintingData->getNoiseImage();
SkASSERT(SkIsPow2(noiseImage->width()) && SkIsPow2(noiseImage->height()));
sk_sp<GrTextureProxy> noiseProxy = GrMakeCachedImageProxy(proxyProvider,
std::move(noiseImage));
if (permutationsProxy && noiseProxy) {
auto inner = GrPerlinNoise2Effect::Make(fType,