| /* |
| * Copyright 2021 Google LLC |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef skgpu_GraphicsPipelineDesc_DEFINED |
| #define skgpu_GraphicsPipelineDesc_DEFINED |
| |
| #include "include/core/SkTypes.h" |
| |
| #include "include/core/SkSpan.h" |
| #include "include/private/SkOpts_spi.h" |
| #include "include/private/SkTArray.h" |
| #include "include/private/SkUniquePaintParamsID.h" |
| #include "src/gpu/graphite/Attribute.h" |
| #include "src/gpu/graphite/DrawTypes.h" |
| |
| #include <array> |
| namespace skgpu::graphite { |
| |
| class RenderStep; |
| |
| /** |
| * GraphicsPipelineDesc represents the state needed to create a backend specific GraphicsPipeline, |
| * minus the target-specific properties that can be inferred from the DrawPass and RenderPassTask. |
| */ |
| class GraphicsPipelineDesc { |
| public: |
| GraphicsPipelineDesc(); |
| |
| SkSpan<const uint32_t> asKey() const { return SkSpan(fKey.data(), fKey.size()); } |
| |
| bool operator==(const GraphicsPipelineDesc& that) const { |
| return this->fKey == that.fKey; |
| } |
| |
| bool operator!=(const GraphicsPipelineDesc& other) const { |
| return !(*this == other); |
| } |
| |
| // Describes the geometric portion of the pipeline's program and the pipeline's fixed state |
| // (except for renderpass-level state that will never change between draws). |
| const RenderStep* renderStep() const { return fRenderStep; } |
| // UniqueID of the required PaintParams |
| SkUniquePaintParamsID paintParamsID() const { return fUniqueID; } |
| |
| void setProgram(const RenderStep* step, SkUniquePaintParamsID uniqueID) { |
| SkASSERT(step); |
| fRenderStep = step; |
| fUniqueID = uniqueID; |
| |
| uintptr_t addr = reinterpret_cast<uintptr_t>(fRenderStep); |
| memcpy(fKey.data(), &addr, sizeof(uintptr_t)); |
| fKey[kWords - 1] = fUniqueID.asUInt(); |
| } |
| |
| struct Hash { |
| uint32_t operator()(const GraphicsPipelineDesc& desc) const { |
| return SkOpts::hash_fn(desc.fKey.data(), desc.fKey.size() * sizeof(uint32_t), 0); |
| } |
| }; |
| |
| private: |
| // The key is the RenderStep address and the uint32_t key from Combination |
| static constexpr int kWords = sizeof(uintptr_t) / sizeof(uint32_t) + 1; |
| static_assert(sizeof(uintptr_t) % sizeof(uint32_t) == 0); |
| |
| // TODO: I wonder if we could expose the "key" as just a char[] union over the renderstep and |
| // paint combination? That would avoid extra size, but definitely locks GraphicsPipelineDesc |
| // keys to the current process, which is probably okay since we can have something a with a more |
| // stable hash used for the pre-compilation combos. |
| std::array<uint32_t, kWords> fKey; |
| |
| // Each RenderStep defines a fixed set of attributes and rasterization state, as well as the |
| // shader fragments that control the geometry and coverage calculations. The RenderStep's shader |
| // is combined with the rest of the shader generated from the PaintParams. Because each |
| // RenderStep is fixed, its pointer can be used as a proxy for everything that it specifies in |
| // the GraphicsPipeline. |
| const RenderStep* fRenderStep = nullptr; |
| |
| SkUniquePaintParamsID fUniqueID; |
| }; |
| |
| } // namespace skgpu |
| |
| #endif // skgpu_GraphicsPipelineDesc_DEFINED |