| /* | |
| * Copyright 2023 Google LLC | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef skgpu_graphite_AtlasProvider_DEFINED | |
| #define skgpu_graphite_AtlasProvider_DEFINED | |
| #include "include/core/SkRefCnt.h" | |
| #include "include/private/base/SkTo.h" | |
| #include "src/base/SkEnumBitMask.h" | |
| #include <cstdint> | |
| #include <memory> | |
| #include <unordered_map> | |
| enum SkColorType : int; | |
| namespace skgpu::graphite { | |
| class Caps; | |
| class ClipAtlasManager; | |
| class ComputePathAtlas; | |
| class DrawContext; | |
| class RasterPathAtlas; | |
| class Recorder; | |
| class TextAtlasManager; | |
| class TextureProxy; | |
| /** | |
| * AtlasProvider groups various texture atlas management algorithms together. | |
| */ | |
| class AtlasProvider final { | |
| public: | |
| enum class PathAtlasFlags : unsigned { | |
| kNone = 0b000, | |
| // ComputePathAtlas is supported | |
| kCompute = 0b001, | |
| // RasterPathAtlas is supported | |
| kRaster = 0b010, | |
| }; | |
| SK_DECL_BITMASK_OPS_FRIENDS(PathAtlasFlags) | |
| using PathAtlasFlagsBitMask = SkEnumBitMask<PathAtlasFlags>; | |
| // Query the supported path atlas algorithms based on device capabilities. | |
| static PathAtlasFlagsBitMask QueryPathAtlasSupport(const Caps*); | |
| explicit AtlasProvider(Recorder*); | |
| ~AtlasProvider(); | |
| // Returns the TextAtlasManager that provides access to persistent DrawAtlas instances used in | |
| // glyph rendering. This TextAtlasManager is always available. | |
| TextAtlasManager* textAtlasManager() const { return fTextAtlasManager.get(); } | |
| // Returns whether a particular atlas type is available. Currently PathAtlasFlags::kRaster is | |
| // always supported. | |
| bool isAvailable(PathAtlasFlags atlasType) const { | |
| return SkToBool(fPathAtlasFlags & atlasType); | |
| } | |
| // Creates a new transient atlas handler that uses compute shaders to rasterize coverage masks | |
| // for path rendering. This method returns nullptr if compute shaders are not supported by the | |
| // owning Recorder's context. | |
| std::unique_ptr<ComputePathAtlas> createComputePathAtlas(Recorder* recorder) const; | |
| // Gets the atlas handler that uses the CPU raster pipeline to create coverage masks | |
| // for path rendering. | |
| RasterPathAtlas* getRasterPathAtlas() const; | |
| // Gets the atlas handler that uses the CPU raster pipeline to create coverage masks | |
| // for clips. | |
| ClipAtlasManager* getClipAtlasManager() const; | |
| // Return a TextureProxy with the given dimensions and color type. | |
| sk_sp<TextureProxy> getAtlasTexture( | |
| Recorder*, uint16_t width, uint16_t height, SkColorType, uint16_t identifier, | |
| bool requireStorageUsage); | |
| // This frees textures held in the atlas pool, and compacts the pages within the other | |
| // atlas managers. It does not free resources that are in use or clear cached masks. | |
| void freeGpuResources(); | |
| // Push any pending uploads to atlases onto the draw context | |
| void recordUploads(DrawContext*); | |
| // Handle any post-flush work (garbage collection) | |
| void compact(); | |
| // Invalidate any cached state about what may or may not already be uploaded in the atlas. | |
| void invalidateAtlases(); | |
| private: | |
| std::unique_ptr<TextAtlasManager> fTextAtlasManager; | |
| // Accumulates atlas coverage masks generated by software rendering that are required by one or | |
| // more entries in `fPendingDraws`. During the snapUploadTask step, prior to pending draws | |
| // being snapped into a new DrawPass, any necessary uploads into an atlas texture are recorded | |
| // for the accumulated masks. | |
| // | |
| // TODO: We may need a method to generate raster-generated masks in separate threads prior to | |
| // upload. | |
| std::unique_ptr<RasterPathAtlas> fRasterPathAtlas; | |
| // Accumulates atlas coverage masks corresponding to an ElementList in the ClipStack. | |
| std::unique_ptr<ClipAtlasManager> fClipAtlasManager; | |
| // Allocated and cached texture proxies shared by all PathAtlas instances. It is possible for | |
| // the same texture to be bound to multiple DispatchGroups and DrawPasses across flushes. The | |
| // owning Recorder must guarantee that any uploads or compute dispatches are scheduled to remain | |
| // coherent across flushes. | |
| // TODO: This requirement might change with a more sophisticated reuse scheme for texture | |
| // allocations. For now our model is simple: all PathAtlases target the same texture and only | |
| // one of them will render to the texture during a given command submission. | |
| std::unordered_map<uint64_t, sk_sp<TextureProxy>> fTexturePool; | |
| PathAtlasFlagsBitMask fPathAtlasFlags = PathAtlasFlags::kNone; | |
| }; | |
| SK_MAKE_BITMASK_OPS(AtlasProvider::PathAtlasFlags) | |
| } // namespace skgpu::graphite | |
| #endif // skgpu_graphite_AtlasProvider_DEFINED |