bigrrectaaeffect.cpp revision 4a4f14ba3f93cc6bb9146be0f029a9badb1b95d9
1c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon/* 2c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon * Copyright 2015 Google Inc. 3c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon * 4c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon * Use of this source code is governed by a BSD-style license that can be 5c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon * found in the LICENSE file. 6c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon */ 7c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 8c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon#include "gm.h" 9c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon#if SK_SUPPORT_GPU 10c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon#include "GrTest.h" 11c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon#include "effects/GrRRectEffect.h" 12c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon#include "SkDevice.h" 13c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon#include "SkRRect.h" 14c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 15c41f4d60559b0891353f8028d521b52e7a36d5dabsalomonnamespace skiagm { 16c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 17c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon/////////////////////////////////////////////////////////////////////////////// 18c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 19c41f4d60559b0891353f8028d521b52e7a36d5dabsalomonclass BigRRectAAEffectGM : public GM { 20c41f4d60559b0891353f8028d521b52e7a36d5dabsalomonpublic: 214a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon BigRRectAAEffectGM(const SkRRect& rrect, const char* name) 224a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon : fRRect(rrect) 234a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon , fName(name) { 244a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon this->setBGColor(sk_tool_utils::color_to_565(SK_ColorBLUE)); 254a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon // Each test case draws the rrect with gaps around it. 264a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon fTestWidth = SkScalarCeilToInt(rrect.width()) + 2 * kGap; 274a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon fTestHeight = SkScalarCeilToInt(rrect.height()) + 2 * kGap; 284a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon 294a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon // Add a pad between test cases. 304a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon fTestOffsetX = fTestWidth + kPad; 314a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon fTestOffsetY = fTestHeight + kPad; 324a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon 334a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon // We draw two tests in x (fill and inv-fill) and pad around 344a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon // all four sides of the image. 354a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon fWidth = 2 * fTestOffsetX + kPad; 364a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon fHeight = fTestOffsetY + kPad; 37c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon } 38c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 39c41f4d60559b0891353f8028d521b52e7a36d5dabsalomonprotected: 40c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon SkString onShortName() override { 414a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkString name; 424a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon name.printf("big_rrect_%s_aa_effect", fName); 434a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon return name; 44c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon } 45c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 464a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkISize onISize() override { return SkISize::Make(fWidth, fHeight); } 47c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 48c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon void onDraw(SkCanvas* canvas) override { 49c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget(); 5096fcdcc219d2a0d3579719b84b28bede76efba64halcanary GrContext* context = rt ? rt->getContext() : nullptr; 51c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon if (!context) { 522a24338c777462e04a2b26295f9c034155ee8f3ehalcanary skiagm::GM::DrawGpuOnlyMessage(canvas); 53c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon return; 54c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon } 55c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 56c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon SkPaint paint; 57c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 58c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon int y = kPad; 59c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon int x = kPad; 60c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon static const GrPrimitiveEdgeType kEdgeTypes[] = { 61c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon kFillAA_GrProcessorEdgeType, 62c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon kInverseFillAA_GrProcessorEdgeType, 63c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon }; 644a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkRect testBounds = SkRect::MakeIWH(fTestWidth, fTestHeight); 65c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon for (size_t et = 0; et < SK_ARRAY_COUNT(kEdgeTypes); ++et) { 66c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon GrPrimitiveEdgeType edgeType = kEdgeTypes[et]; 674a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon canvas->save(); 684a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon canvas->translate(SkIntToScalar(x), SkIntToScalar(y)); 694a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon 704a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon // Draw a background for the test case 714a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkPaint paint; 724a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon paint.setColor(SK_ColorWHITE); 734a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon canvas->drawRect(testBounds, paint); 744a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon 754a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon GrTestTarget tt; 764a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon context->getTestTarget(&tt, rt); 774a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon if (!tt.target()) { 784a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkDEBUGFAIL("Couldn't get Gr test target."); 794a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon return; 80c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon } 814a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon GrPipelineBuilder pipelineBuilder; 824a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon pipelineBuilder.setXPFactory( 834a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon GrPorterDuffXPFactory::Create(SkXfermode::kSrc_Mode))->unref(); 844a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon 854a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkRRect rrect = fRRect; 864a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon rrect.offset(SkIntToScalar(x + kGap), SkIntToScalar(y + kGap)); 874a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkAutoTUnref<GrFragmentProcessor> fp(GrRRectEffect::Create(edgeType, rrect)); 884a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkASSERT(fp); 894a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon if (fp) { 904a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon pipelineBuilder.addCoverageFragmentProcessor(fp); 914a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon pipelineBuilder.setRenderTarget(rt); 924a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon 934a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkRect bounds = testBounds; 944a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon bounds.offset(SkIntToScalar(x), SkIntToScalar(y)); 954a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon 964a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon tt.target()->drawNonAARect(pipelineBuilder, 974a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon 0xff000000, 984a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkMatrix::I(), 994a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon bounds); 1004a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon } 1014a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon canvas->restore(); 1024a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon x = x + fTestOffsetX; 103c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon } 104c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon } 105c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 106c41f4d60559b0891353f8028d521b52e7a36d5dabsalomonprivate: 1074a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon // pad between test cases 1084a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon static const int kPad = 7; 1094a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon // gap between rect for each case that is rendered and exterior of rrect 1104a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon static const int kGap = 3; 1114a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon 1124a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon SkRRect fRRect; 1134a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon int fWidth; 1144a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon int fHeight; 1154a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon int fTestWidth; 1164a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon int fTestHeight; 1174a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon int fTestOffsetX; 1184a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon int fTestOffsetY; 1194a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon const char* fName; 120c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon typedef GM INHERITED; 121c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon}; 122c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 123c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon/////////////////////////////////////////////////////////////////////////////// 1244a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon// This value is motivated by bug chromium:477684. It has to be large to cause overflow in 1254a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon// the shader 1264a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomonstatic const int kSize = 700; 1274a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon 1284a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomonDEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRect(SkRect::MakeIWH(kSize, kSize)), "rect"); ) 1294a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomonDEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize, kSize)), "circle"); ) 1304a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomonDEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeOval(SkRect::MakeIWH(kSize - 1, kSize - 10)), "ellipse"); ) 1314a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomon// The next two have small linear segments between the corners 1324a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomonDEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 10.f), "circular_corner"); ) 1334a4f14ba3f93cc6bb9146be0f029a9badb1b95d9bsalomonDEF_GM( return new BigRRectAAEffectGM (SkRRect::MakeRectXY(SkRect::MakeIWH(kSize - 1, kSize - 10), kSize/2.f - 10.f, kSize/2.f - 15.f), "elliptical_corner"); ) 134c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon 135c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon} 136c41f4d60559b0891353f8028d521b52e7a36d5dabsalomon#endif 137