Write GPU buffers directly from GrStrokeGeometry
Removes the intermediate stroke representation that GrStrokeGeometry
used to generate. Uses GrOpFlushState::makeVertexStateAtLeast instead
and writes patches directly to a vertex buffer as we iterate the path.
If the vertex buffer runs out of room we simply allocate a new one and
draw the stroke in chunks.
Bug: skia:10419
Bug: skia:10460
Change-Id: Ic743158366e43d4d3f5a4ff97b039d48c9c9c65b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/305380
Commit-Queue: Chris Dalton <csmartdalton@google.com>
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
diff --git a/samplecode/SampleCCPRGeometry.cpp b/samplecode/SampleCCPRGeometry.cpp
index 0aa8100..758c076 100644
--- a/samplecode/SampleCCPRGeometry.cpp
+++ b/samplecode/SampleCCPRGeometry.cpp
@@ -26,7 +26,6 @@
#include "src/gpu/GrResourceProvider.h"
#include "src/gpu/ccpr/GrCCCoverageProcessor.h"
#include "src/gpu/ccpr/GrCCFillGeometry.h"
-#include "src/gpu/ccpr/GrCCStroker.h"
#include "src/gpu/ccpr/GrGSCoverageProcessor.h"
#include "src/gpu/ccpr/GrVSCoverageProcessor.h"
#include "src/gpu/geometry/GrPathUtils.h"
@@ -66,7 +65,7 @@
void updateGpuData();
- PrimitiveType fPrimitiveType = PrimitiveType::kTriangles;
+ PrimitiveType fPrimitiveType = PrimitiveType::kCubics;
SkCubicType fCubicType;
SkMatrix fCubicKLM;
@@ -75,7 +74,9 @@
float fConicWeight = .5;
float fStrokeWidth = 40;
- bool fDoStroke = false;
+ SkPaint::Join fStrokeJoin = SkPaint::kMiter_Join;
+ SkPaint::Cap fStrokeCap = SkPaint::kButt_Cap;
+ bool fDoStroke = true;
SkTArray<TriPointInstance> fTriPointInstances;
SkTArray<QuadPointInstance> fQuadPointInstances;
@@ -176,14 +177,18 @@
void CCPRGeometryView::onDrawContent(SkCanvas* canvas) {
canvas->clear(SK_ColorBLACK);
- if (!fDoStroke) {
- SkPaint outlinePaint;
- outlinePaint.setColor(0x80ffffff);
- outlinePaint.setStyle(SkPaint::kStroke_Style);
+ SkPaint outlinePaint;
+ outlinePaint.setColor(0xff808080);
+ outlinePaint.setStyle(SkPaint::kStroke_Style);
+ if (fDoStroke) {
+ outlinePaint.setStrokeWidth(fStrokeWidth);
+ } else {
outlinePaint.setStrokeWidth(0);
- outlinePaint.setAntiAlias(true);
- canvas->drawPath(fPath, outlinePaint);
}
+ outlinePaint.setStrokeJoin(fStrokeJoin);
+ outlinePaint.setStrokeCap(fStrokeCap);
+ outlinePaint.setAntiAlias(true);
+ canvas->drawPath(fPath, outlinePaint);
#if 0
SkPaint gridPaint;
@@ -200,7 +205,18 @@
#endif
SkString caption;
- if (GrRenderTargetContext* rtc = canvas->internal_private_accessTopLayerRenderTargetContext()) {
+ caption.appendf("PrimitiveType_%s",
+ GrCCCoverageProcessor::PrimitiveTypeName(fPrimitiveType));
+ if (PrimitiveType::kCubics == fPrimitiveType) {
+ caption.appendf(" (%s)", SkCubicTypeName(fCubicType));
+ } else if (PrimitiveType::kConics == fPrimitiveType) {
+ caption.appendf(" (w=%f)", fConicWeight);
+ }
+
+ if (fDoStroke) {
+ caption.appendf(" (stroke_width=%f)", fStrokeWidth);
+ } else if (GrRenderTargetContext* rtc =
+ canvas->internal_private_accessTopLayerRenderTargetContext()) {
// Render coverage count.
auto ctx = canvas->recordingContext();
SkASSERT(ctx);
@@ -222,18 +238,6 @@
paint.setPorterDuffXPFactory(SkBlendMode::kSrcOver);
rtc->drawRect(nullptr, std::move(paint), GrAA::kNo, SkMatrix::I(),
SkRect::MakeIWH(this->width(), this->height()));
-
- // Add label.
- caption.appendf("PrimitiveType_%s",
- GrCCCoverageProcessor::PrimitiveTypeName(fPrimitiveType));
- if (PrimitiveType::kCubics == fPrimitiveType) {
- caption.appendf(" (%s)", SkCubicTypeName(fCubicType));
- } else if (PrimitiveType::kConics == fPrimitiveType) {
- caption.appendf(" (w=%f)", fConicWeight);
- }
- if (fDoStroke) {
- caption.appendf(" (stroke_width=%f)", fStrokeWidth);
- }
} else {
caption = "Use GPU backend to visualize geometry.";
}
@@ -345,8 +349,8 @@
void CCPRGeometryView::DrawCoverageCountOp::onExecute(GrOpFlushState* state,
const SkRect& chainBounds) {
GrResourceProvider* rp = state->resourceProvider();
- auto direct = state->gpu()->getContext();
#ifdef SK_GL
+ auto direct = state->gpu()->getContext();
GrGLGpu* glGpu = GrBackendApi::kOpenGL == direct->backend()
? static_cast<GrGLGpu*>(state->gpu())
: nullptr;
@@ -370,52 +374,30 @@
GrOpsRenderPass* renderPass = state->opsRenderPass();
- if (!fView->fDoStroke) {
- for (int i = 0; i < proc->numSubpasses(); ++i) {
- proc->reset(fView->fPrimitiveType, i, rp);
- proc->bindPipeline(state, pipeline, this->bounds());
+ for (int i = 0; i < proc->numSubpasses(); ++i) {
+ proc->reset(fView->fPrimitiveType, i, rp);
+ proc->bindPipeline(state, pipeline, this->bounds());
- if (PrimitiveType::kCubics == fView->fPrimitiveType ||
- PrimitiveType::kConics == fView->fPrimitiveType) {
- sk_sp<GrGpuBuffer> instBuff(rp->createBuffer(
- fView->fQuadPointInstances.count() * sizeof(QuadPointInstance),
- GrGpuBufferType::kVertex, kDynamic_GrAccessPattern,
- fView->fQuadPointInstances.begin()));
- if (!fView->fQuadPointInstances.empty() && instBuff) {
- proc->bindBuffers(renderPass, std::move(instBuff));
- proc->drawInstances(renderPass, fView->fQuadPointInstances.count(), 0);
- }
- } else {
- sk_sp<GrGpuBuffer> instBuff(rp->createBuffer(
- fView->fTriPointInstances.count() * sizeof(TriPointInstance),
- GrGpuBufferType::kVertex, kDynamic_GrAccessPattern,
- fView->fTriPointInstances.begin()));
- if (!fView->fTriPointInstances.empty() && instBuff) {
- proc->bindBuffers(renderPass, std::move(instBuff));
- proc->drawInstances(renderPass, fView->fTriPointInstances.count(), 0);
- }
+ if (PrimitiveType::kCubics == fView->fPrimitiveType ||
+ PrimitiveType::kConics == fView->fPrimitiveType) {
+ sk_sp<GrGpuBuffer> instBuff(rp->createBuffer(
+ fView->fQuadPointInstances.count() * sizeof(QuadPointInstance),
+ GrGpuBufferType::kVertex, kDynamic_GrAccessPattern,
+ fView->fQuadPointInstances.begin()));
+ if (!fView->fQuadPointInstances.empty() && instBuff) {
+ proc->bindBuffers(renderPass, std::move(instBuff));
+ proc->drawInstances(renderPass, fView->fQuadPointInstances.count(), 0);
+ }
+ } else {
+ sk_sp<GrGpuBuffer> instBuff(rp->createBuffer(
+ fView->fTriPointInstances.count() * sizeof(TriPointInstance),
+ GrGpuBufferType::kVertex, kDynamic_GrAccessPattern,
+ fView->fTriPointInstances.begin()));
+ if (!fView->fTriPointInstances.empty() && instBuff) {
+ proc->bindBuffers(renderPass, std::move(instBuff));
+ proc->drawInstances(renderPass, fView->fTriPointInstances.count(), 0);
}
}
- } else if (PrimitiveType::kConics != fView->fPrimitiveType) { // No conic stroke support yet.
- GrCCStroker stroker(0,0,0);
-
- SkPaint p;
- p.setStyle(SkPaint::kStroke_Style);
- p.setStrokeWidth(fView->fStrokeWidth);
- p.setStrokeJoin(SkPaint::kMiter_Join);
- p.setStrokeMiter(4);
- // p.setStrokeCap(SkPaint::kRound_Cap);
- stroker.parseDeviceSpaceStroke(fView->fPath, SkPathPriv::PointData(fView->fPath),
- SkStrokeRec(p), p.getStrokeWidth(), GrScissorTest::kDisabled,
- SkIRect::MakeWH(fView->width(), fView->height()), {0, 0});
- GrCCStroker::BatchID batchID = stroker.closeCurrentBatch();
-
- GrOnFlushResourceProvider onFlushRP(direct->priv().drawingManager());
- stroker.prepareToDraw(&onFlushRP);
-
- SkIRect ibounds;
- this->bounds().roundOut(&ibounds);
- stroker.drawStrokes(state, proc.get(), batchID, ibounds);
}
#ifdef SK_GL
@@ -511,6 +493,17 @@
if (unichar == 'S') {
fDoStroke = !fDoStroke;
this->updateAndInval();
+ return true;
+ }
+ if (unichar == 'J') {
+ fStrokeJoin = (SkPaint::Join)((fStrokeJoin + 1) % 3);
+ this->updateAndInval();
+ return true;
+ }
+ if (unichar == 'C') {
+ fStrokeCap = (SkPaint::Cap)((fStrokeCap + 1) % 3);
+ this->updateAndInval();
+ return true;
}
return false;
}