Add mip support to GrAHardwareBufferImageGenerator
Bug: skia:
Change-Id: I482d8f9937c86ed441016afef2d8f924282dd17a
Reviewed-on: https://skia-review.googlesource.com/63861
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
diff --git a/gm/image_pict.cpp b/gm/image_pict.cpp
index 0e39d3b..bf1c651 100644
--- a/gm/image_pict.cpp
+++ b/gm/image_pict.cpp
@@ -186,8 +186,11 @@
desc.fHeight = info.height();
desc.fConfig = fProxy->config();
+ GrMipMapped mipMapped = willBeMipped ? GrMipMapped::kYes : GrMipMapped::kNo;
+
sk_sp<GrSurfaceContext> dstContext(fCtx->contextPriv().makeDeferredSurfaceContext(
desc,
+ mipMapped,
SkBackingFit::kExact,
SkBudgeted::kYes));
if (!dstContext) {
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index 2bbf02a..0eccdce 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -326,12 +326,12 @@
// 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. The copy is is not a render target and not multisampled.
- static sk_sp<GrTextureProxy> Copy(GrContext*, GrSurfaceProxy* src,
+ static sk_sp<GrTextureProxy> Copy(GrContext*, GrSurfaceProxy* src, GrMipMapped,
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,
+ static sk_sp<GrTextureProxy> Copy(GrContext* context, GrSurfaceProxy* src, GrMipMapped,
SkBudgeted budgeted);
// Test-only entry point - should decrease in use as proxies propagate
diff --git a/src/core/SkSpecialImage.cpp b/src/core/SkSpecialImage.cpp
index db4fadc..df56afd 100644
--- a/src/core/SkSpecialImage.cpp
+++ b/src/core/SkSpecialImage.cpp
@@ -464,7 +464,8 @@
}
sk_sp<GrTextureProxy> subsetProxy(GrSurfaceProxy::Copy(fContext, fTextureProxy.get(),
- *subset, SkBudgeted::kYes));
+ GrMipMapped::kNo, *subset,
+ SkBudgeted::kYes));
if (!subsetProxy) {
return nullptr;
}
diff --git a/src/gpu/GrAHardwareBufferImageGenerator.cpp b/src/gpu/GrAHardwareBufferImageGenerator.cpp
index 164e3d6..bdfdbd0 100644
--- a/src/gpu/GrAHardwareBufferImageGenerator.cpp
+++ b/src/gpu/GrAHardwareBufferImageGenerator.cpp
@@ -104,17 +104,44 @@
return nullptr;
}
+ bool makingASubset = true;
if (0 == origin.fX && 0 == origin.fY &&
info.width() == getInfo().width() && info.height() == getInfo().height()) {
- // If the caller wants the entire texture, we're done
- return proxy;
- } else {
- // Otherwise, make a copy of the requested subset.
- return GrSurfaceProxy::Copy(context, proxy.get(),
- SkIRect::MakeXYWH(origin.fX, origin.fY, info.width(),
- info.height()),
- SkBudgeted::kYes);
+ makingASubset = false;
+ if (!willNeedMipMaps || GrMipMapped::kYes == proxy->mipMapped()) {
+ // If the caller wants the full texture and we have the correct mip support, we're done
+ return proxy;
+ }
}
+ // Otherwise, make a copy for the requested subset or for mip maps.
+ SkIRect subset = SkIRect::MakeXYWH(origin.fX, origin.fY, info.width(), info.height());
+
+ GrMipMapped mipMapped = willNeedMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo;
+
+ sk_sp<GrTextureProxy> texProxy = GrSurfaceProxy::Copy(context, proxy.get(), mipMapped,
+ subset, SkBudgeted::kYes);
+ if (!makingASubset && texProxy) {
+ // We are in this case if we wanted the full texture, but we will be mip mapping the
+ // texture. Therefore we want to update the cached texture so that we point to the
+ // mipped version instead of the old one.
+ SkASSERT(willNeedMipMaps);
+ SkASSERT(GrMipMapped::kYes == texProxy->mipMapped());
+
+ // The only way we should get into here is if we just made a new texture in makeProxy or
+ // we found a cached texture in the same context. Thus the current and cached contexts
+ // should match.
+ SkASSERT(context->uniqueID() == fOwningContextID);
+
+ // Clear out the old cached texture.
+ this->clear();
+
+ // We need to get the actual GrTexture so force instantiation of the GrTextureProxy
+ texProxy->instantiate(context->resourceProvider());
+ GrTexture* texture = texProxy->priv().peekTexture();
+ SkASSERT(texture);
+ fOriginalTexture = texture;
+ }
+ return texProxy;
}
#endif
diff --git a/src/gpu/GrBlurUtils.cpp b/src/gpu/GrBlurUtils.cpp
index 68fd9f3..9760205d 100644
--- a/src/gpu/GrBlurUtils.cpp
+++ b/src/gpu/GrBlurUtils.cpp
@@ -85,6 +85,7 @@
sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeDeferredSurfaceContext(
desc,
+ GrMipMapped::kNo,
SkBackingFit::kApprox,
SkBudgeted::kYes);
if (!sContext) {
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index f4f1d6c..605fe2e 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -750,11 +750,19 @@
}
sk_sp<GrSurfaceContext> GrContextPriv::makeDeferredSurfaceContext(const GrSurfaceDesc& dstDesc,
+ GrMipMapped mipMapped,
SkBackingFit fit,
SkBudgeted isDstBudgeted) {
- sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferred(fContext->resourceProvider(),
- dstDesc, fit, isDstBudgeted);
+ sk_sp<GrTextureProxy> proxy;
+ if (GrMipMapped::kNo == mipMapped) {
+ proxy = GrSurfaceProxy::MakeDeferred(fContext->resourceProvider(), dstDesc, fit,
+ isDstBudgeted);
+ } else {
+ SkASSERT(SkBackingFit::kExact == fit);
+ proxy = GrSurfaceProxy::MakeDeferredMipMap(fContext->resourceProvider(), dstDesc,
+ isDstBudgeted);
+ }
if (!proxy) {
return nullptr;
}
diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h
index e1773c8..cdd04b4 100644
--- a/src/gpu/GrContextPriv.h
+++ b/src/gpu/GrContextPriv.h
@@ -27,6 +27,7 @@
sk_sp<GrSurfaceContext> makeWrappedSurfaceContext(sk_sp<GrSurfaceProxy>, sk_sp<SkColorSpace>);
sk_sp<GrSurfaceContext> makeDeferredSurfaceContext(const GrSurfaceDesc&,
+ GrMipMapped,
SkBackingFit,
SkBudgeted);
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index 5f071e8..44550e1 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -1890,6 +1890,7 @@
sk_sp<GrSurfaceContext> sContext = fContext->contextPriv().makeDeferredSurfaceContext(
desc,
+ GrMipMapped::kNo,
fit,
SkBudgeted::kYes);
if (!sContext) {
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index d45847a..1005758 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -100,6 +100,7 @@
sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeDeferredSurfaceContext(
desc,
+ GrMipMapped::kNo,
fit,
SkBudgeted::kYes);
if (!sContext || !sContext->asTextureProxy()) {
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index da5bb17..3e188b8 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -411,6 +411,7 @@
sk_sp<GrTextureProxy> GrSurfaceProxy::Copy(GrContext* context,
GrSurfaceProxy* src,
+ GrMipMapped mipMapped,
SkIRect srcRect,
SkBudgeted budgeted) {
if (!srcRect.intersect(SkIRect::MakeWH(src->width(), src->height()))) {
@@ -425,6 +426,7 @@
sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
dstDesc,
+ mipMapped,
SkBackingFit::kExact,
budgeted));
if (!dstContext) {
@@ -439,8 +441,8 @@
}
sk_sp<GrTextureProxy> GrSurfaceProxy::Copy(GrContext* context, GrSurfaceProxy* src,
- SkBudgeted budgeted) {
- return Copy(context, src, SkIRect::MakeWH(src->width(), src->height()), budgeted);
+ GrMipMapped mipMapped, SkBudgeted budgeted) {
+ return Copy(context, src, mipMapped, SkIRect::MakeWH(src->width(), src->height()), budgeted);
}
sk_sp<GrSurfaceContext> GrSurfaceProxy::TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc,
@@ -448,6 +450,7 @@
sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext(
dstDesc,
+ GrMipMapped::kNo,
SkBackingFit::kExact,
SkBudgeted::kYes));
if (!dstContext) {
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index 085e5be..d6a5666 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -109,7 +109,9 @@
(yuvDesc.fHeight != yuvInfo.fSizeInfo.fSizes[SkYUVSizeInfo::kY].fHeight)
? SkBackingFit::kExact : SkBackingFit::kApprox;
- yuvTextureContexts[i] = ctx->contextPriv().makeDeferredSurfaceContext(yuvDesc, fit,
+ yuvTextureContexts[i] = ctx->contextPriv().makeDeferredSurfaceContext(yuvDesc,
+ GrMipMapped::kNo,
+ fit,
SkBudgeted::kYes);
if (!yuvTextureContexts[i]) {
return nullptr;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 93414ed..fe1f6ae 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1238,6 +1238,7 @@
// filter
proxy = GrSurfaceProxy::Copy(fContext.get(),
this->accessRenderTargetContext()->asSurfaceProxy(),
+ GrMipMapped::kNo,
SkBudgeted::kYes);
if (!proxy) {
return nullptr;
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 9f1586c..e89af42 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -249,6 +249,7 @@
sk_sp<GrSurfaceContext> sContext(fContext->contextPriv().makeDeferredSurfaceContext(
desc,
+ GrMipMapped::kNo,
SkBackingFit::kExact,
fBudgeted));
if (!sContext) {
diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp
index 6e9bc3f..8b7a065 100644
--- a/src/image/SkSurface_Gpu.cpp
+++ b/src/image/SkSurface_Gpu.cpp
@@ -110,7 +110,9 @@
if (!srcProxy || rtc->priv().refsWrappedObjects()) {
SkASSERT(rtc->origin() == rtc->asSurfaceProxy()->origin());
- srcProxy = GrSurfaceProxy::Copy(ctx, rtc->asSurfaceProxy(), budgeted);
+ // TODO: We should look at the rtc to see if it is mipped and if so create the copy as well
+ // with mips.
+ srcProxy = GrSurfaceProxy::Copy(ctx, rtc->asSurfaceProxy(), GrMipMapped::kNo, budgeted);
}
const SkImageInfo info = fDevice->imageInfo();
diff --git a/tests/GrSurfaceTest.cpp b/tests/GrSurfaceTest.cpp
index e5dc6ae..eff8c25 100644
--- a/tests/GrSurfaceTest.cpp
+++ b/tests/GrSurfaceTest.cpp
@@ -212,7 +212,8 @@
// Try creating the texture as a deferred proxy.
for (int i = 0; i < 2; ++i) {
auto surfCtx = context->contextPriv().makeDeferredSurfaceContext(
- desc, approx ? SkBackingFit::kApprox : SkBackingFit::kExact,
+ desc, GrMipMapped::kNo,
+ approx ? SkBackingFit::kApprox : SkBackingFit::kExact,
SkBudgeted::kYes);
if (!surfCtx) {
continue;
diff --git a/tests/SRGBReadWritePixelsTest.cpp b/tests/SRGBReadWritePixelsTest.cpp
index a52e961..6ebdcf7 100644
--- a/tests/SRGBReadWritePixelsTest.cpp
+++ b/tests/SRGBReadWritePixelsTest.cpp
@@ -176,8 +176,9 @@
context->caps()->isConfigTexturable(desc.fConfig)) {
sk_sp<GrSurfaceContext> sContext = context->contextPriv().makeDeferredSurfaceContext(
- desc, SkBackingFit::kExact,
- SkBudgeted::kNo);
+ desc, GrMipMapped::kNo,
+ SkBackingFit::kExact,
+ SkBudgeted::kNo);
if (!sContext) {
ERRORF(reporter, "Could not create SRGBA surface context.");
return;
@@ -215,7 +216,9 @@
}
desc.fConfig = kRGBA_8888_GrPixelConfig;
- sContext = context->contextPriv().makeDeferredSurfaceContext(desc, SkBackingFit::kExact,
+ sContext = context->contextPriv().makeDeferredSurfaceContext(desc,
+ GrMipMapped::kNo,
+ SkBackingFit::kExact,
SkBudgeted::kNo);
if (!sContext) {
ERRORF(reporter, "Could not create RGBA surface context.");