diff options
author | Greg Daniel <egdaniel@google.com> | 2017-10-30 13:41:26 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-10-30 20:06:53 +0000 |
commit | 45d6303f6e8403db9499ab28494f672b2bcd034e (patch) | |
tree | e3729181fa9bdccbb6fc87f3bf4489d8daba5edd | |
parent | 1b361150239a2ae79979a5bab5c35dfa0c5adb9c (diff) |
Have mip status match surface when snapping image from wrapped object
Also fixes some bugs involved with creating mipped SkSurfaces.
Bug: skia:
Change-Id: I6e0109000eadd2bdee4a907d3ee2231104528165
Reviewed-on: https://skia-review.googlesource.com/65063
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Greg Daniel <egdaniel@google.com>
-rw-r--r-- | include/gpu/GrContext.h | 4 | ||||
-rw-r--r-- | src/core/SkColorSpaceXformImageGenerator.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrBackendTextureImageGenerator.cpp | 4 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 10 | ||||
-rw-r--r-- | src/gpu/GrTextureProducer.cpp | 3 | ||||
-rw-r--r-- | src/gpu/GrYUVProvider.cpp | 2 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 5 | ||||
-rw-r--r-- | src/gpu/gl/GrGLGpu.cpp | 2 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 2 | ||||
-rw-r--r-- | src/image/SkSurface_Gpu.cpp | 4 | ||||
-rw-r--r-- | tests/GLProgramsTest.cpp | 2 | ||||
-rw-r--r-- | tests/GpuSampleLocationsTest.cpp | 4 | ||||
-rw-r--r-- | tests/GrMipMappedTest.cpp | 75 | ||||
-rw-r--r-- | tests/PathRendererCacheTests.cpp | 2 | ||||
-rw-r--r-- | tests/TessellatingPathRendererTests.cpp | 1 |
15 files changed, 98 insertions, 26 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index d0d0df7350..e5f568c9e9 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -231,7 +231,7 @@ public: GrPixelConfig config, sk_sp<SkColorSpace> colorSpace, int sampleCnt = 0, - bool willNeedMipMaps = false, + GrMipMapped = GrMipMapped::kNo, GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin, const SkSurfaceProps* surfaceProps = nullptr, SkBudgeted = SkBudgeted::kYes); @@ -247,7 +247,7 @@ public: GrPixelConfig config, sk_sp<SkColorSpace> colorSpace, int sampleCnt = 0, - bool willNeedMipMaps = false, + GrMipMapped = GrMipMapped::kNo, GrSurfaceOrigin origin = kBottomLeft_GrSurfaceOrigin, const SkSurfaceProps* surfaceProps = nullptr, SkBudgeted budgeted = SkBudgeted::kYes); diff --git a/src/core/SkColorSpaceXformImageGenerator.cpp b/src/core/SkColorSpaceXformImageGenerator.cpp index 0ca6ab1e04..8121cf9b51 100644 --- a/src/core/SkColorSpaceXformImageGenerator.cpp +++ b/src/core/SkColorSpaceXformImageGenerator.cpp @@ -85,9 +85,11 @@ sk_sp<GrTextureProxy> SkColorSpaceXformImageGenerator::onGenerateTexture( return nullptr; } + GrMipMapped mipMapped = willNeedMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo; + sk_sp<GrRenderTargetContext> renderTargetContext = ctx->makeDeferredRenderTargetContext( SkBackingFit::kExact, info.width(), info.height(), kRGBA_8888_GrPixelConfig, nullptr, - 0, willNeedMipMaps, kTopLeft_GrSurfaceOrigin); + 0, mipMapped, kTopLeft_GrSurfaceOrigin); if (!renderTargetContext) { return nullptr; } diff --git a/src/gpu/GrBackendTextureImageGenerator.cpp b/src/gpu/GrBackendTextureImageGenerator.cpp index 7240c7976f..58dacf6549 100644 --- a/src/gpu/GrBackendTextureImageGenerator.cpp +++ b/src/gpu/GrBackendTextureImageGenerator.cpp @@ -183,9 +183,11 @@ sk_sp<GrTextureProxy> GrBackendTextureImageGenerator::onGenerateTexture( // 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. + GrMipMapped mipMapped = willNeedMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo; + sk_sp<GrRenderTargetContext> rtContext(context->makeDeferredRenderTargetContext( SkBackingFit::kExact, info.width(), info.height(), proxy->config(), nullptr, - 0, willNeedMipMaps, proxy->origin(), nullptr, SkBudgeted::kYes)); + 0, mipMapped, proxy->origin(), nullptr, SkBudgeted::kYes)); if (!rtContext) { return nullptr; diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 605fe2e793..2d9f0115e3 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -617,7 +617,7 @@ bool GrContextPriv::readSurfacePixels(GrSurfaceContext* src, tempDrawInfo.fTempSurfaceDesc.fConfig, nullptr, tempDrawInfo.fTempSurfaceDesc.fSampleCnt, - false, + GrMipMapped::kNo, tempDrawInfo.fTempSurfaceDesc.fOrigin); if (tempRTC) { SkMatrix textureMatrix = SkMatrix::MakeTrans(SkIntToScalar(left), SkIntToScalar(top)); @@ -885,7 +885,7 @@ sk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContextWithFallb GrPixelConfig config, sk_sp<SkColorSpace> colorSpace, int sampleCnt, - bool willNeedMipMaps, + GrMipMapped mipMapped, GrSurfaceOrigin origin, const SkSurfaceProps* surfaceProps, SkBudgeted budgeted) { @@ -894,7 +894,7 @@ sk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContextWithFallb } return this->makeDeferredRenderTargetContext(fit, width, height, config, std::move(colorSpace), - sampleCnt, willNeedMipMaps, origin, surfaceProps, + sampleCnt, mipMapped, origin, surfaceProps, budgeted); } @@ -904,7 +904,7 @@ sk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContext( GrPixelConfig config, sk_sp<SkColorSpace> colorSpace, int sampleCnt, - bool willNeedMipMaps, + GrMipMapped mipMapped, GrSurfaceOrigin origin, const SkSurfaceProps* surfaceProps, SkBudgeted budgeted) { @@ -921,7 +921,7 @@ sk_sp<GrRenderTargetContext> GrContext::makeDeferredRenderTargetContext( desc.fSampleCnt = sampleCnt; sk_sp<GrTextureProxy> rtp; - if (!willNeedMipMaps) { + if (GrMipMapped::kNo == mipMapped) { rtp = GrSurfaceProxy::MakeDeferred(this->resourceProvider(), desc, fit, budgeted); } else { rtp = GrSurfaceProxy::MakeDeferredMipMap(this->resourceProvider(), desc, budgeted); diff --git a/src/gpu/GrTextureProducer.cpp b/src/gpu/GrTextureProducer.cpp index cf7ee7cca7..f5ae0ad565 100644 --- a/src/gpu/GrTextureProducer.cpp +++ b/src/gpu/GrTextureProducer.cpp @@ -23,10 +23,11 @@ sk_sp<GrTextureProxy> GrTextureProducer::CopyOnGpu(GrContext* context, SkASSERT(context); const SkRect dstRect = SkRect::MakeIWH(copyParams.fWidth, copyParams.fHeight); + GrMipMapped mipMapped = dstWillRequireMipMaps ? GrMipMapped::kYes : GrMipMapped::kNo; sk_sp<GrRenderTargetContext> copyRTC = context->makeDeferredRenderTargetContextWithFallback( SkBackingFit::kExact, dstRect.width(), dstRect.height(), inputProxy->config(), nullptr, - 0, dstWillRequireMipMaps, inputProxy->origin()); + 0, mipMapped, inputProxy->origin()); if (!copyRTC) { return nullptr; } diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp index d6a56660a4..930a33e961 100644 --- a/src/gpu/GrYUVProvider.cpp +++ b/src/gpu/GrYUVProvider.cpp @@ -131,7 +131,7 @@ sk_sp<GrTextureProxy> GrYUVProvider::refAsTextureProxy(GrContext* ctx, const GrS desc.fWidth, desc.fHeight, desc.fConfig, nullptr, desc.fSampleCnt, - false, // always non mipped + GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin)); if (!renderTargetContext) { return nullptr; diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index fe1f6aefaa..df81d0494b 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -164,7 +164,7 @@ sk_sp<GrRenderTargetContext> SkGpuDevice::MakeRenderTargetContext( SkBackingFit::kExact, origInfo.width(), origInfo.height(), config, origInfo.refColorSpace(), sampleCount, - false, origin, surfaceProps, budgeted); + mipMapped, origin, surfaceProps, budgeted); } sk_sp<SkSpecialImage> SkGpuDevice::filterTexture(SkSpecialImage* srcImg, @@ -1703,7 +1703,8 @@ SkBaseDevice* SkGpuDevice::onCreateDevice(const CreateInfo& cinfo, const SkPaint fit, cinfo.fInfo.width(), cinfo.fInfo.height(), fRenderTargetContext->colorSpaceInfo().config(), fRenderTargetContext->colorSpaceInfo().refColorSpace(), - fRenderTargetContext->numStencilSamples(), false, kBottomLeft_GrSurfaceOrigin, &props)); + fRenderTargetContext->numStencilSamples(), GrMipMapped::kNo, + kBottomLeft_GrSurfaceOrigin, &props)); if (!rtc) { return nullptr; } diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 1bee54879e..d3bd6e3cd0 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -4415,7 +4415,7 @@ GrBackendObject GrGLGpu::createTestingOnlyBackendTexture(void* pixels, int w, in int width = w; int height = h; for (int i = 0; i < mipLevels; ++i) { - GL_CALL(TexImage2D(info->fTarget, 0, internalFormat, width, height, 0, externalFormat, + GL_CALL(TexImage2D(info->fTarget, i, internalFormat, width, height, 0, externalFormat, externalType, pixels)); width = SkTMax(1, width / 2); height = SkTMax(1, height / 2); diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index e89af42432..856b3b8108 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -390,7 +390,7 @@ static sk_sp<SkImage> make_from_yuv_textures_copy(GrContext* ctx, SkYUVColorSpac kRGBA_8888_GrPixelConfig, std::move(imageColorSpace), 0, - false, + GrMipMapped::kNo, origin)); if (!renderTargetContext) { return nullptr; diff --git a/src/image/SkSurface_Gpu.cpp b/src/image/SkSurface_Gpu.cpp index 8b7a065478..891f03709b 100644 --- a/src/image/SkSurface_Gpu.cpp +++ b/src/image/SkSurface_Gpu.cpp @@ -110,9 +110,7 @@ sk_sp<SkImage> SkSurface_Gpu::onNewImageSnapshot() { if (!srcProxy || rtc->priv().refsWrappedObjects()) { SkASSERT(rtc->origin() == rtc->asSurfaceProxy()->origin()); - // 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); + srcProxy = GrSurfaceProxy::Copy(ctx, rtc->asSurfaceProxy(), rtc->mipMapped(), budgeted); } const SkImageInfo info = fDevice->imageInfo(); diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp index 55ffca911f..e0ac272009 100644 --- a/tests/GLProgramsTest.cpp +++ b/tests/GLProgramsTest.cpp @@ -159,7 +159,7 @@ static sk_sp<GrRenderTargetContext> random_render_target_context(GrContext* cont kRGBA_8888_GrPixelConfig, nullptr, sampleCnt, - false, + GrMipMapped::kNo, origin)); return renderTargetContext; } diff --git a/tests/GpuSampleLocationsTest.cpp b/tests/GpuSampleLocationsTest.cpp index fa99a9ae9e..36b518111f 100644 --- a/tests/GpuSampleLocationsTest.cpp +++ b/tests/GpuSampleLocationsTest.cpp @@ -119,11 +119,11 @@ void test_sampleLocations(skiatest::Reporter* reporter, TestSampleLocationsInter GrAlwaysAssert(numSamples > 1 && SkIsPow2(numSamples)); bottomUps[i] = ctx->makeDeferredRenderTargetContext( SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr, - rand.nextRangeU(1 + numSamples / 2, numSamples), + rand.nextRangeU(1 + numSamples / 2, numSamples), GrMipMapped::kNo, kBottomLeft_GrSurfaceOrigin); topDowns[i] = ctx->makeDeferredRenderTargetContext( SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr, - rand.nextRangeU(1 + numSamples / 2, numSamples), + rand.nextRangeU(1 + numSamples / 2, numSamples), GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin); } diff --git a/tests/GrMipMappedTest.cpp b/tests/GrMipMappedTest.cpp index aad3b60d8d..f023018902 100644 --- a/tests/GrMipMappedTest.cpp +++ b/tests/GrMipMappedTest.cpp @@ -28,6 +28,8 @@ #include "SkSurface_Gpu.h" #include "Test.h" +static constexpr int kSize = 8; + // Test that the correct mip map states are on the GrTextures when wrapping GrBackendTextures in // SkImages and SkSurfaces DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest, reporter, ctxInfo) { @@ -45,8 +47,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest, reporter, ctxInfo) { GrBackend backend = context->contextPriv().getBackend(); GrBackendTexture backendTex = GrTest::CreateBackendTexture(backend, - 8, - 8, + kSize, + kSize, kRGBA_8888_GrPixelConfig, mipMapped, backendHandle); @@ -103,8 +105,6 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrWrappedMipMappedTest, reporter, ctxInfo) { // Test that we correctly copy or don't copy GrBackendTextures in the GrBackendTextureImageGenerator // based on if we will use mips in the draw and the mip status of the GrBackendTexture. DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest, reporter, ctxInfo) { - static const int kSize = 8; - GrContext* context = ctxInfo.grContext(); if (!context->caps()->mipMapSupport()) { return; @@ -218,5 +218,72 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrBackendTextureImageMipMappedTest, reporter, } } +// Test that when we call makeImageSnapshot on an SkSurface we retains the same mip status as the +// resource we took the snapshot of. +DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrImageSnapshotMipMappedTest, reporter, ctxInfo) { + GrContext* context = ctxInfo.grContext(); + if (!context->caps()->mipMapSupport()) { + return; + } + + for (auto willUseMips : {false, true}) { + for (auto isWrapped : {false, true}) { + GrMipMapped mipMapped = willUseMips ? GrMipMapped::kYes : GrMipMapped::kNo; + sk_sp<SkSurface> surface; + GrBackendObject backendHandle = context->getGpu()->createTestingOnlyBackendTexture( + nullptr, 8, 8, kRGBA_8888_GrPixelConfig, true, mipMapped); + if (isWrapped) { + GrBackend backend = context->contextPriv().getBackend(); + GrBackendTexture backendTex = GrTest::CreateBackendTexture(backend, + kSize, + kSize, + kRGBA_8888_GrPixelConfig, + mipMapped, + backendHandle); + + surface = SkSurface::MakeFromBackendTexture(context, + backendTex, + kTopLeft_GrSurfaceOrigin, + 0, + nullptr, + nullptr); + } else { + SkImageInfo info = SkImageInfo::Make(kSize, kSize, kRGBA_8888_SkColorType, + kPremul_SkAlphaType); + surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, info, 0, + kTopLeft_GrSurfaceOrigin, nullptr, + willUseMips); + } + REPORTER_ASSERT(reporter, surface); + if (!surface) { + context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); + } + SkGpuDevice* device = ((SkSurface_Gpu*)surface.get())->getDevice(); + GrTextureProxy* texProxy = device->accessRenderTargetContext()->asTextureProxy(); + REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped()); + + texProxy->instantiate(context->resourceProvider()); + GrTexture* texture = texProxy->priv().peekTexture(); + REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped()); + + sk_sp<SkImage> image = surface->makeImageSnapshot(); + REPORTER_ASSERT(reporter, image); + if (!image) { + context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); + } + texProxy = as_IB(image)->peekProxy(); + REPORTER_ASSERT(reporter, mipMapped == texProxy->mipMapped()); + + texProxy->instantiate(context->resourceProvider()); + texture = texProxy->priv().peekTexture(); + REPORTER_ASSERT(reporter, mipMapped == texture->texturePriv().mipMapped()); + + // Must flush the context to make sure all the cmds (copies, etc.) from above are sent + // to the gpu before we delete the backendHandle. + context->flush(); + context->getGpu()->deleteTestingOnlyBackendTexture(backendHandle); + } + } +} #endif diff --git a/tests/PathRendererCacheTests.cpp b/tests/PathRendererCacheTests.cpp index 33a02ca943..dbf01ab029 100644 --- a/tests/PathRendererCacheTests.cpp +++ b/tests/PathRendererCacheTests.cpp @@ -81,7 +81,7 @@ static void test_path(skiatest::Reporter* reporter, sk_sp<GrRenderTargetContext> rtc(ctx->makeDeferredRenderTargetContext( SkBackingFit::kApprox, 800, 800, kRGBA_8888_GrPixelConfig, nullptr, 0, - kTopLeft_GrSurfaceOrigin)); + GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin)); if (!rtc) { return; } diff --git a/tests/TessellatingPathRendererTests.cpp b/tests/TessellatingPathRendererTests.cpp index 6c414df9bb..b622f3767a 100644 --- a/tests/TessellatingPathRendererTests.cpp +++ b/tests/TessellatingPathRendererTests.cpp @@ -425,6 +425,7 @@ DEF_GPUTEST_FOR_ALL_CONTEXTS(TessellatingPathRendererTests, reporter, ctxInfo) { kRGBA_8888_GrPixelConfig, nullptr, 0, + GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin)); if (!rtc) { return; |