aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/image_pict.cpp3
-rw-r--r--include/gpu/GrSurfaceContext.h8
-rw-r--r--include/gpu/GrTextureContext.h2
-rw-r--r--include/private/GrSurfaceProxy.h3
-rw-r--r--src/core/SkSpecialImage.cpp8
-rw-r--r--src/gpu/GrRenderTargetContext.cpp6
-rw-r--r--src/gpu/GrRenderTargetContext.h2
-rw-r--r--src/gpu/GrSurfaceProxy.cpp17
-rw-r--r--src/gpu/GrSurfaceProxyPriv.h12
-rw-r--r--src/gpu/GrTextureContext.cpp6
-rw-r--r--src/image/SkImageShader.cpp18
-rw-r--r--src/image/SkImage_Base.h3
-rw-r--r--src/image/SkImage_Generator.cpp24
-rw-r--r--src/image/SkImage_Gpu.cpp130
-rw-r--r--src/image/SkImage_Gpu.h34
-rw-r--r--src/image/SkImage_Raster.cpp25
-rw-r--r--src/image/SkSurface_Gpu.cpp2
-rw-r--r--tools/gpu/GrTest.cpp12
18 files changed, 209 insertions, 106 deletions
diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp
index 1f273dc615..a6e0bdfcdd 100644
--- a/gm/image_pict.cpp
+++ b/gm/image_pict.cpp
@@ -360,8 +360,7 @@ protected:
return;
}
// No API to draw a GrTexture directly, so we cheat and create a private image subclass
- sk_sp<SkImage> image(new SkImage_Gpu(cache->info().width(), cache->info().height(),
- cache->uniqueID(), kPremul_SkAlphaType,
+ sk_sp<SkImage> image(new SkImage_Gpu(cache->uniqueID(), kPremul_SkAlphaType,
std::move(texture), std::move(texColorSpace),
SkBudgeted::kNo));
canvas->drawImage(image.get(), x, y);
diff --git a/include/gpu/GrSurfaceContext.h b/include/gpu/GrSurfaceContext.h
index ed049be506..109c4a0ffa 100644
--- a/include/gpu/GrSurfaceContext.h
+++ b/include/gpu/GrSurfaceContext.h
@@ -74,12 +74,12 @@ public:
* unsupported pixel config.
*/
bool readPixels(const SkImageInfo& dstInfo, void* dstBuffer, size_t dstRowBytes,
- int x, int y) {
- return this->onReadPixels(dstInfo, dstBuffer, dstRowBytes, x, y);
+ int x, int y, uint32_t flags = 0) {
+ return this->onReadPixels(dstInfo, dstBuffer, dstRowBytes, x, y, flags);
}
/**
- * Writes a rectangle of pixels [srcInfo, srcBuffer, srcRowbytes] into the
+ * Writes a rectangle of pixels [srcInfo, srcBuffer, srcRowbytes] into the
* renderTargetContext at the specified position.
* @param srcInfo image info for the source pixels
* @param srcBuffer source for the write
@@ -137,7 +137,7 @@ private:
const SkIRect& srcRect,
const SkIPoint& dstPoint) = 0;
virtual bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
- size_t dstRowBytes, int x, int y) = 0;
+ size_t dstRowBytes, int x, int y, uint32_t flags) = 0;
virtual bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
size_t srcRowBytes, int x, int y, uint32_t flags) = 0;
diff --git a/include/gpu/GrTextureContext.h b/include/gpu/GrTextureContext.h
index 6b2f0e379f..d5e1eb9b7c 100644
--- a/include/gpu/GrTextureContext.h
+++ b/include/gpu/GrTextureContext.h
@@ -48,7 +48,7 @@ private:
bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
- size_t dstRowBytes, int x, int y) override;
+ size_t dstRowBytes, int x, int y, uint32_t flags) override;
bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
size_t srcRowBytes, int x, int y, uint32_t flags) override;
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index dd06f323fb..31e0f1d1ca 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -331,7 +331,8 @@ protected:
// For wrapped resources, 'fDesc' will always be filled in from the wrapped resource.
const GrSurfaceDesc fDesc;
const SkBackingFit fFit; // always exact for wrapped resources
- const SkBudgeted fBudgeted; // set from the backing resource for wrapped resources
+ mutable SkBudgeted fBudgeted; // set from the backing resource for wrapped resources
+ // mutable bc of SkSurface/SkImage wishy-washiness
const uint32_t fFlags;
const UniqueID fUniqueID; // set from the backing resource for wrapped resources
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index 1940fb9fc7..dc717095a8 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -353,10 +353,7 @@ static sk_sp<SkImage> wrap_proxy_in_image(GrContext* context, GrTextureProxy* pr
return nullptr;
}
- // Note that we're explicitly using the GrTexture's width & height here b.c. SkImages
- // must be tight.
- return sk_make_sp<SkImage_Gpu>(tex->width(), tex->height(),
- kNeedNewImageUniqueID, alphaType,
+ return sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID, alphaType,
sk_ref_sp(tex),
std::move(colorSpace), SkBudgeted::kYes);
}
@@ -400,8 +397,7 @@ public:
// 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(tex->width(), tex->height(),
- this->uniqueID(), fAlphaType,
+ auto img = sk_sp<SkImage>(new SkImage_Gpu(this->uniqueID(), fAlphaType,
sk_ref_sp(tex),
fColorSpace, SkBudgeted::kNo));
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 5937054dcf..051af824b0 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -157,16 +157,16 @@ bool GrRenderTargetContext::onCopy(GrSurfaceProxy* srcProxy,
// TODO: move this (and GrTextureContext::onReadPixels) to GrSurfaceContext?
bool GrRenderTargetContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
- size_t dstRowBytes, int x, int y) {
+ size_t dstRowBytes, int x, int y, uint32_t flags) {
// TODO: teach GrRenderTarget to take ImageInfo directly to specify the src pixels
GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps());
if (kUnknown_GrPixelConfig == config) {
return false;
}
- uint32_t flags = 0;
+ // TODO: this seems to duplicate code in SkImage_Gpu::onReadPixels
if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
- flags = GrContext::kUnpremul_PixelOpsFlag;
+ flags |= GrContext::kUnpremul_PixelOpsFlag;
}
// Deferral of the VRAM resources must end in this instance anyway
diff --git a/src/gpu/GrRenderTargetContext.h b/src/gpu/GrRenderTargetContext.h
index 479fc932e8..dc4944abf9 100644
--- a/src/gpu/GrRenderTargetContext.h
+++ b/src/gpu/GrRenderTargetContext.h
@@ -469,7 +469,7 @@ private:
bool onCopy(GrSurfaceProxy* src, const SkIRect& srcRect, const SkIPoint& dstPoint) override;
bool onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
- size_t dstRowBytes, int x, int y) override;
+ size_t dstRowBytes, int x, int y, uint32_t flags) override;
bool onWritePixels(const SkImageInfo& srcInfo, const void* srcBuffer,
size_t srcRowBytes, int x, int y, uint32_t flags) override;
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 0c497506e1..180a7f06b2 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -6,6 +6,7 @@
*/
#include "GrSurfaceProxy.h"
+#include "GrSurfaceProxyPriv.h"
#include "GrCaps.h"
#include "GrContext.h"
@@ -302,3 +303,19 @@ sk_sp<GrSurfaceContext> GrSurfaceProxy::TestCopy(GrContext* context, const GrSur
return dstContext;
}
+
+void GrSurfaceProxyPriv::makeBudgeted() {
+ if (fProxy->fTarget) {
+ fProxy->fTarget->resourcePriv().makeBudgeted();
+ }
+
+ fProxy->fBudgeted = SkBudgeted::kYes;
+}
+
+void GrSurfaceProxyPriv::makeUnbudgeted() {
+ if (fProxy->fTarget) {
+ fProxy->fTarget->resourcePriv().makeUnbudgeted();
+ }
+
+ fProxy->fBudgeted = SkBudgeted::kNo;
+}
diff --git a/src/gpu/GrSurfaceProxyPriv.h b/src/gpu/GrSurfaceProxyPriv.h
index 4e43daea9d..390806f0c0 100644
--- a/src/gpu/GrSurfaceProxyPriv.h
+++ b/src/gpu/GrSurfaceProxyPriv.h
@@ -23,6 +23,18 @@ public:
// Don't abuse this!!!!!!!
bool isExact() const { return SkBackingFit::kExact == fProxy->fFit; }
+ // These next two are very specialized and wacky - don't use them!
+
+ // In the case where an unbudgeted, deferred SkSurface_Gpu has snapped a budgeted, deferred
+ // SkImage_Gpu, this serves to propagate the budgeting forward in time. For now, and
+ // presumably forever, this will not change any flushing decisions but may make Ganesh
+ // appear to have gone over budget. In the case of non-deferred proxies this will immediately
+ // propagate the budget decision to the resource, which in itself is dubious.
+ void makeBudgeted();
+ // In the case where a budgeted, deferred SkSurface_Gpu has snapped an unbudgeted, deferred
+ // SkImage_Gpu, this serves to propagate the lack of budgeting forward in time.
+ void makeUnbudgeted();
+
private:
explicit GrSurfaceProxyPriv(GrSurfaceProxy* proxy) : fProxy(proxy) {}
GrSurfaceProxyPriv(const GrSurfaceProxyPriv&) {} // unimpl
diff --git a/src/gpu/GrTextureContext.cpp b/src/gpu/GrTextureContext.cpp
index ffcddbc289..0fbc951ff3 100644
--- a/src/gpu/GrTextureContext.cpp
+++ b/src/gpu/GrTextureContext.cpp
@@ -109,16 +109,16 @@ bool GrTextureContext::onCopy(GrSurfaceProxy* srcProxy,
// TODO: move this (and GrRenderTargetContext::onReadPixels) to GrSurfaceContext?
bool GrTextureContext::onReadPixels(const SkImageInfo& dstInfo, void* dstBuffer,
- size_t dstRowBytes, int x, int y) {
+ size_t dstRowBytes, int x, int y, uint32_t flags) {
// TODO: teach GrTexture to take ImageInfo directly to specify the src pixels
GrPixelConfig config = SkImageInfo2GrPixelConfig(dstInfo, *fContext->caps());
if (kUnknown_GrPixelConfig == config) {
return false;
}
- uint32_t flags = 0;
+ // TODO: this seems to duplicate code in SkImage_Gpu::onReadPixels
if (kUnpremul_SkAlphaType == dstInfo.alphaType()) {
- flags = GrContext::kUnpremul_PixelOpsFlag;
+ flags |= GrContext::kUnpremul_PixelOpsFlag;
}
// Deferral of the VRAM resources must end in this instance anyway
diff --git a/src/image/SkImageShader.cpp b/src/image/SkImageShader.cpp
index 4f739f3893..de225ccd27 100644
--- a/src/image/SkImageShader.cpp
+++ b/src/image/SkImageShader.cpp
@@ -154,25 +154,29 @@ sk_sp<GrFragmentProcessor> SkImageShader::asFragmentProcessor(const AsFPArgs& ar
GrSamplerParams params(tm, textureFilterMode);
sk_sp<SkColorSpace> texColorSpace;
SkScalar scaleAdjust[2] = { 1.0f, 1.0f };
- sk_sp<GrTexture> texture(as_IB(fImage)->asTextureRef(args.fContext, params, args.fDstColorSpace,
- &texColorSpace, scaleAdjust));
- if (!texture) {
+ sk_sp<GrTextureProxy> proxy(as_IB(fImage)->asTextureProxyRef(args.fContext, params,
+ args.fDstColorSpace,
+ &texColorSpace, scaleAdjust));
+ if (!proxy) {
return nullptr;
}
+ bool isAlphaOnly = GrPixelConfigIsAlphaOnly(proxy->config());
+
lmInverse.postScale(scaleAdjust[0], scaleAdjust[1]);
sk_sp<GrColorSpaceXform> colorSpaceXform = GrColorSpaceXform::Make(texColorSpace.get(),
args.fDstColorSpace);
sk_sp<GrFragmentProcessor> inner;
if (doBicubic) {
- inner = GrBicubicEffect::Make(texture.get(), std::move(colorSpaceXform), lmInverse, tm);
+ inner = GrBicubicEffect::Make(args.fContext, std::move(proxy), std::move(colorSpaceXform),
+ lmInverse, tm);
} else {
- inner = GrSimpleTextureEffect::Make(texture.get(), std::move(colorSpaceXform),
- lmInverse, params);
+ inner = GrSimpleTextureEffect::Make(args.fContext, std::move(proxy),
+ std::move(colorSpaceXform), lmInverse, params);
}
- if (GrPixelConfigIsAlphaOnly(texture->config())) {
+ if (isAlphaOnly) {
return inner;
}
return sk_sp<GrFragmentProcessor>(GrFragmentProcessor::MulOutputByInputAlpha(std::move(inner)));
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index cc5335833f..e08d7610f7 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -50,6 +50,9 @@ public:
virtual GrTexture* peekTexture() const { return nullptr; }
#if SK_SUPPORT_GPU
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; }
#endif
virtual SkImageCacherator* peekCacherator() const { return nullptr; }
diff --git a/src/image/SkImage_Generator.cpp b/src/image/SkImage_Generator.cpp
index 14516e4d5c..ae3f9f83f4 100644
--- a/src/image/SkImage_Generator.cpp
+++ b/src/image/SkImage_Generator.cpp
@@ -26,7 +26,13 @@ public:
return fCache.info().alphaType();
}
- bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY, CachingHint) const override;
+ bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY,
+ CachingHint) const override;
+#if SK_SUPPORT_GPU
+ sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerParams&,
+ SkColorSpace*, sk_sp<SkColorSpace>*,
+ SkScalar scaleAdjust[2]) const override;
+#endif
SkImageCacherator* peekCacherator() const override { return &fCache; }
SkData* onRefEncoded(GrContext*) const override;
sk_sp<SkImage> onMakeSubset(const SkIRect&) const override;
@@ -77,6 +83,22 @@ bool SkImage_Generator::getROPixels(SkBitmap* bitmap, SkColorSpace* dstColorSpac
return fCache.lockAsBitmap(nullptr, bitmap, this, dstColorSpace, chint);
}
+#if SK_SUPPORT_GPU
+sk_sp<GrTextureProxy> SkImage_Generator::asTextureProxyRef(GrContext* context,
+ const GrSamplerParams& params,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* texColorSpace,
+ SkScalar scaleAdjust[2]) const {
+ sk_sp<GrTexture> tex(fCache.lockAsTexture(context, params, dstColorSpace,
+ texColorSpace, this, scaleAdjust));
+ if (!tex) {
+ return nullptr;
+ }
+
+ return GrSurfaceProxy::MakeWrapped(std::move(tex));
+}
+#endif
+
GrTexture* SkImage_Generator::asTextureRef(GrContext* ctx, const GrSamplerParams& params,
SkColorSpace* dstColorSpace,
sk_sp<SkColorSpace>* texColorSpace,
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 9ca790c300..a3649acf19 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -35,17 +35,27 @@
#include "SkPixelRef.h"
#include "SkReadPixelsRec.h"
-SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, sk_sp<GrTexture> tex,
+SkImage_Gpu::SkImage_Gpu(uint32_t uniqueID, SkAlphaType at, sk_sp<GrTexture> tex,
sk_sp<SkColorSpace> colorSpace, SkBudgeted budgeted)
- : INHERITED(w, h, uniqueID)
- , fTexture(std::move(tex))
+ : 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)
-{
- SkASSERT(fTexture->width() == w);
- SkASSERT(fTexture->height() == h);
+ , fAddedRasterVersionToCache(false) {
+}
+
+SkImage_Gpu::SkImage_Gpu(GrContext* context, uint32_t uniqueID, SkAlphaType at,
+ sk_sp<GrTextureProxy> proxy,
+ sk_sp<SkColorSpace> colorSpace, SkBudgeted budgeted)
+ : INHERITED(proxy->width(), proxy->height(), uniqueID)
+ , fContext(context)
+ , fProxy(std::move(proxy))
+ , fAlphaType(at)
+ , fBudgeted(budgeted)
+ , fColorSpace(std::move(colorSpace))
+ , fAddedRasterVersionToCache(false) {
}
SkImage_Gpu::~SkImage_Gpu() {
@@ -62,10 +72,10 @@ extern void SkTextureImageApplyBudgetedDecision(SkImage* image) {
SkImageInfo SkImage_Gpu::onImageInfo() const {
SkColorType ct;
- if (!GrPixelConfigToColorType(fTexture->config(), &ct)) {
+ if (!GrPixelConfigToColorType(fProxy->config(), &ct)) {
ct = kUnknown_SkColorType;
}
- return SkImageInfo::Make(fTexture->width(), fTexture->height(), ct, fAlphaType, fColorSpace);
+ return SkImageInfo::Make(fProxy->width(), fProxy->height(), ct, fAlphaType, fColorSpace);
}
static SkImageInfo make_info(int w, int h, SkAlphaType at, sk_sp<SkColorSpace> colorSpace) {
@@ -81,12 +91,20 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst, SkColorSpace* dstColorSpace,
return true;
}
- if (!dst->tryAllocPixels(make_info(this->width(), this->height(), this->alphaType(),
- this->fColorSpace))) {
+ SkImageInfo ii = make_info(this->width(), this->height(), this->alphaType(),
+ sk_ref_sp(dstColorSpace));
+ if (!dst->tryAllocPixels(ii)) {
+ return false;
+ }
+
+ sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeWrappedSurfaceContext(
+ fProxy,
+ fColorSpace);
+ if (!sContext) {
return false;
}
- if (!fTexture->readPixels(0, 0, dst->width(), dst->height(), kSkia8888_GrPixelConfig,
- dst->getPixels(), dst->rowBytes())) {
+
+ if (!sContext->readPixels(dst->info(), dst->getPixels(), dst->rowBytes(), 0, 0)) {
return false;
}
@@ -98,18 +116,35 @@ bool SkImage_Gpu::getROPixels(SkBitmap* dst, SkColorSpace* dstColorSpace,
return true;
}
-sk_sp<GrTextureProxy> SkImage_Gpu::asTextureProxyRef() const {
- return GrSurfaceProxy::MakeWrapped(fTexture);
+sk_sp<GrTextureProxy> SkImage_Gpu::asTextureProxyRef(GrContext* context,
+ const GrSamplerParams& params,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* texColorSpace,
+ SkScalar scaleAdjust[2]) const {
+ sk_sp<GrTexture> tex(this->asTextureRef(context, params, dstColorSpace,
+ texColorSpace, scaleAdjust));
+
+ return GrSurfaceProxy::MakeWrapped(std::move(tex));
}
GrTexture* SkImage_Gpu::asTextureRef(GrContext* ctx, const GrSamplerParams& params,
SkColorSpace* dstColorSpace,
sk_sp<SkColorSpace>* texColorSpace,
SkScalar scaleAdjust[2]) const {
+ if (ctx != fContext) {
+ SkASSERT(0);
+ return nullptr;
+ }
+
if (texColorSpace) {
*texColorSpace = this->fColorSpace;
}
- GrTextureAdjuster adjuster(fTexture.get(), this->alphaType(), this->bounds(),
+ GrTexture* texture = fProxy->instantiate(fContext->resourceProvider());
+ if (!texture) {
+ return nullptr;
+ }
+
+ GrTextureAdjuster adjuster(texture, this->alphaType(), this->bounds(),
this->uniqueID(), this->fColorSpace.get());
return adjuster.refTextureSafeForParams(params, nullptr, scaleAdjust);
}
@@ -137,11 +172,8 @@ static void apply_premul(const SkImageInfo& info, void* pixels, size_t rowBytes)
bool SkImage_Gpu::onReadYUV8Planes(const SkISize sizes[3], void* const planes[3],
const size_t rowBytes[3], SkYUVColorSpace colorSpace) const {
- if (sk_sp<GrTextureProxy> proxy = as_IB(this)->asTextureProxyRef()) {
- if (GrTextureToYUVPlanes(fTexture->getContext(), std::move(proxy), sizes, planes,
- rowBytes, colorSpace)) {
- return true;
- }
+ if (GrTextureToYUVPlanes(fContext, fProxy, sizes, planes, rowBytes, colorSpace)) {
+ return true;
}
return INHERITED::onReadYUV8Planes(sizes, planes, rowBytes, colorSpace);
@@ -158,17 +190,25 @@ bool SkImage_Gpu::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
return false;
}
- GrPixelConfig config = SkImageInfo2GrPixelConfig(rec.fInfo, *fTexture->getContext()->caps());
+ // TODO: this seems to duplicate code in GrTextureContext::onReadPixels and
+ // GrRenderTargetContext::onReadPixels
uint32_t flags = 0;
if (kUnpremul_SkAlphaType == rec.fInfo.alphaType() && kPremul_SkAlphaType == fAlphaType) {
// let the GPU perform this transformation for us
flags = GrContext::kUnpremul_PixelOpsFlag;
}
- if (!fTexture->readPixels(fColorSpace.get(), rec.fX, rec.fY, rec.fInfo.width(),
- rec.fInfo.height(), config, rec.fInfo.colorSpace(), rec.fPixels,
- rec.fRowBytes, flags)) {
+
+ sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeWrappedSurfaceContext(
+ fProxy,
+ fColorSpace);
+ if (!sContext) {
+ return false;
+ }
+
+ if (!sContext->readPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY, flags)) {
return false;
}
+
// do we have to manually fix-up the alpha channel?
// src dst
// unpremul premul fix manually
@@ -184,12 +224,11 @@ bool SkImage_Gpu::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size
}
sk_sp<SkImage> SkImage_Gpu::onMakeSubset(const SkIRect& subset) const {
- GrContext* ctx = fTexture->getContext();
- GrSurfaceDesc desc = fTexture->desc();
+ GrSurfaceDesc desc = fProxy->desc();
desc.fWidth = subset.width();
desc.fHeight = subset.height();
- sk_sp<GrSurfaceContext> sContext(ctx->contextPriv().makeDeferredSurfaceContext(
+ sk_sp<GrSurfaceContext> sContext(fContext->contextPriv().makeDeferredSurfaceContext(
desc,
SkBackingFit::kExact,
fBudgeted));
@@ -197,24 +236,13 @@ sk_sp<SkImage> SkImage_Gpu::onMakeSubset(const SkIRect& subset) const {
return nullptr;
}
- // TODO: make gpu images be proxy-backed so we don't need to do this
- sk_sp<GrSurfaceProxy> tmpSrc(GrSurfaceProxy::MakeWrapped(fTexture));
- if (!tmpSrc) {
- return nullptr;
- }
-
- if (!sContext->copy(tmpSrc.get(), subset, SkIPoint::Make(0, 0))) {
+ if (!sContext->copy(fProxy.get(), subset, SkIPoint::Make(0, 0))) {
return nullptr;
}
- // TODO: make gpu images be proxy-backed so we don't need to do this
- GrSurface* subTx = sContext->asSurfaceProxy()->instantiate(ctx->resourceProvider());
- if (!subTx) {
- return nullptr;
- }
-
- return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID,
- fAlphaType, sk_ref_sp(subTx->asTexture()),
+ // MDB: this call is okay bc we know 'sContext' was kExact
+ return sk_make_sp<SkImage_Gpu>(fContext, kNeedNewImageUniqueID,
+ fAlphaType, sContext->asTextureProxyRef(),
fColorSpace, fBudgeted);
}
@@ -237,7 +265,7 @@ static sk_sp<SkImage> new_wrapped_texture_common(GrContext* ctx, const GrBackend
}
const SkBudgeted budgeted = SkBudgeted::kNo;
- return sk_make_sp<SkImage_Gpu>(desc.fWidth, desc.fHeight, kNeedNewImageUniqueID,
+ return sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
at, std::move(tex), std::move(colorSpace), budgeted);
}
@@ -332,7 +360,7 @@ static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac
sk_ref_sp(uProxy->asTextureProxy()),
sk_ref_sp(vProxy->asTextureProxy()), yuvSizes, colorSpace, nv12));
- const SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
+ const SkRect rect = SkRect::MakeIWH(width, height);
renderTargetContext->drawRect(GrNoClip(), std::move(paint), GrAA::kNo, SkMatrix::I(), rect);
@@ -340,8 +368,10 @@ static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac
return nullptr;
}
ctx->flushSurfaceWrites(renderTargetContext->accessRenderTarget());
- return sk_make_sp<SkImage_Gpu>(width, height, kNeedNewImageUniqueID,
- kOpaque_SkAlphaType, renderTargetContext->asTexture(),
+
+ // MDB: this call is okay bc we know 'renderTargetContext' was exact
+ return sk_make_sp<SkImage_Gpu>(ctx, kNeedNewImageUniqueID,
+ kOpaque_SkAlphaType, renderTargetContext->asTextureProxyRef(),
renderTargetContext->refColorSpace(), budgeted);
}
@@ -370,7 +400,7 @@ static sk_sp<SkImage> create_image_from_maker(GrTextureMaker* maker, SkAlphaType
if (!texture) {
return nullptr;
}
- return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), id, at, std::move(texture),
+ return sk_make_sp<SkImage_Gpu>(id, at, std::move(texture),
std::move(texColorSpace), SkBudgeted::kNo);
}
@@ -477,7 +507,7 @@ sk_sp<SkImage> SkImage::MakeTextureFromPixmap(GrContext* ctx, const SkPixmap& pi
if (!texture) {
return nullptr;
}
- return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNewImageUniqueID,
+ return sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
pixmap.alphaType(), std::move(texture),
sk_ref_sp(pixmap.info().colorSpace()), budgeted);
}
@@ -808,7 +838,7 @@ sk_sp<SkImage> SkImage::MakeTextureFromMipMap(GrContext* ctx, const SkImageInfo&
return nullptr;
}
texture->texturePriv().setMipColorMode(colorMode);
- return sk_make_sp<SkImage_Gpu>(texture->width(), texture->height(), kNeedNewImageUniqueID,
+ return sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
info.alphaType(), std::move(texture),
sk_ref_sp(info.colorSpace()), budgeted);
}
diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h
index 0ad44d3a59..c70c18ac78 100644
--- a/src/image/SkImage_Gpu.h
+++ b/src/image/SkImage_Gpu.h
@@ -10,6 +10,7 @@
#include "GrClip.h"
#include "GrGpuResourcePriv.h"
+#include "GrSurfaceProxyPriv.h"
#include "GrTexture.h"
#include "SkAtomics.h"
#include "SkBitmap.h"
@@ -20,12 +21,9 @@
class SkImage_Gpu : public SkImage_Base {
public:
- /**
- * An "image" can be a subset/window into a larger texture, so we explicit take the
- * width and height.
- */
- SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType, sk_sp<GrTexture>, sk_sp<SkColorSpace>,
- SkBudgeted);
+ 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;
SkImageInfo onImageInfo() const override;
@@ -33,22 +31,29 @@ public:
void applyBudgetDecision() const {
if (SkBudgeted::kYes == fBudgeted) {
- fTexture->resourcePriv().makeBudgeted();
+ fProxy->priv().makeBudgeted();
} else {
- fTexture->resourcePriv().makeUnbudgeted();
+ fProxy->priv().makeUnbudgeted();
}
}
bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override;
- GrTexture* asTextureRef(GrContext* ctx, const GrSamplerParams& params, SkColorSpace*,
+ GrTexture* asTextureRef(GrContext*, const GrSamplerParams&, SkColorSpace*,
sk_sp<SkColorSpace>*, SkScalar scaleAdjust[2]) const override;
sk_sp<SkImage> onMakeSubset(const SkIRect&) const override;
- GrTexture* peekTexture() const override { return fTexture.get(); }
- sk_sp<GrTextureProxy> asTextureProxyRef() const override;
+ GrTexture* peekTexture() const override {
+ return fProxy->instantiate(fContext->resourceProvider());
+ }
+ sk_sp<GrTextureProxy> asTextureProxyRef() const override {
+ return fProxy;
+ }
+ 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 fTexture;
+ return sk_ref_sp(this->peekTexture());
}
bool onReadYUV8Planes(const SkISize sizes[3], void* const planes[3],
@@ -57,11 +62,12 @@ public:
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
int srcX, int srcY, CachingHint) const override;
- GrContext* context() { return fTexture->getContext(); }
+ GrContext* context() { return fContext; }
sk_sp<SkColorSpace> refColorSpace() { return fColorSpace; }
private:
- sk_sp<GrTexture> fTexture;
+ GrContext* fContext;
+ sk_sp<GrTextureProxy> fProxy;
const SkAlphaType fAlphaType;
const SkBudgeted fBudgeted;
sk_sp<SkColorSpace> fColorSpace;
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 61be7b715a..220cc01b11 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -86,9 +86,16 @@ public:
bool onPeekPixels(SkPixmap*) const override;
const SkBitmap* onPeekBitmap() const override { return &fBitmap; }
- bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override;
+#if SK_SUPPORT_GPU
+ sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerParams&,
+ SkColorSpace*, sk_sp<SkColorSpace>*,
+ SkScalar scaleAdjust[2]) const override;
+#endif
+
GrTexture* asTextureRef(GrContext*, const GrSamplerParams&, SkColorSpace*,
sk_sp<SkColorSpace>*, SkScalar scaleAdjust[2]) const override;
+
+ bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override;
sk_sp<SkImage> onMakeSubset(const SkIRect&) const override;
SkPixelRef* getPixelRef() const { return fBitmap.pixelRef(); }
@@ -170,6 +177,18 @@ bool SkImage_Raster::getROPixels(SkBitmap* dst, SkColorSpace* dstColorSpace, Cac
return true;
}
+#if SK_SUPPORT_GPU
+sk_sp<GrTextureProxy> SkImage_Raster::asTextureProxyRef(GrContext* context,
+ const GrSamplerParams& params,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* texColorSpace,
+ SkScalar scaleAdjust[2]) const {
+ sk_sp<GrTexture> tex(this->asTextureRef(context, params, dstColorSpace, texColorSpace,
+ scaleAdjust));
+ return GrSurfaceProxy::MakeWrapped(std::move(tex));
+}
+#endif
+
GrTexture* SkImage_Raster::asTextureRef(GrContext* ctx, const GrSamplerParams& params,
SkColorSpace* dstColorSpace,
sk_sp<SkColorSpace>* texColorSpace,
@@ -192,9 +211,9 @@ GrTexture* SkImage_Raster::asTextureRef(GrContext* ctx, const GrSamplerParams& p
}
return GrRefCachedBitmapTexture(ctx, fBitmap, params, scaleAdjust);
-#endif
-
+#else
return nullptr;
+#endif
}
#if SK_SUPPORT_GPU
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index d1f6d24a0c..0bd34f8150 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -120,7 +120,7 @@ sk_sp<SkImage> SkSurface_Gpu::onNewImageSnapshot(SkBudgeted budgeted) {
const SkImageInfo info = fDevice->imageInfo();
sk_sp<SkImage> image;
if (tex) {
- image = sk_make_sp<SkImage_Gpu>(info.width(), info.height(), kNeedNewImageUniqueID,
+ image = sk_make_sp<SkImage_Gpu>(kNeedNewImageUniqueID,
info.alphaType(), sk_ref_sp(tex),
sk_ref_sp(info.colorSpace()), budgeted);
}
diff --git a/tools/gpu/GrTest.cpp b/tools/gpu/GrTest.cpp
index fa0556d11f..15faffadac 100644
--- a/tools/gpu/GrTest.cpp
+++ b/tools/gpu/GrTest.cpp
@@ -130,15 +130,9 @@ sk_sp<SkImage> GrContext::getFontAtlasImage_ForTesting(GrMaskFormat format) {
return nullptr;
}
- GrTexture* tex = proxy->instantiate(this->resourceProvider());
- if (!tex) {
- return nullptr;
- }
-
- // MDB TODO: add proxy-backed SkImage_Gpu's
- sk_sp<SkImage> image(new SkImage_Gpu(tex->width(), tex->height(),
- kNeedNewImageUniqueID, kPremul_SkAlphaType,
- sk_ref_sp(tex), nullptr, SkBudgeted::kNo));
+ SkASSERT(proxy->priv().isExact());
+ sk_sp<SkImage> image(new SkImage_Gpu(this, kNeedNewImageUniqueID, kPremul_SkAlphaType,
+ std::move(proxy), nullptr, SkBudgeted::kNo));
return image;
}