1 /*
2 * Copyright 2021 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "tests/Test.h"
9
10 #include "experimental/graphite/include/Recorder.h"
11 #include "experimental/graphite/src/ContextPriv.h"
12 #include "experimental/graphite/src/ContextUtils.h"
13 #include "experimental/graphite/src/GlobalCache.h"
14 #include "experimental/graphite/src/PaintParams.h"
15 #include "experimental/graphite/src/RecorderPriv.h"
16 #include "experimental/graphite/src/ResourceProvider.h"
17 #include "include/core/SkPaint.h"
18 #include "include/effects/SkGradientShader.h"
19 #include "include/private/SkUniquePaintParamsID.h"
20 #include "src/core/SkKeyHelpers.h"
21 #include "src/core/SkShaderCodeDictionary.h"
22 #include "src/core/SkUniformData.h"
23
24 namespace {
25
create_paint(skgpu::ShaderCombo::ShaderType shaderType,SkTileMode tm,SkBlendMode bm)26 std::tuple<SkPaint, int> create_paint(skgpu::ShaderCombo::ShaderType shaderType,
27 SkTileMode tm,
28 SkBlendMode bm) {
29 SkPoint pts[2] = {{-100, -100},
30 {100, 100}};
31 SkColor colors[2] = {SK_ColorRED, SK_ColorGREEN};
32 SkScalar offsets[2] = {0.0f, 1.0f};
33
34 sk_sp<SkShader> s;
35 int numUniforms = 0;
36 switch (shaderType) {
37 case skgpu::ShaderCombo::ShaderType::kNone:
38 SkDEBUGFAIL("kNone cannot be represented as an SkPaint");
39 break;
40 case skgpu::ShaderCombo::ShaderType::kSolidColor:
41 numUniforms += 1;
42 break;
43 case skgpu::ShaderCombo::ShaderType::kLinearGradient:
44 s = SkGradientShader::MakeLinear(pts, colors, offsets, 2, tm);
45 numUniforms += 7;
46 break;
47 case skgpu::ShaderCombo::ShaderType::kRadialGradient:
48 s = SkGradientShader::MakeRadial({0, 0}, 100, colors, offsets, 2, tm);
49 numUniforms += 7;
50 break;
51 case skgpu::ShaderCombo::ShaderType::kSweepGradient:
52 s = SkGradientShader::MakeSweep(0, 0, colors, offsets, 2, tm,
53 0, 359, 0, nullptr);
54 numUniforms += 7;
55 break;
56 case skgpu::ShaderCombo::ShaderType::kConicalGradient:
57 s = SkGradientShader::MakeTwoPointConical({100, 100}, 100,
58 {-100, -100}, 100,
59 colors, offsets, 2, tm);
60 numUniforms += 7;
61 break;
62 }
63 SkPaint p;
64 p.setColor(SK_ColorRED);
65 p.setShader(std::move(s));
66 p.setBlendMode(bm);
67 return { p, numUniforms };
68 }
69
70 } // anonymous namespace
71
DEF_GRAPHITE_TEST_FOR_CONTEXTS(UniformTest,reporter,context)72 DEF_GRAPHITE_TEST_FOR_CONTEXTS(UniformTest, reporter, context) {
73 using namespace skgpu;
74
75 auto recorder = context->makeRecorder();
76 auto dict = recorder->priv().resourceProvider()->shaderCodeDictionary();
77
78 // Intentionally does not include ShaderType::kNone, which represents no fragment shading stage
79 // and is thus not relevant to uniform extraction/caching.
80 for (auto s : { ShaderCombo::ShaderType::kSolidColor,
81 ShaderCombo::ShaderType::kLinearGradient,
82 ShaderCombo::ShaderType::kRadialGradient,
83 ShaderCombo::ShaderType::kSweepGradient,
84 ShaderCombo::ShaderType::kConicalGradient }) {
85 for (auto tm: { SkTileMode::kClamp,
86 SkTileMode::kRepeat,
87 SkTileMode::kMirror,
88 SkTileMode::kDecal }) {
89 if (s == ShaderCombo::ShaderType::kSolidColor) {
90 tm = SkTileMode::kClamp; // the TileMode doesn't matter for this case
91 }
92
93 for (auto bm : { SkBlendMode::kSrc, SkBlendMode::kSrcOver }) {
94 std::unique_ptr<SkPaintParamsKey> expected = CreateKey(dict, SkBackend::kGraphite,
95 s, tm, bm);
96
97 auto [ p, expectedNumUniforms ] = create_paint(s, tm, bm);
98 auto [ actualID, uniformBlock] = ExtractPaintData(dict, PaintParams(p));
99 int actualNumUniforms = uniformBlock->count();
100
101 auto entry = dict->lookup(actualID);
102
103
104 REPORTER_ASSERT(reporter, *expected == *entry->paintParamsKey());
105 REPORTER_ASSERT(reporter, expectedNumUniforms == actualNumUniforms);
106 for (auto& u : *uniformBlock) {
107 for (int i = 0; i < u->count(); ++i) {
108 REPORTER_ASSERT(reporter,
109 u->offset(i) >= 0 && u->offset(i) < u->dataSize());
110 }
111 }
112 }
113 }
114 }
115 }
116