aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Robert Phillips <robertphillips@google.com>2017-03-20 14:37:13 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-21 11:39:41 +0000
commit0db235bc0278887c344eb25b4681e9cca4cf892a (patch)
tree853a3e84db8d689e36ff5e6730ac38d77a621f14
parent53262d0ff466668bfbc76893ba5a581203269572 (diff)
Make SkImage_Gpu be deferred
This CL removes the GrTexture-based ctor forcing everyone to create deferred SkImage_Gpus. split out into: https://skia-review.googlesource.com/c/9106/ (Remove atlas creation from GrResourceProvider) Change-Id: I266bbe089c242fe54d5b7adcc7895aa5a39440a0 Reviewed-on: https://skia-review.googlesource.com/6680 Commit-Queue: Robert Phillips <robertphillips@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
-rw-r--r--gm/image_pict.cpp9
-rw-r--r--include/private/GrSurfaceProxy.h3
-rw-r--r--src/core/SkSpecialImage.cpp38
-rw-r--r--src/gpu/GrDrawOpAtlas.h1
-rw-r--r--src/gpu/SkGpuDevice.cpp13
-rw-r--r--src/gpu/SkGpuDevice.h4
-rw-r--r--src/gpu/SkGr.cpp9
-rw-r--r--src/gpu/SkGr.h5
-rw-r--r--src/image/SkImage.cpp17
-rw-r--r--src/image/SkImage_Base.h7
-rw-r--r--src/image/SkImage_Gpu.cpp69
-rw-r--r--src/image/SkImage_Gpu.h8
-rw-r--r--src/image/SkSurface_Gpu.cpp37
-rw-r--r--tests/SpecialImageTest.cpp2
-rw-r--r--tests/SurfaceTest.cpp2
15 files changed, 142 insertions, 82 deletions
diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp
index a6e0bdfcdd..883fd34725 100644
--- a/gm/image_pict.cpp
+++ b/gm/image_pict.cpp
@@ -344,6 +344,7 @@ protected:
static void draw_as_tex(SkCanvas* canvas, SkImageCacherator* cache, SkScalar x, SkScalar y) {
#if SK_SUPPORT_GPU
sk_sp<SkColorSpace> texColorSpace;
+ // MDB TODO: this should be lockAsTextureRef
sk_sp<GrTexture> texture(
cache->lockAsTexture(canvas->getGrContext(), GrSamplerParams::ClampBilerp(),
canvas->imageInfo().colorSpace(), &texColorSpace,
@@ -359,9 +360,13 @@ protected:
canvas->drawLine(r.left(), r.bottom(), r.right(), r.top(), paint);
return;
}
+
+ sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(texture));
+
// No API to draw a GrTexture directly, so we cheat and create a private image subclass
- sk_sp<SkImage> image(new SkImage_Gpu(cache->uniqueID(), kPremul_SkAlphaType,
- std::move(texture), std::move(texColorSpace),
+ sk_sp<SkImage> image(new SkImage_Gpu(canvas->getGrContext(),
+ cache->uniqueID(), kPremul_SkAlphaType,
+ std::move(proxy), std::move(texColorSpace),
SkBudgeted::kNo));
canvas->drawImage(image.get(), x, y);
#endif
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index 454916ef17..d7aa279994 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -281,10 +281,13 @@ public:
}
// Helper function that creates a temporary SurfaceContext to perform the copy
+ // It always returns a kExact-backed proxy bc it is used when converting an SkSpecialImage
+ // to an SkImage.
static sk_sp<GrTextureProxy> Copy(GrContext*, GrSurfaceProxy* src,
SkIRect srcRect, SkBudgeted);
// Copy the entire 'src'
+ // It always returns a kExact-backed proxy bc it is used in SkGpuDevice::snapSpecial
static sk_sp<GrTextureProxy> Copy(GrContext* context, GrSurfaceProxy* src,
SkBudgeted budgeted);
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index 411b0ea289..4c7e96188a 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -346,17 +346,10 @@ sk_sp<SkSpecialImage> SkSpecialImage::MakeFromRaster(const SkIRect& subset,
///////////////////////////////////////////////////////////////////////////////
#include "GrTexture.h"
-static sk_sp<SkImage> wrap_proxy_in_image(GrContext* context, GrTextureProxy* proxy,
+static sk_sp<SkImage> wrap_proxy_in_image(GrContext* context, sk_sp<GrTextureProxy> proxy,
SkAlphaType alphaType, sk_sp<SkColorSpace> colorSpace) {
- // TODO: add GrTextureProxy-backed SkImage_Gpus
- GrTexture* tex = proxy->instantiate(context->resourceProvider());
- if (!tex) {
- return nullptr;
- }
-
- return sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID, alphaType,
- sk_ref_sp(tex),
- std::move(colorSpace), SkBudgeted::kYes);
+ return sk_make_sp<SkImage_Gpu>(context, kNeedNewImageUniqueID, alphaType,
+ std::move(proxy), std::move(colorSpace), SkBudgeted::kYes);
}
class SkSpecialImage_Gpu : public SkSpecialImage_Base {
@@ -386,21 +379,16 @@ public:
SkRect dst = SkRect::MakeXYWH(x, y,
this->subset().width(), this->subset().height());
- // TODO: add GrTextureProxy-backed SkImage_Gpus
- GrTexture* tex = fTextureProxy->instantiate(fContext->resourceProvider());
- if (!tex) {
- return;
- }
-
// TODO: In this instance we know we're going to draw a sub-portion of the backing
// texture into the canvas so it is okay to wrap it in an SkImage. This poses
// some problems for full deferral however in that when the deferred SkImage_Gpu
// instantiates itself it is going to have to either be okay with having a larger
// than expected backing texture (unlikely) or the 'fit' of the SurfaceProxy needs
// to be tightened (if it is deferred).
- auto img = sk_sp<SkImage>(new SkImage_Gpu(this->uniqueID(), fAlphaType,
- sk_ref_sp(tex),
- fColorSpace, SkBudgeted::kNo));
+ sk_sp<SkImage> img = sk_sp<SkImage>(new SkImage_Gpu(canvas->getGrContext(),
+ this->uniqueID(), fAlphaType,
+ fTextureProxy,
+ fColorSpace, SkBudgeted::kNo));
canvas->drawImageRect(img, this->subset(),
dst, paint, SkCanvas::kStrict_SrcRectConstraint);
@@ -480,16 +468,22 @@ public:
fTextureProxy->width() == subset->width() &&
fTextureProxy->height() == subset->height()) {
// The existing GrTexture is already tight so reuse it in the SkImage
- return wrap_proxy_in_image(fContext, fTextureProxy.get(), fAlphaType, fColorSpace);
+ return wrap_proxy_in_image(fContext, fTextureProxy, fAlphaType, fColorSpace);
}
sk_sp<GrTextureProxy> subsetProxy(GrSurfaceProxy::Copy(fContext, fTextureProxy.get(),
*subset, SkBudgeted::kYes));
+ if (!subsetProxy) {
+ return nullptr;
+ }
- return wrap_proxy_in_image(fContext, subsetProxy.get(), fAlphaType, fColorSpace);
+ SkASSERT(subsetProxy->priv().isExact());
+ // MDB: this is acceptable (wrapping subsetProxy in an SkImage) bc Copy will
+ // return a kExact-backed proxy
+ return wrap_proxy_in_image(fContext, std::move(subsetProxy), fAlphaType, fColorSpace);
}
- return wrap_proxy_in_image(fContext, fTextureProxy.get(), fAlphaType, fColorSpace);
+ return wrap_proxy_in_image(fContext, fTextureProxy, fAlphaType, fColorSpace);
}
sk_sp<SkSurface> onMakeTightSurface(const SkImageFilter::OutputProperties& outProps,
diff --git a/src/gpu/GrDrawOpAtlas.h b/src/gpu/GrDrawOpAtlas.h
index c857d07703..1119e3de18 100644
--- a/src/gpu/GrDrawOpAtlas.h
+++ b/src/gpu/GrDrawOpAtlas.h
@@ -8,7 +8,6 @@
#ifndef GrDrawOpAtlas_DEFINED
#define GrDrawOpAtlas_DEFINED
-#include "GrTexture.h"
#include "SkPoint.h"
#include "SkTDArray.h"
#include "SkTInternalLList.h"
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 676dc2b9d9..8a6d973394 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -14,6 +14,7 @@
#include "GrImageTextureMaker.h"
#include "GrRenderTargetContextPriv.h"
#include "GrStyle.h"
+#include "GrSurfaceProxyPriv.h"
#include "GrTextureAdjuster.h"
#include "GrTextureProxy.h"
#include "GrTracing.h"
@@ -165,7 +166,9 @@ sk_sp<GrRenderTargetContext> SkGpuDevice::MakeRenderTargetContext(
}
GrPixelConfig config = SkImageInfo2GrPixelConfig(origInfo, *context->caps());
- return context->makeRenderTargetContext(SkBackingFit::kExact, // Why exact?
+ // This method is used to create SkGpuDevice's for SkSurface_Gpus. In this case
+ // they need to be exact.
+ return context->makeRenderTargetContext(SkBackingFit::kExact,
origInfo.width(), origInfo.height(),
config, origInfo.refColorSpace(), sampleCount,
origin, surfaceProps, budgeted);
@@ -245,16 +248,19 @@ void SkGpuDevice::replaceRenderTargetContext(bool shouldRetainContent) {
SkBudgeted budgeted = fRenderTargetContext->priv().isBudgeted();
+ // This entry point is used by SkSurface_Gpu::onCopyOnWrite so it must create a
+ // kExact-backed render target context.
sk_sp<GrRenderTargetContext> newRTC(MakeRenderTargetContext(
this->context(),
budgeted,
this->imageInfo(),
- fRenderTargetContext->numColorSamples(),
- fRenderTargetContext->origin(),
+ fRenderTargetContext->numColorSamples(),
+ fRenderTargetContext->origin(),
&this->surfaceProps()));
if (!newRTC) {
return;
}
+ SkASSERT(newRTC->asSurfaceProxy()->priv().isExact());
if (shouldRetainContent) {
if (fRenderTargetContext->wasAbandoned()) {
@@ -1326,6 +1332,7 @@ sk_sp<SkSpecialImage> SkGpuDevice::snapSpecial() {
const SkImageInfo ii = this->imageInfo();
const SkIRect srcRect = SkIRect::MakeWH(ii.width(), ii.height());
+ SkASSERT(proxy->priv().isExact());
return SkSpecialImage::MakeDeferredFromGpu(fContext.get(),
srcRect,
kNeedNewImageUniqueID_SpecialImage,
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 8c2bf04881..b40eaddcb1 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -48,9 +48,11 @@ public:
* New device that will create an offscreen renderTarget based on the ImageInfo and
* sampleCount. The Budgeted param controls whether the device's backing store counts against
* the resource cache budget. On failure, returns nullptr.
+ * This entry point creates a kExact backing store. It is used when creating SkGpuDevices
+ * for SkSurfaces.
*/
static sk_sp<SkGpuDevice> Make(GrContext*, SkBudgeted, const SkImageInfo&,
- int sampleCount, GrSurfaceOrigin,
+ int sampleCount, GrSurfaceOrigin,
const SkSurfaceProps*, InitContents);
~SkGpuDevice() override {}
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 18f2abb951..0b9b8aabcf 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -301,6 +301,15 @@ GrTexture* GrUploadMipMapToTexture(GrContext* ctx, const SkImageInfo& info,
mipLevelCount, 0, colorMode);
}
+sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext* ctx, const SkImageInfo& info,
+ const GrMipLevel* texels,
+ int mipLevelCount,
+ SkDestinationSurfaceColorMode colorMode) {
+ sk_sp<GrTexture> tex(GrUploadMipMapToTexture(ctx, info, texels, mipLevelCount, colorMode));
+
+ return GrSurfaceProxy::MakeWrapped(std::move(tex));
+}
+
GrTexture* GrRefCachedBitmapTexture(GrContext* ctx, const SkBitmap& bitmap,
const GrSamplerParams& params, SkScalar scaleAdjust[2]) {
// Caller doesn't care about the texture's color space (they can always get it from the bitmap)
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index 993bf839bb..b9fa0e8867 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -236,6 +236,11 @@ sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider*,
GrTexture* GrUploadMipMapToTexture(GrContext*, const SkImageInfo&, const GrMipLevel* texels,
int mipLevelCount, SkDestinationSurfaceColorMode colorMode);
+sk_sp<GrTextureProxy> GrUploadMipMapToTextureProxy(GrContext*, const SkImageInfo&,
+ const GrMipLevel* texels,
+ int mipLevelCount,
+ SkDestinationSurfaceColorMode colorMode);
+
sk_sp<GrTexture> GrMakeCachedBitmapTexture(GrContext*, const SkBitmap&,
const GrSamplerParams&, SkScalar scaleAdjust[2]);
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index 6217f4ecda..fe6369ed35 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -169,25 +169,14 @@ sk_sp<SkImage> SkImage::makeSubset(const SkIRect& subset) const {
#if SK_SUPPORT_GPU
GrTexture* SkImage::getTexture() const {
- return as_IB(this)->peekTexture();
+ return as_IB(this)->onGetTexture();
}
-bool SkImage::isTextureBacked() const { return SkToBool(as_IB(this)->peekTexture()); }
+bool SkImage::isTextureBacked() const { return SkToBool(as_IB(this)->peekProxy()); }
GrBackendObject SkImage::getTextureHandle(bool flushPendingGrContextIO,
GrSurfaceOrigin* origin) const {
- GrTexture* texture = as_IB(this)->peekTexture();
- if (texture) {
- GrContext* context = texture->getContext();
- if (context && flushPendingGrContextIO) {
- context->prepareSurfaceForExternalIO(texture);
- }
- if (origin) {
- *origin = texture->origin();
- }
- return texture->getTextureHandle();
- }
- return 0;
+ return as_IB(this)->onGetTextureHandle(flushPendingGrContextIO, origin);
}
#else
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index 284af0d1a6..e0319ddc25 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -47,13 +47,20 @@ public:
virtual bool onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY, CachingHint) const = 0;
+ // MDB TODO: this entry point needs to go away
virtual GrTexture* peekTexture() const { return nullptr; }
#if SK_SUPPORT_GPU
+ virtual GrTextureProxy* peekProxy() const { return nullptr; }
virtual sk_sp<GrTextureProxy> asTextureProxyRef() const { return nullptr; }
virtual sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerParams&,
SkColorSpace*, sk_sp<SkColorSpace>*,
SkScalar scaleAdjust[2]) const = 0;
virtual sk_sp<GrTexture> refPinnedTexture(uint32_t* uniqueID) const { return nullptr; }
+ virtual GrBackendObject onGetTextureHandle(bool flushPendingGrContextIO,
+ GrSurfaceOrigin* origin) const {
+ return 0;
+ }
+ virtual GrTexture* onGetTexture() const { return nullptr; }
#endif
virtual SkImageCacherator* peekCacherator() const { return nullptr; }
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index bcd7275279..c9bc2ee9a4 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -36,17 +36,6 @@
#include "SkPixelRef.h"
#include "SkReadPixelsRec.h"
-SkImage_Gpu::SkImage_Gpu(uint32_t uniqueID, SkAlphaType at, sk_sp<GrTexture> tex,
- sk_sp<SkColorSpace> colorSpace, SkBudgeted budgeted)
- : INHERITED(tex->width(), tex->height(), uniqueID)
- , fContext(tex->getContext())
- , fProxy(GrSurfaceProxy::MakeWrapped(std::move(tex)))
- , fAlphaType(at)
- , fBudgeted(budgeted)
- , fColorSpace(std::move(colorSpace))
- , fAddedRasterVersionToCache(false) {
-}
-
SkImage_Gpu::SkImage_Gpu(GrContext* context, uint32_t uniqueID, SkAlphaType at,
sk_sp<GrTextureProxy> proxy,
sk_sp<SkColorSpace> colorSpace, SkBudgeted budgeted)
@@ -165,6 +154,33 @@ static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes)
}
}
+GrBackendObject SkImage_Gpu::onGetTextureHandle(bool flushPendingGrContextIO,
+ GrSurfaceOrigin* origin) const {
+ GrTextureProxy* proxy = this->peekProxy();
+ SkASSERT(proxy);
+
+ GrSurface* surface = proxy->instantiate(fContext->resourceProvider());
+ if (surface && surface->asTexture()) {
+ if (flushPendingGrContextIO) {
+ fContext->prepareSurfaceForExternalIO(surface);
+ }
+ if (origin) {
+ *origin = surface->origin();
+ }
+ return surface->asTexture()->getTextureHandle();
+ }
+ return 0;
+}
+
+GrTexture* SkImage_Gpu::onGetTexture() const {
+ GrTextureProxy* proxy = this->peekProxy();
+ if (!proxy) {
+ return nullptr;
+ }
+
+ return proxy->instantiate(fContext->resourceProvider());
+}
+
bool SkImage_Gpu::onReadYUV8Planes(const SkISize sizes[3], void* const planes[3],
const size_t rowBytes[3], SkYUVColorSpace colorSpace) const {
if (GrTextureToYUVPlanes(fContext, fProxy, sizes, planes, rowBytes, colorSpace)) {
@@ -251,6 +267,7 @@ static sk_sp<SkImage> new_wrapped_texture_common(GrContext* ctx, const GrBackend
if (desc.fWidth <= 0 || desc.fHeight <= 0) {
return nullptr;
}
+
sk_sp<GrTexture> tex = ctx->resourceProvider()->wrapBackendTexture(desc, ownership);
if (!tex) {
return nullptr;
@@ -261,8 +278,9 @@ static sk_sp<SkImage> new_wrapped_texture_common(GrContext* ctx, const GrBackend
const SkBudgeted budgeted = (kAdoptAndCache_GrWrapOwnership == ownership)
? SkBudgeted::kYes : SkBudgeted::kNo;
- return sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
- at, std::move(tex), std::move(colorSpace), budgeted);
+ sk_sp<GrTextureProxy> proxy(GrSurfaceProxy::MakeWrapped(std::move(tex)));
+ return sk_make_sp<SkImage_Gpu>(ctx, kNeedNewImageUniqueID,
+ at, std::move(proxy), std::move(colorSpace), budgeted);
}
sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx, const GrBackendTextureDesc& desc,
@@ -388,7 +406,8 @@ sk_sp<SkImage> SkImage::MakeFromNV12TexturesCopy(GrContext* ctx, SkYUVColorSpace
std::move(imageColorSpace));
}
-static sk_sp<SkImage> create_image_from_maker(GrTextureMaker* maker, SkAlphaType at, uint32_t id,
+static sk_sp<SkImage> create_image_from_maker(GrContext* context,
+ GrTextureMaker* maker, SkAlphaType at, uint32_t id,
SkColorSpace* dstColorSpace) {
sk_sp<SkColorSpace> texColorSpace;
sk_sp<GrTexture> texture(maker->refTextureForParams(GrSamplerParams::ClampNoFilter(),
@@ -396,7 +415,8 @@ static sk_sp<SkImage> create_image_from_maker(GrTextureMaker* maker, SkAlphaType
if (!texture) {
return nullptr;
}
- return sk_make_sp<SkImage_Gpu>(id, at, std::move(texture),
+ sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeWrapped(std::move(texture));
+ return sk_make_sp<SkImage_Gpu>(context, id, at, std::move(proxy),
std::move(texColorSpace), SkBudgeted::kNo);
}
@@ -410,12 +430,14 @@ sk_sp<SkImage> SkImage::makeTextureImage(GrContext* context, SkColorSpace* dstCo
if (SkImageCacherator* cacher = as_IB(this)->peekCacherator()) {
GrImageTextureMaker maker(context, cacher, this, kDisallow_CachingHint);
- return create_image_from_maker(&maker, this->alphaType(), this->uniqueID(), dstColorSpace);
+ return create_image_from_maker(context, &maker, this->alphaType(),
+ this->uniqueID(), dstColorSpace);
}
if (const SkBitmap* bmp = as_IB(this)->onPeekBitmap()) {
GrBitmapTextureMaker maker(context, *bmp);
- return create_image_from_maker(&maker, this->alphaType(), this->uniqueID(), dstColorSpace);
+ return create_image_from_maker(context, &maker, this->alphaType(),
+ this->uniqueID(), dstColorSpace);
}
return nullptr;
}
@@ -824,13 +846,16 @@ sk_sp<SkImage> SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo&
if (!ctx) {
return nullptr;
}
- sk_sp<GrTexture> texture(GrUploadMipMapToTexture(ctx, info, texels, mipLevelCount, colorMode));
- if (!texture) {
+ sk_sp<GrTextureProxy> proxy(GrUploadMipMapToTextureProxy(ctx, info, texels, mipLevelCount,
+ colorMode));
+ if (!proxy) {
return nullptr;
}
- return sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
- info.alphaType(), std::move(texture),
- sk_ref_sp(info.colorSpace()), budgeted);
+
+ SkASSERT(proxy->priv().isExact());
+ return sk_make_sp<SkImage_Gpu>(ctx, kNeedNewImageUniqueID,
+ info.alphaType(), std::move(proxy),
+ info.refColorSpace(), budgeted);
}
sk_sp<SkImage> SkImage_Gpu::onMakeColorSpace(sk_sp<SkColorSpace> colorSpace) const {
diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h
index 53c38dc278..858419156c 100644
--- a/src/image/SkImage_Gpu.h
+++ b/src/image/SkImage_Gpu.h
@@ -21,7 +21,6 @@
class SkImage_Gpu : public SkImage_Base {
public:
- SkImage_Gpu(uint32_t uniqueID, SkAlphaType, sk_sp<GrTexture>, sk_sp<SkColorSpace>, SkBudgeted);
SkImage_Gpu(GrContext*, uint32_t uniqueID, SkAlphaType, sk_sp<GrTextureProxy>,
sk_sp<SkColorSpace>, SkBudgeted);
~SkImage_Gpu() override;
@@ -34,6 +33,9 @@ public:
sk_sp<SkColorSpace>*, SkScalar scaleAdjust[2]) const override;
sk_sp<SkImage> onMakeSubset(const SkIRect&) const override;
+ GrTextureProxy* peekProxy() const override {
+ return fProxy.get();
+ }
GrTexture* peekTexture() const override {
return fProxy->instantiate(fContext->resourceProvider());
}
@@ -43,10 +45,14 @@ public:
sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerParams&, SkColorSpace*,
sk_sp<SkColorSpace>*,
SkScalar scaleAdjust[2]) const override;
+
sk_sp<GrTexture> refPinnedTexture(uint32_t* uniqueID) const override {
*uniqueID = this->uniqueID();
return sk_ref_sp(this->peekTexture());
}
+ GrBackendObject onGetTextureHandle(bool flushPendingGrContextIO,
+ GrSurfaceOrigin* origin) const override;
+ GrTexture* onGetTexture() const override;
bool onReadYUV8Planes(const SkISize sizes[3], void* const planes[3],
const size_t rowBytes[3], SkYUVColorSpace colorSpace) const override;
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index b610c9c9a1..fdbbf82779 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -8,14 +8,15 @@
#include "SkSurface_Gpu.h"
#include "GrContextPriv.h"
+#include "GrRenderTargetContextPriv.h"
#include "GrResourceProvider.h"
+
#include "SkCanvas.h"
#include "SkColorSpace_Base.h"
#include "SkGpuDevice.h"
#include "SkImage_Base.h"
#include "SkImage_Gpu.h"
#include "SkImagePriv.h"
-#include "GrRenderTargetContextPriv.h"
#include "SkSurface_Base.h"
#if SK_SUPPORT_GPU
@@ -23,6 +24,7 @@
SkSurface_Gpu::SkSurface_Gpu(sk_sp<SkGpuDevice> device)
: INHERITED(device->width(), device->height(), &device->surfaceProps())
, fDevice(std::move(device)) {
+ SkASSERT(fDevice->accessRenderTargetContext()->asSurfaceProxy()->priv().isExact());
}
SkSurface_Gpu::~SkSurface_Gpu() {
@@ -91,38 +93,45 @@ sk_sp<SkImage> SkSurface_Gpu::onNewImageSnapshot() {
GrContext* ctx = fDevice->context();
- GrSurfaceProxy* srcProxy = rtc->asSurfaceProxy();
- sk_sp<GrSurfaceContext> copyCtx;
+ if (!rtc->asSurfaceProxy()) {
+ return nullptr;
+ }
+
+ SkBudgeted budgeted = rtc->asSurfaceProxy()->isBudgeted();
+
+ sk_sp<GrTextureProxy> srcProxy = rtc->asTextureProxyRef();
// If the original render target is a buffer originally created by the client, then we don't
// want to ever retarget the SkSurface at another buffer we create. Force a copy now to avoid
// copy-on-write.
if (!srcProxy || rtc->priv().refsWrappedObjects()) {
+ // MDB TODO: replace this with GrSurfaceProxy::Copy?
GrSurfaceDesc desc = rtc->desc();
desc.fFlags = desc.fFlags & ~kRenderTarget_GrSurfaceFlag;
- copyCtx = ctx->contextPriv().makeDeferredSurfaceContext(desc,
+ sk_sp<GrSurfaceContext> copyCtx = ctx->contextPriv().makeDeferredSurfaceContext(
+ desc,
SkBackingFit::kExact,
- srcProxy->isBudgeted());
+ budgeted);
if (!copyCtx) {
return nullptr;
}
- if (!copyCtx->copy(srcProxy)) {
+ if (!copyCtx->copy(rtc->asSurfaceProxy())) {
return nullptr;
}
- srcProxy = copyCtx->asSurfaceProxy();
+ srcProxy = copyCtx->asTextureProxyRef();
}
- // TODO: add proxy-backed SkImage_Gpu
- GrTexture* tex = srcProxy->instantiate(ctx->resourceProvider())->asTexture();
-
const SkImageInfo info = fDevice->imageInfo();
sk_sp<SkImage> image;
- if (tex) {
- image = sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
- info.alphaType(), sk_ref_sp(tex),
- sk_ref_sp(info.colorSpace()), srcProxy->isBudgeted());
+ if (srcProxy) {
+ // The renderTargetContext coming out of SkGpuDevice should always be exact and the
+ // above copy creates a kExact surfaceContext.
+ SkASSERT(srcProxy->priv().isExact());
+ image = sk_make_sp<SkImage_Gpu>(ctx, kNeedNewImageUniqueID,
+ info.alphaType(), std::move(srcProxy),
+ info.refColorSpace(), budgeted);
}
return image;
}
diff --git a/tests/SpecialImageTest.cpp b/tests/SpecialImageTest.cpp
index 6c1f1bc04a..70d6fd4b38 100644
--- a/tests/SpecialImageTest.cpp
+++ b/tests/SpecialImageTest.cpp
@@ -120,7 +120,7 @@ static void test_image(const sk_sp<SkSpecialImage>& img, skiatest::Reporter* rep
REPORTER_ASSERT(reporter, tightImg->width() == subset.width());
REPORTER_ASSERT(reporter, tightImg->height() == subset.height());
- REPORTER_ASSERT(reporter, isGPUBacked == !!tightImg->isTextureBacked());
+ REPORTER_ASSERT(reporter, isGPUBacked == tightImg->isTextureBacked());
SkPixmap tmpPixmap;
REPORTER_ASSERT(reporter, isGPUBacked != !!tightImg->peekPixels(&tmpPixmap));
}
diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp
index 6264196640..f620cff996 100644
--- a/tests/SurfaceTest.cpp
+++ b/tests/SurfaceTest.cpp
@@ -451,7 +451,7 @@ static SkBudgeted is_budgeted(const sk_sp<SkSurface>& surf) {
}
static SkBudgeted is_budgeted(SkImage* image) {
- return ((SkImage_Gpu*)image)->peekTexture()->resourcePriv().isBudgeted();
+ return ((SkImage_Gpu*)image)->peekProxy()->isBudgeted();
}
static SkBudgeted is_budgeted(const sk_sp<SkImage> image) {