2 * Copyright 2022 Google LLC
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "src/core/SkOpts.h"
9 #include "src/core/SkPipelineData.h"
10 #include "src/core/SkShaderCodeDictionary.h"
12 #ifdef SK_GRAPHITE_ENABLED
13 SkPipelineDataGatherer::SkPipelineDataGatherer(skgpu::graphite::Layout layout)
14 : fUniformManager(layout)
15 , fSnippetRequirementFlags(SnippetRequirementFlags::kNone) {
19 void SkPipelineDataGatherer::reset() {
20 #ifdef SK_GRAPHITE_ENABLED
21 fTextureDataBlock.reset();
22 fBlendInfo = BlendInfo();
23 fUniformManager.reset();
25 fSnippetRequirementFlags = SnippetRequirementFlags::kNone;
29 void SkPipelineDataGatherer::checkReset() {
30 #ifdef SK_GRAPHITE_ENABLED
31 SkASSERT(fTextureDataBlock.empty());
32 SkASSERT(fBlendInfo == BlendInfo());
33 SkDEBUGCODE(fUniformManager.checkReset());
35 SkASSERT(fSnippetRequirementFlags == SnippetRequirementFlags::kNone);
39 void SkPipelineDataGatherer::addFlags(SnippetRequirementFlags flags) {
40 fSnippetRequirementFlags |= flags;
43 bool SkPipelineDataGatherer::needsLocalCoords() const {
44 return fSnippetRequirementFlags & SnippetRequirementFlags::kLocalCoords;
47 ////////////////////////////////////////////////////////////////////////////////////////////////////
48 SkUniformDataBlock* SkUniformDataBlock::Make(const SkUniformDataBlock& other,
49 SkArenaAlloc* arena) {
50 static constexpr size_t kUniformAlignment = alignof(void*);
51 char* mem = static_cast<char*>(arena->makeBytesAlignedTo(other.size(), kUniformAlignment));
52 memcpy(mem, other.data(), other.size());
54 return arena->make([&](void* ptr) {
55 return new (ptr) SkUniformDataBlock(SkSpan<const char>(mem, other.size()));
59 uint32_t SkUniformDataBlock::hash() const {
60 return SkOpts::hash_fn(fData.data(), fData.size(), 0);
63 ////////////////////////////////////////////////////////////////////////////////////////////////////
64 #ifdef SK_GRAPHITE_ENABLED
65 static constexpr int kSkFilterModeCount = static_cast<int>(SkFilterMode::kLast) + 1;
67 std::unique_ptr<SkTextureDataBlock> SkTextureDataBlock::Make(const SkTextureDataBlock& other,
68 SkArenaAlloc* /* arena */) {
69 return std::make_unique<SkTextureDataBlock>(other);
72 bool SkTextureDataBlock::TextureInfo::operator==(const TextureInfo& other) const {
73 return fProxy == other.fProxy &&
74 fSamplingOptions == other.fSamplingOptions &&
75 fTileModes[0] == other.fTileModes[0] &&
76 fTileModes[1] == other.fTileModes[1];
79 uint32_t SkTextureDataBlock::TextureInfo::samplerKey() const {
80 static_assert(kSkTileModeCount <= 4 && kSkFilterModeCount <= 2);
81 return (static_cast<int>(fTileModes[0]) << 0) |
82 (static_cast<int>(fTileModes[1]) << 2) |
83 (static_cast<int>(fSamplingOptions.filter) << 4) |
84 (static_cast<int>(fSamplingOptions.mipmap) << 5);
87 bool SkTextureDataBlock::operator==(const SkTextureDataBlock& other) const {
88 if (fTextureData.size() != other.fTextureData.size()) {
92 for (size_t i = 0; i < fTextureData.size(); ++i) {
93 if (fTextureData[i] != other.fTextureData[i]) {
101 uint32_t SkTextureDataBlock::hash() const {
104 for (auto& d : fTextureData) {
105 uint32_t samplerKey = d.samplerKey();
106 hash = SkOpts::hash_fn(&samplerKey, sizeof(samplerKey), hash);
108 // Because the lifetime of the TextureDataCache is for just one Recording and the
109 // TextureDataBlocks hold refs on their proxies, we can just use the proxy's pointer
110 // for the hash here. This is a bit sloppy though in that it would be nice if proxies backed
111 // by the same scratch texture hashed the same (it is tough to see how we could do that
112 // at DrawPass creation time though).
113 hash = SkOpts::hash_fn(d.fProxy.get(), sizeof(skgpu::graphite::TextureProxy*), hash);