From 5ba36ba9f5b414ffbe6f1a60598f47c5da57941f Mon Sep 17 00:00:00 2001 From: Chris Dalton Date: Wed, 9 May 2018 01:08:38 -0600 Subject: ccpr: Clean up GrCoverageCountingPathRenderer Extracts all the nested classes to their own files and detangles their interactions. Encapsulates the per-flush resources in their in their own separate class. Bug: skia: Change-Id: Ic134b627f6b66cb2ce1e5d6f896ac6b2f75f6fa2 Reviewed-on: https://skia-review.googlesource.com/126845 Commit-Queue: Chris Dalton Reviewed-by: Brian Salomon --- src/gpu/ccpr/GrCCPerFlushResources.cpp | 126 +++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 src/gpu/ccpr/GrCCPerFlushResources.cpp (limited to 'src/gpu/ccpr/GrCCPerFlushResources.cpp') diff --git a/src/gpu/ccpr/GrCCPerFlushResources.cpp b/src/gpu/ccpr/GrCCPerFlushResources.cpp new file mode 100644 index 0000000000..a658bf7438 --- /dev/null +++ b/src/gpu/ccpr/GrCCPerFlushResources.cpp @@ -0,0 +1,126 @@ +/* + * Copyright 2018 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrCCPerFlushResources.h" + +#include "GrOnFlushResourceProvider.h" +#include "GrRenderTargetContext.h" +#include "SkIPoint16.h" + +using PathInstance = GrCCPathProcessor::Instance; + +GrCCPerFlushResources::GrCCPerFlushResources(GrOnFlushResourceProvider* onFlushRP, + int numPathDraws, int numClipPaths, + const GrCCPathParser::PathStats& pathStats) + : fPathParser(sk_make_sp(numPathDraws + numClipPaths, pathStats)) + , fIndexBuffer(GrCCPathProcessor::FindIndexBuffer(onFlushRP)) + , fVertexBuffer(GrCCPathProcessor::FindVertexBuffer(onFlushRP)) + , fInstanceBuffer(onFlushRP->makeBuffer(kVertex_GrBufferType, + numPathDraws * sizeof(PathInstance))) { + if (!fIndexBuffer) { + SkDebugf("WARNING: failed to allocate CCPR index buffer. No paths will be drawn.\n"); + return; + } + if (!fVertexBuffer) { + SkDebugf("WARNING: failed to allocate CCPR vertex buffer. No paths will be drawn.\n"); + return; + } + if (!fInstanceBuffer) { + SkDebugf("WARNING: failed to allocate CCPR instance buffer. No paths will be drawn.\n"); + return; + } + fPathInstanceData = static_cast(fInstanceBuffer->map()); + SkASSERT(fPathInstanceData); + SkDEBUGCODE(fPathInstanceBufferCount = numPathDraws); +} + +GrCCAtlas* GrCCPerFlushResources::addPathToAtlas(const GrCaps& caps, const SkIRect& clipIBounds, + const SkMatrix& m, const SkPath& path, + SkRect* devBounds, SkRect* devBounds45, + int16_t* atlasOffsetX, int16_t* atlasOffsetY) { + SkASSERT(this->isMapped()); + SkIRect devIBounds; + fPathParser->parsePath(m, path, devBounds, devBounds45); + devBounds->roundOut(&devIBounds); + return this->placeParsedPathInAtlas(caps, clipIBounds, devIBounds, atlasOffsetX, atlasOffsetY); +} + +GrCCAtlas* GrCCPerFlushResources::addDeviceSpacePathToAtlas(const GrCaps& caps, + const SkIRect& clipIBounds, + const SkPath& devPath, + const SkIRect& devPathIBounds, + int16_t* atlasOffsetX, + int16_t* atlasOffsetY) { + SkASSERT(this->isMapped()); + fPathParser->parseDeviceSpacePath(devPath); + return this->placeParsedPathInAtlas(caps, clipIBounds, devPathIBounds, atlasOffsetX, + atlasOffsetY); +} + +GrCCAtlas* GrCCPerFlushResources::placeParsedPathInAtlas(const GrCaps& caps, + const SkIRect& clipIBounds, + const SkIRect& pathIBounds, + int16_t* atlasOffsetX, + int16_t* atlasOffsetY) { + using ScissorMode = GrCCPathParser::ScissorMode; + ScissorMode scissorMode; + SkIRect clippedPathIBounds; + if (clipIBounds.contains(pathIBounds)) { + clippedPathIBounds = pathIBounds; + scissorMode = ScissorMode::kNonScissored; + } else if (clippedPathIBounds.intersect(clipIBounds, pathIBounds)) { + scissorMode = ScissorMode::kScissored; + } else { + fPathParser->discardParsedPath(); + return nullptr; + } + + SkIPoint16 atlasLocation; + int h = clippedPathIBounds.height(), w = clippedPathIBounds.width(); + if (fAtlases.empty() || !fAtlases.back().addRect(w, h, &atlasLocation)) { + if (!fAtlases.empty()) { + // The atlas is out of room and can't grow any bigger. + auto coverageCountBatchID = fPathParser->closeCurrentBatch(); + fAtlases.back().setCoverageCountBatchID(coverageCountBatchID); + } + fAtlases.emplace_back(caps, SkTMax(w, h)); + SkAssertResult(fAtlases.back().addRect(w, h, &atlasLocation)); + } + + *atlasOffsetX = atlasLocation.x() - static_cast(clippedPathIBounds.left()); + *atlasOffsetY = atlasLocation.y() - static_cast(clippedPathIBounds.top()); + fPathParser->saveParsedPath(scissorMode, clippedPathIBounds, *atlasOffsetX, *atlasOffsetY); + + return &fAtlases.back(); +} + +bool GrCCPerFlushResources::finalize(GrOnFlushResourceProvider* onFlushRP, + SkTArray>* atlasDraws) { + SkASSERT(this->isMapped()); + fInstanceBuffer->unmap(); + fPathInstanceData = nullptr; + + if (!fAtlases.empty()) { + auto coverageCountBatchID = fPathParser->closeCurrentBatch(); + fAtlases.back().setCoverageCountBatchID(coverageCountBatchID); + } + + if (!fPathParser->finalize(onFlushRP)) { + SkDebugf("WARNING: failed to allocate GPU buffers for CCPR. No paths will be drawn.\n"); + return false; + } + + // Draw the atlas(es). + GrTAllocator::Iter atlasIter(&fAtlases); + while (atlasIter.next()) { + if (auto rtc = atlasIter.get()->finalize(onFlushRP, fPathParser)) { + atlasDraws->push_back(std::move(rtc)); + } + } + + return true; +} -- cgit v1.2.3