From 795c5ea6572ca8b58961ed64d628cc407005f1b3 Mon Sep 17 00:00:00 2001 From: Mike Reed Date: Fri, 17 Mar 2017 14:29:05 -0400 Subject: [PATCH] don't use deprecated (raw) form of SkPatchUtils, delete duplicate util deprecated API still used in android -- will fix (and then delete) BUG=skia:6366 Change-Id: Icd87acc680f7c8ae66ac231cb5d254f5eb178008 Reviewed-on: https://skia-review.googlesource.com/9864 Reviewed-by: Brian Salomon Commit-Queue: Mike Reed --- bench/PatchGridBench.cpp | 258 --------------------------------------------- gm/patchgrid.cpp | 159 ---------------------------- gn/bench.gni | 1 - gn/gm.gni | 1 - gn/utils.gni | 2 - src/core/SkDevice.cpp | 10 +- src/utils/SkPatchGrid.cpp | 189 --------------------------------- src/utils/SkPatchGrid.h | 142 ------------------------- src/utils/SkPatchUtils.cpp | 146 +++++++++++++++++++++++++ src/utils/SkPatchUtils.h | 6 ++ 10 files changed, 155 insertions(+), 759 deletions(-) delete mode 100644 bench/PatchGridBench.cpp delete mode 100644 gm/patchgrid.cpp delete mode 100644 src/utils/SkPatchGrid.cpp delete mode 100644 src/utils/SkPatchGrid.h diff --git a/bench/PatchGridBench.cpp b/bench/PatchGridBench.cpp deleted file mode 100644 index 9892658..0000000 --- a/bench/PatchGridBench.cpp +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "Benchmark.h" -#include "SkCanvas.h" -#include "SkGradientShader.h" -#include "SkPaint.h" -#include "SkPatchGrid.h" -#include "SkString.h" - - /** - * This bench measures the rendering time of a gridof patches. - * This bench also tests the different combination of optional parameters for the function - * (passing texture coordinates and colors, only textures coordinates, only colors or none). - * Finally, it also has 3 possible sizes small, medium and big to test if the size of the patches - * in the grid affects time. - */ - -class PatchGridBench : public Benchmark { - -public: - - enum Size { - kSmall_Size, - kMedium_Size, - kBig_Size - }; - - enum VertexMode { - kNone_VertexMode, - kColors_VertexMode, - kTexCoords_VertexMode, - kBoth_VertexMode - }; - - PatchGridBench(Size size, VertexMode vertexMode) - : fVertexMode(vertexMode) - , fSize(size) { } - - void setScale(SkCanvas* canvas){ - switch (fSize) { - case kSmall_Size: - canvas->scale(0.1f, 0.1f); - break; - case kMedium_Size: - canvas->scale(1.0f, 1.0f); - break; - case kBig_Size: - canvas->scale(3.0f, 3.0f); - break; - } - } - - void setGrid() { - SkPoint vertices[4][5] = { - {{50,50}, {150,50}, {250,50},{350,50},{450,50}}, - {{50,150}, {120,120}, {250,150},{350,150},{450,150}}, - {{50,250}, {150,250}, {250,250},{350,250},{450,250}}, - {{100,300}, {150,350}, {250,350},{350,350},{450,350}} - }; - - SkColor cornerColors[4][5] = { - {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE}, - {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED}, - {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE}, - {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED}, - }; - - SkPoint texCoords[4][5] = { - {{0.0f,0.0f}, {1.0f,0.0f}, {2.0f,0.0f}, {3.0f,0.0f}, {4.0f,0.0f}}, - {{0.0f,1.0f}, {1.0f,1.0f}, {2.0f,1.0f}, {3.0f,1.0f}, {4.0f,1.0f}}, - {{0.0f,2.0f}, {1.0f,2.0f}, {2.0f,2.0f}, {3.0f,2.0f}, {4.0f,2.0f}}, - {{0.0f,3.0f}, {1.0f,3.0f}, {2.0f,3.0f}, {3.0f,3.0f}, {4.0f,3.0f}}, - }; - - SkPoint hrzCtrl[4][8] = { - {{75,30},{125,45},{175,70},{225,20},{275,50},{325,50},{375,5},{425,90}}, - {{75,150},{125,150},{175,150},{225,150},{275,150},{325,150},{375,150},{425,150}}, - {{75,250},{125,250},{175,250},{225,250},{275,200},{325,150},{375,250},{425,250}}, - {{75,350},{125,350},{175,350},{225,350},{275,350},{325,350},{375,350},{425,350}} - }; - - SkPoint vrtCtrl[6][5] = { - {{50,75},{150,75},{250,75},{350,75},{450,75}}, - {{50,125},{150,125},{250,125},{350,125},{450,125}}, - {{50,175},{150,175},{220,225},{350,175},{470,225}}, - {{50,225},{150,225},{220,175},{350,225},{470,155}}, - {{50,275},{150,275},{250,275},{350,275},{400,305}}, - {{50,325},{150,325},{250,325},{350,325},{450,325}} - }; - - static const int kRows = 3; - static const int kCols = 4; - - fGrid.reset(kRows, kCols, SkPatchGrid::kColors_VertexType, SkBlendMode::kModulate); - for (int i = 0; i < kRows; i++) { - for (int j = 0; j < kCols; j++) { - SkPoint points[12]; - - //set corners - points[SkPatchUtils::kTopP0_CubicCtrlPts] = vertices[i][j]; - points[SkPatchUtils::kTopP3_CubicCtrlPts] = vertices[i][j + 1]; - points[SkPatchUtils::kBottomP0_CubicCtrlPts] = vertices[i + 1][j]; - points[SkPatchUtils::kBottomP3_CubicCtrlPts] = vertices[i + 1][j + 1]; - - points[SkPatchUtils::kTopP1_CubicCtrlPts] = hrzCtrl[i][j * 2]; - points[SkPatchUtils::kTopP2_CubicCtrlPts] = hrzCtrl[i][j * 2 + 1]; - points[SkPatchUtils::kBottomP1_CubicCtrlPts] = hrzCtrl[i + 1][j * 2]; - points[SkPatchUtils::kBottomP2_CubicCtrlPts] = hrzCtrl[i + 1][j * 2 + 1]; - - points[SkPatchUtils::kLeftP1_CubicCtrlPts] = vrtCtrl[i * 2][j]; - points[SkPatchUtils::kLeftP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j]; - points[SkPatchUtils::kRightP1_CubicCtrlPts] = vrtCtrl[i * 2][j + 1]; - points[SkPatchUtils::kRightP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j + 1]; - - SkColor colors[4]; - colors[0] = cornerColors[i][j]; - colors[1] = cornerColors[i][j + 1]; - colors[3] = cornerColors[i + 1][j]; - colors[2] = cornerColors[i + 1][j + 1]; - - SkPoint texs[4]; - texs[0] = texCoords[i][j]; - texs[1] = texCoords[i][j + 1]; - texs[3] = texCoords[i + 1][j]; - texs[2] = texCoords[i + 1][j + 1]; - - switch (fVertexMode) { - case kNone_VertexMode: - fGrid.setPatch(j, i, points, nullptr, nullptr); - break; - case kColors_VertexMode: - fGrid.setPatch(j, i, points, colors, nullptr); - break; - case kTexCoords_VertexMode: - fGrid.setPatch(j, i, points, nullptr, texs); - break; - case kBoth_VertexMode: - fGrid.setPatch(j, i, points, colors, texs); - break; - default: - break; - } - } - } - } - - // override this method to change the shader - sk_sp createShader() { - const SkColor colors[] = { - SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE, - SK_ColorMAGENTA, SK_ColorBLUE, SK_ColorYELLOW, - }; - const SkPoint pts[] = { { 200.f / 4.f, 0.f }, { 3.f * 200.f / 4, 200.f } }; - - return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors), - SkShader::kMirror_TileMode); - } - -protected: - const char* onGetName() override { - SkString vertexMode; - switch (fVertexMode) { - case kNone_VertexMode: - vertexMode.set("meshlines"); - break; - case kColors_VertexMode: - vertexMode.set("colors"); - break; - case kTexCoords_VertexMode: - vertexMode.set("texs"); - break; - case kBoth_VertexMode: - vertexMode.set("colors_texs"); - break; - default: - break; - } - - SkString size; - switch (fSize) { - case kSmall_Size: - size.set("small"); - break; - case kMedium_Size: - size.set("medium"); - break; - case kBig_Size: - size.set("big"); - break; - default: - break; - } - fName.printf("patch_grid_%s_%s", vertexMode.c_str(), size.c_str()); - return fName.c_str(); - } - - void onDelayedSetup() override { - this->setGrid(); - switch (fVertexMode) { - case kTexCoords_VertexMode: - case kBoth_VertexMode: - fPaint.setShader(createShader()); - break; - default: - fPaint.setShader(nullptr); - break; - } - this->setupPaint(&fPaint); - } - - void onDraw(int loops, SkCanvas* canvas) override { - this->setScale(canvas); - for (int i = 0; i < loops; i++) { - fGrid.draw(canvas, fPaint); - } - } - - SkPaint fPaint; - SkString fName; - SkPatchGrid fGrid; - VertexMode fVertexMode; - Size fSize; - - typedef Benchmark INHERITED; -}; - - -/////////////////////////////////////////////////////////////////////////////// - -DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size, - PatchGridBench::kNone_VertexMode); ) -DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size, - PatchGridBench::kColors_VertexMode); ) -DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size, - PatchGridBench::kTexCoords_VertexMode); ) -DEF_BENCH( return new PatchGridBench(PatchGridBench::kSmall_Size, - PatchGridBench::kBoth_VertexMode); ) -DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size, - PatchGridBench::kNone_VertexMode); ) -DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size, - PatchGridBench::kColors_VertexMode); ) -DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size, - PatchGridBench::kTexCoords_VertexMode); ) -DEF_BENCH( return new PatchGridBench(PatchGridBench::kMedium_Size, - PatchGridBench::kBoth_VertexMode); ) -DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size, - PatchGridBench::kNone_VertexMode); ) -DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size, - PatchGridBench::kColors_VertexMode); ) -DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size, - PatchGridBench::kTexCoords_VertexMode); ) -DEF_BENCH( return new PatchGridBench(PatchGridBench::kBig_Size, - PatchGridBench::kBoth_VertexMode); ) diff --git a/gm/patchgrid.cpp b/gm/patchgrid.cpp deleted file mode 100644 index 6f32231..0000000 --- a/gm/patchgrid.cpp +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2014 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 "SkPatchGrid.h" - -static void draw_control_points(SkCanvas* canvas, const SkPoint cubics[12]) { - //draw control points - SkPaint paint; - SkPoint bottom[4]; - SkPatchUtils::getBottomCubic(cubics, bottom); - SkPoint top[4]; - SkPatchUtils::getTopCubic(cubics, top); - SkPoint left[4]; - SkPatchUtils::getLeftCubic(cubics, left); - SkPoint right[4]; - SkPatchUtils::getRightCubic(cubics, right); - - paint.setColor(SK_ColorBLACK); - paint.setStrokeWidth(0.5); - SkPoint corners[4] = { bottom[0], bottom[3], top[0], top[3] }; - canvas->drawPoints(SkCanvas::kLines_PointMode, 4, bottom, paint); - canvas->drawPoints(SkCanvas::kLines_PointMode, 2, bottom+1, paint); - canvas->drawPoints(SkCanvas::kLines_PointMode, 4, top, paint); - canvas->drawPoints(SkCanvas::kLines_PointMode, 4, left, paint); - canvas->drawPoints(SkCanvas::kLines_PointMode, 4, right, paint); - - canvas->drawPoints(SkCanvas::kLines_PointMode, 2, top+1, paint); - canvas->drawPoints(SkCanvas::kLines_PointMode, 2, left+1, paint); - canvas->drawPoints(SkCanvas::kLines_PointMode, 2, right+1, paint); - - paint.setStrokeWidth(2); - - paint.setColor(SK_ColorRED); - canvas->drawPoints(SkCanvas::kPoints_PointMode, 4, corners, paint); - - paint.setColor(SK_ColorBLUE); - canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, bottom+1, paint); - - paint.setColor(SK_ColorCYAN); - canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, top+1, paint); - - paint.setColor(SK_ColorYELLOW); - canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, left+1, paint); - - paint.setColor(SK_ColorGREEN); - canvas->drawPoints(SkCanvas::kPoints_PointMode, 2, right+1, paint); -} - -namespace skiagm { -/** - * This GM draws a grid of patches, it only uses colors so it could be considered a mesh gradient. - */ -class SkPatchGridGM : public GM { - -public: - SkPatchGridGM() { - this->setBGColor(0xFFFFFFFF); - } - -protected: - SkString onShortName() override { - return SkString("patch_grid"); - } - - SkISize onISize() override { - return SkISize::Make(800, 800); - } - - void onDraw(SkCanvas* canvas) override { - - SkPaint paint; - - SkPoint vertices[4][5] = { - {{50,50}, {150,50}, {250,50},{350,50},{450,50}}, - {{50,150}, {120,120}, {250,150},{350,150},{450,150}}, - {{50,250}, {150,250}, {250,250},{350,250},{450,250}}, - {{100,300}, {150,350}, {250,350},{350,350},{450,350}} - }; - - SkColor cornerColors[4][5] = { - {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE}, - {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED}, - {SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE}, - {SK_ColorRED, SK_ColorBLUE, SK_ColorRED, SK_ColorBLUE, SK_ColorRED}, - }; - - SkPoint hrzCtrl[4][8] = { - {{75,30},{125,45},{175,70},{225,20},{275,50},{325,50},{375,5},{425,90}}, - {{75,150},{125,150},{175,150},{225,150},{275,150},{325,150},{375,150},{425,150}}, - {{75,250},{125,250},{175,250},{225,250},{275,200},{325,150},{375,250},{425,250}}, - {{75,350},{125,350},{175,350},{225,350},{275,350},{325,350},{375,350},{425,350}} - }; - - SkPoint vrtCtrl[6][5] = { - {{50,75},{150,75},{250,75},{350,75},{450,75}}, - {{50,125},{150,125},{250,125},{350,125},{450,125}}, - {{50,175},{150,175},{220,225},{350,175},{470,225}}, - {{50,225},{150,225},{220,175},{350,225},{470,155}}, - {{50,275},{150,275},{250,275},{350,275},{400,305}}, - {{50,325},{150,325},{250,325},{350,325},{450,325}} - }; - - constexpr int kRows = 3; - constexpr int kCols = 4; - - canvas->scale(3, 3); - SkPatchGrid grid(kRows, kCols, SkPatchGrid::kColors_VertexType); - for (int i = 0; i < kRows; i++) { - for (int j = 0; j < kCols; j++) { - SkPoint points[12]; - - //set corners - points[SkPatchUtils::kTopP0_CubicCtrlPts] = vertices[i][j]; - points[SkPatchUtils::kTopP3_CubicCtrlPts] = vertices[i][j + 1]; - points[SkPatchUtils::kBottomP0_CubicCtrlPts] = vertices[i + 1][j]; - points[SkPatchUtils::kBottomP3_CubicCtrlPts] = vertices[i + 1][j + 1]; - - points[SkPatchUtils::kTopP1_CubicCtrlPts] = hrzCtrl[i][j * 2]; - points[SkPatchUtils::kTopP2_CubicCtrlPts] = hrzCtrl[i][j * 2 + 1]; - points[SkPatchUtils::kBottomP1_CubicCtrlPts] = hrzCtrl[i + 1][j * 2]; - points[SkPatchUtils::kBottomP2_CubicCtrlPts] = hrzCtrl[i + 1][j * 2 + 1]; - - points[SkPatchUtils::kLeftP1_CubicCtrlPts] = vrtCtrl[i * 2][j]; - points[SkPatchUtils::kLeftP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j]; - points[SkPatchUtils::kRightP1_CubicCtrlPts] = vrtCtrl[i * 2][j + 1]; - points[SkPatchUtils::kRightP2_CubicCtrlPts] = vrtCtrl[i * 2 + 1][j + 1]; - - SkColor colors[4]; - colors[0] = cornerColors[i][j]; - colors[1] = cornerColors[i][j + 1]; - colors[3] = cornerColors[i + 1][j]; - colors[2] = cornerColors[i + 1][j + 1]; - - grid.setPatch(j, i, points, colors, nullptr); - } - } - - grid.draw(canvas, paint); - SkISize dims = grid.getDimensions(); - for (int y = 0; y < dims.height(); y++) { - for (int x = 0; x < dims.width(); x++) { - SkPoint cubics[12]; - grid.getPatch(x, y, cubics, nullptr, nullptr); - draw_control_points(canvas, cubics); - } - } - } - -private: - typedef GM INHERITED; -}; - -DEF_GM(return new SkPatchGridGM;) -} diff --git a/gn/bench.gni b/gn/bench.gni index 843964c..cf6ce88 100644 --- a/gn/bench.gni +++ b/gn/bench.gni @@ -78,7 +78,6 @@ bench_sources = [ "$_bench/MutexBench.cpp", "$_bench/pack_int_uint16_t_Bench.cpp", "$_bench/PatchBench.cpp", - "$_bench/PatchGridBench.cpp", "$_bench/PathBench.cpp", "$_bench/PathIterBench.cpp", "$_bench/PDFBench.cpp", diff --git a/gn/gm.gni b/gn/gm.gni index 3b94be5..65c6766 100644 --- a/gn/gm.gni +++ b/gn/gm.gni @@ -207,7 +207,6 @@ gm_sources = [ "$_gm/overdrawcolorfilter.cpp", "$_gm/OverStroke.cpp", "$_gm/patch.cpp", - "$_gm/patchgrid.cpp", "$_gm/path_stroke_with_zero_length.cpp", "$_gm/pathcontourstart.cpp", "$_gm/patheffects.cpp", diff --git a/gn/utils.gni b/gn/utils.gni index 4dd09e8..4a3841b 100644 --- a/gn/utils.gni +++ b/gn/utils.gni @@ -58,8 +58,6 @@ skia_utils_sources = [ "$_src/utils/SkParse.cpp", "$_src/utils/SkParseColor.cpp", "$_src/utils/SkParsePath.cpp", - "$_src/utils/SkPatchGrid.cpp", - "$_src/utils/SkPatchGrid.h", "$_src/utils/SkPatchUtils.cpp", "$_src/utils/SkPatchUtils.h", "$_src/utils/SkRGBAToYUV.cpp", diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp index 44c9dfb..11a6a87 100644 --- a/src/core/SkDevice.cpp +++ b/src/core/SkDevice.cpp @@ -129,13 +129,9 @@ void SkBaseDevice::drawPatch(const SkPoint cubics[12], const SkColor colors[4], SkPatchUtils::VertexData data; SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &this->ctm()); - - // It automatically adjusts lodX and lodY in case it exceeds the number of indices. - // If it fails to generate the vertices, then we do not draw. - if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) { - this->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints, - data.fTexCoords, data.fColors, bmode, data.fIndices, data.fIndexCount, - paint); + auto vertices = SkPatchUtils::MakeVertices(cubics, colors, texCoords, lod.width(), lod.height()); + if (vertices) { + this->drawVerticesObject(vertices.get(), bmode, paint); } } diff --git a/src/utils/SkPatchGrid.cpp b/src/utils/SkPatchGrid.cpp deleted file mode 100644 index ee30ce1..0000000 --- a/src/utils/SkPatchGrid.cpp +++ /dev/null @@ -1,189 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "SkPatchGrid.h" -#include "SkPatchUtils.h" - -SkPatchGrid::SkPatchGrid(int rows, int cols, VertexType flags) - : fRows(0) - , fCols(0) - , fModeFlags(kNone_VertexType) - , fCornerPts(nullptr) - , fCornerColors(nullptr) - , fTexCoords(nullptr) - , fHrzCtrlPts(nullptr) - , fVrtCtrlPts(nullptr) -{ - this->reset(rows, cols, flags, SkBlendMode::kModulate); -} - -SkPatchGrid::~SkPatchGrid() { - delete[] fCornerPts; - delete[] fCornerColors; - delete[] fTexCoords; - delete[] fHrzCtrlPts; - delete[] fVrtCtrlPts; -} - -bool SkPatchGrid::setPatch(int x, int y, const SkPoint cubics[12], const SkColor colors[4], - const SkPoint texCoords[4]) { - // Check for the passed paramaters to be within the range of the grid dimensions and a valid - // pointer for the cubics' control points. - if (x < 0 || y < 0 || x > fCols - 1 || y > fRows - 1 || nullptr == cubics) { - return false; - } - - // setup corners and colors - int cornerPos = y * (fCols + 1) + x; - fCornerPts[cornerPos] = cubics[SkPatchUtils::kTopP0_CubicCtrlPts]; - fCornerPts[cornerPos + 1] = cubics[SkPatchUtils::kTopP3_CubicCtrlPts]; - fCornerPts[cornerPos + (fCols + 1)] = cubics[SkPatchUtils::kBottomP0_CubicCtrlPts]; - fCornerPts[cornerPos + (fCols + 1) + 1] = cubics[SkPatchUtils::kBottomP3_CubicCtrlPts]; - - // set horizontal control points - int hrzPos = y * (fCols * 2) + (x * 2); - fHrzCtrlPts[hrzPos] = cubics[SkPatchUtils::kTopP1_CubicCtrlPts]; - fHrzCtrlPts[hrzPos + 1] = cubics[SkPatchUtils::kTopP2_CubicCtrlPts]; - fHrzCtrlPts[hrzPos + (fCols * 2)] = cubics[SkPatchUtils::kBottomP1_CubicCtrlPts]; - fHrzCtrlPts[hrzPos + (fCols * 2) + 1] = cubics[SkPatchUtils::kBottomP2_CubicCtrlPts]; - - // set vertical control points - int vrtPos = (y*2) * (fCols + 1) + x; - fVrtCtrlPts[vrtPos] = cubics[SkPatchUtils::kLeftP1_CubicCtrlPts]; - fVrtCtrlPts[vrtPos + 1] = cubics[SkPatchUtils::kRightP1_CubicCtrlPts]; - fVrtCtrlPts[vrtPos + (fCols + 1)] = cubics[SkPatchUtils::kLeftP2_CubicCtrlPts]; - fVrtCtrlPts[vrtPos + (fCols + 1) + 1] = cubics[SkPatchUtils::kRightP2_CubicCtrlPts]; - - // set optional values (colors and texture coordinates) - if ((fModeFlags & kColors_VertexType) && colors) { - fCornerColors[cornerPos] = colors[0]; - fCornerColors[cornerPos + 1] = colors[1]; - fCornerColors[cornerPos + (fCols + 1)] = colors[3]; - fCornerColors[cornerPos + (fCols + 1) + 1] = colors[2]; - } - - if ((fModeFlags & kTexs_VertexType) && texCoords) { - fTexCoords[cornerPos] = texCoords[0]; - fTexCoords[cornerPos + 1] = texCoords[1]; - fTexCoords[cornerPos + (fCols + 1)] = texCoords[3]; - fTexCoords[cornerPos + (fCols + 1) + 1] = texCoords[2]; - } - - return true; -} - -bool SkPatchGrid::getPatch(int x, int y, SkPoint cubics[12], SkColor colors[4], - SkPoint texCoords[4]) const { - - if (x < 0 || y < 0 || x > fCols - 1 || y > fRows - 1 || nullptr == cubics) { - return false; - } - - // set the patch by building the array of points and colors with the corresponding values. - int cornerPos = y * (fCols + 1) + x; - cubics[SkPatchUtils::kTopP0_CubicCtrlPts] = fCornerPts[cornerPos]; - cubics[SkPatchUtils::kTopP3_CubicCtrlPts] = fCornerPts[cornerPos + 1]; - cubics[SkPatchUtils::kBottomP0_CubicCtrlPts] = fCornerPts[cornerPos + (fCols + 1)]; - cubics[SkPatchUtils::kBottomP3_CubicCtrlPts] = fCornerPts[cornerPos + (fCols + 1) + 1]; - - int hrzPos = y * (fCols * 2) + (x * 2); - cubics[SkPatchUtils::kTopP1_CubicCtrlPts] = fHrzCtrlPts[hrzPos]; - cubics[SkPatchUtils::kTopP2_CubicCtrlPts] = fHrzCtrlPts[hrzPos + 1]; - cubics[SkPatchUtils::kBottomP1_CubicCtrlPts] = fHrzCtrlPts[hrzPos + (fCols * 2)]; - cubics[SkPatchUtils::kBottomP2_CubicCtrlPts] = fHrzCtrlPts[hrzPos + (fCols * 2) + 1]; - - int vrtPos = (y*2) * (fCols + 1) + x; - cubics[SkPatchUtils::kLeftP1_CubicCtrlPts] = fVrtCtrlPts[vrtPos]; - cubics[SkPatchUtils::kRightP1_CubicCtrlPts] = fVrtCtrlPts[vrtPos + 1]; - cubics[SkPatchUtils::kLeftP2_CubicCtrlPts] = fVrtCtrlPts[vrtPos + (fCols + 1)]; - cubics[SkPatchUtils::kRightP2_CubicCtrlPts] = fVrtCtrlPts[vrtPos + (fCols + 1) + 1]; - - if ((fModeFlags & kColors_VertexType) && colors) { - colors[0] = fCornerColors[cornerPos]; - colors[1] = fCornerColors[cornerPos + 1]; - colors[3] = fCornerColors[cornerPos + (fCols + 1)]; - colors[2] = fCornerColors[cornerPos + (fCols + 1) + 1]; - } - - if ((fModeFlags & kTexs_VertexType) && texCoords) { - texCoords[0] = fTexCoords[cornerPos]; - texCoords[1] = fTexCoords[cornerPos + 1]; - texCoords[3] = fTexCoords[cornerPos + (fCols + 1)]; - texCoords[2] = fTexCoords[cornerPos + (fCols + 1) + 1]; - } - - return true; -} - -void SkPatchGrid::reset(int rows, int cols, VertexType flags, SkBlendMode blendmode) { - delete[] fCornerPts; - delete[] fCornerColors; - delete[] fTexCoords; - delete[] fHrzCtrlPts; - delete[] fVrtCtrlPts; - - fCols = cols; - fRows = rows; - fModeFlags = flags; - fBlendMode = blendmode; - - fCornerPts = new SkPoint[(fRows + 1) * (fCols + 1)]; - fHrzCtrlPts = new SkPoint[(fRows + 1) * fCols * 2]; - fVrtCtrlPts = new SkPoint[fRows * 2 * (fCols + 1)]; - memset(fCornerPts, 0, (fRows + 1) * (fCols + 1) * sizeof(SkPoint)); - memset(fHrzCtrlPts, 0, (fRows + 1) * fCols * 2 * sizeof(SkPoint)); - memset(fVrtCtrlPts, 0, fRows * 2 * (fCols + 1) * sizeof(SkPoint)); - - if (fModeFlags & kColors_VertexType) { - fCornerColors = new SkColor[(fRows + 1) * (fCols + 1)]; - memset(fCornerColors, 0, (fRows + 1) * (fCols + 1) * sizeof(SkColor)); - } - - if (fModeFlags & kTexs_VertexType) { - fTexCoords = new SkPoint[(fRows + 1) * (fCols + 1)]; - memset(fTexCoords, 0, (fRows + 1) * (fCols + 1) * sizeof(SkPoint)); - } -} - -void SkPatchGrid::draw(SkCanvas* canvas, SkPaint& paint) { - int* maxCols = new int[fCols]; - int* maxRows = new int[fRows]; - memset(maxCols, 0, fCols * sizeof(int)); - memset(maxRows, 0, fRows * sizeof(int)); - - // Get the maximum level of detail per axis for each row and column - for (int y = 0; y < fRows; y++) { - for (int x = 0; x < fCols; x++) { - SkPoint cubics[12]; - this->getPatch(x, y, cubics, nullptr, nullptr); - SkMatrix matrix = canvas->getTotalMatrix(); - SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &matrix); - maxCols[x] = SkMax32(maxCols[x], lod.width()); - maxRows[y] = SkMax32(maxRows[y], lod.height()); - } - } - // Draw the patches by generating their geometry with the maximum level of detail per axis. - for (int x = 0; x < fCols; x++) { - for (int y = 0; y < fRows; y++) { - SkPoint cubics[12]; - SkPoint texCoords[4]; - SkColor colors[4]; - this->getPatch(x, y, cubics, colors, texCoords); - SkPatchUtils::VertexData data; - if (SkPatchUtils::getVertexData(&data, cubics, - fModeFlags & kColors_VertexType ? colors : nullptr, - fModeFlags & kTexs_VertexType ? texCoords : nullptr, - maxCols[x], maxRows[y])) { - canvas->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, - data.fPoints, data.fTexCoords, data.fColors, fBlendMode, - data.fIndices, data.fIndexCount, paint); - } - } - } - delete[] maxCols; - delete[] maxRows; -} diff --git a/src/utils/SkPatchGrid.h b/src/utils/SkPatchGrid.h deleted file mode 100644 index 97a6cb3..0000000 --- a/src/utils/SkPatchGrid.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2014 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef SkPatchGrid_DEFINED -#define SkPatchGrid_DEFINED - -#include "SkCanvas.h" -#include "SkPatchUtils.h" - -/** - * Class that represents a grid of patches. Adjacent patches share their corners and a color is - * specified at each one of them. The colors are bilinearly interpolated across the patch. - * - * This implementation defines a bidimensional array of patches. There are 3 arrays to store the - * control points of the patches to avoid storing repeated data since there are several points - * shared between adjacent patches. - * - * The array fCornerPts stores the corner control points of the patches. - * The array fHrzPts holds the intermidiate control points of the top and bottom curves of a patch. - * The array fVrtPts holds the intermidiate control points of the left and right curves of a patch. - * The array fCornerColors holds the corner colors in the same format as fCornerPts. - * The array fTexCoords holds the texture coordinates in the same format as fCornerpts. - * - * fCornerPts fHrzPts fVrtPts - * -------------- ------------------- -------------- - * | C0 | C1 | C2 | | H0 | H1 | H2 | H3 | | V0 | V1 | V2 | - * -------------- ------------------ --------------- - * | C3 | C4 | C5 | | H4 | H5 | H6 | H7 | | V4 | V5 | V6 | - * -------------- ------------------- -------------- - * | C6 | C7 | C8 | | H8 | H9 | H10| H11| | V6 | V7 | V8 | - * -------------- ------------------- -------------- - * | V9 | V10| V11| - * -------------- - * - * With the above configuration we would have a 2x2 grid of patches: - * H0 H1 H2 H3 - * / \/ \ - * C0-------C1-------C2 - * /| | |\ - * v0 | v1 | v2 - * v3 | V4 | v5 - * \| | |/ - * C3-H4-H5-C4-H6-H7-C5 - * /| | |\ - * v6 | v7 | v8 - * v9 | v10 | v11 - * \| | |/ - * C6-------C7-------C8 - * \ / \ / - * H8 H9 H10 H11 - * - * When trying to get a patch at a certain position it justs builds it with the corresponding - * points. - * When adding a patch it tries to add the points at their corresponding position trying to comply - * with the adjacent points or overwriting them. - * - * Based the idea on the SVG2 spec for mesh gradients in which a grid of patches is build as in the - * the following example: - * - * - * - * - * Up to four stops in first patch. See details below. - * - * - * Any number of meshPatches in row. - * - * - * - * Any number of meshRows, each with the same number of meshPatches as in the first row. - * - * - */ -class SkPatchGrid { - -public: - - enum VertexType { - kNone_VertexType = 0X00, - kColors_VertexType = 0x01, - kTexs_VertexType = 0x02, - kColorsAndTexs_VertexType = 0x03 - }; - - SkPatchGrid(int rows = 0, int cols = 0, VertexType flags = kNone_VertexType); - - ~SkPatchGrid(); - - /** - * Add a patch at location (x,y) overwriting the previous patch and shared points so they - * mantain C0 connectivity. - * The control points must be passed in a clockwise order starting at the top left corner. - * The colors and texCoords are the values at the corners of the patch which will be bilerp - * across it, they must also be in counterclockwise order starting at the top left corner. - */ - bool setPatch(int x, int y, const SkPoint cubics[12], const SkColor colors[4], - const SkPoint texCoords[4]); - - /** - * Get patch at location (x,y). If cubics, colors or texCoords is not nullptr it sets patch's - * array with its corresponding values. - * The function returns false if the cubics parameter is nullptr or if the (x,y) coordinates are - * not within the range of the grid. - */ - bool getPatch(int x, int y, SkPoint cubics[12], SkColor colors[4], SkPoint texCoords[4]) const; - - /** - * Resets the grid of patches to contain rows and cols of patches. - */ - void reset(int rows, int cols, VertexType flags, SkBlendMode); - - /** - * Draws the grid of patches. The patches are drawn starting at patch (0,0) drawing columns, so - * for a 2x2 grid the order would be (0,0)->(0,1)->(1,0)->(1,1). The order follows the order - * of the parametric coordinates of the coons patch. - */ - void draw(SkCanvas* canvas, SkPaint& paint); - - /** - * Get the dimensions of the grid of patches. - */ - SkISize getDimensions() const { - return SkISize::Make(fCols, fRows); - } - -private: - int fRows, fCols; - VertexType fModeFlags; - SkPoint* fCornerPts; - SkColor* fCornerColors; - SkPoint* fTexCoords; - SkPoint* fHrzCtrlPts; - SkPoint* fVrtCtrlPts; - SkBlendMode fBlendMode = SkBlendMode::kModulate; -}; - - -#endif diff --git a/src/utils/SkPatchUtils.cpp b/src/utils/SkPatchUtils.cpp index cbaae39..52ecfb1 100644 --- a/src/utils/SkPatchUtils.cpp +++ b/src/utils/SkPatchUtils.cpp @@ -309,3 +309,149 @@ bool SkPatchUtils::getVertexData(SkPatchUtils::VertexData* data, const SkPoint c return true; } + +/////////////////////////////////////////////////////////////////////////////////////////////////// + +sk_sp SkPatchUtils::MakeVertices(const SkPoint cubics[12], const SkColor srcColors[4], + const SkPoint srcTexCoords[4], int lodX, int lodY) { + if (lodX < 1 || lodY < 1 || nullptr == cubics) { + return nullptr; + } + + // check for overflow in multiplication + const int64_t lodX64 = (lodX + 1), + lodY64 = (lodY + 1), + mult64 = lodX64 * lodY64; + if (mult64 > SK_MaxS32) { + return nullptr; + } + + int vertexCount = SkToS32(mult64); + // it is recommended to generate draw calls of no more than 65536 indices, so we never generate + // more than 60000 indices. To accomplish that we resize the LOD and vertex count + if (vertexCount > 10000 || lodX > 200 || lodY > 200) { + float weightX = static_cast(lodX) / (lodX + lodY); + float weightY = static_cast(lodY) / (lodX + lodY); + + // 200 comes from the 100 * 2 which is the max value of vertices because of the limit of + // 60000 indices ( sqrt(60000 / 6) that comes from data->fIndexCount = lodX * lodY * 6) + lodX = static_cast(weightX * 200); + lodY = static_cast(weightY * 200); + vertexCount = (lodX + 1) * (lodY + 1); + } + const int indexCount = lodX * lodY * 6; + uint32_t flags = 0; + if (srcTexCoords) { + flags |= SkVertices::kHasTexCoords_BuilderFlag; + } + if (srcColors) { + flags |= SkVertices::kHasColors_BuilderFlag; + } + + SkVertices::Builder builder(SkCanvas::kTriangles_VertexMode, vertexCount, indexCount, flags); + SkPoint* pos = builder.positions(); + SkPoint* texs = builder.texCoords(); + SkColor* colors = builder.colors(); + uint16_t* indices = builder.indices(); + + // if colors is not null then create array for colors + SkPMColor colorsPM[kNumCorners]; + if (srcColors) { + // premultiply colors to avoid color bleeding. + for (int i = 0; i < kNumCorners; i++) { + colorsPM[i] = SkPreMultiplyColor(srcColors[i]); + } + srcColors = colorsPM; + } + + SkPoint pts[kNumPtsCubic]; + SkPatchUtils::getBottomCubic(cubics, pts); + FwDCubicEvaluator fBottom(pts); + SkPatchUtils::getTopCubic(cubics, pts); + FwDCubicEvaluator fTop(pts); + SkPatchUtils::getLeftCubic(cubics, pts); + FwDCubicEvaluator fLeft(pts); + SkPatchUtils::getRightCubic(cubics, pts); + FwDCubicEvaluator fRight(pts); + + fBottom.restart(lodX); + fTop.restart(lodX); + + SkScalar u = 0.0f; + int stride = lodY + 1; + for (int x = 0; x <= lodX; x++) { + SkPoint bottom = fBottom.next(), top = fTop.next(); + fLeft.restart(lodY); + fRight.restart(lodY); + SkScalar v = 0.f; + for (int y = 0; y <= lodY; y++) { + int dataIndex = x * (lodY + 1) + y; + + SkPoint left = fLeft.next(), right = fRight.next(); + + SkPoint s0 = SkPoint::Make((1.0f - v) * top.x() + v * bottom.x(), + (1.0f - v) * top.y() + v * bottom.y()); + SkPoint s1 = SkPoint::Make((1.0f - u) * left.x() + u * right.x(), + (1.0f - u) * left.y() + u * right.y()); + SkPoint s2 = SkPoint::Make( + (1.0f - v) * ((1.0f - u) * fTop.getCtrlPoints()[0].x() + + u * fTop.getCtrlPoints()[3].x()) + + v * ((1.0f - u) * fBottom.getCtrlPoints()[0].x() + + u * fBottom.getCtrlPoints()[3].x()), + (1.0f - v) * ((1.0f - u) * fTop.getCtrlPoints()[0].y() + + u * fTop.getCtrlPoints()[3].y()) + + v * ((1.0f - u) * fBottom.getCtrlPoints()[0].y() + + u * fBottom.getCtrlPoints()[3].y())); + pos[dataIndex] = s0 + s1 - s2; + + if (colors) { + uint8_t a = uint8_t(bilerp(u, v, + SkScalar(SkColorGetA(colorsPM[kTopLeft_Corner])), + SkScalar(SkColorGetA(colorsPM[kTopRight_Corner])), + SkScalar(SkColorGetA(colorsPM[kBottomLeft_Corner])), + SkScalar(SkColorGetA(colorsPM[kBottomRight_Corner])))); + uint8_t r = uint8_t(bilerp(u, v, + SkScalar(SkColorGetR(colorsPM[kTopLeft_Corner])), + SkScalar(SkColorGetR(colorsPM[kTopRight_Corner])), + SkScalar(SkColorGetR(colorsPM[kBottomLeft_Corner])), + SkScalar(SkColorGetR(colorsPM[kBottomRight_Corner])))); + uint8_t g = uint8_t(bilerp(u, v, + SkScalar(SkColorGetG(colorsPM[kTopLeft_Corner])), + SkScalar(SkColorGetG(colorsPM[kTopRight_Corner])), + SkScalar(SkColorGetG(colorsPM[kBottomLeft_Corner])), + SkScalar(SkColorGetG(colorsPM[kBottomRight_Corner])))); + uint8_t b = uint8_t(bilerp(u, v, + SkScalar(SkColorGetB(colorsPM[kTopLeft_Corner])), + SkScalar(SkColorGetB(colorsPM[kTopRight_Corner])), + SkScalar(SkColorGetB(colorsPM[kBottomLeft_Corner])), + SkScalar(SkColorGetB(colorsPM[kBottomRight_Corner])))); + colors[dataIndex] = SkPackARGB32(a,r,g,b); + } + + if (texs) { + texs[dataIndex] = SkPoint::Make(bilerp(u, v, srcTexCoords[kTopLeft_Corner].x(), + srcTexCoords[kTopRight_Corner].x(), + srcTexCoords[kBottomLeft_Corner].x(), + srcTexCoords[kBottomRight_Corner].x()), + bilerp(u, v, srcTexCoords[kTopLeft_Corner].y(), + srcTexCoords[kTopRight_Corner].y(), + srcTexCoords[kBottomLeft_Corner].y(), + srcTexCoords[kBottomRight_Corner].y())); + + } + + if(x < lodX && y < lodY) { + int i = 6 * (x * lodY + y); + indices[i] = x * stride + y; + indices[i + 1] = x * stride + 1 + y; + indices[i + 2] = (x + 1) * stride + 1 + y; + indices[i + 3] = indices[i]; + indices[i + 4] = indices[i + 2]; + indices[i + 5] = (x + 1) * stride + y; + } + v = SkScalarClampMax(v + 1.f / lodY, 1); + } + u = SkScalarClampMax(u + 1.f / lodX, 1); + } + return builder.detach(); +} diff --git a/src/utils/SkPatchUtils.h b/src/utils/SkPatchUtils.h index 67ab621..c1e8ac1 100644 --- a/src/utils/SkPatchUtils.h +++ b/src/utils/SkPatchUtils.h @@ -10,10 +10,12 @@ #include "SkColorPriv.h" #include "SkMatrix.h" +#include "SkVertices.h" class SK_API SkPatchUtils { public: + // DEPRECATED -- use MakeVertices() /** * Structure that holds the vertex data related to the tessellation of a patch. It is passed * as a parameter to the function getVertexData which sets the points, colors and texture @@ -104,6 +106,7 @@ public: */ static void getRightCubic(const SkPoint cubics[12], SkPoint points[4]); + // DEPRECATED -- use MakeVertices() /** * Function that evaluates the coons patch interpolation. * data refers to the pointer of the PatchData struct in which the tessellation data is set. @@ -116,6 +119,9 @@ public: static bool getVertexData(SkPatchUtils::VertexData* data, const SkPoint cubics[12], const SkColor colors[4], const SkPoint texCoords[4], int lodX, int lodY); + + static sk_sp MakeVertices(const SkPoint cubics[12], const SkColor colors[4], + const SkPoint texCoords[4], int lodX, int lodY); }; #endif -- 2.7.4