1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2017 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTypes.h" 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "Test.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if SK_SUPPORT_GPU 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContext.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrContextPriv.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrClip.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrDrawingManager.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrPathRenderer.h" 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrPaint.h" 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRenderTargetContext.h" 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrRenderTargetContextPriv.h" 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrShape.h" 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMatrix.h" 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkPathPriv.h" 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkRect.h" 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "ccpr/GrCoverageCountingPathRenderer.h" 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "mock/GrMockTypes.h" 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include <cmath> 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotstatic constexpr int kCanvasSize = 100; 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass CCPRClip : public GrClip { 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot CCPRClip(GrCoverageCountingPathRenderer* ccpr, const SkPath& path) : fCCPR(ccpr), fPath(path) {} 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool apply(GrContext* context, GrRenderTargetContext* rtc, bool, bool, GrAppliedClip* out, 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect* bounds) const override { 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider(); 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot out->addCoverageFP(fCCPR->makeClipProcessor(proxyProvider, 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rtc->priv().testingOnly_getOpListID(), fPath, 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect::MakeWH(rtc->width(), rtc->height()), 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rtc->width(), rtc->height())); 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool quickContains(const SkRect&) const final { return false; } 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool isRRect(const SkRect& rtBounds, SkRRect* rr, GrAA*) const final { return false; } 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void getConservativeBounds(int width, int height, SkIRect* rect, bool* iior) const final { 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot rect->set(0, 0, width, height); 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (iior) { 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *iior = false; 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrCoverageCountingPathRenderer* const fCCPR; 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkPath fPath; 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass CCPRPathDrawer { 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot CCPRPathDrawer(GrContext* ctx, skiatest::Reporter* reporter) 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fCtx(ctx) 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fCCPR(fCtx->contextPriv().drawingManager()->getCoverageCountingPathRenderer()) 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fRTC(fCtx->makeDeferredRenderTargetContext(SkBackingFit::kExact, kCanvasSize, 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot kCanvasSize, kRGBA_8888_GrPixelConfig, 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot nullptr)) { 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fCCPR) { 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ERRORF(reporter, "ccpr not enabled in GrContext for ccpr tests"); 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fRTC) { 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ERRORF(reporter, "failed to create GrRenderTargetContext for ccpr tests"); 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool valid() const { return fCCPR && fRTC; } 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void clear() const { fRTC->clear(nullptr, 0, GrRenderTargetContext::CanClearFullscreen::kYes); } 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void abandonGrContext() { fCtx = nullptr; fCCPR = nullptr; fRTC = nullptr; } 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void drawPath(SkPath path, GrColor4f color = GrColor4f(0, 1, 0, 1)) const { 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->valid()); 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrPaint paint; 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setColor4f(color); 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrNoClip noClip; 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkIRect clipBounds = SkIRect::MakeWH(kCanvasSize, kCanvasSize); 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkMatrix matrix = SkMatrix::I(); 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot path.setIsVolatile(true); 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrShape shape(path); 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCCPR->drawPath({fCtx, std::move(paint), &GrUserStencilSettings::kUnused, fRTC.get(), 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot &noClip, &clipBounds, &matrix, &shape, GrAAType::kCoverage, false}); 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void clipFullscreenRect(SkPath clipPath, GrColor4f color = GrColor4f(0, 1, 0, 1)) { 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->valid()); 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrPaint paint; 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot paint.setColor4f(color); 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fRTC->drawRect(CCPRClip(fCCPR, clipPath), std::move(paint), GrAA::kYes, SkMatrix::I(), 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkRect::MakeIWH(kCanvasSize, kCanvasSize)); 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void flush() const { 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->valid()); 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fCtx->flush(); 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrContext* fCtx; 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrCoverageCountingPathRenderer* fCCPR; 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrRenderTargetContext> fRTC; 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass CCPRTest { 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void run(skiatest::Reporter* reporter) { 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrMockOptions mockOptions; 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mockOptions.fInstanceAttribSupport = true; 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mockOptions.fMapBufferFlags = GrCaps::kCanMap_MapFlag; 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fRenderable[0] = true; 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mockOptions.fConfigOptions[kAlpha_half_GrPixelConfig].fTexturable = true; 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mockOptions.fGeometryShaderSupport = true; 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mockOptions.fIntegerSupport = true; 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot mockOptions.fFlatInterpolationSupport = true; 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrContextOptions ctxOptions; 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ctxOptions.fAllowPathMaskCaching = false; 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ctxOptions.fGpuPathRenderers = GpuPathRenderers::kCoverageCounting; 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMockContext = GrContext::MakeMock(&mockOptions, ctxOptions); 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fMockContext) { 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ERRORF(reporter, "could not create mock context"); 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!fMockContext->unique()) { 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ERRORF(reporter, "mock context is not unique"); 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot CCPRPathDrawer ccpr(fMockContext.get(), reporter); 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!ccpr.valid()) { 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPath.moveTo(0, 0); 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPath.cubicTo(50, 50, 0, 50, 50, 0); 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->onRun(reporter, ccpr); 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual ~CCPRTest() {} 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected: 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) = 0; 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sk_sp<GrContext> fMockContext; 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath fPath; 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define DEF_CCPR_TEST(name) \ 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot DEF_GPUTEST(name, reporter, /* options */) { \ 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot name test; \ 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test.run(reporter); \ 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrCCPRTest_cleanup : public CCPRTest { 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) override { 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath)); 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Ensure paths get unreffed. 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < 10; ++i) { 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.drawPath(fPath); 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.clipFullscreenRect(fPath); 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath)); 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.flush(); 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath)); 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Ensure paths get unreffed when we delete the context without flushing. 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < 10; ++i) { 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.drawPath(fPath); 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.clipFullscreenRect(fPath); 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.abandonGrContext(); 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath)); 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMockContext.reset(); 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath)); 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_CCPR_TEST(GrCCPRTest_cleanup) 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrCCPRTest_unregisterCulledOps : public CCPRTest { 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) override { 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath)); 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Ensure Ops get unregistered from CCPR when culled early. 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.drawPath(fPath); 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath)); 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.clear(); // Clear should delete the CCPR Op. 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath)); 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.flush(); // Should not crash (DrawPathsOp should have unregistered itself). 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Ensure Op unregisters work when we delete the context without flushing. 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.drawPath(fPath); 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, !SkPathPriv::TestingOnly_unique(fPath)); 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.clear(); // Clear should delete the CCPR DrawPathsOp. 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath)); 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.abandonGrContext(); 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMockContext.reset(); // Should not crash (DrawPathsOp should have unregistered itself). 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_CCPR_TEST(GrCCPRTest_unregisterCulledOps) 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrCCPRTest_parseEmptyPath : public CCPRTest { 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onRun(skiatest::Reporter* reporter, CCPRPathDrawer& ccpr) override { 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot REPORTER_ASSERT(reporter, SkPathPriv::TestingOnly_unique(fPath)); 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Make a path large enough that ccpr chooses to crop it by the RT bounds, and ends up with 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // an empty path. 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath largeOutsidePath; 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot largeOutsidePath.moveTo(-1e30f, -1e30f); 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot largeOutsidePath.lineTo(-1e30f, +1e30f); 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot largeOutsidePath.lineTo(-1e10f, +1e30f); 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.drawPath(largeOutsidePath); 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Normally an empty path is culled before reaching ccpr, however we use a back door for 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // testing so this path will make it. 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath emptyPath; 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(emptyPath.isEmpty()); 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.drawPath(emptyPath); 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // This is the test. It will exercise various internal asserts and verify we do not crash. 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.flush(); 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Now try again with clips. 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.clipFullscreenRect(largeOutsidePath); 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.clipFullscreenRect(emptyPath); 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.flush(); 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // ... and both. 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.drawPath(largeOutsidePath); 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.clipFullscreenRect(largeOutsidePath); 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.drawPath(emptyPath); 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.clipFullscreenRect(emptyPath); 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.flush(); 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_CCPR_TEST(GrCCPRTest_parseEmptyPath) 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass CCPRRenderingTest { 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void run(skiatest::Reporter* reporter, GrContext* ctx) const { 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!ctx->contextPriv().drawingManager()->getCoverageCountingPathRenderer()) { 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; // CCPR is not enabled on this GPU. 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot CCPRPathDrawer ccpr(ctx, reporter); 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!ccpr.valid()) { 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->onRun(reporter, ccpr); 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual ~CCPRRenderingTest() {} 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprotected: 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot virtual void onRun(skiatest::Reporter* reporter, const CCPRPathDrawer& ccpr) const = 0; 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#define DEF_CCPR_RENDERING_TEST(name) \ 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot DEF_GPUTEST_FOR_RENDERING_CONTEXTS(name, reporter, ctxInfo) { \ 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot name test; \ 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot test.run(reporter, ctxInfo.grContext()); \ 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrCCPRTest_busyPath : public CCPRRenderingTest { 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void onRun(skiatest::Reporter* reporter, const CCPRPathDrawer& ccpr) const override { 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static constexpr int kNumBusyVerbs = 1 << 17; 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.clear(); 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkPath busyPath; 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot busyPath.moveTo(0, 0); // top left 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot busyPath.lineTo(kCanvasSize, kCanvasSize); // bottom right 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 2; i < kNumBusyVerbs; ++i) { 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot float offset = i * ((float)kCanvasSize / kNumBusyVerbs); 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot busyPath.lineTo(kCanvasSize - offset, kCanvasSize + offset); // offscreen 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.drawPath(busyPath); 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ccpr.flush(); // If this doesn't crash, the test passed. 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // If it does, maybe fiddle with fMaxInstancesPerDrawArraysWithoutCrashing in 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // your platform's GrGLCaps. 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDEF_CCPR_RENDERING_TEST(GrCCPRTest_busyPath) 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 297