diff options
author | Chris Dalton <csmartdalton@google.com> | 2018-03-14 02:04:09 -0600 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-03-14 16:38:40 +0000 |
commit | 04a1de5545add49c6e5edc3ebc44877133a3e1f9 (patch) | |
tree | 9f92113056759c6417badef8c94a4cab3f7096ea /gm/sharedcorners.cpp | |
parent | c2d0dd658bbb8caebf0cc9d5cf4b98b1bda616e7 (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.cpp | 158 |
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;) + +} |