From d58f040532f2f5a63d24bd17d7c588e52c0b99c3 Mon Sep 17 00:00:00 2001 From: Eric Karl Date: Fri, 31 Mar 2017 09:38:52 -0700 Subject: Respect kRectsMustMatchForMSAASrc_BlitFramebufferFlag in dst setup Crurently, when preparing a texture for blitFramebuffer, we ignore the kRectsMustMatchForMSAASrc_BlitFramebufferFlag, and may attempt to copy from one src rect to a different dst rect. This change updates initDescForDstCopy and setupDstTexture to allocate larger textures if necessary and accomodate this flags requirements. Bug: 658277 Change-Id: I9f45a03d4055e0ad87c01e1d826287695096e609 Reviewed-on: https://skia-review.googlesource.com/10941 Commit-Queue: Brian Salomon Reviewed-by: Brian Salomon --- tests/BlendTest.cpp | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 2 deletions(-) (limited to 'tests/BlendTest.cpp') diff --git a/tests/BlendTest.cpp b/tests/BlendTest.cpp index 785acb8681..8ac8fea838 100644 --- a/tests/BlendTest.cpp +++ b/tests/BlendTest.cpp @@ -5,11 +5,24 @@ * found in the LICENSE file. */ -#include "Test.h" +#include +#include "SkBitmap.h" +#include "SkCanvas.h" #include "SkColor.h" #include "SkColorPriv.h" +#include "SkSurface.h" #include "SkTaskGroup.h" -#include +#include "SkUtils.h" +#include "Test.h" + +#if SK_SUPPORT_GPU +#include "GrContext.h" +#include "GrContextPriv.h" +#include "GrResourceProvider.h" +#include "GrSurfaceContext.h" +#include "GrSurfaceProxy.h" +#include "GrTexture.h" +#endif struct Results { int diffs, diffs_0x00, diffs_0xff, diffs_by_1; }; @@ -66,3 +79,116 @@ DEF_TEST(Blend_byte_multiply, r) { }; for (auto multiply : perfect) { REPORTER_ASSERT(r, test(multiply).diffs == 0); } } + +#if SK_SUPPORT_GPU +namespace { +static sk_sp create_gpu_surface_backend_texture_as_render_target( + GrContext* context, int sampleCnt, int width, int height, GrPixelConfig config, + sk_sp* backingSurface) { + GrSurfaceDesc backingDesc; + backingDesc.fHeight = height; + backingDesc.fWidth = width; + backingDesc.fConfig = config; + backingDesc.fOrigin = kDefault_GrSurfaceOrigin; + backingDesc.fFlags = kRenderTarget_GrSurfaceFlag; + + (*backingSurface) + .reset(context->resourceProvider()->createTexture(backingDesc, SkBudgeted::kNo)); + + GrBackendTextureDesc desc; + desc.fConfig = config; + desc.fWidth = width; + desc.fHeight = height; + desc.fFlags = kRenderTarget_GrBackendTextureFlag; + desc.fTextureHandle = (*backingSurface)->getTextureHandle(); + desc.fSampleCnt = sampleCnt; + sk_sp surface = + SkSurface::MakeFromBackendTextureAsRenderTarget(context, desc, nullptr); + return surface; +} +} + +// Tests blending to a surface with no texture available. +DEF_GPUTEST_FOR_GL_RENDERING_CONTEXTS(ES2BlendWithNoTexture, reporter, ctxInfo) { + GrContext* context = ctxInfo.grContext(); + const int kWidth = 10; + const int kHeight = 10; + const GrPixelConfig kConfig = kRGBA_8888_GrPixelConfig; + const SkColorType kColorType = kRGBA_8888_SkColorType; + + // Build our test cases: + struct RectAndSamplePoint { + SkRect rect; + SkIPoint outPoint; + SkIPoint inPoint; + } allRectsAndPoints[3] = { + {SkRect::MakeXYWH(0, 0, 5, 5), SkIPoint::Make(7, 7), SkIPoint::Make(2, 2)}, + {SkRect::MakeXYWH(2, 2, 5, 5), SkIPoint::Make(0, 0), SkIPoint::Make(4, 4)}, + {SkRect::MakeXYWH(5, 5, 5, 5), SkIPoint::Make(2, 2), SkIPoint::Make(7, 7)}, + }; + + struct TestCase { + RectAndSamplePoint rectAndPoints; + int sampleCnt; + }; + std::vector testCases; + + for (int sampleCnt : {0, 4, 8}) { + for (auto rectAndPoints : allRectsAndPoints) { + testCases.push_back({rectAndPoints, sampleCnt}); + } + } + + // Run each test case: + for (auto testCase : testCases) { + int sampleCnt = testCase.sampleCnt; + SkRect paintRect = testCase.rectAndPoints.rect; + SkIPoint outPoint = testCase.rectAndPoints.outPoint; + SkIPoint inPoint = testCase.rectAndPoints.inPoint; + + sk_sp backingSurface; + // BGRA forces a framebuffer blit on ES2. + sk_sp surface = create_gpu_surface_backend_texture_as_render_target( + context, sampleCnt, kWidth, kHeight, kConfig, &backingSurface); + + if (!surface && sampleCnt > 0) { + // Some platforms don't support MSAA. + continue; + } + REPORTER_ASSERT(reporter, !!surface); + + // Fill our canvas with 0xFFFF80 + SkCanvas* canvas = surface->getCanvas(); + SkPaint black_paint; + black_paint.setColor(SkColorSetRGB(0xFF, 0xFF, 0x80)); + canvas->drawRect(SkRect::MakeXYWH(0, 0, kWidth, kHeight), black_paint); + + // Blend 2x2 pixels at 5,5 with 0x80FFFF. Use multiply blend mode as this will trigger + // a copy of the destination. + SkPaint white_paint; + white_paint.setColor(SkColorSetRGB(0x80, 0xFF, 0xFF)); + white_paint.setBlendMode(SkBlendMode::kMultiply); + canvas->drawRect(paintRect, white_paint); + + // Read the result into a bitmap. + SkBitmap bitmap; + REPORTER_ASSERT(reporter, bitmap.tryAllocPixels(SkImageInfo::Make( + kWidth, kHeight, kColorType, kPremul_SkAlphaType))); + bitmap.lockPixels(); + REPORTER_ASSERT( + reporter, + surface->readPixels(bitmap.info(), bitmap.getPixels(), bitmap.rowBytes(), 0, 0)); + + // Check the in/out pixels. + REPORTER_ASSERT(reporter, bitmap.getColor(outPoint.x(), outPoint.y()) == + SkColorSetRGB(0xFF, 0xFF, 0x80)); + REPORTER_ASSERT(reporter, bitmap.getColor(inPoint.x(), inPoint.y()) == + SkColorSetRGB(0x80, 0xFF, 0x80)); + + // Clean up - surface depends on backingSurface and must be released first. + bitmap.unlockPixels(); + surface.reset(); + backingSurface.reset(); + } +} +#endif -- cgit v1.2.3