diff options
author | Robert Phillips <robertphillips@google.com> | 2017-01-25 12:10:37 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-01-25 17:53:10 +0000 |
commit | d46697ac36d5cb3b58571c6129cb5b26fe9d25d7 (patch) | |
tree | 5f7efe30049183c3248ce2cb8fe651e62f5c9392 | |
parent | 74b16edd98e4fd560baaf5655dd7e4ae43f8ae69 (diff) |
Use GrSurfaceContext::read/write-Pixels more
Change-Id: I04bcaf91aa7a43e0563e332c1fe2836d762a04d4
Reviewed-on: https://skia-review.googlesource.com/7520
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
-rw-r--r-- | include/gpu/GrRenderTargetContext.h | 3 | ||||
-rw-r--r-- | include/gpu/GrSurfaceContext.h | 8 | ||||
-rw-r--r-- | include/gpu/GrTextureContext.h | 1 | ||||
-rw-r--r-- | include/private/GrSurfaceProxy.h | 5 | ||||
-rw-r--r-- | src/gpu/GrContextPriv.h | 6 | ||||
-rw-r--r-- | src/gpu/GrSurfaceProxy.cpp | 15 | ||||
-rw-r--r-- | tests/CopySurfaceTest.cpp | 14 | ||||
-rw-r--r-- | tests/EGLImageTest.cpp | 94 | ||||
-rw-r--r-- | tests/FloatingPointTextureTest.cpp | 3 | ||||
-rw-r--r-- | tests/GrTextureStripAtlasTest.cpp | 19 | ||||
-rw-r--r-- | tests/IntTextureTest.cpp | 203 | ||||
-rw-r--r-- | tests/RectangleTextureTest.cpp | 142 |
12 files changed, 290 insertions, 223 deletions
diff --git a/include/gpu/GrRenderTargetContext.h b/include/gpu/GrRenderTargetContext.h index aab105087f..b3f15bef47 100644 --- a/include/gpu/GrRenderTargetContext.h +++ b/include/gpu/GrRenderTargetContext.h @@ -343,9 +343,12 @@ public: } GrSurfaceProxy* asDeferredSurface() override { return fRenderTargetProxy.get(); } + const GrSurfaceProxy* asDeferredSurface() const override { return fRenderTargetProxy.get(); } GrTextureProxy* asDeferredTexture() override; GrRenderTargetProxy* asDeferredRenderTarget() override { return fRenderTargetProxy.get(); } + GrRenderTargetContext* asRenderTargetContext() override { return this; } + sk_sp<GrTexture> asTexture() { if (!this->accessRenderTarget()) { return nullptr; diff --git a/include/gpu/GrSurfaceContext.h b/include/gpu/GrSurfaceContext.h index 6a40f2f8b2..75ee95276e 100644 --- a/include/gpu/GrSurfaceContext.h +++ b/include/gpu/GrSurfaceContext.h @@ -14,6 +14,7 @@ class GrAuditTrail; class GrContext; +class GrRenderTargetContext; class GrRenderTargetProxy; class GrSingleOwner; class GrSurface; @@ -34,6 +35,10 @@ public: sk_sp<SkColorSpace> refColorSpace() const { return fColorSpace; } bool isGammaCorrect() const { return SkToBool(fColorSpace.get()); } + // TODO: these two calls would be way cooler if this object had a GrSurfaceProxy pointer + int width() const { return this->asDeferredSurface()->width(); } + int height() const { return this->asDeferredSurface()->height(); } + /* * Copy 'src' into the proxy backing this context * @param src src of pixels @@ -91,9 +96,12 @@ public: // TODO: this is virtual b.c. this object doesn't have a pointer to the wrapped GrSurfaceProxy? virtual GrSurfaceProxy* asDeferredSurface() = 0; + virtual const GrSurfaceProxy* asDeferredSurface() const = 0; virtual GrTextureProxy* asDeferredTexture() = 0; virtual GrRenderTargetProxy* asDeferredRenderTarget() = 0; + virtual GrRenderTargetContext* asRenderTargetContext() { return nullptr; } + GrAuditTrail* auditTrail() { return fAuditTrail; } // Provides access to functions that aren't part of the public API. diff --git a/include/gpu/GrTextureContext.h b/include/gpu/GrTextureContext.h index b49b27255a..79a1719ac2 100644 --- a/include/gpu/GrTextureContext.h +++ b/include/gpu/GrTextureContext.h @@ -28,6 +28,7 @@ public: ~GrTextureContext() override; GrSurfaceProxy* asDeferredSurface() override { return fTextureProxy.get(); } + const GrSurfaceProxy* asDeferredSurface() const override { return fTextureProxy.get(); } GrTextureProxy* asDeferredTexture() override { return fTextureProxy.get(); } GrRenderTargetProxy* asDeferredRenderTarget() override; diff --git a/include/private/GrSurfaceProxy.h b/include/private/GrSurfaceProxy.h index 12972c21be..9363b8280b 100644 --- a/include/private/GrSurfaceProxy.h +++ b/include/private/GrSurfaceProxy.h @@ -16,6 +16,7 @@ class GrCaps; class GrRenderTargetOpList; class GrRenderTargetProxy; +class GrSurfaceContext; class GrTextureOpList; class GrTextureProvider; class GrTextureProxy; @@ -277,8 +278,8 @@ public: } // Test-only entry point - should decrease in use as proxies propagate - static sk_sp<GrSurfaceProxy> TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc, - GrTexture* srcTexture, SkBudgeted budgeted); + static sk_sp<GrSurfaceContext> TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc, + GrSurfaceProxy* srcProxy); bool isWrapped_ForTesting() const; diff --git a/src/gpu/GrContextPriv.h b/src/gpu/GrContextPriv.h index 3315c94e91..ed9691c656 100644 --- a/src/gpu/GrContextPriv.h +++ b/src/gpu/GrContextPriv.h @@ -35,6 +35,12 @@ public: SkBackingFit dstFit, SkBudgeted isDstBudgeted); + // TODO: add: + // sk_sp<GrSurfaceContext> makeBackendSurfaceContext(const GrBackendTextureDesc& desc, + // sk_sp<SkColorSpace> colorSpace, + // GrWrapOwnership = kBorrow_GrWrapOwnership); + // Maybe add a 'surfaceProps' param that is ignored for non-RTs? + sk_sp<GrRenderTargetContext> makeBackendTextureRenderTargetContext( const GrBackendTextureDesc& desc, sk_sp<SkColorSpace> colorSpace, diff --git a/src/gpu/GrSurfaceProxy.cpp b/src/gpu/GrSurfaceProxy.cpp index 48fc401b4e..4cf4611f91 100644 --- a/src/gpu/GrSurfaceProxy.cpp +++ b/src/gpu/GrSurfaceProxy.cpp @@ -196,25 +196,20 @@ sk_sp<GrSurfaceProxy> GrSurfaceProxy::Copy(GrContext* context, return sk_ref_sp(dstContext->asDeferredSurface()); } -sk_sp<GrSurfaceProxy> GrSurfaceProxy::TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc, - GrTexture* srcTexture, SkBudgeted budgeted) { +sk_sp<GrSurfaceContext> GrSurfaceProxy::TestCopy(GrContext* context, const GrSurfaceDesc& dstDesc, + GrSurfaceProxy* srcProxy) { sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext( dstDesc, SkBackingFit::kExact, - budgeted)); + SkBudgeted::kYes)); if (!dstContext) { return nullptr; } - sk_sp<GrSurfaceProxy> srcProxy(GrSurfaceProxy::MakeWrapped(sk_ref_sp(srcTexture))); - if (!srcProxy) { + if (!dstContext->copy(srcProxy)) { return nullptr; } - if (!dstContext->copy(srcProxy.get())) { - return nullptr; - } - - return sk_ref_sp(dstContext->asDeferredSurface()); + return dstContext; } diff --git a/tests/CopySurfaceTest.cpp b/tests/CopySurfaceTest.cpp index efb6b2d43d..19037d9200 100644 --- a/tests/CopySurfaceTest.cpp +++ b/tests/CopySurfaceTest.cpp @@ -56,6 +56,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) { {-1 , -1 }, }; + const SkImageInfo ii = SkImageInfo::Make(kW, kH, kRGBA_8888_SkColorType, kPremul_SkAlphaType); + SkAutoTMalloc<uint32_t> read(kW * kH); for (auto sOrigin : {kBottomLeft_GrSurfaceOrigin, kTopLeft_GrSurfaceOrigin}) { @@ -90,10 +92,11 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) { continue; } - sk_sp<GrSurfaceContext> sContext = - context->contextPriv().makeWrappedSurfaceContext(dst, nullptr); + sk_sp<GrSurfaceContext> dstContext = + context->contextPriv().makeWrappedSurfaceContext(std::move(dst), + nullptr); - bool result = sContext->copy(src.get(), srcRect, dstPoint); + bool result = dstContext->copy(src.get(), srcRect, dstPoint); bool expectedResult = true; SkIPoint dstOffset = { dstPoint.fX - srcRect.fLeft, @@ -130,11 +133,8 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(CopySurface, reporter, ctxInfo) { continue; } - GrSurface* dstSurf = dst->instantiate(context->textureProvider()); - sk_memset32(read.get(), 0, kW * kH); - if (!dstSurf->readPixels(0, 0, kW, kH, baseDesc.fConfig, read.get(), - kRowBytes)) { + if (!dstContext->readPixels(ii, read.get(), kRowBytes, 0, 0)) { ERRORF(reporter, "Error calling readPixels"); continue; } diff --git a/tests/EGLImageTest.cpp b/tests/EGLImageTest.cpp index 0dcacf9b6b..79d326156a 100644 --- a/tests/EGLImageTest.cpp +++ b/tests/EGLImageTest.cpp @@ -8,6 +8,7 @@ #include "Test.h" #if SK_SUPPORT_GPU #include "GrContext.h" +#include "GrContextPriv.h" #include "GrContextFactory.h" #include "GrShaderCaps.h" #include "GrSurfaceContext.h" @@ -41,13 +42,16 @@ static void cleanup(GLTestContext* glctx0, GrGLuint texID0, GLTestContext* glctx } static void test_read_pixels(skiatest::Reporter* reporter, GrContext* context, - GrSurface* externalTexture, uint32_t expectedPixelValues[]) { - int pixelCnt = externalTexture->width() * externalTexture->height(); + GrSurfaceContext* externalTextureContext, + uint32_t expectedPixelValues[]) { + int pixelCnt = externalTextureContext->width() * externalTextureContext->height(); SkAutoTMalloc<uint32_t> pixels(pixelCnt); memset(pixels.get(), 0, sizeof(uint32_t)*pixelCnt); - bool read = externalTexture->readPixels(0, 0, externalTexture->width(), - externalTexture->height(), kRGBA_8888_GrPixelConfig, - pixels.get()); + + SkImageInfo ii = SkImageInfo::Make(externalTextureContext->width(), + externalTextureContext->height(), + kRGBA_8888_SkColorType, kPremul_SkAlphaType); + bool read = externalTextureContext->readPixels(ii, pixels.get(), 0, 0, 0); if (!read) { ERRORF(reporter, "Error reading external texture."); } @@ -61,29 +65,32 @@ static void test_read_pixels(skiatest::Reporter* reporter, GrContext* context, } static void test_write_pixels(skiatest::Reporter* reporter, GrContext* context, - GrTexture* externalTexture) { - int pixelCnt = externalTexture->width() * externalTexture->height(); + GrSurfaceContext* externalTextureContext) { + int pixelCnt = externalTextureContext->width() * externalTextureContext->height(); SkAutoTMalloc<uint32_t> pixels(pixelCnt); memset(pixels.get(), 0, sizeof(uint32_t)*pixelCnt); - bool write = externalTexture->writePixels(0, 0, 0, 0, kRGBA_8888_GrPixelConfig, pixels.get()); + + SkImageInfo ii = SkImageInfo::Make(externalTextureContext->width(), + externalTextureContext->height(), + kRGBA_8888_SkColorType, kPremul_SkAlphaType); + bool write = externalTextureContext->writePixels(ii, pixels.get(), 0, 0, 0); REPORTER_ASSERT_MESSAGE(reporter, !write, "Should not be able to write to a EXTERNAL" " texture."); } static void test_copy_surface(skiatest::Reporter* reporter, GrContext* context, - GrTexture* externalTexture, uint32_t expectedPixelValues[]) { + GrSurfaceProxy* externalTextureProxy, + uint32_t expectedPixelValues[]) { GrSurfaceDesc copyDesc; copyDesc.fConfig = kRGBA_8888_GrPixelConfig; - copyDesc.fWidth = externalTexture->width(); - copyDesc.fHeight = externalTexture->height(); + copyDesc.fWidth = externalTextureProxy->width(); + copyDesc.fHeight = externalTextureProxy->height(); copyDesc.fFlags = kRenderTarget_GrSurfaceFlag; - sk_sp<GrSurfaceProxy> copy(GrSurfaceProxy::TestCopy(context, copyDesc, - externalTexture, SkBudgeted::kYes)); - - GrSurface* copySurf = copy->instantiate(context->textureProvider()); + sk_sp<GrSurfaceContext> copyContext(GrSurfaceProxy::TestCopy(context, copyDesc, + externalTextureProxy)); - test_read_pixels(reporter, context, copySurf, expectedPixelValues); + test_read_pixels(reporter, context, copyContext.get(), expectedPixelValues); } DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(EGLImageTest, reporter, ctxInfo) { @@ -178,37 +185,50 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(EGLImageTest, reporter, ctxInfo) { externalDesc.fWidth = kSize; externalDesc.fHeight = kSize; externalDesc.fTextureHandle = reinterpret_cast<GrBackendObject>(&externalTexture); - sk_sp<GrTexture> externalTextureObj( - context0->textureProvider()->wrapBackendTexture(externalDesc)); - if (!externalTextureObj) { - ERRORF(reporter, "Error wrapping external texture in GrTexture."); - cleanup(glCtx0, externalTexture.fID, glCtx1.get(), context1, backendTexture1, image); - return; + + sk_sp<GrSurfaceContext> externalTextureContext; + + { + sk_sp<GrTexture> externalTextureObj( + context0->textureProvider()->wrapBackendTexture(externalDesc)); + if (!externalTextureObj) { + ERRORF(reporter, "Error wrapping external texture in GrTexture."); + cleanup(glCtx0, externalTexture.fID, glCtx1.get(), context1, backendTexture1, image); + return; + } + + externalTextureContext = context0->contextPriv().makeWrappedSurfaceContext( + std::move(externalTextureObj)); } // Should not be able to wrap as a RT - externalDesc.fFlags = kRenderTarget_GrBackendTextureFlag; - sk_sp<GrTexture> externalTextureRTObj( - context0->textureProvider()->wrapBackendTexture(externalDesc)); - if (externalTextureRTObj) { - ERRORF(reporter, "Should not be able to wrap an EXTERNAL texture as a RT."); + { + externalDesc.fFlags = kRenderTarget_GrBackendTextureFlag; + sk_sp<GrTexture> externalTextureRTObj( + context0->textureProvider()->wrapBackendTexture(externalDesc)); + if (externalTextureRTObj) { + ERRORF(reporter, "Should not be able to wrap an EXTERNAL texture as a RT."); + } + externalDesc.fFlags = kNone_GrBackendTextureFlag; } - externalDesc.fFlags = kNone_GrBackendTextureFlag; // Should not be able to wrap with a sample count - externalDesc.fSampleCnt = 4; - sk_sp<GrTexture> externalTextureMSAAObj( - context0->textureProvider()->wrapBackendTexture(externalDesc)); - if (externalTextureMSAAObj) { - ERRORF(reporter, "Should not be able to wrap an EXTERNAL texture with MSAA."); + { + externalDesc.fSampleCnt = 4; + sk_sp<GrTexture> externalTextureMSAAObj( + context0->textureProvider()->wrapBackendTexture(externalDesc)); + if (externalTextureMSAAObj) { + ERRORF(reporter, "Should not be able to wrap an EXTERNAL texture with MSAA."); + } + externalDesc.fSampleCnt = 0; } - externalDesc.fSampleCnt = 0; - test_read_pixels(reporter, context0, externalTextureObj.get(), pixels.get()); + test_read_pixels(reporter, context0, externalTextureContext.get(), pixels.get()); - test_write_pixels(reporter, context0, externalTextureObj.get()); + test_write_pixels(reporter, context0, externalTextureContext.get()); - test_copy_surface(reporter, context0, externalTextureObj.get(), pixels.get()); + test_copy_surface(reporter, context0, externalTextureContext->asDeferredSurface(), + pixels.get()); cleanup(glCtx0, externalTexture.fID, glCtx1.get(), context1, backendTexture1, image); } diff --git a/tests/FloatingPointTextureTest.cpp b/tests/FloatingPointTextureTest.cpp index 8f0be39360..95917b46ad 100644 --- a/tests/FloatingPointTextureTest.cpp +++ b/tests/FloatingPointTextureTest.cpp @@ -43,8 +43,7 @@ void runFPTest(skiatest::Reporter* reporter, GrContext* context, desc.fWidth = DEV_W; desc.fHeight = DEV_H; desc.fConfig = config; - desc.fOrigin = 0 == origin ? - kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin; + desc.fOrigin = 0 == origin ? kTopLeft_GrSurfaceOrigin : kBottomLeft_GrSurfaceOrigin; sk_sp<GrTexture> fpTexture(context->textureProvider()->createTexture( desc, SkBudgeted::kNo, controlPixelData.begin(), 0)); // Floating point textures are NOT supported everywhere diff --git a/tests/GrTextureStripAtlasTest.cpp b/tests/GrTextureStripAtlasTest.cpp index 2def782f38..5b1a14e1b2 100644 --- a/tests/GrTextureStripAtlasTest.cpp +++ b/tests/GrTextureStripAtlasTest.cpp @@ -34,7 +34,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo) } // Add a pending read to the src texture, and then make it available for reuse. - sk_sp<GrSurfaceProxy> targetProxy; + sk_sp<GrSurfaceContext> dstContext; GrSurface* srcSurface; { @@ -42,18 +42,15 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo) targetDesc.fFlags = kRenderTarget_GrSurfaceFlag; // We can't use GrSurfaceProxy::Copy bc we may be changing the dst proxy type - sk_sp<GrSurfaceContext> dstContext(context->contextPriv().makeDeferredSurfaceContext( - targetDesc, - SkBackingFit::kExact, - SkBudgeted::kYes)); + dstContext = context->contextPriv().makeDeferredSurfaceContext(targetDesc, + SkBackingFit::kExact, + SkBudgeted::kYes); REPORTER_ASSERT(reporter, dstContext); if (!dstContext->copy(srcProxy.get())) { return; } - targetProxy = sk_ref_sp(dstContext->asDeferredSurface()); - srcSurface = srcProxy->instantiate(context->textureProvider()); srcProxy.reset(); } @@ -87,11 +84,9 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(GrTextureStripAtlasFlush, reporter, ctxInfo) { SkAutoTMalloc<uint8_t> actualPixels(sizeof(uint32_t) * desc.fWidth * desc.fHeight); - // TODO: move readPixels to GrSurfaceProxy? - GrSurface* surf = targetProxy->instantiate(context->textureProvider()); - - bool success = surf->readPixels(0, 0, desc.fWidth, desc.fHeight, - kRGBA_8888_GrPixelConfig, actualPixels.get()); + SkImageInfo ii = SkImageInfo::Make(desc.fWidth, desc.fHeight, + kRGBA_8888_SkColorType, kPremul_SkAlphaType); + bool success = dstContext->readPixels(ii, actualPixels.get(), 0, 0, 0); REPORTER_ASSERT(reporter, success); bool good = true; diff --git a/tests/IntTextureTest.cpp b/tests/IntTextureTest.cpp index 3edd4cc986..23ccb50cb6 100644 --- a/tests/IntTextureTest.cpp +++ b/tests/IntTextureTest.cpp @@ -36,11 +36,12 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(IntTexture, reporter, ctxInfo) { return; } static const int kS = UINT8_MAX + 1; + static const size_t kRowBytes = kS * sizeof(int32_t); + GrSurfaceDesc desc; desc.fConfig = kRGBA_8888_sint_GrPixelConfig; desc.fWidth = kS; desc.fHeight = kS; - sk_sp<GrTexture> texture; std::unique_ptr<int32_t[]> testData(new int32_t[kS * kS]); for (int j = 0; j < kS; ++j) { @@ -53,66 +54,86 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(IntTexture, reporter, ctxInfo) { } } - // Test that attempting to create a integer texture with multiple MIP level fails. - GrMipLevel levels[2]; - levels[0].fPixels = testData.get(); - levels[0].fRowBytes = kS * sizeof(int32_t); - levels[1].fPixels = testData.get(); - levels[1].fRowBytes = (kS / 2) * sizeof(int32_t); - texture.reset(context->textureProvider()->createMipMappedTexture(desc, SkBudgeted::kYes, levels, - 2)); - REPORTER_ASSERT(reporter, !texture); - - // Test that we can create a integer texture. - texture.reset(context->textureProvider()->createTexture(desc, SkBudgeted::kYes, - levels[0].fPixels, - levels[0].fRowBytes)); + // Test that attempting to create a integer texture with multiple MIP levels fails. + { + GrMipLevel levels[2]; + levels[0].fPixels = testData.get(); + levels[0].fRowBytes = kRowBytes; + levels[1].fPixels = testData.get(); + levels[1].fRowBytes = (kS / 2) * sizeof(int32_t); + + sk_sp<GrTexture> temp(context->textureProvider()->createMipMappedTexture(desc, + SkBudgeted::kYes, + levels, 2)); + REPORTER_ASSERT(reporter, !temp); + } + + // Test that we can create an integer texture. + sk_sp<GrSurfaceProxy> proxy = GrSurfaceProxy::MakeDeferred(*context->caps(), + context->textureProvider(), + desc, SkBudgeted::kYes, + testData.get(), + kRowBytes); + REPORTER_ASSERT(reporter, proxy); + if (!proxy || !proxy->asTextureProxy()) { + return; + } + + GrTexture* texture = proxy->asTextureProxy()->instantiate(context->textureProvider()); REPORTER_ASSERT(reporter, texture); if (!texture) { return; } - // Test that reading to a non-integer config fails. std::unique_ptr<int32_t[]> readData(new int32_t[kS * kS]); - bool success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_GrPixelConfig, readData.get()); - REPORTER_ASSERT(reporter, !success); - std::unique_ptr<uint16_t[]> halfData(new uint16_t[4 * kS * kS]); - success = texture->readPixels(0, 0, kS, kS, kRGBA_half_GrPixelConfig, halfData.get()); - REPORTER_ASSERT(reporter, !success); - - // Can read back as ints. (ES only requires being able to read back into 32bit ints which - // we don't support. Right now this test is counting on GR_RGBA_INTEGER/GL_BYTE being the - // implementation-dependent second format). - sk_bzero(readData.get(), sizeof(int32_t) * kS * kS); - success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig, readData.get()); - REPORTER_ASSERT(reporter, success); - if (success) { - check_pixels(reporter, kS, kS, testData.get(), readData.get(), "readPixels"); - } - - // readPixels should fail if we attempt to use the unpremul flag with an integer texture. - success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig, readData.get(), 0, - GrContext::kUnpremul_PixelOpsFlag); - REPORTER_ASSERT(reporter, !success); + // Test that reading to a non-integer config fails. + { + bool success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_GrPixelConfig, readData.get()); + REPORTER_ASSERT(reporter, !success); + } + { + std::unique_ptr<uint16_t[]> halfData(new uint16_t[4 * kS * kS]); + bool success = texture->readPixels(0, 0, kS, kS, kRGBA_half_GrPixelConfig, halfData.get()); + REPORTER_ASSERT(reporter, !success); + } + { + // Can read back as ints. (ES only requires being able to read back into 32bit ints which + // we don't support. Right now this test is counting on GR_RGBA_INTEGER/GL_BYTE being the + // implementation-dependent second format). + sk_bzero(readData.get(), sizeof(int32_t) * kS * kS); + bool success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig, + readData.get()); + REPORTER_ASSERT(reporter, success); + if (success) { + check_pixels(reporter, kS, kS, testData.get(), readData.get(), "readPixels"); + } + } + { + // readPixels should fail if we attempt to use the unpremul flag with an integer texture. + bool success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig, + readData.get(), 0, GrContext::kUnpremul_PixelOpsFlag); + REPORTER_ASSERT(reporter, !success); + } // Test that copying from one integer texture to another succeeds. { - sk_sp<GrSurfaceProxy> copy(GrSurfaceProxy::TestCopy(context, desc, - texture.get(), SkBudgeted::kYes)); - REPORTER_ASSERT(reporter, copy); - if (!copy) { + sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, desc, + proxy.get())); + REPORTER_ASSERT(reporter, dstContext); + if (!dstContext || !dstContext->asDeferredTexture()) { return; } - GrSurface* copySurface = copy->instantiate(context->textureProvider()); + GrSurface* copySurface = dstContext->asDeferredTexture()->instantiate( + context->textureProvider()); REPORTER_ASSERT(reporter, copySurface); if (!copySurface) { return; } sk_bzero(readData.get(), sizeof(int32_t) * kS * kS); - success = copySurface->readPixels(0, 0, kS, kS, - kRGBA_8888_sint_GrPixelConfig, readData.get()); + bool success = copySurface->readPixels(0, 0, kS, kS, + kRGBA_8888_sint_GrPixelConfig, readData.get()); REPORTER_ASSERT(reporter, success); if (success) { check_pixels(reporter, kS, kS, testData.get(), readData.get(), "copyIntegerToInteger"); @@ -125,9 +146,9 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(IntTexture, reporter, ctxInfo) { GrSurfaceDesc nonIntDesc = desc; nonIntDesc.fConfig = kRGBA_8888_GrPixelConfig; - sk_sp<GrSurfaceProxy> copy(GrSurfaceProxy::TestCopy(context, nonIntDesc, - texture.get(), SkBudgeted::kYes)); - REPORTER_ASSERT(reporter, !copy); + sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, nonIntDesc, + proxy.get())); + REPORTER_ASSERT(reporter, !dstContext); } // Test that copying to a non-integer (RGBA_half) texture fails. @@ -135,49 +156,53 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(IntTexture, reporter, ctxInfo) { GrSurfaceDesc nonIntDesc = desc; nonIntDesc.fConfig = kRGBA_half_GrPixelConfig; - sk_sp<GrSurfaceProxy> copy(GrSurfaceProxy::TestCopy(context, nonIntDesc, - texture.get(), SkBudgeted::kYes)); - REPORTER_ASSERT(reporter, !copy); + sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, nonIntDesc, + proxy.get())); + REPORTER_ASSERT(reporter, !dstContext); } // We overwrite the top left quarter of the texture with the bottom right quarter of the // original data. const void* bottomRightQuarter = testData.get() + kS / 2 * kS + kS / 2; - size_t rowBytes = kS * sizeof(int32_t); - - // Can't write pixels from a non-int config. - success = texture->writePixels(0, 0, kS/2, kS/2, kRGBA_8888_GrPixelConfig, bottomRightQuarter, - rowBytes); - REPORTER_ASSERT(reporter, !success); - - // Can't use unpremul flag. - success = texture->writePixels(0, 0, kS/2, kS/2, kRGBA_8888_sint_GrPixelConfig, - bottomRightQuarter, rowBytes, - GrContext::kUnpremul_PixelOpsFlag); - REPORTER_ASSERT(reporter, !success); - - success = texture->writePixels(0, 0, kS/2, kS/2, kRGBA_8888_sint_GrPixelConfig, - bottomRightQuarter, rowBytes); - REPORTER_ASSERT(reporter, success); - if (!success) { - return; + + { + // Can't write pixels from a non-int config. + bool success = texture->writePixels(0, 0, kS/2, kS/2, kRGBA_8888_GrPixelConfig, + bottomRightQuarter, kRowBytes); + REPORTER_ASSERT(reporter, !success); } - sk_bzero(readData.get(), sizeof(int32_t) * kS * kS); - success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig, readData.get()); - REPORTER_ASSERT(reporter, success); - if (!success) { - return; + { + // Can't use unpremul flag. + bool success = texture->writePixels(0, 0, kS/2, kS/2, kRGBA_8888_sint_GrPixelConfig, + bottomRightQuarter, kRowBytes, + GrContext::kUnpremul_PixelOpsFlag); + REPORTER_ASSERT(reporter, !success); } - std::unique_ptr<int32_t[]> overwrittenTestData(new int32_t[kS * kS]); - memcpy(overwrittenTestData.get(), testData.get(), sizeof(int32_t) * kS * kS); - char* dst = (char*)overwrittenTestData.get(); - char* src = (char*)(testData.get() + kS/2 * kS + kS/2); - for (int i = 0; i < kS/2; ++i) { - memcpy(dst, src, sizeof(int32_t) * kS/2); - dst += rowBytes; - src += rowBytes; + { + bool success = texture->writePixels(0, 0, kS/2, kS/2, kRGBA_8888_sint_GrPixelConfig, + bottomRightQuarter, kRowBytes); + REPORTER_ASSERT(reporter, success); + if (!success) { + return; + } + + sk_bzero(readData.get(), sizeof(int32_t) * kS * kS); + success = texture->readPixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig, readData.get()); + REPORTER_ASSERT(reporter, success); + if (!success) { + return; + } + std::unique_ptr<int32_t[]> overwrittenTestData(new int32_t[kS * kS]); + memcpy(overwrittenTestData.get(), testData.get(), sizeof(int32_t) * kS * kS); + char* dst = (char*)overwrittenTestData.get(); + char* src = (char*)(testData.get() + kS/2 * kS + kS/2); + for (int i = 0; i < kS/2; ++i) { + memcpy(dst, src, sizeof(int32_t) * kS/2); + dst += kRowBytes; + src += kRowBytes; + } + check_pixels(reporter, kS, kS, overwrittenTestData.get(), readData.get(), "overwrite"); } - check_pixels(reporter, kS, kS, overwrittenTestData.get(), readData.get(), "overwrite"); // Test drawing from the integer texture to a fixed point texture. To avoid any premul issues // we init the int texture with 0s and 1s and make alpha always be 1. We expect that 1s turn @@ -194,6 +219,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(IntTexture, reporter, ctxInfo) { ((0xFF * g) << 8) | (0xFF * r); } texture->writePixels(0, 0, kS, kS, kRGBA_8888_sint_GrPixelConfig, testData.get()); + sk_sp<GrRenderTargetContext> rtContext = context->makeRenderTargetContext( SkBackingFit::kExact, kS, kS, kRGBA_8888_GrPixelConfig, nullptr); @@ -207,7 +233,7 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(IntTexture, reporter, ctxInfo) { }; for (auto filter : kNamedFilters) { - sk_sp<GrFragmentProcessor> fp(GrSimpleTextureEffect::Make(texture.get(), nullptr, + sk_sp<GrFragmentProcessor> fp(GrSimpleTextureEffect::Make(texture, nullptr, SkMatrix::I(), filter.fMode)); REPORTER_ASSERT(reporter, fp); @@ -225,11 +251,14 @@ DEF_GPUTEST_FOR_RENDERING_CONTEXTS(IntTexture, reporter, ctxInfo) { check_pixels(reporter, kS, kS, expectedData.get(), actualData.get(), filter.fName); } - // No rendering to integer textures. - GrSurfaceDesc intRTDesc = desc; - intRTDesc.fFlags = kRenderTarget_GrSurfaceFlag; - texture.reset(context->textureProvider()->createTexture(intRTDesc, SkBudgeted::kYes)); - REPORTER_ASSERT(reporter, !texture); + { + // No rendering to integer textures. + GrSurfaceDesc intRTDesc = desc; + intRTDesc.fFlags = kRenderTarget_GrSurfaceFlag; + sk_sp<GrTexture> temp(context->textureProvider()->createTexture(intRTDesc, + SkBudgeted::kYes)); + REPORTER_ASSERT(reporter, !temp); + } } #endif diff --git a/tests/RectangleTextureTest.cpp b/tests/RectangleTextureTest.cpp index 6d075df203..523c2e3437 100644 --- a/tests/RectangleTextureTest.cpp +++ b/tests/RectangleTextureTest.cpp @@ -15,15 +15,18 @@ #include "gl/GLTestContext.h" static void test_read_pixels(skiatest::Reporter* reporter, GrContext* context, - GrSurface* texture, uint32_t expectedPixelValues[]) { - int pixelCnt = texture->width() * texture->height(); + GrSurfaceContext* srcContext, uint32_t expectedPixelValues[]) { + int pixelCnt = srcContext->width() * srcContext->height(); SkAutoTMalloc<uint32_t> pixels(pixelCnt); memset(pixels.get(), 0, sizeof(uint32_t)*pixelCnt); - bool read = texture->readPixels(0, 0, texture->width(), texture->height(), - kRGBA_8888_GrPixelConfig, pixels.get()); + + SkImageInfo ii = SkImageInfo::Make(srcContext->width(), srcContext->height(), + kRGBA_8888_SkColorType, kPremul_SkAlphaType); + bool read = srcContext->readPixels(ii, pixels.get(), 0, 0, 0); if (!read) { ERRORF(reporter, "Error reading rectangle texture."); } + for (int i = 0; i < pixelCnt; ++i) { if (pixels.get()[i] != expectedPixelValues[i]) { ERRORF(reporter, "Error, pixel value %d should be 0x%08x, got 0x%08x.", i, @@ -34,110 +37,102 @@ static void test_read_pixels(skiatest::Reporter* reporter, GrContext* context, } static void test_write_pixels(skiatest::Reporter* reporter, GrContext* context, - GrTexture* rectangleTexture) { - int pixelCnt = rectangleTexture->width() * rectangleTexture->height(); + GrSurfaceContext* rectSurfaceContext) { + int pixelCnt = rectSurfaceContext->width() * rectSurfaceContext->height(); SkAutoTMalloc<uint32_t> pixels(pixelCnt); - for (int y = 0; y < rectangleTexture->width(); ++y) { - for (int x = 0; x < rectangleTexture->height(); ++x) { - pixels.get()[y * rectangleTexture->width() + x] = GrColorPackRGBA(x, y, x + y, x * y); + for (int y = 0; y < rectSurfaceContext->width(); ++y) { + for (int x = 0; x < rectSurfaceContext->height(); ++x) { + pixels.get()[y * rectSurfaceContext->width() + x] = GrColorPackRGBA(x, y, x + y, x * y); } } - bool write = rectangleTexture->writePixels(0, 0, rectangleTexture->width(), - rectangleTexture->height(), kRGBA_8888_GrPixelConfig, - pixels.get()); + + SkImageInfo ii = SkImageInfo::Make(rectSurfaceContext->width(), rectSurfaceContext->height(), + kRGBA_8888_SkColorType, kPremul_SkAlphaType); + bool write = rectSurfaceContext->writePixels(ii, pixels.get(), 0, 0, 0); if (!write) { ERRORF(reporter, "Error writing to rectangle texture."); } - test_read_pixels(reporter, context, rectangleTexture, pixels.get()); + + test_read_pixels(reporter, context, rectSurfaceContext, pixels.get()); } static void test_copy_surface_src(skiatest::Reporter* reporter, GrContext* context, - GrTexture* rectTexture, uint32_t expectedPixelValues[]) { + GrSurfaceProxy* rectProxy, uint32_t expectedPixelValues[]) { GrSurfaceDesc copyDstDesc; copyDstDesc.fConfig = kRGBA_8888_GrPixelConfig; - copyDstDesc.fWidth = rectTexture->width(); - copyDstDesc.fHeight = rectTexture->height(); + copyDstDesc.fWidth = rectProxy->width(); + copyDstDesc.fHeight = rectProxy->height(); for (auto flags : {kNone_GrSurfaceFlags, kRenderTarget_GrSurfaceFlag}) { copyDstDesc.fFlags = flags; - sk_sp<GrSurfaceProxy> dst(GrSurfaceProxy::TestCopy(context, copyDstDesc, - rectTexture, SkBudgeted::kYes)); + sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, copyDstDesc, + rectProxy)); - GrSurface* dstSurf = dst->instantiate(context->textureProvider()); - - test_read_pixels(reporter, context, dstSurf, expectedPixelValues); + test_read_pixels(reporter, context, dstContext.get(), expectedPixelValues); } } static void test_copy_surface_dst(skiatest::Reporter* reporter, GrContext* context, - GrTexture* rectangleTexture) { - - sk_sp<GrSurfaceContext> sContext(context->contextPriv().makeWrappedSurfaceContext( - sk_ref_sp(rectangleTexture))); + GrSurfaceContext* rectContext) { - int pixelCnt = rectangleTexture->width() * rectangleTexture->height(); + int pixelCnt = rectContext->width() * rectContext->height(); SkAutoTMalloc<uint32_t> pixels(pixelCnt); - for (int y = 0; y < rectangleTexture->width(); ++y) { - for (int x = 0; x < rectangleTexture->height(); ++x) { - pixels.get()[y * rectangleTexture->width() + x] = GrColorPackRGBA(y, x, x * y, x *+ y); + for (int y = 0; y < rectContext->width(); ++y) { + for (int x = 0; x < rectContext->height(); ++x) { + pixels.get()[y * rectContext->width() + x] = GrColorPackRGBA(y, x, x * y, x *+ y); } } for (auto flags : {kNone_GrSurfaceFlags, kRenderTarget_GrSurfaceFlag}) { GrSurfaceDesc copySrcDesc; copySrcDesc.fConfig = kRGBA_8888_GrPixelConfig; - copySrcDesc.fWidth = rectangleTexture->width(); - copySrcDesc.fHeight = rectangleTexture->height(); + copySrcDesc.fWidth = rectContext->width(); + copySrcDesc.fHeight = rectContext->height(); copySrcDesc.fFlags = flags; sk_sp<GrSurfaceProxy> src(GrSurfaceProxy::MakeDeferred(*context->caps(), context->textureProvider(), copySrcDesc, SkBudgeted::kYes, pixels.get(), 0)); - sContext->copy(src.get()); + rectContext->copy(src.get()); - test_read_pixels(reporter, context, rectangleTexture, pixels.get()); + test_read_pixels(reporter, context, rectContext, pixels.get()); } } // skbug.com/5932 -static void test_basic_draw(skiatest::Reporter* reporter, GrContext* context, - GrTexture* rectangleTexture, uint32_t expectedPixelValues[]) { +static void test_basic_draw_as_src(skiatest::Reporter* reporter, GrContext* context, + sk_sp<GrSurfaceProxy> rectProxy, uint32_t expectedPixelValues[]) { sk_sp<GrRenderTargetContext> rtContext( - context->makeRenderTargetContext(SkBackingFit::kExact, rectangleTexture->width(), - rectangleTexture->height(), rectangleTexture->config(), + context->makeRenderTargetContext(SkBackingFit::kExact, rectProxy->width(), + rectProxy->height(), rectProxy->config(), nullptr)); for (auto filter : {GrSamplerParams::kNone_FilterMode, GrSamplerParams::kBilerp_FilterMode, GrSamplerParams::kMipMap_FilterMode}) { rtContext->clear(nullptr, 0xDDCCBBAA, true); - sk_sp<GrFragmentProcessor> fp(GrSimpleTextureEffect::Make(rectangleTexture, nullptr, - SkMatrix::I(), filter)); + sk_sp<GrFragmentProcessor> fp(GrSimpleTextureEffect::Make( + context, + sk_ref_sp(rectProxy->asTextureProxy()), + nullptr, + SkMatrix::I(), filter)); GrPaint paint; paint.setPorterDuffXPFactory(SkBlendMode::kSrc); paint.addColorFragmentProcessor(std::move(fp)); rtContext->drawPaint(GrNoClip(), std::move(paint), SkMatrix::I()); - test_read_pixels(reporter, context, rtContext->asTexture().get(), expectedPixelValues); + test_read_pixels(reporter, context, rtContext.get(), expectedPixelValues); } } static void test_clear(skiatest::Reporter* reporter, GrContext* context, - GrTexture* rectangleTexture) { - if (rectangleTexture->asRenderTarget()) { - sk_sp<GrRenderTargetContext> rtc(context->contextPriv().makeWrappedRenderTargetContext( - sk_ref_sp(rectangleTexture->asRenderTarget()), - nullptr)); - if (!rtc) { - ERRORF(reporter, "Could not get GrRenderTargetContext for rectangle texture."); - return; - } - + GrSurfaceContext* rectContext) { + if (GrRenderTargetContext* rtc = rectContext->asRenderTargetContext()) { // Clear the whole thing. GrColor color0 = GrColorPackRGBA(0xA, 0xB, 0xC, 0xD); rtc->clear(nullptr, color0, false); - int w = rectangleTexture->width(); - int h = rectangleTexture->height(); + int w = rtc->width(); + int h = rtc->height(); int pixelCnt = w * h; SkAutoTMalloc<uint32_t> expectedPixels(pixelCnt); @@ -148,7 +143,7 @@ static void test_clear(skiatest::Reporter* reporter, GrContext* context, expectedBytes0[1] = GrColorUnpackG(color0); expectedBytes0[2] = GrColorUnpackB(color0); expectedBytes0[3] = GrColorUnpackA(color0); - for (int i = 0; i < rectangleTexture->width() * rectangleTexture->height(); ++i) { + for (int i = 0; i < rtc->width() * rtc->height(); ++i) { expectedPixels.get()[i] = expectedColor0; } @@ -170,7 +165,7 @@ static void test_clear(skiatest::Reporter* reporter, GrContext* context, } } - test_read_pixels(reporter, context, rectangleTexture, expectedPixels.get()); + test_read_pixels(reporter, context, rtc, expectedPixels.get()); } } @@ -221,25 +216,40 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(RectangleTexture, reporter, ctxInfo) { } } - sk_sp<GrTexture> rectangleTexture( - context->textureProvider()->wrapBackendTexture(rectangleDesc)); - if (!rectangleTexture) { - ERRORF(reporter, "Error wrapping rectangle texture in GrTexture."); - GR_GL_CALL(glContext->gl(), DeleteTextures(1, &rectTexID)); - continue; + sk_sp<GrSurfaceProxy> rectProxy; + + { + sk_sp<GrTexture> rectangleTexture( + context->textureProvider()->wrapBackendTexture(rectangleDesc)); + if (!rectangleTexture) { + ERRORF(reporter, "Error wrapping rectangle texture in GrTexture."); + GR_GL_CALL(glContext->gl(), DeleteTextures(1, &rectTexID)); + continue; + } + + rectProxy = GrSurfaceProxy::MakeWrapped(std::move(rectangleTexture)); + if (!rectProxy) { + ERRORF(reporter, "Error creating proxy for rectangle texture."); + GR_GL_CALL(glContext->gl(), DeleteTextures(1, &rectTexID)); + continue; + } } - test_read_pixels(reporter, context, rectangleTexture.get(), refPixels); + test_basic_draw_as_src(reporter, context, rectProxy, refPixels); + + test_copy_surface_src(reporter, context, rectProxy.get(), refPixels); - test_basic_draw(reporter, context, rectangleTexture.get(), refPixels); + sk_sp<GrSurfaceContext> rectContext = context->contextPriv().makeWrappedSurfaceContext( + std::move(rectProxy), nullptr); + SkASSERT(rectContext); - test_copy_surface_src(reporter, context, rectangleTexture.get(), refPixels); + test_read_pixels(reporter, context, rectContext.get(), refPixels); - test_copy_surface_dst(reporter, context, rectangleTexture.get()); + test_copy_surface_dst(reporter, context, rectContext.get()); - test_write_pixels(reporter, context, rectangleTexture.get()); + test_write_pixels(reporter, context, rectContext.get()); - test_clear(reporter, context, rectangleTexture.get()); + test_clear(reporter, context, rectContext.get()); GR_GL_CALL(glContext->gl(), DeleteTextures(1, &rectTexID)); } |