• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 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 
11 #include "src/gpu/graphite/ContextPriv.h"
12 #include "src/gpu/graphite/PaintParamsKey.h"
13 #include "src/gpu/graphite/ShaderCodeDictionary.h"
14 
15 using namespace skgpu::graphite;
16 
17 namespace {
18 
create_key_with_data(PaintParamsKeyBuilder * builder,int snippetID,SkSpan<const uint8_t> dataPayload)19 PaintParamsKey create_key_with_data(PaintParamsKeyBuilder* builder,
20                                     int snippetID,
21                                     SkSpan<const uint8_t> dataPayload) {
22     SkDEBUGCODE(builder->checkReset());
23 
24     builder->beginBlock(snippetID);
25     builder->addBytes(dataPayload.size(), dataPayload.data());
26     builder->endBlock();
27 
28     return builder->lockAsKey();
29 }
30 
create_key(PaintParamsKeyBuilder * builder,int snippetID,int size)31 PaintParamsKey create_key(PaintParamsKeyBuilder* builder, int snippetID, int size) {
32     SkASSERT(size <= 1024);
33     static constexpr uint8_t kEmptyBuffer[1024] = {};
34     return create_key_with_data(builder, snippetID, SkSpan(kEmptyBuffer, size));
35 }
36 
37 } // anonymous namespace
38 
39 // These are intended to be unit tests of the PaintParamsKeyBuilder and PaintParamsKey.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyWithInvalidCodeSnippetIDTest,reporter,context)40 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyWithInvalidCodeSnippetIDTest, reporter, context) {
41 
42     ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
43     PaintParamsKeyBuilder builder(dict);
44 
45     // Invalid code snippet ID, key creation fails.
46     PaintParamsKey key = create_key(&builder, kBuiltInCodeSnippetIDCount, /*size=*/32);
47     REPORTER_ASSERT(reporter, key.isErrorKey());
48 }
49 
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyValidBlockSizeTest,reporter,context)50 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyValidBlockSizeTest, reporter, context) {
51 
52     ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
53     PaintParamsKeyBuilder builder(dict);
54 
55     // _Just_ on the edge of being too big
56     static const int kMaxBlockDataSize = PaintParamsKey::kMaxBlockSize -
57                                          sizeof(PaintParamsKey::Header);
58     static constexpr PaintParamsKey::DataPayloadField kDataFields[] = {
59             {"data", PaintParamsKey::DataPayloadType::kByte, kMaxBlockDataSize},
60     };
61 
62     int userSnippetID = dict->addUserDefinedSnippet("keyAlmostTooBig", kDataFields);
63     PaintParamsKey key = create_key(&builder, userSnippetID, kMaxBlockDataSize);
64 
65     // Key is created successfully.
66     REPORTER_ASSERT(reporter, key.sizeInBytes() == PaintParamsKey::kMaxBlockSize);
67 }
68 
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyTooLargeBlockSizeTest,reporter,context)69 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyTooLargeBlockSizeTest, reporter, context) {
70 
71     ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
72     PaintParamsKeyBuilder builder(dict);
73 
74     // Too big by one byte
75     static const int kBlockDataSize = PaintParamsKey::kMaxBlockSize -
76                                       sizeof(PaintParamsKey::Header) + 1;
77     static constexpr PaintParamsKey::DataPayloadField kDataFields[] = {
78             {"data", PaintParamsKey::DataPayloadType::kByte, kBlockDataSize},
79     };
80 
81     int userSnippetID = dict->addUserDefinedSnippet("keyTooBig", kDataFields);
82     PaintParamsKey key = create_key(&builder, userSnippetID, kBlockDataSize);
83 
84     // Key creation fails.
85     REPORTER_ASSERT(reporter, key.isErrorKey());
86 }
87 
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyEqualityChecksSnippetID,reporter,context)88 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyEqualityChecksSnippetID, reporter, context) {
89 
90     ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
91     static const int kBlockDataSize = 4;
92     static constexpr PaintParamsKey::DataPayloadField kDataFields[] = {
93             {"data", PaintParamsKey::DataPayloadType::kByte, kBlockDataSize},
94     };
95 
96     int userSnippetID1 = dict->addUserDefinedSnippet("key1", kDataFields);
97     int userSnippetID2 = dict->addUserDefinedSnippet("key2", kDataFields);
98 
99     PaintParamsKeyBuilder builderA(dict);
100     PaintParamsKeyBuilder builderB(dict);
101     PaintParamsKeyBuilder builderC(dict);
102     PaintParamsKey keyA = create_key(&builderA, userSnippetID1, kBlockDataSize);
103     PaintParamsKey keyB = create_key(&builderB, userSnippetID1, kBlockDataSize);
104     PaintParamsKey keyC = create_key(&builderC, userSnippetID2, kBlockDataSize);
105 
106     // Verify that keyA matches keyB, and that it does not match keyC.
107     REPORTER_ASSERT(reporter, keyA == keyB);
108     REPORTER_ASSERT(reporter, keyA != keyC);
109     REPORTER_ASSERT(reporter, !(keyA == keyC));
110     REPORTER_ASSERT(reporter, !(keyA != keyB));
111 }
112 
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyEqualityChecksData,reporter,context)113 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyEqualityChecksData, reporter, context) {
114 
115     ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
116     static const int kBlockDataSize = 4;
117     static constexpr PaintParamsKey::DataPayloadField kDataFields[] = {
118             {"data", PaintParamsKey::DataPayloadType::kByte, kBlockDataSize},
119     };
120 
121     int userSnippetID = dict->addUserDefinedSnippet("key", kDataFields);
122 
123     static constexpr uint8_t kData [kBlockDataSize] = {1, 2, 3, 4};
124     static constexpr uint8_t kData2[kBlockDataSize] = {1, 2, 3, 99};
125 
126     PaintParamsKeyBuilder builderA(dict);
127     PaintParamsKeyBuilder builderB(dict);
128     PaintParamsKeyBuilder builderC(dict);
129     PaintParamsKey keyA = create_key_with_data(&builderA, userSnippetID, kData);
130     PaintParamsKey keyB = create_key_with_data(&builderB, userSnippetID, kData);
131     PaintParamsKey keyC = create_key_with_data(&builderC, userSnippetID, kData2);
132 
133     // Verify that keyA matches keyB, and that it does not match keyC.
134     REPORTER_ASSERT(reporter, keyA == keyB);
135     REPORTER_ASSERT(reporter, keyA != keyC);
136     REPORTER_ASSERT(reporter, !(keyA == keyC));
137     REPORTER_ASSERT(reporter, !(keyA != keyB));
138 }
139 
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyBlockReaderWorks,reporter,context)140 DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyBlockReaderWorks, reporter, context) {
141 
142     ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
143     static const int kCountX = 3;
144     static const int kCountY = 2;
145     static const int kCountZ = 7;
146     static constexpr PaintParamsKey::DataPayloadField kDataFields[] = {
147             {"ByteX",   PaintParamsKey::DataPayloadType::kByte,   kCountX},
148             {"Float4Y", PaintParamsKey::DataPayloadType::kFloat4, kCountY},
149             {"IntZ",    PaintParamsKey::DataPayloadType::kInt,    kCountZ},
150     };
151 
152     int userSnippetID = dict->addUserDefinedSnippet("key", kDataFields);
153 
154     static constexpr uint8_t   kDataX[kCountX] = {1, 2, 3};
155     static constexpr SkColor4f kDataY[kCountY] = {{4, 5, 6, 7}, {8, 9, 10, 11}};
156     static constexpr int32_t   kDataZ[kCountZ] = {-1234567, 13, 14, 15, 16, 17, 7654321};
157 
158     PaintParamsKeyBuilder builder(dict);
159     builder.beginBlock(userSnippetID);
160     builder.addBytes(kCountX, kDataX);
161     builder.add     (kCountY, kDataY);
162     builder.addInts (kCountZ, kDataZ);
163     builder.endBlock();
164 
165     PaintParamsKey key = builder.lockAsKey();
166 
167     // Verify that the block reader can extract out our data from the PaintParamsKey.
168     PaintParamsKey::BlockReader reader = key.reader(dict, /*headerOffset=*/0);
169     REPORTER_ASSERT(reporter,
170                     reader.blockSize() == (sizeof(PaintParamsKey::Header) +
171                                            sizeof(kDataX) + sizeof(kDataY) + sizeof(kDataZ)));
172 
173     SkSpan<const uint8_t> readerDataX = reader.bytes(0);
174     REPORTER_ASSERT(reporter, readerDataX.size() == kCountX);
175     REPORTER_ASSERT(reporter, 0 == memcmp(readerDataX.data(), kDataX, sizeof(kDataX)));
176 
177     SkSpan<const SkColor4f> readerDataY = reader.colors(1);
178     REPORTER_ASSERT(reporter, readerDataY.size() == kCountY);
179     REPORTER_ASSERT(reporter, 0 == memcmp(readerDataY.data(), kDataY, sizeof(kDataY)));
180 
181     SkSpan<const int32_t> readerBytesZ = reader.ints(2);
182     REPORTER_ASSERT(reporter, readerBytesZ.size() == kCountZ);
183     REPORTER_ASSERT(reporter, 0 == memcmp(readerBytesZ.data(), kDataZ, sizeof(kDataZ)));
184 }
185