aboutsummaryrefslogtreecommitdiffhomepage
path: root/samplecode/SampleCCPRGeometry.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'samplecode/SampleCCPRGeometry.cpp')
-rw-r--r--samplecode/SampleCCPRGeometry.cpp130
1 files changed, 91 insertions, 39 deletions
diff --git a/samplecode/SampleCCPRGeometry.cpp b/samplecode/SampleCCPRGeometry.cpp
index afbeae4839..3fb4fb6cbf 100644
--- a/samplecode/SampleCCPRGeometry.cpp
+++ b/samplecode/SampleCCPRGeometry.cpp
@@ -10,12 +10,12 @@
#if SK_SUPPORT_GPU
#include "GrContextPriv.h"
+#include "GrPathUtils.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetContextPriv.h"
#include "GrResourceProvider.h"
#include "SampleCode.h"
#include "SkCanvas.h"
-#include "SkGeometry.h"
#include "SkMakeUnique.h"
#include "SkPaint.h"
#include "SkPath.h"
@@ -30,11 +30,11 @@ using CurveInstance = GrCCPRCoverageProcessor::CurveInstance;
using Mode = GrCCPRCoverageProcessor::Mode;
static int num_points(Mode mode) {
- return mode >= Mode::kSerpentineInsets ? 4 : 3;
+ return mode >= Mode::kSerpentineHulls ? 4 : 3;
}
static int is_quadratic(Mode mode) {
- return mode >= Mode::kQuadraticHulls && mode < Mode::kSerpentineInsets;
+ return mode >= Mode::kQuadraticHulls && mode < Mode::kSerpentineHulls;
}
/**
@@ -64,6 +64,7 @@ private:
void updateGpuData();
Mode fMode = Mode::kTriangleHulls;
+ SkMatrix fCubicKLM;
SkPoint fPoints[4] = {
{100.05f, 100.05f},
@@ -105,6 +106,27 @@ private:
typedef GrDrawOp INHERITED;
};
+static void draw_klm_line(int w, int h, SkCanvas* canvas, const SkScalar line[3], SkColor color) {
+ SkPoint p1, p2;
+ if (SkScalarAbs(line[1]) > SkScalarAbs(line[0])) {
+ // Draw from vertical edge to vertical edge.
+ p1 = {0, -line[2] / line[1]};
+ p2 = {(SkScalar) w, (-line[2] - w * line[0]) / line[1]};
+ } else {
+ // Draw from horizontal edge to horizontal edge.
+ p1 = {-line[2] / line[0], 0};
+ p2 = {(-line[2] - h * line[1]) / line[0], (SkScalar) h};
+ }
+
+ SkPaint linePaint;
+ linePaint.setColor(color);
+ linePaint.setAlpha(128);
+ linePaint.setStyle(SkPaint::kStroke_Style);
+ linePaint.setStrokeWidth(0);
+ linePaint.setAntiAlias(true);
+ canvas->drawLine(p1, p2, linePaint);
+}
+
void CCPRGeometryView::onDrawContent(SkCanvas* canvas) {
SkAutoCanvasRestore acr(canvas, true);
canvas->setMatrix(SkMatrix::I());
@@ -118,17 +140,30 @@ void CCPRGeometryView::onDrawContent(SkCanvas* canvas) {
} else {
outline.lineTo(fPoints[1]);
outline.lineTo(fPoints[3]);
+ outline.close();
}
- outline.close();
SkPaint outlinePaint;
outlinePaint.setColor(0x30000000);
outlinePaint.setStyle(SkPaint::kStroke_Style);
outlinePaint.setStrokeWidth(0);
outlinePaint.setAntiAlias(true);
-
canvas->drawPath(outline, outlinePaint);
+#if 0
+ SkPaint gridPaint;
+ gridPaint.setColor(0x10000000);
+ gridPaint.setStyle(SkPaint::kStroke_Style);
+ gridPaint.setStrokeWidth(0);
+ gridPaint.setAntiAlias(true);
+ for (int y = 0; y < this->height(); y += GrCCPRCoverageProcessor::kDebugBloat) {
+ canvas->drawLine(0, y, this->width(), y, gridPaint);
+ }
+ for (int x = 0; x < this->width(); x += GrCCPRCoverageProcessor::kDebugBloat) {
+ canvas->drawLine(x, 0, x, this->height(), outlinePaint);
+ }
+#endif
+
const char* caption = "Use GPU backend to visualize geometry.";
if (GrRenderTargetContext* rtc =
@@ -143,7 +178,11 @@ void CCPRGeometryView::onDrawContent(SkCanvas* canvas) {
pointsPaint.setAntiAlias(true);
if (4 == num_points(fMode)) {
+ int w = this->width(), h = this->height();
canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, fPoints, pointsPaint);
+ draw_klm_line(w, h, canvas, &fCubicKLM[0], SK_ColorYELLOW);
+ draw_klm_line(w, h, canvas, &fCubicKLM[3], SK_ColorBLUE);
+ draw_klm_line(w, h, canvas, &fCubicKLM[6], SK_ColorRED);
} else {
canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, fPoints, pointsPaint);
canvas->drawPoints(SkCanvas::kPoints_PointMode, 1, fPoints + 3, pointsPaint);
@@ -165,41 +204,45 @@ void CCPRGeometryView::updateGpuData() {
if (4 == vertexCount) {
double t[2], s[2];
- SkCubicType type = SkClassifyCubic(fPoints, t, s);
- SkSTArray<2, float> chops;
- for (int i = 0; i < 2; ++i) {
- float chop = t[i] / s[i];
- if (chop > 0 && chop < 1) {
- chops.push_back(chop);
- }
+ SkCubicType type = GrPathUtils::getCubicKLM(fPoints, &fCubicKLM, t, s);
+ if (Mode::kSerpentineHulls == fMode && SkCubicType::kLoop == type) {
+ fMode = Mode::kLoopHulls;
}
-
- int instanceCount = chops.count() + 1;
- SkPoint chopped[10];
- SkChopCubicAt(fPoints, chopped, chops.begin(), chops.count());
-
- fGpuPoints.push_back(chopped[0]);
- for (int i = 0; i < instanceCount; ++i) {
- fGpuPoints.push_back(chopped[3*i + 1]);
- fGpuPoints.push_back(chopped[3*i + 2]);
- if (3 == instanceCount && SkCubicType::kLoop == type) {
- fGpuPoints.push_back(chopped[3*i]); // Account for floating point error.
- } else {
- fGpuPoints.push_back(chopped[3*i + 3]);
- }
+ if (Mode::kSerpentineCorners == fMode && SkCubicType::kLoop == type) {
+ fMode = Mode::kLoopCorners;
}
-
- if (fMode < Mode::kLoopInsets && SkCubicType::kLoop == type) {
- fMode = (Mode) ((int) fMode + 2);
+ if (Mode::kLoopHulls == fMode && SkCubicType::kLoop != type) {
+ fMode = Mode::kSerpentineHulls;
}
- if (fMode >= Mode::kLoopInsets && SkCubicType::kLoop != type) {
- fMode = (Mode) ((int) fMode - 2);
+ if (Mode::kLoopCorners == fMode && SkCubicType::kLoop != type) {
+ fMode = Mode::kSerpentineCorners;
}
- for (int i = 0; i < instanceCount; ++i) {
- fInstanceData.push_back(3*i);
- fInstanceData.push_back(0); // Atlas offset.
- ++fInstanceCount;
+ GrCCPRGeometry geometry;
+ geometry.beginContour(fPoints[0]);
+ geometry.cubicTo(fPoints[1], fPoints[2], fPoints[3],
+ GrCCPRCoverageProcessor::kDebugBloat / 2,
+ GrCCPRCoverageProcessor::kDebugBloat / 2);
+ geometry.endContour();
+ fGpuPoints.push_back_n(geometry.points().count(), geometry.points().begin());
+ int ptsIdx = 0;
+ for (GrCCPRGeometry::Verb verb : geometry.verbs()) {
+ switch (verb) {
+ case GrCCPRGeometry::Verb::kLineTo:
+ ++ptsIdx;
+ continue;
+ case GrCCPRGeometry::Verb::kMonotonicQuadraticTo:
+ ptsIdx += 2;
+ continue;
+ case GrCCPRGeometry::Verb::kMonotonicSerpentineTo:
+ case GrCCPRGeometry::Verb::kMonotonicLoopTo:
+ fInstanceData.push_back(ptsIdx);
+ fInstanceData.push_back(0); // Atlas offset.
+ ptsIdx += 3;
+ ++fInstanceCount;
+ continue;
+ default: continue;
+ }
}
} else if (is_quadratic(fMode)) {
GrCCPRGeometry geometry;
@@ -230,6 +273,10 @@ void CCPRGeometryView::updateGpuData() {
}
void CCPRGeometryView::Op::onExecute(GrOpFlushState* state) {
+ if (fView->fInstanceData.empty()) {
+ return;
+ }
+
GrResourceProvider* rp = state->resourceProvider();
GrContext* context = state->gpu()->getContext();
GrGLGpu* glGpu = kOpenGL_GrBackend == context->contextPriv().getBackend() ?
@@ -330,15 +377,20 @@ bool CCPRGeometryView::onQuery(SkEvent* evt) {
if (fMode >= Mode::kCombinedTriangleHullsAndEdges) {
fMode = Mode(int(fMode) + 1);
}
+ if (fMode >= Mode::kLoopHulls) {
+ // '6' -> kSerpentineHulls, '7' -> kSerpentineCorners. updateGpuData converts to
+ // kLoop* if needed.
+ fMode = Mode(int(fMode) + 1);
+ }
this->updateAndInval();
return true;
}
if (unichar == 'D') {
SkDebugf(" SkPoint fPoints[4] = {\n");
- SkDebugf(" {%f, %f},\n", fPoints[0].x(), fPoints[0].y());
- SkDebugf(" {%f, %f},\n", fPoints[1].x(), fPoints[1].y());
- SkDebugf(" {%f, %f},\n", fPoints[2].x(), fPoints[2].y());
- SkDebugf(" {%f, %f}\n", fPoints[3].x(), fPoints[3].y());
+ SkDebugf(" {%ff, %ff},\n", fPoints[0].x(), fPoints[0].y());
+ SkDebugf(" {%ff, %ff},\n", fPoints[1].x(), fPoints[1].y());
+ SkDebugf(" {%ff, %ff},\n", fPoints[2].x(), fPoints[2].y());
+ SkDebugf(" {%ff, %ff}\n", fPoints[3].x(), fPoints[3].y());
SkDebugf(" };\n");
return true;
}