From b609e6dc6a02336aed04caaddcdd5ccfbe7ba9ec Mon Sep 17 00:00:00 2001 From: Ruiqi Mao Date: Tue, 17 Jul 2018 10:19:38 -0400 Subject: added byte and ubyte types to SKSL created new GMs for skinning Bug: skia: Change-Id: I15fb2bd02fba8beb6dd2dd3f3716da016ea92192 Reviewed-on: https://skia-review.googlesource.com/140241 Commit-Queue: Ruiqi Mao Reviewed-by: Brian Osman Reviewed-by: Ethan Nicholas --- gm/convexpolyeffect.cpp | 6 +- gm/skinning.cpp | 228 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 gm/skinning.cpp (limited to 'gm') diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp index 78dcfe1add..41d53e6241 100644 --- a/gm/convexpolyeffect.cpp +++ b/gm/convexpolyeffect.cpp @@ -80,7 +80,11 @@ private: Color color(fColor); sk_sp gp(GrDefaultGeoProcFactory::Make( - color, Coverage::kSolid_Type, LocalCoords::kUnused_Type, SkMatrix::I())); + target->caps().shaderCaps(), + color, + Coverage::kSolid_Type, + LocalCoords::kUnused_Type, + SkMatrix::I())); SkASSERT(gp->debugOnly_vertexStride() == sizeof(SkPoint)); QuadHelper helper; diff --git a/gm/skinning.cpp b/gm/skinning.cpp new file mode 100644 index 0000000000..101522fa48 --- /dev/null +++ b/gm/skinning.cpp @@ -0,0 +1,228 @@ +/* + * 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 "SkCanvas.h" +#include "SkVertices.h" +#include "SkPoint.h" +#include +#include + +using namespace skiagm; + +static const int kCellSize = 60; +static const int kColumnSize = 36; + +static const int kBoneCount = 7; +static const SkMatrix kBones[] = { + SkMatrix::I(), + SkMatrix::MakeTrans(10, 0), + SkMatrix::MakeTrans(0, 10), + SkMatrix::MakeTrans(-10, 0), + SkMatrix::MakeTrans(0, -10), + SkMatrix::MakeScale(0.5f), + SkMatrix::MakeScale(1.5f), +}; + +static const int kVertexCount = 4; +static const SkPoint kPositions[] = { + { 0, 0 }, + { 0, 30 }, + { 30, 30 }, + { 30, 0 }, +}; +static const SkColor kColors[] = { + 0xFFFF0000, + 0xFF00FF00, + 0xFF0000FF, + 0xFFFFFF00, +}; +static const SkVertices::BoneIndices kBoneIndices[] = { + {{ 1, 0, 0, 0 }}, + {{ 2, 1, 0, 0 }}, + {{ 3, 2, 1, 0 }}, + {{ 4, 3, 2, 1 }}, +}; +static const SkVertices::BoneWeights kBoneWeights[] = { + {{ 1.0f, 0.0f, 0.0f, 0.0f }}, + {{ 0.5f, 0.5f, 0.0f, 0.0f }}, + {{ 0.34f, 0.33f, 0.33f, 0.0f }}, + {{ 0.25f, 0.25f, 0.25f, 0.25f }}, +}; + +static const int kIndexCount = 6; +static const uint16_t kIndices[] = { + 0, 1, 2, + 2, 3, 0, +}; + +// Swap two SkMatrix pointers in place. +static void swap(const SkMatrix** x, const SkMatrix** y) { + const SkMatrix* temp = *x; + *x = *y; + *y = temp; +} + +class SkinningGM : public GM { + +public: + SkinningGM(bool deformUsingCPU) + : fPaint() + , fVertices(nullptr) + , fDeformUsingCPU(deformUsingCPU) + {} + +protected: + bool runAsBench() const override { + return true; + } + + SkString onShortName() override { + SkString name("skinning"); + if (fDeformUsingCPU) { + name.append("_cpu"); + } + return name; + } + + SkISize onISize() override { + return SkISize::Make(2400, 2400); + } + + void onOnceBeforeDraw() override { + fVertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, + kVertexCount, + kPositions, + nullptr, + kColors, + kBoneIndices, + kBoneWeights, + kIndexCount, + kIndices, + false); // Keep the vertices non-volatile. + } + + void onDraw(SkCanvas* canvas) override { + // Set the initial position. + int xpos = kCellSize; + int ypos = kCellSize; + + // Create the mutable set of bones. + const SkMatrix* bones[kBoneCount]; + for (int i = 0; i < kBoneCount; i ++) { + bones[i] = &kBones[i]; + } + + // Draw the vertices. + drawPermutations(canvas, xpos, ypos, bones, 1); + } + +private: + void drawPermutations(SkCanvas* canvas, + int& xpos, + int& ypos, + const SkMatrix** bones, + int start) { + if (start == kBoneCount) { + // Reached the end of the permutations, so draw. + canvas->save(); + + // Copy the bones. + SkMatrix copiedBones[kBoneCount]; + for (int i = 0; i < kBoneCount; i ++) { + copiedBones[i] = *bones[i]; + } + + // Set the position. + canvas->translate(xpos, ypos); + + // Draw the vertices. + if (fDeformUsingCPU) { + // Deform with CPU. + std::vector positions(kVertexCount); + for (int i = 0; i < kVertexCount; i ++) { + const SkVertices::BoneIndices& indices = kBoneIndices[i]; + const SkVertices::BoneWeights& weights = kBoneWeights[i]; + + // Apply deformations. + SkPoint& result = positions[i]; + SkPoint transformed; + for (uint32_t j = 0; j < 4; j ++) { + // Get the bone attachment data. + uint32_t index = indices.indices[j]; + float weight = weights.weights[j]; + + // Skip the bone is there is no weight. + if (weight == 0.0f) { + continue; + } + SkASSERT(index != 0); + + // transformed = M * v + copiedBones[index].mapPoints(&transformed, &kPositions[i], 1); + + // result += transformed * w + result += transformed * weight; + } + } + + sk_sp vertices = SkVertices::MakeCopy(SkVertices::kTriangles_VertexMode, + kVertexCount, + positions.data(), + nullptr, + kColors, + kIndexCount, + kIndices); + canvas->drawVertices(vertices.get(), + SkBlendMode::kSrc, + fPaint); + } else { + // Deform with GPU. + canvas->drawVertices(fVertices.get(), + copiedBones, + kBoneCount, + SkBlendMode::kSrc, + fPaint); + } + + canvas->restore(); + + // Get a new position to draw the vertices. + xpos += kCellSize; + if (xpos > kCellSize * kColumnSize) { + xpos = kCellSize; + ypos += kCellSize; + } + + return; + } + + // Find all possible permutations within the given range. + for (int i = start; i < kBoneCount; i ++) { + // Swap the start and i-th elements. + swap(bones + start, bones + i); + + // Find permutations of the sub array. + drawPermutations(canvas, xpos, ypos, bones, start + 1); + + // Swap the elements back. + swap(bones + i, bones + start); + } + } + +private: + SkPaint fPaint; + sk_sp fVertices; + bool fDeformUsingCPU; + + typedef GM INHERITED; +}; + +///////////////////////////////////////////////////////////////////////////////////// + +DEF_GM(return new SkinningGM(true);) +DEF_GM(return new SkinningGM(false);) -- cgit v1.2.3