Add SkBudgeted parameter to SkImage::makeTextureImage().
Also strengthens/adds some guarantees about this function:
* Always returns the same image if the original is texture-backed and
compatible with GrMipMapped (WRT HW MIP support)
* If a new texture backed image is returned it is always an uncached
texture that is not shared with another image or owned by an image
generator.
Adds a GrImageTexGenPolicy that allows control through image/bitmap
GrTextureProducers of whether a new texture must be made and whether
that texture should be budgeted or not.
Increases unit test coverage of this API.
Bug: skia:8669
Change-Id: Ifc0681856114a08fc8cfc57ca83d22efb1c1f166
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/274938
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/RELEASE_NOTES.txt b/RELEASE_NOTES.txt
index 74c0bb2..c34c846 100644
--- a/RELEASE_NOTES.txt
+++ b/RELEASE_NOTES.txt
@@ -7,6 +7,7 @@
Milestone 83
<Insert new notes here- top is most recent.>
+ * SkImage::makeTextureImage() takes an optional SkBudgeted param
*
diff --git a/gm/fpcoordinateoverride.cpp b/gm/fpcoordinateoverride.cpp
index a16d2fa..e5c1032 100644
--- a/gm/fpcoordinateoverride.cpp
+++ b/gm/fpcoordinateoverride.cpp
@@ -82,7 +82,7 @@
SkBitmap bmp;
GetResourceAsBitmap("images/mandrill_512_q075.jpg", &bmp);
- GrBitmapTextureMaker maker(ctx, bmp);
+ GrBitmapTextureMaker maker(ctx, bmp, GrImageTexGenPolicy::kDraw);
auto view = maker.view(GrMipMapped::kNo);
if (!view) {
return;
diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp
index 36adfbf..629eeea 100644
--- a/gm/image_pict.cpp
+++ b/gm/image_pict.cpp
@@ -184,7 +184,8 @@
}
protected:
GrSurfaceProxyView onGenerateTexture(GrRecordingContext* ctx, const SkImageInfo& info,
- const SkIPoint& origin, GrMipMapped mipMapped) override {
+ const SkIPoint& origin, GrMipMapped mipMapped,
+ GrImageTexGenPolicy) override {
SkASSERT(ctx);
SkASSERT(ctx == fCtx.get());
diff --git a/gm/texelsubset.cpp b/gm/texelsubset.cpp
index 121b103..d957403 100644
--- a/gm/texelsubset.cpp
+++ b/gm/texelsubset.cpp
@@ -80,7 +80,7 @@
GrMipMapped mipMapped = fFilter == GrSamplerState::Filter::kMipMap &&
context->priv().caps()->mipMapSupport()
? GrMipMapped::kYes : GrMipMapped::kNo;
- GrBitmapTextureMaker maker(context, fBitmap);
+ GrBitmapTextureMaker maker(context, fBitmap, GrImageTexGenPolicy::kDraw);
auto view = maker.view(mipMapped);
if (!view) {
*errorMsg = "Failed to create proxy.";
@@ -114,7 +114,7 @@
SkBitmap subsetBmp;
fBitmap.extractSubset(&subsetBmp, texelSubset);
subsetBmp.setImmutable();
- GrBitmapTextureMaker subsetMaker(context, subsetBmp);
+ GrBitmapTextureMaker subsetMaker(context, subsetBmp, GrImageTexGenPolicy::kDraw);
auto subsetView = subsetMaker.view(mipMapped);
SkRect localRect = SkRect::Make(fBitmap.bounds()).makeOutset(kDrawPad, kDrawPad);
diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp
index 7e3ffda..25f8c4c 100644
--- a/gm/yuvtorgbeffect.cpp
+++ b/gm/yuvtorgbeffect.cpp
@@ -98,7 +98,7 @@
GrSurfaceProxyView views[3];
for (int i = 0; i < 3; ++i) {
- GrBitmapTextureMaker maker(context, fBitmaps[i]);
+ GrBitmapTextureMaker maker(context, fBitmaps[i], GrImageTexGenPolicy::kDraw);
views[i] = maker.view(GrMipMapped::kNo);
if (!views[i]) {
*errorMsg = "Failed to create proxy";
@@ -214,7 +214,7 @@
GrSurfaceProxyView views[2];
for (int i = 0; i < 2; ++i) {
- GrBitmapTextureMaker maker(context, fBitmaps[i]);
+ GrBitmapTextureMaker maker(context, fBitmaps[i], GrImageTexGenPolicy::kDraw);
views[i] = maker.view(GrMipMapped::kNo);
if (!views[i]) {
*errorMsg = "Failed to create proxy";
@@ -315,7 +315,7 @@
GrSurfaceProxyView views[3];
for (int i = 0; i < 3; ++i) {
- GrBitmapTextureMaker maker(context, fBitmaps[i]);
+ GrBitmapTextureMaker maker(context, fBitmaps[i], GrImageTexGenPolicy::kDraw);
views[i] = maker.view(GrMipMapped::kNo);
if (!views[i]) {
*errorMsg = "Failed to create proxy";
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index 5073fe6..db88539 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -1035,18 +1035,26 @@
/** Returns SkImage backed by GPU texture associated with context. Returned SkImage is
compatible with SkSurface created with dstColorSpace. The returned SkImage respects
mipMapped setting; if mipMapped equals GrMipMapped::kYes, the backing texture
- allocates mip map levels. Returns original SkImage if context
- and dstColorSpace match and mipMapped is compatible with backing GPU texture.
+ allocates mip map levels.
+
+ The mipMapped parameter is effectively treated as kNo if MIP maps are not supported by the
+ GPU.
+
+ Returns original SkImage if the image is already texture-backed, the context matches, and
+ mipMapped is compatible with the backing GPU texture. SkBudgeted is ignored in this case.
Returns nullptr if context is nullptr, or if SkImage was created with another
GrContext.
- @param context GPU context
- @param dstColorSpace range of colors of matching SkSurface on GPU
- @param mipMapped whether created SkImage texture must allocate mip map levels
+ @param GrContext GPU context
+ @param GrMipMapped whether created SkImage texture must allocate mip map levels
+ @param SkBudgeted whether to count a newly created texture for the returned image
+ counts against the GrContext's budget.
@return created SkImage, or nullptr
*/
- sk_sp<SkImage> makeTextureImage(GrContext* context, GrMipMapped = GrMipMapped::kNo) const;
+ sk_sp<SkImage> makeTextureImage(GrContext*,
+ GrMipMapped = GrMipMapped::kNo,
+ SkBudgeted = SkBudgeted::kYes) const;
/** Returns raster image or lazy image. Copies SkImage backed by GPU texture into
CPU memory if needed. Returns original SkImage if decoded in raster bitmap,
diff --git a/include/core/SkImageGenerator.h b/include/core/SkImageGenerator.h
index abc6d89..2929314 100644
--- a/include/core/SkImageGenerator.h
+++ b/include/core/SkImageGenerator.h
@@ -24,6 +24,8 @@
class SkPaint;
class SkPicture;
+enum class GrImageTexGenPolicy : int;
+
class SK_API SkImageGenerator {
public:
/**
@@ -138,9 +140,13 @@
* at least has the mip levels allocated and the base layer filled in. If this is not possible,
* the generator is allowed to return a non mipped proxy, but this will have some additional
* overhead in later allocating mips and copying of the base layer.
+ *
+ * GrImageTexGenPolicy determines whether or not a new texture must be created (and its budget
+ * status) or whether this may (but is not required to) return a pre-existing texture that is
+ * retained by the generator (kDraw).
*/
GrSurfaceProxyView generateTexture(GrRecordingContext*, const SkImageInfo& info,
- const SkIPoint& origin, GrMipMapped);
+ const SkIPoint& origin, GrMipMapped, GrImageTexGenPolicy);
#endif
@@ -175,14 +181,9 @@
virtual bool onGetYUVA8Planes(const SkYUVASizeInfo&, const SkYUVAIndex[SkYUVAIndex::kIndexCount],
void*[4] /*planes*/) { return false; }
#if SK_SUPPORT_GPU
- enum class TexGenType {
- kNone, //image generator does not implement onGenerateTexture
- kCheap, //onGenerateTexture is implemented and it is fast (does not render offscreen)
- kExpensive, //onGenerateTexture is implemented and it is relatively slow
- };
-
+ // returns nullptr
virtual GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&,
- const SkIPoint&, GrMipMapped); // returns nullptr
+ const SkIPoint&, GrMipMapped, GrImageTexGenPolicy);
#endif
private:
diff --git a/src/core/SkImageGenerator.cpp b/src/core/SkImageGenerator.cpp
index 66e1e4c..50a3100 100644
--- a/src/core/SkImageGenerator.cpp
+++ b/src/core/SkImageGenerator.cpp
@@ -64,18 +64,20 @@
GrSurfaceProxyView SkImageGenerator::generateTexture(GrRecordingContext* ctx,
const SkImageInfo& info,
const SkIPoint& origin,
- GrMipMapped mipMapped) {
+ GrMipMapped mipMapped,
+ GrImageTexGenPolicy texGenPolicy) {
SkIRect srcRect = SkIRect::MakeXYWH(origin.x(), origin.y(), info.width(), info.height());
if (!SkIRect::MakeWH(fInfo.width(), fInfo.height()).contains(srcRect)) {
return {};
}
- return this->onGenerateTexture(ctx, info, origin, mipMapped);
+ return this->onGenerateTexture(ctx, info, origin, mipMapped, texGenPolicy);
}
GrSurfaceProxyView SkImageGenerator::onGenerateTexture(GrRecordingContext*,
const SkImageInfo&,
const SkIPoint&,
- GrMipMapped) {
+ GrMipMapped,
+ GrImageTexGenPolicy) {
return {};
}
#endif
diff --git a/src/core/SkPictureImageGenerator.cpp b/src/core/SkPictureImageGenerator.cpp
index 7344d60..fac6c89 100644
--- a/src/core/SkPictureImageGenerator.cpp
+++ b/src/core/SkPictureImageGenerator.cpp
@@ -12,6 +12,7 @@
#include "include/core/SkPicture.h"
#include "include/core/SkSurface.h"
#include "src/core/SkTLazy.h"
+#include "src/gpu/SkGr.h"
#include "src/image/SkImage_Base.h"
class SkPictureImageGenerator : public SkImageGenerator {
@@ -25,7 +26,7 @@
#if SK_SUPPORT_GPU
GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&, const SkIPoint&,
- GrMipMapped) override;
+ GrMipMapped, GrImageTexGenPolicy) override;
#endif
private:
@@ -96,13 +97,17 @@
GrSurfaceProxyView SkPictureImageGenerator::onGenerateTexture(GrRecordingContext* ctx,
const SkImageInfo& info,
const SkIPoint& origin,
- GrMipMapped mipMapped) {
+ GrMipMapped mipMapped,
+ GrImageTexGenPolicy texGenPolicy) {
SkASSERT(ctx);
SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+ SkBudgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
+ ? SkBudgeted::kNo
+ : SkBudgeted::kYes;
// CONTEXT TODO: remove this use of 'backdoor' to create an SkSkSurface
- auto surface = SkSurface::MakeRenderTarget(ctx->priv().backdoor(), SkBudgeted::kYes, info, 0,
+ auto surface = SkSurface::MakeRenderTarget(ctx->priv().backdoor(), budgeted, info, 0,
kTopLeft_GrSurfaceOrigin, &props,
mipMapped == GrMipMapped::kYes);
if (!surface) {
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.cpp b/src/gpu/GrAHardwareBufferImageGenerator.cpp
index 174fb35..4062e8f 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.cpp
+++ b/src/gpu/GrAHardwareBufferImageGenerator.cpp
@@ -31,6 +31,7 @@
#include "src/gpu/GrResourceProviderPriv.h"
#include "src/gpu/GrTexture.h"
#include "src/gpu/GrTextureProxy.h"
+#include "src/gpu/SkGr.h"
#include "src/gpu/gl/GrGLDefines.h"
#include <EGL/egl.h>
@@ -186,28 +187,33 @@
return GrSurfaceProxyView(std::move(texProxy), fSurfaceOrigin, readSwizzle);
}
-GrSurfaceProxyView GrAHardwareBufferImageGenerator::onGenerateTexture(GrRecordingContext* context,
- const SkImageInfo& info,
- const SkIPoint& origin,
- GrMipMapped mipMapped) {
+GrSurfaceProxyView GrAHardwareBufferImageGenerator::onGenerateTexture(
+ GrRecordingContext* context,
+ const SkImageInfo& info,
+ const SkIPoint& origin,
+ GrMipMapped mipMapped,
+ GrImageTexGenPolicy texGenPolicy) {
GrSurfaceProxyView texProxyView = this->makeView(context);
if (!texProxyView.proxy()) {
return {};
}
SkASSERT(texProxyView.asTextureProxy());
- if (origin.isZero() && info.dimensions() == this->getInfo().dimensions() &&
- mipMapped == GrMipMapped::kNo) {
+ if (texGenPolicy == GrImageTexGenPolicy::kDraw && origin.isZero() &&
+ info.dimensions() == this->getInfo().dimensions() && mipMapped == GrMipMapped::kNo) {
// If the caller wants the full non-MIP mapped texture we're done.
return texProxyView;
}
// Otherwise, make a copy for the requested subset and/or MIP maps.
SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, info.width(), info.height());
+ SkBudgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
+ ? SkBudgeted::kNo
+ : SkBudgeted::kYes;
+
GrColorType grColorType = SkColorTypeToGrColorType(this->getInfo().colorType());
return GrSurfaceProxy::Copy(context, texProxyView.proxy(), texProxyView.origin(), grColorType,
- mipMapped, subset, SkBackingFit::kExact,
- SkBudgeted::kYes);
+ mipMapped, subset, SkBackingFit::kExact, budgeted);
}
bool GrAHardwareBufferImageGenerator::onIsValid(GrContext* context) const {
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.h b/src/gpu/GrAHardwareBufferImageGenerator.h
index aa3803c..fdebf4c 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.h
+++ b/src/gpu/GrAHardwareBufferImageGenerator.h
@@ -43,7 +43,7 @@
bool onIsValid(GrContext*) const override;
GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&, const SkIPoint&,
- GrMipMapped) override;
+ GrMipMapped, GrImageTexGenPolicy) override;
private:
GrAHardwareBufferImageGenerator(const SkImageInfo&, AHardwareBuffer*, SkAlphaType,
diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp
index 6b90c80..504bbcb 100644
--- a/src/gpu/GrBackendTextureImageGenerator.cpp
+++ b/src/gpu/GrBackendTextureImageGenerator.cpp
@@ -93,10 +93,12 @@
refHelper->unref();
}
-GrSurfaceProxyView GrBackendTextureImageGenerator::onGenerateTexture(GrRecordingContext* context,
- const SkImageInfo& info,
- const SkIPoint& origin,
- GrMipMapped mipMapped) {
+GrSurfaceProxyView GrBackendTextureImageGenerator::onGenerateTexture(
+ GrRecordingContext* context,
+ const SkImageInfo& info,
+ const SkIPoint& origin,
+ GrMipMapped mipMapped,
+ GrImageTexGenPolicy texGenPolicy) {
SkASSERT(context);
if (context->backend() != fBackendTexture.backend()) {
@@ -210,18 +212,19 @@
return {};
}
- if (origin.isZero() && info.dimensions() == fBackendTexture.dimensions() &&
+ if (texGenPolicy == GrImageTexGenPolicy::kDraw && origin.isZero() &&
+ info.dimensions() == fBackendTexture.dimensions() &&
(mipMapped == GrMipMapped::kNo || proxy->mipMapped() == GrMipMapped::kYes)) {
// If the caller wants the entire texture and we have the correct mip support, we're done
return GrSurfaceProxyView(std::move(proxy), fSurfaceOrigin, readSwizzle);
} else {
- // Otherwise, make a copy of the requested subset. Make sure our temporary is renderable,
- // because Vulkan will want to do the copy as a draw. All other copies would require a
- // layout change in Vulkan and we do not change the layout of borrowed images.
SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, info.width(), info.height());
- return GrSurfaceProxy::Copy(
- context, proxy.get(), fSurfaceOrigin, grColorType, mipMapped, subset,
- SkBackingFit::kExact, SkBudgeted::kYes);
+ SkBudgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
+ ? SkBudgeted::kNo
+ : SkBudgeted::kYes;
+
+ return GrSurfaceProxy::Copy(context, proxy.get(), fSurfaceOrigin, grColorType, mipMapped,
+ subset, SkBackingFit::kExact, budgeted);
}
}
diff --git a/src/gpu/GrBackendTextureImageGenerator.h b/src/gpu/GrBackendTextureImageGenerator.h
index a85ead6..e426653 100644
--- a/src/gpu/GrBackendTextureImageGenerator.h
+++ b/src/gpu/GrBackendTextureImageGenerator.h
@@ -41,7 +41,7 @@
bool onIsValid(GrContext*) const override { return true; }
GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&, const SkIPoint&,
- GrMipMapped mipMapped) override;
+ GrMipMapped mipMapped, GrImageTexGenPolicy) override;
private:
GrBackendTextureImageGenerator(const SkImageInfo& info, GrTexture*, GrSurfaceOrigin,
diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp
index 172d34a..f6bc4f2 100644
--- a/src/gpu/GrBitmapTextureMaker.cpp
+++ b/src/gpu/GrBitmapTextureMaker.cpp
@@ -26,10 +26,27 @@
return {ct, bitmap.alphaType(), bitmap.refColorSpace(), bitmap.dimensions()};
}
-GrBitmapTextureMaker::GrBitmapTextureMaker(GrRecordingContext* context, const SkBitmap& bitmap,
- Cached cached, SkBackingFit fit)
- : INHERITED(context, get_image_info(context, bitmap)), fBitmap(bitmap), fFit(fit) {
- if (!bitmap.isVolatile() && cached == Cached::kYes) {
+GrBitmapTextureMaker::GrBitmapTextureMaker(GrRecordingContext* context,
+ const SkBitmap& bitmap,
+ SkBackingFit fit)
+ : GrBitmapTextureMaker(context, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted, fit) {}
+
+GrBitmapTextureMaker::GrBitmapTextureMaker(GrRecordingContext* context,
+ const SkBitmap& bitmap,
+ GrImageTexGenPolicy cachePolicy)
+ : GrBitmapTextureMaker(context, bitmap, cachePolicy, SkBackingFit::kExact) {}
+
+GrBitmapTextureMaker::GrBitmapTextureMaker(GrRecordingContext* context,
+ const SkBitmap& bitmap,
+ GrImageTexGenPolicy cachePolicy,
+ SkBackingFit fit)
+ : INHERITED(context, get_image_info(context, bitmap))
+ , fBitmap(bitmap)
+ , fFit(fit)
+ , fBudgeted(cachePolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
+ ? SkBudgeted::kNo
+ : SkBudgeted::kYes) {
+ if (!bitmap.isVolatile() && cachePolicy == GrImageTexGenPolicy::kDraw) {
SkIPoint origin = bitmap.pixelRefOrigin();
SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, bitmap.width(),
bitmap.height());
@@ -69,9 +86,9 @@
return {};
}
copy8888.setImmutable();
- proxy = proxyProvider->createProxyFromBitmap(copy8888, mipMapped, fFit);
+ proxy = proxyProvider->createProxyFromBitmap(copy8888, mipMapped, fFit, fBudgeted);
} else {
- proxy = proxyProvider->createProxyFromBitmap(fBitmap, mipMapped, fFit);
+ proxy = proxyProvider->createProxyFromBitmap(fBitmap, mipMapped, fFit, fBudgeted);
}
if (proxy) {
swizzle = this->context()->priv().caps()->getReadSwizzle(proxy->backendFormat(),
diff --git a/src/gpu/GrBitmapTextureMaker.h b/src/gpu/GrBitmapTextureMaker.h
index bff4c62..fc92966 100644
--- a/src/gpu/GrBitmapTextureMaker.h
+++ b/src/gpu/GrBitmapTextureMaker.h
@@ -10,22 +10,27 @@
#include "include/core/SkBitmap.h"
#include "src/gpu/GrTextureMaker.h"
+#include "src/gpu/SkGr.h"
/** This class manages the conversion of SW-backed bitmaps to GrTextures. If the input bitmap is
non-volatile the texture is cached using a key created from the pixels' image id and the
subset of the pixelref specified by the bitmap. */
class GrBitmapTextureMaker final : public GrTextureMaker {
public:
- enum class Cached { kNo, kYes };
+ GrBitmapTextureMaker(GrRecordingContext*, const SkBitmap&, GrImageTexGenPolicy);
- GrBitmapTextureMaker(GrRecordingContext* context, const SkBitmap& bitmap,
- Cached cached = Cached::kNo, SkBackingFit = SkBackingFit::kExact);
+ // Always uncached-budgeted. It doesn't make sense to have kApprox cached textures. Moreover,we
+ // create kApprox textures intermediate buffers and those ought to be budgeted.
+ GrBitmapTextureMaker(GrRecordingContext*, const SkBitmap&, SkBackingFit);
private:
+ GrBitmapTextureMaker(GrRecordingContext*, const SkBitmap&, GrImageTexGenPolicy, SkBackingFit);
+
GrSurfaceProxyView refOriginalTextureProxyView(GrMipMapped) override;
const SkBitmap fBitmap;
const SkBackingFit fFit;
+ const SkBudgeted fBudgeted;
GrUniqueKey fKey;
typedef GrTextureMaker INHERITED;
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index cfd9657..2d4ba21 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -151,8 +151,7 @@
}
bm.setImmutable();
- GrBitmapTextureMaker maker(context, bm, GrBitmapTextureMaker::Cached::kNo,
- SkBackingFit::kApprox);
+ GrBitmapTextureMaker maker(context, bm, SkBackingFit::kApprox);
filteredMaskView = maker.view(GrMipMapped::kNo);
if (!filteredMaskView.proxy()) {
return false;
diff --git a/src/gpu/GrImageTextureMaker.cpp b/src/gpu/GrImageTextureMaker.cpp
index b1539ed..5a4f7e7 100644
--- a/src/gpu/GrImageTextureMaker.cpp
+++ b/src/gpu/GrImageTextureMaker.cpp
@@ -24,16 +24,17 @@
return {ct, client->alphaType(), client->refColorSpace(), client->dimensions()};
}
-GrImageTextureMaker::GrImageTextureMaker(GrRecordingContext* context, const SkImage* client,
- SkImage::CachingHint chint)
+GrImageTextureMaker::GrImageTextureMaker(GrRecordingContext* context,
+ const SkImage* client,
+ GrImageTexGenPolicy texGenPolicy)
: INHERITED(context, get_image_info(context, client))
, fImage(static_cast<const SkImage_Lazy*>(client))
- , fCachingHint(chint) {
+ , fTexGenPolicy(texGenPolicy) {
SkASSERT(client->isLazyGenerated());
}
GrSurfaceProxyView GrImageTextureMaker::refOriginalTextureProxyView(GrMipMapped mipMapped) {
- return fImage->lockTextureProxyView(this->context(), fCachingHint, mipMapped);
+ return fImage->lockTextureProxyView(this->context(), fTexGenPolicy, mipMapped);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/gpu/GrImageTextureMaker.h b/src/gpu/GrImageTextureMaker.h
index 380ebef..a84042f 100644
--- a/src/gpu/GrImageTextureMaker.h
+++ b/src/gpu/GrImageTextureMaker.h
@@ -10,6 +10,7 @@
#include "include/core/SkImage.h"
#include "src/gpu/GrTextureMaker.h"
+#include "src/gpu/SkGr.h"
class SkImage_Lazy;
class SkImage_GpuYUVA;
@@ -18,14 +19,13 @@
is kAllow the image's ID is used for the cache key. */
class GrImageTextureMaker final : public GrTextureMaker {
public:
- GrImageTextureMaker(GrRecordingContext* context, const SkImage* client,
- SkImage::CachingHint chint);
+ GrImageTextureMaker(GrRecordingContext*, const SkImage* client, GrImageTexGenPolicy);
private:
GrSurfaceProxyView refOriginalTextureProxyView(GrMipMapped) override;
const SkImage_Lazy* fImage;
- SkImage::CachingHint fCachingHint;
+ GrImageTexGenPolicy fTexGenPolicy;
typedef GrTextureMaker INHERITED;
};
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 9f79983..10cb353 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -240,7 +240,8 @@
sk_sp<GrTextureProxy> GrProxyProvider::createProxyFromBitmap(const SkBitmap& bitmap,
GrMipMapped mipMapped,
- SkBackingFit fit) {
+ SkBackingFit fit,
+ SkBudgeted budgeted) {
ASSERT_SINGLE_OWNER
SkASSERT(fit == SkBackingFit::kExact || mipMapped == GrMipMapped::kNo);
@@ -277,9 +278,9 @@
sk_sp<GrTextureProxy> proxy;
if (mipMapped == GrMipMapped::kNo ||
0 == SkMipMap::ComputeLevelCount(copyBitmap.width(), copyBitmap.height())) {
- proxy = this->createNonMippedProxyFromBitmap(copyBitmap, fit, format, grCT);
+ proxy = this->createNonMippedProxyFromBitmap(copyBitmap, fit, format, grCT, budgeted);
} else {
- proxy = this->createMippedProxyFromBitmap(copyBitmap, format, grCT);
+ proxy = this->createMippedProxyFromBitmap(copyBitmap, format, grCT, budgeted);
}
if (!proxy) {
@@ -302,20 +303,21 @@
sk_sp<GrTextureProxy> GrProxyProvider::createNonMippedProxyFromBitmap(const SkBitmap& bitmap,
SkBackingFit fit,
const GrBackendFormat& format,
- GrColorType colorType) {
+ GrColorType colorType,
+ SkBudgeted budgeted) {
GrSwizzle swizzle = this->caps()->getReadSwizzle(format, colorType);
auto dims = bitmap.dimensions();
sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
- [dims, format, bitmap, fit, colorType](GrResourceProvider* resourceProvider) {
+ [dims, format, bitmap, fit, colorType, budgeted](GrResourceProvider* resourceProvider) {
GrMipLevel mipLevel = { bitmap.getPixels(), bitmap.rowBytes() };
return LazyCallbackResult(resourceProvider->createTexture(
- dims, format, colorType, GrRenderable::kNo, 1, SkBudgeted::kYes, fit,
+ dims, format, colorType, GrRenderable::kNo, 1, budgeted, fit,
GrProtected::kNo, mipLevel));
},
format, dims, swizzle, GrRenderable::kNo, 1, GrMipMapped::kNo,
- GrMipMapsStatus::kNotAllocated, GrInternalSurfaceFlags::kNone, fit, SkBudgeted::kYes,
+ GrMipMapsStatus::kNotAllocated, GrInternalSurfaceFlags::kNone, fit, budgeted,
GrProtected::kNo, UseAllocator::kYes);
if (!proxy) {
@@ -327,7 +329,8 @@
sk_sp<GrTextureProxy> GrProxyProvider::createMippedProxyFromBitmap(const SkBitmap& bitmap,
const GrBackendFormat& format,
- GrColorType colorType) {
+ GrColorType colorType,
+ SkBudgeted budgeted) {
SkASSERT(this->caps()->mipMapSupport());
@@ -340,7 +343,7 @@
auto dims = bitmap.dimensions();
sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
- [dims, format, bitmap, mipmaps](GrResourceProvider* resourceProvider) {
+ [dims, format, bitmap, mipmaps, budgeted](GrResourceProvider* resourceProvider) {
const int mipLevelCount = mipmaps->countLevels() + 1;
std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
@@ -357,12 +360,12 @@
SkASSERT(generatedMipLevel.fPixmap.colorType() == bitmap.colorType());
}
return LazyCallbackResult(resourceProvider->createTexture(
- dims, format, colorType, GrRenderable::kNo, 1, SkBudgeted::kYes,
- GrProtected::kNo, texels.get(), mipLevelCount));
+ dims, format, colorType, GrRenderable::kNo, 1, budgeted, GrProtected::kNo,
+ texels.get(), mipLevelCount));
},
format, dims, readSwizzle, GrRenderable::kNo, 1, GrMipMapped::kYes,
- GrMipMapsStatus::kValid, GrInternalSurfaceFlags::kNone, SkBackingFit::kExact,
- SkBudgeted::kYes, GrProtected::kNo, UseAllocator::kYes);
+ GrMipMapsStatus::kValid, GrInternalSurfaceFlags::kNone, SkBackingFit::kExact, budgeted,
+ GrProtected::kNo, UseAllocator::kYes);
if (!proxy) {
return nullptr;
diff --git a/src/gpu/GrProxyProvider.h b/src/gpu/GrProxyProvider.h
index e82146a..e4ea2d4 100644
--- a/src/gpu/GrProxyProvider.h
+++ b/src/gpu/GrProxyProvider.h
@@ -66,8 +66,10 @@
* Creates a new texture proxy for the bitmap, optionally with mip levels generated by the cpu.
* The bitmap is uploaded to the texture proxy assuming a kTopLeft_GrSurfaceOrigin.
*/
- sk_sp<GrTextureProxy> createProxyFromBitmap(const SkBitmap& bitmap, GrMipMapped,
- SkBackingFit fit);
+ sk_sp<GrTextureProxy> createProxyFromBitmap(const SkBitmap&,
+ GrMipMapped,
+ SkBackingFit,
+ SkBudgeted);
/*
* Create a GrSurfaceProxy without any data.
@@ -273,16 +275,15 @@
/*
* Create an un-mipmapped texture proxy for the bitmap.
*/
- sk_sp<GrTextureProxy> createNonMippedProxyFromBitmap(const SkBitmap& bitmap,
- SkBackingFit fit,
- const GrBackendFormat& format,
- GrColorType colorType);
+ sk_sp<GrTextureProxy> createNonMippedProxyFromBitmap(
+ const SkBitmap&, SkBackingFit, const GrBackendFormat&, GrColorType, SkBudgeted);
/*
* Create an mipmapped texture proxy for the bitmap.
*/
- sk_sp<GrTextureProxy> createMippedProxyFromBitmap(const SkBitmap& bitmap,
- const GrBackendFormat& format,
- GrColorType colorType);
+ sk_sp<GrTextureProxy> createMippedProxyFromBitmap(const SkBitmap&,
+ const GrBackendFormat&,
+ GrColorType,
+ SkBudgeted);
// GrColorType is used to determine the proxy's texture swizzle.
sk_sp<GrTextureProxy> createWrapped(sk_sp<GrTexture> tex, GrColorType,
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 38bed95..02dc626 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -103,6 +103,6 @@
nullptr));
bitmap.setImmutable();
- GrBitmapTextureMaker maker(context, bitmap, GrBitmapTextureMaker::Cached::kNo, fit);
+ GrBitmapTextureMaker maker(context, bitmap, fit);
return maker.view(GrMipMapped::kNo);
}
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index 905bbd1..6a25a79 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -108,7 +108,8 @@
SkISize dimensions,
GrColorType colorType,
SkColorSpace* srcColorSpace,
- SkColorSpace* dstColorSpace) {
+ SkColorSpace* dstColorSpace,
+ SkBudgeted budgeted) {
SkYUVASizeInfo yuvSizeInfo;
SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount];
SkYUVColorSpace yuvColorSpace;
@@ -152,7 +153,7 @@
YUVGen_DataReleaseProc, dataStoragePtr));
bitmap.setImmutable();
- GrBitmapTextureMaker maker(ctx, bitmap, GrBitmapTextureMaker::Cached::kNo, fit);
+ GrBitmapTextureMaker maker(ctx, bitmap, fit);
yuvViews[i] = maker.view(GrMipMapped::kNo);
if (!yuvViews[i]) {
@@ -165,7 +166,7 @@
// TODO: investigate preallocating mip maps here
auto renderTargetContext = GrRenderTargetContext::Make(
ctx, colorType, nullptr, SkBackingFit::kExact, dimensions, 1, GrMipMapped::kNo,
- GrProtected::kNo, kTopLeft_GrSurfaceOrigin);
+ GrProtected::kNo, kTopLeft_GrSurfaceOrigin, budgeted);
if (!renderTargetContext) {
return {};
}
diff --git a/src/gpu/GrYUVProvider.h b/src/gpu/GrYUVProvider.h
index 6e3af05..d253e82 100644
--- a/src/gpu/GrYUVProvider.h
+++ b/src/gpu/GrYUVProvider.h
@@ -44,7 +44,8 @@
SkISize,
GrColorType colorType,
SkColorSpace* srcColorSpace,
- SkColorSpace* dstColorSpace);
+ SkColorSpace* dstColorSpace,
+ SkBudgeted budgeted);
sk_sp<SkCachedData> getPlanes(SkYUVASizeInfo*, SkYUVAIndex[SkYUVAIndex::kIndexCount],
SkYUVColorSpace*, const void* planes[SkYUVASizeInfo::kMaxCount]);
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 4438766..aebb7bf 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -881,10 +881,10 @@
} else {
SkBitmap bm;
if (image->isLazyGenerated()) {
- GrImageTextureMaker maker(fContext.get(), image, SkImage::kAllow_CachingHint);
+ GrImageTextureMaker maker(fContext.get(), image, GrImageTexGenPolicy::kDraw);
this->drawProducerLattice(&maker, std::move(iter), dst, paint);
} else if (as_IB(image)->getROPixels(&bm)) {
- GrBitmapTextureMaker maker(fContext.get(), bm, GrBitmapTextureMaker::Cached::kYes);
+ GrBitmapTextureMaker maker(fContext.get(), bm, GrImageTexGenPolicy::kDraw);
this->drawProducerLattice(&maker, std::move(iter), dst, paint);
}
}
@@ -932,10 +932,10 @@
} else {
SkBitmap bm;
if (image->isLazyGenerated()) {
- GrImageTextureMaker maker(fContext.get(), image, SkImage::kAllow_CachingHint);
+ GrImageTextureMaker maker(fContext.get(), image, GrImageTexGenPolicy::kDraw);
this->drawProducerLattice(&maker, std::move(iter), dst, paint);
} else if (as_IB(image)->getROPixels(&bm)) {
- GrBitmapTextureMaker maker(fContext.get(), bm, GrBitmapTextureMaker::Cached::kYes);
+ GrBitmapTextureMaker maker(fContext.get(), bm, GrImageTexGenPolicy::kDraw);
this->drawProducerLattice(&maker, std::move(iter), dst, paint);
}
}
diff --git a/src/gpu/SkGpuDevice_drawTexture.cpp b/src/gpu/SkGpuDevice_drawTexture.cpp
index 4f86c19..0b880e3 100644
--- a/src/gpu/SkGpuDevice_drawTexture.cpp
+++ b/src/gpu/SkGpuDevice_drawTexture.cpp
@@ -569,8 +569,7 @@
SkASSERT(tmpB.width() <= context->priv().caps()->maxTileSize() &&
tmpB.height() <= context->priv().caps()->maxTileSize());
- GrBitmapTextureMaker tileProducer(context, tmpB, GrBitmapTextureMaker::Cached::kYes,
- SkBackingFit::kExact);
+ GrBitmapTextureMaker tileProducer(context, tmpB, GrImageTexGenPolicy::kDraw);
GrQuadAAFlags aaFlags = GrQuadAAFlags::kNone;
if (aa == GrAA::kYes) {
@@ -719,7 +718,7 @@
// Lazily generated images must get drawn as a texture producer that handles the final
// texture creation.
if (image->isLazyGenerated()) {
- GrImageTextureMaker maker(fContext.get(), image, SkImage::kAllow_CachingHint);
+ GrImageTextureMaker maker(fContext.get(), image, GrImageTexGenPolicy::kDraw);
draw_texture_producer(fContext.get(), fRenderTargetContext.get(), clip, ctm, paint,
&maker, src, dst, dstClip, srcToDst, aa, aaFlags, constraint,
wrapMode, fm, doBicubic);
@@ -728,8 +727,7 @@
SkBitmap bm;
if (as_IB(image)->getROPixels(&bm)) {
- GrBitmapTextureMaker maker(fContext.get(), bm, GrBitmapTextureMaker::Cached::kYes,
- SkBackingFit::kExact);
+ GrBitmapTextureMaker maker(fContext.get(), bm, GrImageTexGenPolicy::kDraw);
draw_texture_producer(fContext.get(), fRenderTargetContext.get(), clip, ctm, paint,
&maker, src, dst, dstClip, srcToDst, aa, aaFlags, constraint,
wrapMode, fm, doBicubic);
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index f528992..05f7d6d 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -134,32 +134,37 @@
GrSurfaceProxyView GrCopyBaseMipMapToTextureProxy(GrRecordingContext* ctx,
GrSurfaceProxy* baseProxy,
GrSurfaceOrigin origin,
- GrColorType srcColorType) {
+ GrColorType srcColorType,
+ SkBudgeted budgeted) {
SkASSERT(baseProxy);
if (!ctx->priv().caps()->isFormatCopyable(baseProxy->backendFormat())) {
return {};
}
- GrSurfaceProxyView view = GrSurfaceProxy::Copy(ctx, baseProxy, origin, srcColorType,
- GrMipMapped::kYes, SkBackingFit::kExact,
- SkBudgeted::kYes);
+ GrSurfaceProxyView view = GrSurfaceProxy::Copy(ctx,
+ baseProxy,
+ origin,
+ srcColorType,
+ GrMipMapped::kYes,
+ SkBackingFit::kExact,
+ budgeted);
SkASSERT(!view.proxy() || view.asTextureProxy());
return view;
}
GrSurfaceProxyView GrRefCachedBitmapView(GrRecordingContext* ctx, const SkBitmap& bitmap,
GrMipMapped mipMapped) {
- GrBitmapTextureMaker maker(ctx, bitmap, GrBitmapTextureMaker::Cached::kYes);
+ GrBitmapTextureMaker maker(ctx, bitmap, GrImageTexGenPolicy::kDraw);
return maker.view(mipMapped);
}
-GrSurfaceProxyView GrMakeCachedBitmapProxyView(GrRecordingContext* context, const SkBitmap& bitmap,
- SkBackingFit fit) {
+GrSurfaceProxyView GrMakeCachedBitmapProxyView(GrRecordingContext* context,
+ const SkBitmap& bitmap) {
if (!bitmap.peekPixels(nullptr)) {
return {};
}
- GrBitmapTextureMaker maker(context, bitmap, GrBitmapTextureMaker::Cached::kYes, fit);
+ GrBitmapTextureMaker maker(context, bitmap, GrImageTexGenPolicy::kDraw);
return maker.view(GrMipMapped::kNo);
}
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index 8c77f83..7626963 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -164,6 +164,18 @@
// Texture management
/**
+ * Policies for how to create textures for SkImages (and SkBitmaps).
+ */
+enum class GrImageTexGenPolicy : int {
+ // Choose the cheapest way to generate the texture. Use GrResourceCache if appropriate.
+ kDraw,
+ // Always make a new texture that is uncached and unbudgeted.
+ kNew_Uncached_Unbudgeted,
+ // Always make a new texture that is uncached and budgeted.
+ kNew_Uncached_Budgeted
+};
+
+/**
* Returns a view that wraps a texture representing the bitmap. The texture is inserted into the
* cache (unless the bitmap is marked volatile and can be retrieved again via this function.
* A MIP mapped texture may be returned even when GrMipMapped is kNo. The function will succeed
@@ -177,14 +189,14 @@
GrSurfaceProxyView GrCopyBaseMipMapToTextureProxy(GrRecordingContext*,
GrSurfaceProxy* baseProxy,
GrSurfaceOrigin origin,
- GrColorType srcColorType);
+ GrColorType srcColorType,
+ SkBudgeted = SkBudgeted::kYes);
/*
* Create a texture proxy from the provided bitmap and add it to the texture cache
* using the key also extracted from 'bitmp'.
*/
-GrSurfaceProxyView GrMakeCachedBitmapProxyView(GrRecordingContext*, const SkBitmap& bitmap,
- SkBackingFit fit = SkBackingFit::kExact);
+GrSurfaceProxyView GrMakeCachedBitmapProxyView(GrRecordingContext*, const SkBitmap& bitmap);
/**
* Our key includes the offset, width, and height so that bitmaps created by extractSubset()
diff --git a/src/gpu/effects/GrCircleBlurFragmentProcessor.fp b/src/gpu/effects/GrCircleBlurFragmentProcessor.fp
index 5582538..d0e2e78 100644
--- a/src/gpu/effects/GrCircleBlurFragmentProcessor.fp
+++ b/src/gpu/effects/GrCircleBlurFragmentProcessor.fp
@@ -256,7 +256,7 @@
bm.setImmutable();
- GrBitmapTextureMaker maker(context, bm);
+ GrBitmapTextureMaker maker(context, bm, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto blurView = maker.view(GrMipMapped::kNo);
if (!blurView) {
return {};
diff --git a/src/gpu/effects/GrConfigConversionEffect.fp b/src/gpu/effects/GrConfigConversionEffect.fp
index f3932f5..6e08ad3 100644
--- a/src/gpu/effects/GrConfigConversionEffect.fp
+++ b/src/gpu/effects/GrConfigConversionEffect.fp
@@ -59,7 +59,7 @@
bitmap.installPixels(ii, srcData, 4 * kSize);
bitmap.setImmutable();
- GrBitmapTextureMaker maker(context, bitmap);
+ GrBitmapTextureMaker maker(context, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto dataView = maker.view(GrMipMapped::kNo);
if (!dataView) {
return false;
diff --git a/src/gpu/effects/GrRectBlurEffect.fp b/src/gpu/effects/GrRectBlurEffect.fp
index 667d92b..b57556e 100644
--- a/src/gpu/effects/GrRectBlurEffect.fp
+++ b/src/gpu/effects/GrRectBlurEffect.fp
@@ -84,7 +84,7 @@
*bitmap.getAddr8(width - 1, 0) = 0;
bitmap.setImmutable();
- GrBitmapTextureMaker maker(context, bitmap);
+ GrBitmapTextureMaker maker(context, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto view = maker.view(GrMipMapped::kNo);
if (!view) {
return {};
diff --git a/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.cpp b/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.cpp
index 5a8bf80..02c62a1 100644
--- a/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.cpp
+++ b/src/gpu/effects/generated/GrCircleBlurFragmentProcessor.cpp
@@ -233,7 +233,7 @@
bm.setImmutable();
- GrBitmapTextureMaker maker(context, bm);
+ GrBitmapTextureMaker maker(context, bm, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto blurView = maker.view(GrMipMapped::kNo);
if (!blurView) {
return {};
diff --git a/src/gpu/effects/generated/GrConfigConversionEffect.h b/src/gpu/effects/generated/GrConfigConversionEffect.h
index f6bbd62..f6172b9 100644
--- a/src/gpu/effects/generated/GrConfigConversionEffect.h
+++ b/src/gpu/effects/generated/GrConfigConversionEffect.h
@@ -68,7 +68,7 @@
bitmap.installPixels(ii, srcData, 4 * kSize);
bitmap.setImmutable();
- GrBitmapTextureMaker maker(context, bitmap);
+ GrBitmapTextureMaker maker(context, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto dataView = maker.view(GrMipMapped::kNo);
if (!dataView) {
return false;
diff --git a/src/gpu/effects/generated/GrRectBlurEffect.h b/src/gpu/effects/generated/GrRectBlurEffect.h
index f7331fe..486e060 100644
--- a/src/gpu/effects/generated/GrRectBlurEffect.h
+++ b/src/gpu/effects/generated/GrRectBlurEffect.h
@@ -67,7 +67,7 @@
*bitmap.getAddr8(width - 1, 0) = 0;
bitmap.setImmutable();
- GrBitmapTextureMaker maker(context, bitmap);
+ GrBitmapTextureMaker maker(context, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto view = maker.view(GrMipMapped::kNo);
if (!view) {
return {};
diff --git a/src/gpu/ops/GrShadowRRectOp.cpp b/src/gpu/ops/GrShadowRRectOp.cpp
index b766fc4..d735cb1 100644
--- a/src/gpu/ops/GrShadowRRectOp.cpp
+++ b/src/gpu/ops/GrShadowRRectOp.cpp
@@ -690,7 +690,7 @@
}
bitmap.setImmutable();
- GrBitmapTextureMaker maker(context, bitmap);
+ GrBitmapTextureMaker maker(context, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto view = maker.view(GrMipMapped::kNo);
SkASSERT(view.origin() == kTopLeft_GrSurfaceOrigin);
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index a2f0ecd..cbfc769 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -500,7 +500,7 @@
return nullptr;
}
-sk_sp<SkImage> SkImage::makeTextureImage(GrContext*, GrMipMapped mipMapped) const {
+sk_sp<SkImage> SkImage::makeTextureImage(GrContext*, GrMipMapped, SkBudgeted) const {
return nullptr;
}
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 90c434d..accda874 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -418,7 +418,9 @@
producer->alphaType(), sk_ref_sp(producer->colorSpace()));
}
-sk_sp<SkImage> SkImage::makeTextureImage(GrContext* context, GrMipMapped mipMapped) const {
+sk_sp<SkImage> SkImage::makeTextureImage(GrContext* context,
+ GrMipMapped mipMapped,
+ SkBudgeted budgeted) const {
if (!context) {
return nullptr;
}
@@ -428,22 +430,35 @@
return nullptr;
}
+ // TODO: Don't flatten YUVA images here.
const GrSurfaceProxyView* view = as_IB(this)->view(context);
SkASSERT(view && view->asTextureProxy());
- if (GrMipMapped::kNo == mipMapped || view->asTextureProxy()->mipMapped() == mipMapped) {
+
+ if (mipMapped == GrMipMapped::kNo || view->asTextureProxy()->mipMapped() == mipMapped ||
+ !context->priv().caps()->mipMapSupport()) {
return sk_ref_sp(const_cast<SkImage*>(this));
}
- GrTextureAdjuster adjuster(context, *view, this->imageInfo().colorInfo(), this->uniqueID());
- return create_image_from_producer(context, &adjuster, this->uniqueID(), mipMapped);
+ auto copy = GrCopyBaseMipMapToTextureProxy(context->priv().asRecordingContext(),
+ view->proxy(),
+ view->origin(),
+ SkColorTypeToGrColorType(this->colorType()),
+ budgeted);
+ if (!copy) {
+ return nullptr;
+ }
+ return sk_make_sp<SkImage_Gpu>(sk_ref_sp(context), this->uniqueID(), std::move(copy),
+ this->colorType(), this->alphaType(), this->refColorSpace());
}
+ auto policy = budgeted == SkBudgeted::kYes ? GrImageTexGenPolicy::kNew_Uncached_Budgeted
+ : GrImageTexGenPolicy::kNew_Uncached_Unbudgeted;
if (this->isLazyGenerated()) {
- GrImageTextureMaker maker(context, this, kDisallow_CachingHint);
+ GrImageTextureMaker maker(context, this, policy);
return create_image_from_producer(context, &maker, this->uniqueID(), mipMapped);
}
if (const SkBitmap* bmp = as_IB(this)->onPeekBitmap()) {
- GrBitmapTextureMaker maker(context, *bmp, GrBitmapTextureMaker::Cached::kYes);
+ GrBitmapTextureMaker maker(context, *bmp, policy);
return create_image_from_producer(context, &maker, this->uniqueID(), mipMapped);
}
return nullptr;
@@ -545,7 +560,7 @@
// Turn the pixmap into a GrTextureProxy
SkBitmap bmp;
bmp.installPixels(*pixmap);
- GrBitmapTextureMaker bitmapMaker(context, bmp);
+ GrBitmapTextureMaker bitmapMaker(context, bmp, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
GrMipMapped mipMapped = buildMips ? GrMipMapped::kYes : GrMipMapped::kNo;
auto view = bitmapMaker.view(mipMapped);
if (!view) {
diff --git a/src/image/SkImage_GpuYUVA.cpp b/src/image/SkImage_GpuYUVA.cpp
index 89f63d2..99108c1 100644
--- a/src/image/SkImage_GpuYUVA.cpp
+++ b/src/image/SkImage_GpuYUVA.cpp
@@ -291,7 +291,7 @@
// Turn the pixmap into a GrTextureProxy
SkBitmap bmp;
bmp.installPixels(*pixmap);
- GrBitmapTextureMaker bitmapMaker(context, bmp);
+ GrBitmapTextureMaker bitmapMaker(context, bmp, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
GrMipMapped mipMapped = buildMips ? GrMipMapped::kYes : GrMipMapped::kNo;
GrSurfaceProxyView view;
tempViews[i] = bitmapMaker.view(mipMapped);
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
index b46c77a..bdfbdc6 100644
--- a/src/image/SkImage_Lazy.cpp
+++ b/src/image/SkImage_Lazy.cpp
@@ -235,7 +235,7 @@
return {};
}
- GrImageTextureMaker textureMaker(context, this, kAllow_CachingHint);
+ GrImageTextureMaker textureMaker(context, this, GrImageTexGenPolicy::kDraw);
return textureMaker.view(mipMapped);
}
#endif
@@ -386,7 +386,7 @@
* 4. Ask the generator to return RGB(A) data, which the GPU can convert
*/
GrSurfaceProxyView SkImage_Lazy::lockTextureProxyView(GrRecordingContext* ctx,
- SkImage::CachingHint chint,
+ GrImageTexGenPolicy texGenPolicy,
GrMipMapped mipMapped) const {
// Values representing the various texture lock paths we can take. Used for logging the path
// taken to a histogram.
@@ -402,7 +402,9 @@
enum { kLockTexturePathCount = kRGBA_LockTexturePath + 1 };
GrUniqueKey key;
- GrMakeKeyFromImageID(&key, this->uniqueID(), SkIRect::MakeSize(this->dimensions()));
+ if (texGenPolicy == GrImageTexGenPolicy::kDraw) {
+ GrMakeKeyFromImageID(&key, this->uniqueID(), SkIRect::MakeSize(this->dimensions()));
+ }
const GrCaps* caps = ctx->priv().caps();
GrProxyProvider* proxyProvider = ctx->priv().proxyProvider();
@@ -418,7 +420,7 @@
auto ct = this->colorTypeOfLockTextureProxy(caps);
- // 1. Check the cache for a pre-existing one
+ // 1. Check the cache for a pre-existing one.
if (key.isValid()) {
auto proxy = proxyProvider->findOrCreateProxyByUniqueKey(key, ct);
if (proxy) {
@@ -448,19 +450,20 @@
}
}
- // 2. Ask the generator to natively create one
+ // 2. Ask the generator to natively create one.
{
- ScopedGenerator generator(fSharedGenerator);
- if (auto view = generator->generateTexture(ctx, this->imageInfo(), fOrigin, mipMapped)) {
- SK_HISTOGRAM_ENUMERATION("LockTexturePath", kNative_LockTexturePath,
- kLockTexturePathCount);
- installKey(view);
- return view;
- }
+ ScopedGenerator generator(fSharedGenerator);
+ if (auto view = generator->generateTexture(ctx, this->imageInfo(), fOrigin, mipMapped,
+ texGenPolicy)) {
+ SK_HISTOGRAM_ENUMERATION("LockTexturePath", kNative_LockTexturePath,
+ kLockTexturePathCount);
+ installKey(view);
+ return view;
+ }
}
// 3. Ask the generator to return YUV planes, which the GPU can convert. If we will be mipping
- // the texture we fall through here and have the CPU generate the mip maps for us.
+ // the texture we skip this step so the CPU generate non-planar MIP maps for us.
if (mipMapped == GrMipMapped::kNo && !ctx->priv().options().fDisableGpuYUVConversion) {
SkColorType colorType = this->colorType();
@@ -476,9 +479,12 @@
// TODO: Update to create the mipped surface in the YUV generator and draw the base
// layer directly into the mipped surface.
+ SkBudgeted budgeted = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
+ ? SkBudgeted::kNo
+ : SkBudgeted::kYes;
auto view = provider.refAsTextureProxyView(ctx, this->imageInfo().dimensions(),
SkColorTypeToGrColorType(colorType),
- generatorColorSpace, thisColorSpace);
+ generatorColorSpace, thisColorSpace, budgeted);
if (view) {
SK_HISTOGRAM_ENUMERATION("LockTexturePath", kYUV_LockTexturePath,
kLockTexturePathCount);
@@ -487,9 +493,16 @@
}
}
- // 4. Ask the generator to return RGB(A) data, which the GPU can convert
- if (SkBitmap bitmap; this->getROPixels(&bitmap, chint)) {
- GrBitmapTextureMaker bitmapMaker(ctx, bitmap, GrBitmapTextureMaker::Cached::kNo);
+ // 4. Ask the generator to return a bitmap, which the GPU can convert.
+ auto hint = texGenPolicy == GrImageTexGenPolicy::kDraw ? CachingHint::kAllow_CachingHint
+ : CachingHint::kDisallow_CachingHint;
+ if (SkBitmap bitmap; this->getROPixels(&bitmap, hint)) {
+ // We always pass uncached here because we will cache it external to the maker based on
+ // *our* cache policy. We're just using the maker to generate the texture.
+ auto makerPolicy = texGenPolicy == GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
+ ? GrImageTexGenPolicy::kNew_Uncached_Unbudgeted
+ : GrImageTexGenPolicy::kNew_Uncached_Budgeted;
+ GrBitmapTextureMaker bitmapMaker(ctx, bitmap, makerPolicy);
auto view = bitmapMaker.view(mipMapped);
if (view) {
installKey(view);
diff --git a/src/image/SkImage_Lazy.h b/src/image/SkImage_Lazy.h
index 7477256..f278814 100644
--- a/src/image/SkImage_Lazy.h
+++ b/src/image/SkImage_Lazy.h
@@ -10,6 +10,7 @@
#include "include/private/SkIDChangeListener.h"
#include "include/private/SkMutex.h"
+#include "src/gpu/SkGr.h"
#include "src/image/SkImage_Base.h"
#if SK_SUPPORT_GPU
@@ -60,7 +61,7 @@
// Returns the texture proxy. CachingHint refers to whether the generator's output should be
// cached in CPU memory. We will always cache the generated texture on success.
GrSurfaceProxyView lockTextureProxyView(GrRecordingContext*,
- SkImage::CachingHint,
+ GrImageTexGenPolicy,
GrMipMapped) const;
// Returns the GrColorType to use with the GrTextureProxy returned from lockTextureProxy. This
diff --git a/tests/GrMipMappedTest.cpp b/tests/GrMipMappedTest.cpp
index ff71aa7..45a5813 100644
--- a/tests/GrMipMappedTest.cpp
+++ b/tests/GrMipMappedTest.cpp
@@ -152,8 +152,8 @@
SkIPoint origin = SkIPoint::Make(0,0);
SkImageInfo imageInfo = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType,
kPremul_SkAlphaType);
- GrSurfaceProxyView genView =
- imageGen->generateTexture(context, imageInfo, origin, requestMipMapped);
+ GrSurfaceProxyView genView = imageGen->generateTexture(
+ context, imageInfo, origin, requestMipMapped, GrImageTexGenPolicy::kDraw);
GrSurfaceProxy* genProxy = genView.proxy();
REPORTER_ASSERT(reporter, genProxy);
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index 892845e..a64390f 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -406,7 +406,8 @@
copySrcBitmap.installPixels(write);
copySrcBitmap.setImmutable();
- GrBitmapTextureMaker maker(context, copySrcBitmap);
+ GrBitmapTextureMaker maker(context, copySrcBitmap,
+ GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto copySrc = maker.view(GrMipMapped::kNo);
REPORTER_ASSERT(reporter, copySrc.proxy());
diff --git a/tests/ImageFilterCacheTest.cpp b/tests/ImageFilterCacheTest.cpp
index 54684be..0a34334 100644
--- a/tests/ImageFilterCacheTest.cpp
+++ b/tests/ImageFilterCacheTest.cpp
@@ -209,7 +209,7 @@
static GrSurfaceProxyView create_proxy_view(GrRecordingContext* context) {
SkBitmap srcBM = create_bm();
- GrBitmapTextureMaker maker(context, srcBM);
+ GrBitmapTextureMaker maker(context, srcBM, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
return maker.view(GrMipMapped::kNo);
}
diff --git a/tests/ImageTest.cpp b/tests/ImageTest.cpp
index 8ef8cff..03c6f4a 100644
--- a/tests/ImageTest.cpp
+++ b/tests/ImageTest.cpp
@@ -146,10 +146,12 @@
auto src = SkEncodeBitmap(bitmap, SkEncodedImageFormat::kPNG, 100);
return SkImage::MakeFromEncoded(std::move(src));
}
-static sk_sp<SkImage> create_gpu_image(GrContext* context, bool withMips = false) {
+static sk_sp<SkImage> create_gpu_image(GrContext* context,
+ bool withMips = false,
+ SkBudgeted budgeted = SkBudgeted::kYes) {
const SkImageInfo info = SkImageInfo::MakeN32(20, 20, kOpaque_SkAlphaType);
- auto surface(SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0,
- kBottomLeft_GrSurfaceOrigin, nullptr, withMips));
+ auto surface = SkSurface::MakeRenderTarget(context, budgeted, info, 0,
+ kBottomLeft_GrSurfaceOrigin, nullptr, withMips);
draw_image_test_pattern(surface->getCanvas());
return surface->makeImageSnapshot();
}
@@ -376,24 +378,19 @@
testContext->makeCurrent();
std::function<sk_sp<SkImage>()> imageFactories[] = {
- create_image,
- create_codec_image,
- create_data_image,
- // Create an image from a picture.
- create_picture_image,
- // Create a texture image.
- [context] { return create_gpu_image(context); },
- // Create a texture image with mips
- //[context] { return create_gpu_image(context, true); },
- // Create a texture image in a another GrContext.
- [otherContextInfo] {
- auto restore = otherContextInfo.testContext()->makeCurrentAndAutoRestore();
- sk_sp<SkImage> otherContextImage = create_gpu_image(otherContextInfo.grContext());
- otherContextInfo.grContext()->flush();
- return otherContextImage;
- }
- };
-
+ create_image, create_codec_image, create_data_image,
+ // Create an image from a picture.
+ create_picture_image,
+ // Create a texture image.
+ [context] { return create_gpu_image(context, true, SkBudgeted::kYes); },
+ [context] { return create_gpu_image(context, false, SkBudgeted::kNo); },
+ // Create a texture image in a another GrContext.
+ [otherContextInfo] {
+ auto restore = otherContextInfo.testContext()->makeCurrentAndAutoRestore();
+ sk_sp<SkImage> otherContextImage = create_gpu_image(otherContextInfo.grContext());
+ otherContextInfo.grContext()->flush();
+ return otherContextImage;
+ }};
for (auto mipMapped : {GrMipMapped::kNo, GrMipMapped::kYes}) {
for (auto factory : imageFactories) {
sk_sp<SkImage> image(factory());
@@ -401,44 +398,49 @@
ERRORF(reporter, "Error creating image.");
continue;
}
-
- sk_sp<SkImage> texImage(image->makeTextureImage(context, mipMapped));
- if (!texImage) {
- GrContext* imageContext = as_IB(image)->context();
-
- // We expect to fail if image comes from a different GrContext.
- if (!image->isTextureBacked() || imageContext == context) {
- ERRORF(reporter, "makeTextureImage failed.");
+ GrTextureProxy* origProxy = nullptr;
+ if (auto sp = as_IB(image)->peekProxy()) {
+ origProxy = sp->asTextureProxy();
+ SkASSERT(origProxy);
+ }
+ for (auto budgeted : {SkBudgeted::kNo, SkBudgeted::kYes}) {
+ auto texImage = image->makeTextureImage(context, mipMapped, budgeted);
+ if (!texImage) {
+ GrContext* imageContext = as_IB(image)->context();
+ // We expect to fail if image comes from a different GrContext
+ if (!image->isTextureBacked() || imageContext == context) {
+ ERRORF(reporter, "makeTextureImage failed.");
+ }
+ continue;
}
- continue;
- }
- if (!texImage->isTextureBacked()) {
- ERRORF(reporter, "makeTextureImage returned non-texture image.");
- continue;
- }
- if (GrMipMapped::kYes == mipMapped &&
- as_IB(texImage)->peekProxy()->mipMapped() != mipMapped &&
- context->priv().caps()->mipMapSupport()) {
- ERRORF(reporter, "makeTextureImage returned non-mipmapped texture.");
- continue;
- }
- if (image->isTextureBacked()) {
- GrSurfaceProxy* origProxy = as_IB(image)->peekProxy();
- GrSurfaceProxy* copyProxy = as_IB(texImage)->peekProxy();
-
- if (origProxy->underlyingUniqueID() != copyProxy->underlyingUniqueID()) {
- SkASSERT(origProxy->asTextureProxy());
- if (GrMipMapped::kNo == mipMapped ||
- GrMipMapped::kYes == origProxy->asTextureProxy()->mipMapped()) {
+ if (!texImage->isTextureBacked()) {
+ ERRORF(reporter, "makeTextureImage returned non-texture image.");
+ continue;
+ }
+ GrTextureProxy* copyProxy = as_IB(texImage)->peekProxy()->asTextureProxy();
+ SkASSERT(copyProxy);
+ bool shouldBeMipped =
+ mipMapped == GrMipMapped::kYes && context->priv().caps()->mipMapSupport();
+ if (shouldBeMipped && copyProxy->mipMapped() == GrMipMapped::kNo) {
+ ERRORF(reporter, "makeTextureImage returned non-mipmapped texture.");
+ continue;
+ }
+ bool origIsMipped = origProxy && origProxy->mipMapped() == GrMipMapped::kYes;
+ if (image->isTextureBacked() && (!shouldBeMipped || origIsMipped)) {
+ if (origProxy->underlyingUniqueID() != copyProxy->underlyingUniqueID()) {
ERRORF(reporter, "makeTextureImage made unnecessary texture copy.");
}
+ } else {
+ auto* texProxy = as_IB(texImage)->peekProxy()->asTextureProxy();
+ REPORTER_ASSERT(reporter, !texProxy->getUniqueKey().isValid());
+ REPORTER_ASSERT(reporter, texProxy->isBudgeted() == budgeted);
}
- }
- if (image->width() != texImage->width() || image->height() != texImage->height()) {
- ERRORF(reporter, "makeTextureImage changed the image size.");
- }
- if (image->alphaType() != texImage->alphaType()) {
- ERRORF(reporter, "makeTextureImage changed image alpha type.");
+ if (image->width() != texImage->width() || image->height() != texImage->height()) {
+ ERRORF(reporter, "makeTextureImage changed the image size.");
+ }
+ if (image->alphaType() != texImage->alphaType()) {
+ ERRORF(reporter, "makeTextureImage changed image alpha type.");
+ }
}
}
}
diff --git a/tests/ProcessorTest.cpp b/tests/ProcessorTest.cpp
index bfbc1fe..d73c9fa 100644
--- a/tests/ProcessorTest.cpp
+++ b/tests/ProcessorTest.cpp
@@ -290,7 +290,7 @@
bitmap.installPixels(ii, rgbaData, ii.minRowBytes(),
[](void* addr, void* context) { delete[] (GrColor*)addr; }, nullptr);
bitmap.setImmutable();
- GrBitmapTextureMaker maker(context, bitmap);
+ GrBitmapTextureMaker maker(context, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto view = maker.view(GrMipMapped::kNo);
if (!view.proxy() || !view.proxy()->instantiate(resourceProvider)) {
return false;
@@ -313,7 +313,7 @@
bitmap.installPixels(ii, alphaData, ii.minRowBytes(),
[](void* addr, void* context) { delete[] (uint8_t*)addr; }, nullptr);
bitmap.setImmutable();
- GrBitmapTextureMaker maker(context, bitmap);
+ GrBitmapTextureMaker maker(context, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto view = maker.view(GrMipMapped::kNo);
if (!view.proxy() || !view.proxy()->instantiate(resourceProvider)) {
return false;
@@ -340,7 +340,7 @@
bitmap.installPixels(ii, data, ii.minRowBytes(),
[](void* addr, void* context) { delete[] (GrColor*)addr; }, nullptr);
bitmap.setImmutable();
- GrBitmapTextureMaker maker(context, bitmap);
+ GrBitmapTextureMaker maker(context, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
return maker.view(GrMipMapped::kNo);
}
diff --git a/tests/ReadWriteAlphaTest.cpp b/tests/ReadWriteAlphaTest.cpp
index b4ddf88..3c7fac3 100644
--- a/tests/ReadWriteAlphaTest.cpp
+++ b/tests/ReadWriteAlphaTest.cpp
@@ -66,7 +66,7 @@
SkBitmap bitmap;
bitmap.installPixels(ii, alphaDataCopy, ii.minRowBytes());
bitmap.setImmutable();
- GrBitmapTextureMaker maker(context, bitmap);
+ GrBitmapTextureMaker maker(context, bitmap, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto view = maker.view(GrMipMapped::kNo);
if (!view.proxy()) {
ERRORF(reporter, "Could not create alpha texture.");
diff --git a/tests/SpecialImageTest.cpp b/tests/SpecialImageTest.cpp
index 74523e7..1144b35 100644
--- a/tests/SpecialImageTest.cpp
+++ b/tests/SpecialImageTest.cpp
@@ -223,7 +223,7 @@
{
// gpu
- GrBitmapTextureMaker maker(context, bm);
+ GrBitmapTextureMaker maker(context, bm, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto view = maker.view(GrMipMapped::kNo);
if (!view) {
return;
@@ -254,7 +254,7 @@
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SpecialImage_Gpu, reporter, ctxInfo) {
GrContext* context = ctxInfo.grContext();
SkBitmap bm = create_bm();
- GrBitmapTextureMaker maker(context, bm);
+ GrBitmapTextureMaker maker(context, bm, GrImageTexGenPolicy::kNew_Uncached_Budgeted);
auto view = maker.view(GrMipMapped::kNo);
if (!view.proxy()) {
return;
diff --git a/tests/TextureProxyTest.cpp b/tests/TextureProxyTest.cpp
index 6570510..f55c900 100644
--- a/tests/TextureProxyTest.cpp
+++ b/tests/TextureProxyTest.cpp
@@ -229,7 +229,7 @@
}
sk_sp<SkImage> textureImg = rasterImg->makeTextureImage(context);
- REPORTER_ASSERT(reporter, 1 == proxyProvider->numUniqueKeyProxies_TestOnly());
+ REPORTER_ASSERT(reporter, 0 == proxyProvider->numUniqueKeyProxies_TestOnly());
REPORTER_ASSERT(reporter, 1 == cache->getResourceCount());
rasterImg = nullptr; // this invalidates the uniqueKey