From fe635fd76bbc375d527d1884af23cc617ca364ee Mon Sep 17 00:00:00 2001 From: kkinnunen Date: Fri, 29 Apr 2016 06:41:29 -0700 Subject: Make stencils be attachable to render targets created via SkSurface::MakeFromBackendTextureAsRenderTarget This is a regression from "Refactor to separate backend object lifecycle and GpuResource budget decision". GrGLRenderTarget::CreateWrapped creates only render targets that wrap the FBO. GrGLRenderTargetTexture::CreateWrapped creates render targets that wrap the texture. Use the latter as the implementation for SkSurface::MakeFromBackendTextureAsRenderTarget. The test contains disabled code. The MakeFromBackendTextureAsRenderTarget does not copy the existing texture contents to the FBO render buffer. GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1924183003 Review-Url: https://codereview.chromium.org/1924183003 --- src/gpu/gl/GrGLGpu.cpp | 17 ++++++------ tests/SurfaceTest.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 8 deletions(-) diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp index 29add839bd..affdadfe77 100644 --- a/src/gpu/gl/GrGLGpu.cpp +++ b/src/gpu/gl/GrGLGpu.cpp @@ -723,19 +723,20 @@ GrRenderTarget* GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTextu } #endif - GrGLTextureInfo texInfo; + GrGLTexture::IDDesc idDesc; + idDesc.fOwnership = GrBackendObjectOwnership::kBorrowed; GrSurfaceDesc surfDesc; #ifdef SK_IGNORE_GL_TEXTURE_TARGET - texInfo.fID = static_cast(desc.fTextureHandle); + idDesc.fInfo.fID = static_cast(desc.fTextureHandle); // We only support GL_TEXTURE_2D at the moment. - texInfo.fTarget = GR_GL_TEXTURE_2D; + idDesc.fInfo.fTarget = GR_GL_TEXTURE_2D; #else - texInfo = *info; + idDesc.fInfo = *info; #endif - if (GR_GL_TEXTURE_RECTANGLE != texInfo.fTarget && - GR_GL_TEXTURE_2D != texInfo.fTarget) { + if (GR_GL_TEXTURE_RECTANGLE != idDesc.fInfo.fTarget && + GR_GL_TEXTURE_2D != idDesc.fInfo.fTarget) { // Only texture rectangle and texture 2d are supported. We do not check whether texture // rectangle is supported by Skia - if the caller provided us with a texture rectangle, // we assume the necessary support exists. @@ -758,10 +759,10 @@ GrRenderTarget* GrGLGpu::onWrapBackendTextureAsRenderTarget(const GrBackendTextu } GrGLRenderTarget::IDDesc rtIDDesc; - if (!this->createRenderTargetObjects(surfDesc, texInfo, &rtIDDesc)) { + if (!this->createRenderTargetObjects(surfDesc, idDesc.fInfo, &rtIDDesc)) { return nullptr; } - return GrGLRenderTarget::CreateWrapped(this, surfDesc, rtIDDesc, 0); + return GrGLTextureRenderTarget::CreateWrapped(this, surfDesc, idDesc, rtIDDesc); } //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/SurfaceTest.cpp b/tests/SurfaceTest.cpp index 878adeda3d..26391f521e 100644 --- a/tests/SurfaceTest.cpp +++ b/tests/SurfaceTest.cpp @@ -900,3 +900,74 @@ DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceClear_Gpu, reporter, ctxInfo) { } } #endif + +#if SK_SUPPORT_GPU +DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(SurfaceWrappedTextureAsRenderTarget, reporter, ctxInfo) { + GrGpu* gpu = ctxInfo.fGrContext->getGpu(); + if (!gpu) { + return; + } + // Validate that we can draw paths to a canvas of a surface created with + // SkSurface::MakeFromBackendTextureAsRenderTarget. The code intends to enforce the use of + // stencil buffer. The original bug prevented the creation of stencil buffer, causing an assert + // while drawing paths. + + static const int kW = 100; + static const int kH = 100; + static const uint32_t kOrigColor = SK_ColorRED; + const SkColor kShapeColor = SK_ColorGREEN; + + SkPath clipPath; + clipPath.quadTo(SkIntToScalar(kW), SkIntToScalar(0), SkIntToScalar(kW), SkIntToScalar(kH)); + clipPath.lineTo(SkIntToScalar(0), SkIntToScalar(kH)); + clipPath.lineTo(SkIntToScalar(0), SkIntToScalar(0)); + clipPath.close(); + SkPath path; + path.quadTo(SkIntToScalar(0), SkIntToScalar(kH), SkIntToScalar(kW), SkIntToScalar(kH)); + path.lineTo(SkIntToScalar(kW), SkIntToScalar(0)); + path.lineTo(SkIntToScalar(0), SkIntToScalar(0)); + path.close(); + SkPaint paint; + paint.setAntiAlias(true); + paint.setColor(kShapeColor); + + SkImageInfo bitmapInfo = SkImageInfo::Make(kW, kH, kRGBA_8888_SkColorType, kPremul_SkAlphaType); + for (int sampleCnt : {0, 4, 8}) { + SkBitmap bitmap; + bitmap.allocPixels(bitmapInfo); + bitmap.eraseColor(kOrigColor); + GrBackendObject texHandle = gpu->createTestingOnlyBackendTexture(bitmap.getPixels(), kW, kH, + kRGBA_8888_GrPixelConfig); + + GrBackendTextureDesc wrappedDesc; + wrappedDesc.fConfig = kRGBA_8888_GrPixelConfig; + wrappedDesc.fWidth = kW; + wrappedDesc.fHeight = kH; + wrappedDesc.fOrigin = kBottomLeft_GrSurfaceOrigin; + wrappedDesc.fFlags = kRenderTarget_GrBackendTextureFlag; + wrappedDesc.fTextureHandle = texHandle; + wrappedDesc.fSampleCnt = sampleCnt; + + sk_sp surface( + SkSurface::MakeFromBackendTextureAsRenderTarget(ctxInfo.fGrContext, wrappedDesc, + nullptr)); + if (!surface) { + continue; + } + + surface->getCanvas()->clipPath(clipPath, SkRegion::kIntersect_Op, true); + surface->getCanvas()->drawPath(path, paint); + SkAssertResult(surface->readPixels(bitmapInfo, bitmap.getPixels(), + bitmap.rowBytes(), 0, 0)); + // Ensure that the shape color ends up to the surface. + REPORTER_ASSERT(reporter, kShapeColor == bitmap.getColor(kW / 2, kH / 2)); + SkColor backgroundColor = bitmap.getColor(kW - 1, 0); + if (!sampleCnt) { + // Ensure that the original texture color is preserved in pixels that aren't rendered to + // via the surface. + REPORTER_ASSERT(reporter, kOrigColor == backgroundColor); + } + gpu->deleteTestingOnlyBackendTexture(texHandle); + } +} +#endif -- cgit v1.2.3