aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Greg Daniel <egdaniel@google.com>2017-10-06 15:59:27 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-06 20:28:00 +0000
commite1da1d9a7dfa6c9ebdcbd2845acebd045edd2a6f (patch)
tree9d7b53269a0b9d96a43358377d9906b774af3a29
parent567d6f4b4bd9ef50fa09c1449d6789ed701fc079 (diff)
Add option to create a deferred render target context with mips
We need this since we have texture generators that draw the base level but nothing more. Thus we want them to be able to directly draw into a pre allocated mipped target instead of doing a copy later. TBR: bsalomon@google.com Bug: skia: Change-Id: I1dfae0da7153b21b30fdfa51a7061fc255739a1e Reviewed-on: https://skia-review.googlesource.com/54100 Reviewed-by: Brian Salomon <bsalomon@google.com> Reviewed-by: Robert Phillips <robertphillips@google.com> Commit-Queue: Greg Daniel <egdaniel@google.com>
-rw-r--r--include/gpu/GrContext.h2
-rw-r--r--include/private/GrSurfaceProxy.h9
-rw-r--r--src/core/SkColorSpaceXformImageGenerator.cpp2
-rw-r--r--src/gpu/GrBitmapTextureMaker.cpp3
-rw-r--r--src/gpu/GrContext.cpp14
-rw-r--r--src/gpu/GrSurfaceProxy.cpp18
-rw-r--r--src/gpu/GrTextureAdjuster.cpp11
-rw-r--r--src/gpu/GrTextureAdjuster.h2
-rw-r--r--src/gpu/GrTextureMaker.cpp4
-rw-r--r--src/gpu/GrTextureProducer.cpp5
-rw-r--r--src/gpu/GrTextureProducer.h3
-rw-r--r--src/gpu/GrYUVProvider.cpp2
-rw-r--r--src/gpu/SkGpuDevice.cpp3
-rw-r--r--src/gpu/SkGr.cpp21
-rw-r--r--src/gpu/SkGr.h3
-rw-r--r--src/image/SkImage_Gpu.cpp1
-rw-r--r--src/image/SkImage_Lazy.cpp2
-rw-r--r--tests/GLProgramsTest.cpp1
18 files changed, 67 insertions, 39 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index d4a69fd238..d0d0df7350 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -231,6 +231,7 @@ public:
GrPixelConfig config,
sk_sp<SkColorSpace> colorSpace,
int sampleCnt = 0,
+ bool willNeedMipMaps = false,
GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
const SkSurfaceProps* surfaceProps = nullptr,
SkBudgeted = SkBudgeted::kYes);
@@ -246,6 +247,7 @@ public:
GrPixelConfig config,
sk_sp<SkColorSpace> colorSpace,
int sampleCnt = 0,
+ bool willNeedMipMaps = false,
GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin,
const SkSurfaceProps* surfaceProps = nullptr,
SkBudgeted budgeted = SkBudgeted::kYes);
diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h
index 0c65055611..57724c4e2b 100644
--- a/include/private/GrSurfaceProxy.h
+++ b/include/private/GrSurfaceProxy.h
@@ -194,6 +194,15 @@ public:
SkDestinationSurfaceColorMode mipColorMode =
SkDestinationSurfaceColorMode::kLegacy);
+ /**
+ * Like the call above but there are no texels to upload. A texture proxy is returned that
+ * simply has space allocated for the mips. We will allocated the full amount of mip levels
+ * based on the width and height in the GrSurfaceDesc.
+ */
+ static sk_sp<GrTextureProxy> MakeDeferredMipMap(GrResourceProvider*,
+ const GrSurfaceDesc& desc, SkBudgeted budgeted);
+
+
// TODO: need to refine ownership semantics of 'srcData' if we're in completely
// deferred mode
static sk_sp<GrTextureProxy> MakeDeferred(GrResourceProvider*,
diff --git a/src/core/SkColorSpaceXformImageGenerator.cpp b/src/core/SkColorSpaceXformImageGenerator.cpp
index bf1275ed6c..ea277fe410 100644
--- a/src/core/SkColorSpaceXformImageGenerator.cpp
+++ b/src/core/SkColorSpaceXformImageGenerator.cpp
@@ -87,7 +87,7 @@ sk_sp<GrTextureProxy> SkColorSpaceXformImageGenerator::onGenerateTexture(
sk_sp<GrRenderTargetContext> renderTargetContext = ctx->makeDeferredRenderTargetContext(
SkBackingFit::kExact, info.width(), info.height(), kRGBA_8888_GrPixelConfig, nullptr,
- 0, kTopLeft_GrSurfaceOrigin);
+ 0, false, kTopLeft_GrSurfaceOrigin);
if (!renderTargetContext) {
return nullptr;
}
diff --git a/src/gpu/GrBitmapTextureMaker.cpp b/src/gpu/GrBitmapTextureMaker.cpp
index efb9e20291..b92ffdacd8 100644
--- a/src/gpu/GrBitmapTextureMaker.cpp
+++ b/src/gpu/GrBitmapTextureMaker.cpp
@@ -77,8 +77,7 @@ sk_sp<GrTextureProxy> GrBitmapTextureMaker::refOriginalTextureProxy(bool willBeM
// We need a mipped proxy, but we either found a proxy earlier that wasn't mipped or
// generated a non mipped proxy. Thus we generate a new mipped surface and copy the original
// proxy into the base layer. We will then let the gpu generate the rest of the mips.
- if (auto mippedProxy = GrCopyBaseMipMapToTextureProxy(this->context(), proxy.get(),
- dstColorSpace)) {
+ if (auto mippedProxy = GrCopyBaseMipMapToTextureProxy(this->context(), proxy.get())) {
SkASSERT(mippedProxy->origin() == kTopLeft_GrSurfaceOrigin);
if (fOriginalKey.isValid()) {
// In this case we are stealing the key from the original proxy which should only
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 9abf953abd..d346a2a726 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -614,6 +614,7 @@ bool GrContextPriv::readSurfacePixels(GrSurfaceContext* src,
tempDrawInfo.fTempSurfaceDesc.fConfig,
nullptr,
tempDrawInfo.fTempSurfaceDesc.fSampleCnt,
+ false,
tempDrawInfo.fTempSurfaceDesc.fOrigin);
if (tempRTC) {
SkMatrix textureMatrix = SkMatrix::MakeTrans(SkIntToScalar(left), SkIntToScalar(top));
@@ -873,6 +874,7 @@ sk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContextWithFallb
GrPixelConfig config,
sk_sp<SkColorSpace> colorSpace,
int sampleCnt,
+ bool willNeedMipMaps,
GrSurfaceOrigin origin,
const SkSurfaceProps* surfaceProps,
SkBudgeted budgeted) {
@@ -881,7 +883,8 @@ sk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContextWithFallb
}
return this->makeDeferredRenderTargetContext(fit, width, height, config, std::move(colorSpace),
- sampleCnt, origin, surfaceProps, budgeted);
+ sampleCnt, willNeedMipMaps, origin, surfaceProps,
+ budgeted);
}
sk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContext(
@@ -890,6 +893,7 @@ sk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContext(
GrPixelConfig config,
sk_sp<SkColorSpace> colorSpace,
int sampleCnt,
+ bool willNeedMipMaps,
GrSurfaceOrigin origin,
const SkSurfaceProps* surfaceProps,
SkBudgeted budgeted) {
@@ -905,8 +909,12 @@ sk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContext(
desc.fConfig = config;
desc.fSampleCnt = sampleCnt;
- sk_sp<GrTextureProxy> rtp = GrSurfaceProxy::MakeDeferred(this->resourceProvider(),
- desc, fit, budgeted);
+ sk_sp<GrTextureProxy> rtp;
+ if (!willNeedMipMaps) {
+ rtp = GrSurfaceProxy::MakeDeferred(this->resourceProvider(), desc, fit, budgeted);
+ } else {
+ rtp = GrSurfaceProxy::MakeDeferredMipMap(this->resourceProvider(), desc, budgeted);
+ }
if (!rtp) {
return nullptr;
}
diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp
index 0cc3621572..803c0eb843 100644
--- a/src/gpu/GrSurfaceProxy.cpp
+++ b/src/gpu/GrSurfaceProxy.cpp
@@ -19,6 +19,7 @@
#include "GrTextureRenderTargetProxy.h"
#include "SkMathPriv.h"
+#include "SkMipMap.h"
GrSurfaceProxy::GrSurfaceProxy(sk_sp<GrSurface> surface, GrSurfaceOrigin origin, SkBackingFit fit)
: INHERITED(std::move(surface))
@@ -313,6 +314,23 @@ sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferred(GrResourceProvider* resourceP
return GrSurfaceProxy::MakeDeferred(resourceProvider, desc, SkBackingFit::kExact, budgeted);
}
+sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferredMipMap(GrResourceProvider* resourceProvider,
+ const GrSurfaceDesc& desc,
+ SkBudgeted budgeted) {
+ // SkMipMap doesn't include the base level in the level count so we have to add 1
+ int mipCount = SkMipMap::ComputeLevelCount(desc.fWidth, desc.fHeight) + 1;
+
+ std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipCount]);
+
+ // We don't want to upload any texel data
+ for (int i = 0; i < mipCount; i++) {
+ texels[i].fPixels = nullptr;
+ texels[i].fRowBytes = 0;
+ }
+
+ return MakeDeferredMipMap(resourceProvider, desc, budgeted, texels.get(), mipCount);
+}
+
sk_sp<GrTextureProxy> GrSurfaceProxy::MakeDeferredMipMap(
GrResourceProvider* resourceProvider,
const GrSurfaceDesc& desc,
diff --git a/src/gpu/GrTextureAdjuster.cpp b/src/gpu/GrTextureAdjuster.cpp
index e42be3fc7f..da3175863c 100644
--- a/src/gpu/GrTextureAdjuster.cpp
+++ b/src/gpu/GrTextureAdjuster.cpp
@@ -42,7 +42,8 @@ void GrTextureAdjuster::didCacheCopy(const GrUniqueKey& copyKey) {
// We don't currently have a mechanism for notifications on Images!
}
-sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxyCopy(const CopyParams& copyParams) {
+sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxyCopy(const CopyParams& copyParams,
+ bool willBeMipped) {
GrUniqueKey key;
this->makeCopyKey(copyParams, &key, nullptr);
if (key.isValid()) {
@@ -57,7 +58,8 @@ sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxyCopy(const CopyParams& c
sk_sp<GrTextureProxy> proxy = this->originalProxyRef();
const SkIRect* contentArea = this->contentAreaOrNull();
- sk_sp<GrTextureProxy> copy = CopyOnGpu(fContext, std::move(proxy), contentArea, copyParams);
+ sk_sp<GrTextureProxy> copy = CopyOnGpu(fContext, std::move(proxy), contentArea, copyParams,
+ willBeMipped);
if (copy) {
if (key.isValid()) {
SkASSERT(copy->origin() == this->originalProxy()->origin());
@@ -79,7 +81,8 @@ sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxySafeForParams(const GrSa
return nullptr;
}
- if (contentArea && GrSamplerState::Filter::kMipMap == params.filter()) {
+ bool willBeMipped = GrSamplerState::Filter::kMipMap == params.filter();
+ if (contentArea && willBeMipped) {
// If we generate a MIP chain for texture it will read pixel values from outside the content
// area.
copyParams.fWidth = contentArea->width();
@@ -90,7 +93,7 @@ sk_sp<GrTextureProxy> GrTextureAdjuster::refTextureProxySafeForParams(const GrSa
return proxy;
}
- return this->refTextureProxyCopy(copyParams);
+ return this->refTextureProxyCopy(copyParams, willBeMipped);
}
std::unique_ptr<GrFragmentProcessor> GrTextureAdjuster::createFragmentProcessor(
diff --git a/src/gpu/GrTextureAdjuster.h b/src/gpu/GrTextureAdjuster.h
index 5ee6edc79c..ca5b0e90c7 100644
--- a/src/gpu/GrTextureAdjuster.h
+++ b/src/gpu/GrTextureAdjuster.h
@@ -58,7 +58,7 @@ private:
SkColorSpace* fColorSpace;
uint32_t fUniqueID;
- sk_sp<GrTextureProxy> refTextureProxyCopy(const CopyParams &copyParams);
+ sk_sp<GrTextureProxy> refTextureProxyCopy(const CopyParams &copyParams, bool willBeMipped);
typedef GrTextureProducer INHERITED;
};
diff --git a/src/gpu/GrTextureMaker.cpp b/src/gpu/GrTextureMaker.cpp
index db0f421cd0..8183188f60 100644
--- a/src/gpu/GrTextureMaker.cpp
+++ b/src/gpu/GrTextureMaker.cpp
@@ -59,7 +59,7 @@ sk_sp<GrTextureProxy> GrTextureMaker::refTextureProxyForParams(const GrSamplerSt
sk_sp<GrTextureProxy> result;
if (original) {
- result = CopyOnGpu(fContext, std::move(original), nullptr, copyParams);
+ result = CopyOnGpu(fContext, std::move(original), nullptr, copyParams, willBeMipped);
} else {
result = this->generateTextureProxyForParams(copyParams, willBeMipped, dstColorSpace);
}
@@ -134,5 +134,5 @@ sk_sp<GrTextureProxy> GrTextureMaker::generateTextureProxyForParams(const CopyPa
return nullptr;
}
- return CopyOnGpu(fContext, std::move(original), nullptr, copyParams);
+ return CopyOnGpu(fContext, std::move(original), nullptr, copyParams, willBeMipped);
}
diff --git a/src/gpu/GrTextureProducer.cpp b/src/gpu/GrTextureProducer.cpp
index 91e196da12..2b9679a478 100644
--- a/src/gpu/GrTextureProducer.cpp
+++ b/src/gpu/GrTextureProducer.cpp
@@ -17,7 +17,8 @@
sk_sp<GrTextureProxy> GrTextureProducer::CopyOnGpu(GrContext* context,
sk_sp<GrTextureProxy> inputProxy,
const SkIRect* subset,
- const CopyParams& copyParams) {
+ const CopyParams& copyParams,
+ bool dstWillRequireMipMaps) {
SkASSERT(!subset || !subset->isEmpty());
SkASSERT(context);
@@ -25,7 +26,7 @@ sk_sp<GrTextureProxy> GrTextureProducer::CopyOnGpu(GrContext* context,
sk_sp<GrRenderTargetContext> copyRTC = context->makeDeferredRenderTargetContextWithFallback(
SkBackingFit::kExact, dstRect.width(), dstRect.height(), inputProxy->config(), nullptr,
- 0, inputProxy->origin());
+ 0, dstWillRequireMipMaps, inputProxy->origin());
if (!copyRTC) {
return nullptr;
}
diff --git a/src/gpu/GrTextureProducer.h b/src/gpu/GrTextureProducer.h
index 7d056640cc..24b23b6e17 100644
--- a/src/gpu/GrTextureProducer.h
+++ b/src/gpu/GrTextureProducer.h
@@ -125,7 +125,8 @@ protected:
};
static sk_sp<GrTextureProxy> CopyOnGpu(GrContext*, sk_sp<GrTextureProxy> inputProxy,
- const SkIRect* subset, const CopyParams& copyParams);
+ const SkIRect* subset, const CopyParams& copyParams,
+ bool dstWillRequireMipMaps);
static DomainMode DetermineDomainMode(const SkRect& constraintRect,
FilterConstraint filterConstraint,
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index 6b58d42cd7..085e5bedd4 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -123,11 +123,13 @@ sk_sp<GrTextureProxy> GrYUVProvider::refAsTextureProxy(GrContext* ctx, const GrS
}
// We never want to perform color-space conversion during the decode
+ // TODO: investigate preallocating mip maps here
sk_sp<GrRenderTargetContext> renderTargetContext(ctx->makeDeferredRenderTargetContext(
SkBackingFit::kExact,
desc.fWidth, desc.fHeight,
desc.fConfig, nullptr,
desc.fSampleCnt,
+ false, // always non mipped
kTopLeft_GrSurfaceOrigin));
if (!renderTargetContext) {
return nullptr;
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index 3f0bdce076..bbc23c2226 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -162,7 +162,7 @@ sk_sp<GrRenderTargetContext> SkGpuDevice::MakeRenderTargetContext(
SkBackingFit::kExact,
origInfo.width(), origInfo.height(),
config, origInfo.refColorSpace(), sampleCount,
- origin, surfaceProps, budgeted);
+ false, origin, surfaceProps, budgeted);
}
sk_sp<SkSpecialImage> SkGpuDevice::filterTexture(SkSpecialImage* srcImg,
@@ -1702,6 +1702,7 @@ SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint
fRenderTargetContext->config(),
fRenderTargetContext->refColorSpace(),
fRenderTargetContext->numStencilSamples(),
+ false,
kBottomLeft_GrSurfaceOrigin,
&props));
if (!rtc) {
diff --git a/src/gpu/SkGr.cpp b/src/gpu/SkGr.cpp
index 8035027732..0c065f9c74 100644
--- a/src/gpu/SkGr.cpp
+++ b/src/gpu/SkGr.cpp
@@ -219,29 +219,13 @@ sk_sp<GrTextureProxy> GrGenerateMipMapsAndUploadToTextureProxy(GrContext* ctx,
}
sk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrContext* ctx,
- GrTextureProxy* baseProxy,
- SkColorSpace* dstColorSpace) {
+ GrTextureProxy* baseProxy) {
SkASSERT(baseProxy);
if (!ctx->caps()->isConfigCopyable(baseProxy->config())) {
return nullptr;
}
- SkDestinationSurfaceColorMode colorMode = dstColorSpace
- ? SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware
- : SkDestinationSurfaceColorMode::kLegacy;
-
- // SkMipMap doesn't include the base level in the level count so we have to add 1
- int mipLevelCount = SkMipMap::ComputeLevelCount(baseProxy->width(), baseProxy->height()) + 1;
-
- std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
-
- // We don't want to upload any texel data
- for (int i = 0; i < mipLevelCount; i++) {
- texels[i].fPixels = nullptr;
- texels[i].fRowBytes = 0;
- }
-
GrSurfaceDesc desc;
desc.fFlags = kNone_GrSurfaceFlags;
desc.fOrigin = baseProxy->origin();
@@ -252,8 +236,7 @@ sk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrContext* ctx,
sk_sp<GrTextureProxy> proxy = GrSurfaceProxy::MakeDeferredMipMap(ctx->resourceProvider(),
desc,
- SkBudgeted::kYes, texels.get(),
- mipLevelCount, colorMode);
+ SkBudgeted::kYes);
if (!proxy) {
return nullptr;
}
diff --git a/src/gpu/SkGr.h b/src/gpu/SkGr.h
index 20110a516f..f4f4d07026 100644
--- a/src/gpu/SkGr.h
+++ b/src/gpu/SkGr.h
@@ -228,8 +228,7 @@ sk_sp<GrTextureProxy> GrUploadPixmapToTextureProxy(GrResourceProvider*,
* Creates a new texture with mipmap levels and copies the baseProxy into the base layer.
*/
sk_sp<GrTextureProxy> GrCopyBaseMipMapToTextureProxy(GrContext*,
- GrTextureProxy* baseProxy,
- SkColorSpace* dstColorSpace);
+ GrTextureProxy* baseProxy);
/**
* Creates a new texture populated with the mipmap levels.
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index e477a5e564..2f7d6636f9 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -387,6 +387,7 @@ static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac
kRGBA_8888_GrPixelConfig,
std::move(imageColorSpace),
0,
+ false,
origin));
if (!renderTargetContext) {
return nullptr;
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
index 26a1ef9f80..5e3c037402 100644
--- a/src/image/SkImage_Lazy.cpp
+++ b/src/image/SkImage_Lazy.cpp
@@ -850,7 +850,7 @@ sk_sp<GrTextureProxy> SkImage_Lazy::lockTextureProxy(GrContext* ctx,
// generate the rest of the mips.
SkASSERT(willBeMipped);
SkASSERT(!proxy->isMipMapped());
- if (auto mippedProxy = GrCopyBaseMipMapToTextureProxy(ctx, proxy.get(), dstColorSpace)) {
+ if (auto mippedProxy = GrCopyBaseMipMapToTextureProxy(ctx, proxy.get())) {
set_key_on_proxy(ctx->resourceProvider(), mippedProxy.get(), proxy.get(), key);
return mippedProxy;
}
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index bab5fa679e..522bb71db7 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -160,6 +160,7 @@ static sk_sp<GrRenderTargetContext> random_render_target_context(GrContext* cont
kRGBA_8888_GrPixelConfig,
nullptr,
sampleCnt,
+ false,
origin));
return renderTargetContext;
}