aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ccpr/GrCCPerFlushResources.cpp
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2018-05-09 01:08:38 -0600
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-05-09 18:14:05 +0000
commit5ba36ba9f5b414ffbe6f1a60598f47c5da57941f (patch)
tree6c614d2517b778b3666cefbfce3c6e24fcdfe4f9 /src/gpu/ccpr/GrCCPerFlushResources.cpp
parent969a738e7f7fe03832acb86362d133db40623c01 (diff)
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 <csmartdalton@google.com> Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/gpu/ccpr/GrCCPerFlushResources.cpp')
-rw-r--r--src/gpu/ccpr/GrCCPerFlushResources.cpp126
1 files changed, 126 insertions, 0 deletions
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<GrCCPathParser>(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<PathInstance*>(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<int16_t>(clippedPathIBounds.left());
+ *atlasOffsetY = atlasLocation.y() - static_cast<int16_t>(clippedPathIBounds.top());
+ fPathParser->saveParsedPath(scissorMode, clippedPathIBounds, *atlasOffsetX, *atlasOffsetY);
+
+ return &fAtlases.back();
+}
+
+bool GrCCPerFlushResources::finalize(GrOnFlushResourceProvider* onFlushRP,
+ SkTArray<sk_sp<GrRenderTargetContext>>* 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<GrCCAtlas>::Iter atlasIter(&fAtlases);
+ while (atlasIter.next()) {
+ if (auto rtc = atlasIter.get()->finalize(onFlushRP, fPathParser)) {
+ atlasDraws->push_back(std::move(rtc));
+ }
+ }
+
+ return true;
+}