Flutter Engine
The Flutter Engine
KeyTest.cpp
Go to the documentation of this file.
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
15
16using namespace skgpu::graphite;
17
18namespace {
19
20void add_block(PaintParamsKeyBuilder* builder, int snippetID) {
21 builder->beginBlock(snippetID);
22 builder->endBlock();
23}
24
25PaintParamsKey create_key(const ShaderCodeDictionary* dict, int snippetID, SkArenaAlloc* arena) {
27 add_block(&builder, snippetID);
28
30 return keyView->clone(arena);
31}
32
33bool coeff_equal(SkBlendModeCoeff skCoeff, skgpu::BlendCoeff gpuCoeff) {
34 switch(skCoeff) {
36 case SkBlendModeCoeff::kOne: return skgpu::BlendCoeff::kOne == gpuCoeff;
37 case SkBlendModeCoeff::kSC: return skgpu::BlendCoeff::kSC == gpuCoeff;
38 case SkBlendModeCoeff::kISC: return skgpu::BlendCoeff::kISC == gpuCoeff;
39 case SkBlendModeCoeff::kDC: return skgpu::BlendCoeff::kDC == gpuCoeff;
40 case SkBlendModeCoeff::kIDC: return skgpu::BlendCoeff::kIDC == gpuCoeff;
41 case SkBlendModeCoeff::kSA: return skgpu::BlendCoeff::kSA == gpuCoeff;
42 case SkBlendModeCoeff::kISA: return skgpu::BlendCoeff::kISA == gpuCoeff;
43 case SkBlendModeCoeff::kDA: return skgpu::BlendCoeff::kDA == gpuCoeff;
44 case SkBlendModeCoeff::kIDA: return skgpu::BlendCoeff::kIDA == gpuCoeff;
45 default: return false;
46 }
47}
48
49} // anonymous namespace
50
51// These are intended to be unit tests of the PaintParamsKeyBuilder and PaintParamsKey.
52DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyWithInvalidCodeSnippetIDTest, reporter, context,
54 SkArenaAlloc arena{256};
55 ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
56
57 // A builder without any data is invalid. The Builder and the PaintParamKeys can include
58 // invalid IDs without themselves becoming invalid. Normally adding an invalid ID triggers an
59 // assert in debug builds, since the properly functioning key system should never encounter an
60 // invalid ID.
63 REPORTER_ASSERT(reporter, !keyView->isValid());
64 REPORTER_ASSERT(reporter, !PaintParamsKey::Invalid().isValid());
65
66 // However, if the program gets in a malformed state on release builds, the key
67 // could contain an invalid ID. In that case the invalid snippet IDs are detected when
68 // reconstructing the key into an effect tree for SkSL generation. To test this, we manually
69 // construct an invalid span and test that it returns a null shader node tree when treated as
70 // a PaintParamsKey.
71 // NOTE: This is intentionally abusing memory to create a corrupt scenario and is dependent on
72 // the structure of PaintParamsKey (just SkSpan<const int32_t>).
73 int32_t invalidKeyData[3] = {(int32_t) BuiltInCodeSnippetID::kSolidColorShader,
75 (int32_t) BuiltInCodeSnippetID::kFixedFunctionSrcBlendMode};
76 SkSpan<const int32_t> invalidKeySpan{invalidKeyData, std::size(invalidKeyData)*sizeof(int32_t)};
77 const PaintParamsKey* fakeKey = reinterpret_cast<const PaintParamsKey*>(&invalidKeySpan);
78 REPORTER_ASSERT(reporter, fakeKey->getRootNodes(dict, &arena).empty());
79}
80
81DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyEqualityChecksSnippetID, reporter, context,
83 SkArenaAlloc arena{256};
84 ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
85
86 int userSnippetID1 = dict->addRuntimeEffectSnippet("key1");
87 int userSnippetID2 = dict->addRuntimeEffectSnippet("key2");
88
89 PaintParamsKey keyA = create_key(dict, userSnippetID1, &arena);
90 PaintParamsKey keyB = create_key(dict, userSnippetID1, &arena);
91 PaintParamsKey keyC = create_key(dict, userSnippetID2, &arena);
92
93 // Verify that keyA matches keyB, and that it does not match keyC.
94 REPORTER_ASSERT(reporter, keyA == keyB);
95 REPORTER_ASSERT(reporter, keyA != keyC);
96 REPORTER_ASSERT(reporter, !(keyA == keyC));
97 REPORTER_ASSERT(reporter, !(keyA != keyB));
98}
99
100DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(ShaderInfoDetectsFixedFunctionBlend, reporter, context,
102 ShaderCodeDictionary* dict = context->priv().shaderCodeDictionary();
103
104 for (int bm = 0; bm <= (int) SkBlendMode::kLastCoeffMode; ++bm) {
107 UniquePaintParamsID paintID = dict->findOrCreate(&builder);
108
109 ShaderInfo shaderInfo{paintID, dict, /*rteDict=*/nullptr, /*ssboIndex=*/""};
110
111 SkBlendModeCoeff expectedSrc, expectedDst;
113 &expectedSrc, &expectedDst));
114 REPORTER_ASSERT(reporter, coeff_equal(expectedSrc, shaderInfo.blendInfo().fSrcBlend));
115 REPORTER_ASSERT(reporter, coeff_equal(expectedDst, shaderInfo.blendInfo().fDstBlend));
116 REPORTER_ASSERT(reporter, shaderInfo.blendInfo().fEquation == skgpu::BlendEquation::kAdd);
117 REPORTER_ASSERT(reporter, shaderInfo.blendInfo().fBlendConstant == SK_PMColor4fTRANSPARENT);
118
119 bool expectedWriteColor = BlendModifiesDst(skgpu::BlendEquation::kAdd,
120 shaderInfo.blendInfo().fSrcBlend,
121 shaderInfo.blendInfo().fDstBlend);
122 REPORTER_ASSERT(reporter, shaderInfo.blendInfo().fWritesColor == expectedWriteColor);
123 }
124}
125
126// TODO: Add unit tests for converting a complex key to a ShaderInfo
reporter
Definition: FontMgrTest.cpp:39
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(KeyWithInvalidCodeSnippetIDTest, reporter, context, CtsEnforcement::kNextRelease)
Definition: KeyTest.cpp:52
SK_API bool SkBlendMode_AsCoeff(SkBlendMode mode, SkBlendModeCoeff *src, SkBlendModeCoeff *dst)
Definition: SkBlendMode.cpp:57
SkBlendMode
Definition: SkBlendMode.h:38
@ kLastCoeffMode
last porter duff blend mode
SkBlendModeCoeff
Definition: SkBlendMode.h:84
static size_t add_block(SkSBlockAllocator< N > &pool)
constexpr SkPMColor4f SK_PMColor4fTRANSPARENT
Definition: SkColorData.h:378
#define REPORTER_ASSERT(r, cond,...)
Definition: Test.h:286
SkSpan< const ShaderNode * > getRootNodes(const ShaderCodeDictionary *, SkArenaAlloc *) const
UniquePaintParamsID findOrCreate(PaintParamsKeyBuilder *) SK_EXCLUDES(fSpinLock)
static constexpr int kSkiaBuiltInReservedCnt
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
static constexpr int kFixedFunctionBlendModeIDOffset
BlendCoeff
Definition: Blend.h:60
static constexpr bool BlendModifiesDst(BlendEquation equation, BlendCoeff srcCoeff, BlendCoeff dstCoeff)
Definition: Blend.h:134