aboutsummaryrefslogtreecommitdiffhomepage
path: root/gm/sharedcorners.cpp
diff options
context:
space:
mode:
authorGravatar Chris Dalton <csmartdalton@google.com>2018-03-14 02:04:09 -0600
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-14 16:38:40 +0000
commit04a1de5545add49c6e5edc3ebc44877133a3e1f9 (patch)
tree9f92113056759c6417badef8c94a4cab3f7096ea /gm/sharedcorners.cpp
parentc2d0dd658bbb8caebf0cc9d5cf4b98b1bda616e7 (diff)
ccpr: Add an attenuation parameter to triangle corners
Adds an attenuation parameter to corners that corrects the over-coverage from linear interpolation. Adds a GM for shared corners that ensures we're doing this right. Bug: skia: Change-Id: Iff8bd40554f9fda2e7e03faa3c9fbefe65f27568 Reviewed-on: https://skia-review.googlesource.com/114272 Reviewed-by: Greg Daniel <egdaniel@google.com> Commit-Queue: Chris Dalton <csmartdalton@google.com>
Diffstat (limited to 'gm/sharedcorners.cpp')
-rw-r--r--gm/sharedcorners.cpp158
1 files changed, 158 insertions, 0 deletions
diff --git a/gm/sharedcorners.cpp b/gm/sharedcorners.cpp
new file mode 100644
index 0000000000..b91a2757f7
--- /dev/null
+++ b/gm/sharedcorners.cpp
@@ -0,0 +1,158 @@
+/*
+ * 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 "gm.h"
+#include "sk_tool_utils.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+#include <array>
+#include <vector>
+
+namespace skiagm {
+
+static constexpr int kPadSize = 20;
+static constexpr int kBoxSize = 100;
+static constexpr SkPoint kJitters[] = {{0, 0}, {.5f, .5f}, {2/3.f, 1/3.f}};
+
+// Tests various corners of different angles falling on the same pixel, particularly to ensure
+// analytic AA is working properly.
+class SharedCornersGM : public GM {
+public:
+ SharedCornersGM() {
+ this->setBGColor(sk_tool_utils::color_to_565(0xFF1A65D7));
+ }
+
+protected:
+ SkString onShortName() override {
+ return SkString("sharedcorners");
+ }
+
+ SkISize onISize() override {
+ constexpr int numRows = 3 * 2;
+ constexpr int numCols = (1 + SK_ARRAY_COUNT(kJitters)) * 2;
+ return SkISize::Make(numCols * (kBoxSize + kPadSize) + kPadSize,
+ numRows * (kBoxSize + kPadSize) + kPadSize);
+ }
+
+ void onOnceBeforeDraw() override {
+ fFillPaint.setColor(SK_ColorWHITE);
+ fFillPaint.setAntiAlias(true);
+
+ fWireFramePaint = fFillPaint;
+ fWireFramePaint.setStyle(SkPaint::kStroke_Style);
+
+ }
+
+ void onDraw(SkCanvas* canvas) override {
+ canvas->translate(kPadSize, kPadSize);
+ canvas->save();
+
+ // Adjacent rects.
+ this->drawTriangleBoxes(canvas,
+ {{0, 0}, {40, 0}, {80, 0}, {120, 0},
+ {0, 20}, {40, 20}, {80, 20}, {120, 20},
+ {40, 40}, {80, 40},
+ {40, 60}, {80, 60}},
+ {{{0, 1, 4}}, {{1, 5, 4}},
+ {{5, 1, 6}}, {{1, 2, 6}},
+ {{2, 3, 6}}, {{3, 7, 6}},
+ {{8, 5, 9}}, {{5, 6, 9}},
+ {{10, 8, 11}}, {{8, 9, 11}}});
+
+ // Obtuse angles.
+ this->drawTriangleBoxes(canvas,
+ {{ 0, 0}, {10, 0}, {20, 0},
+ { 0, 2}, {20, 2},
+ {10, 4},
+ { 0, 6}, {20, 6},
+ { 0, 8}, {10, 8}, {20, 8}},
+ {{{3, 1, 4}}, {{4, 5, 3}}, {{6, 5, 7}}, {{7, 9, 6}},
+ {{0, 1, 3}}, {{1, 2, 4}},
+ {{3, 5, 6}}, {{5, 4, 7}},
+ {{6, 9, 8}}, {{9, 7, 10}}});
+
+ canvas->restore();
+ canvas->translate((kBoxSize + kPadSize) * 4, 0);
+
+ // Right angles.
+ this->drawTriangleBoxes(canvas,
+ {{0, 0}, {-1, 0}, {0, -1}, {1, 0}, {0, 1}},
+ {{{0, 1, 2}}, {{0, 2, 3}}, {{0, 3, 4}}, {{0, 4, 1}}});
+
+ // Acute angles.
+ SkRandom rand;
+ std::vector<SkPoint> pts;
+ std::vector<std::array<int, 3>> indices;
+ SkScalar theta = 0;
+ pts.push_back({0, 0});
+ while (theta < 2*SK_ScalarPI) {
+ pts.push_back({SkScalarCos(theta), SkScalarSin(theta)});
+ if (pts.size() > 2) {
+ indices.push_back({{0, (int)pts.size() - 2, (int)pts.size() - 1}});
+ }
+ theta += rand.nextRangeF(0, SK_ScalarPI/3);
+ }
+ indices.push_back({{0, (int)pts.size() - 1, 1}});
+ this->drawTriangleBoxes(canvas, pts, indices);
+ }
+
+ void drawTriangleBoxes(SkCanvas* canvas, const std::vector<SkPoint>& points,
+ const std::vector<std::array<int, 3>>& triangles) {
+ SkPath path;
+ path.setFillType(SkPath::kEvenOdd_FillType);
+ path.setIsVolatile(true);
+ for (const std::array<int, 3>& triangle : triangles) {
+ path.moveTo(points[triangle[0]]);
+ path.lineTo(points[triangle[1]]);
+ path.lineTo(points[triangle[2]]);
+ path.close();
+ }
+ SkScalar scale = kBoxSize / SkTMax(path.getBounds().height(), path.getBounds().width());
+ path.transform(SkMatrix::MakeScale(scale, scale));
+
+ this->drawRow(canvas, path);
+ canvas->translate(0, kBoxSize + kPadSize);
+
+ SkMatrix rot;
+ rot.setRotate(45, path.getBounds().centerX(), path.getBounds().centerY());
+ path.transform(rot);
+ this->drawRow(canvas, path);
+ canvas->translate(0, kBoxSize + kPadSize);
+
+ rot.setRotate(-45 - 69.38111f, path.getBounds().centerX(), path.getBounds().centerY());
+ path.transform(rot);
+ this->drawRow(canvas, path);
+ canvas->translate(0, kBoxSize + kPadSize);
+ }
+
+ void drawRow(SkCanvas* canvas, const SkPath& path) {
+ SkAutoCanvasRestore acr(canvas, true);
+ const SkRect& bounds = path.getBounds();
+ canvas->translate((kBoxSize - bounds.width()) / 2 - bounds.left(),
+ (kBoxSize - bounds.height()) / 2 - bounds.top());
+
+ canvas->drawPath(path, fWireFramePaint);
+ canvas->translate(kBoxSize + kPadSize, 0);
+
+ for (SkPoint jitter : kJitters) {
+ {
+ SkAutoCanvasRestore acr(canvas, true);
+ canvas->translate(jitter.x(), jitter.y());
+ canvas->drawPath(path, fFillPaint);
+ }
+ canvas->translate(kBoxSize + kPadSize, 0);
+ }
+ }
+
+ SkPaint fWireFramePaint;
+ SkPaint fFillPaint;
+};
+
+DEF_GM(return new SharedCornersGM;)
+
+}