1 /* 2 * Copyright 2023 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 #ifndef skgpu_graphite_AtlasProvider_DEFINED 9 #define skgpu_graphite_AtlasProvider_DEFINED 10 11 #include "include/core/SkColorType.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/private/base/SkTo.h" 14 #include "src/base/SkEnumBitMask.h" 15 16 #include <memory> 17 #include <unordered_map> 18 19 namespace skgpu::graphite { 20 21 class Caps; 22 class ClipAtlasManager; 23 class ComputePathAtlas; 24 class DrawContext; 25 class PathAtlas; 26 class RasterPathAtlas; 27 class Recorder; 28 class TextAtlasManager; 29 class TextureProxy; 30 31 /** 32 * AtlasProvider groups various texture atlas management algorithms together. 33 */ 34 class AtlasProvider final { 35 public: 36 enum class PathAtlasFlags : unsigned { 37 kNone = 0b000, 38 // ComputePathAtlas is supported 39 kCompute = 0b001, 40 // RasterPathAtlas is supported 41 kRaster = 0b010, 42 }; 43 SK_DECL_BITMASK_OPS_FRIENDS(PathAtlasFlags) 44 using PathAtlasFlagsBitMask = SkEnumBitMask<PathAtlasFlags>; 45 46 // Query the supported path atlas algorithms based on device capabilities. 47 static PathAtlasFlagsBitMask QueryPathAtlasSupport(const Caps*); 48 49 explicit AtlasProvider(Recorder*); 50 ~AtlasProvider() = default; 51 52 // Returns the TextAtlasManager that provides access to persistent DrawAtlas instances used in 53 // glyph rendering. This TextAtlasManager is always available. textAtlasManager()54 TextAtlasManager* textAtlasManager() const { return fTextAtlasManager.get(); } 55 56 // Returns whether a particular atlas type is available. Currently PathAtlasFlags::kRaster is 57 // always supported. isAvailable(PathAtlasFlags atlasType)58 bool isAvailable(PathAtlasFlags atlasType) const { 59 return SkToBool(fPathAtlasFlags & atlasType); 60 } 61 62 // Creates a new transient atlas handler that uses compute shaders to rasterize coverage masks 63 // for path rendering. This method returns nullptr if compute shaders are not supported by the 64 // owning Recorder's context. 65 std::unique_ptr<ComputePathAtlas> createComputePathAtlas(Recorder* recorder) const; 66 67 // Gets the atlas handler that uses the CPU raster pipeline to create coverage masks 68 // for path rendering. 69 RasterPathAtlas* getRasterPathAtlas() const; 70 71 // Gets the atlas handler that uses the CPU raster pipeline to create coverage masks 72 // for clips. 73 ClipAtlasManager* getClipAtlasManager() const; 74 75 // Return a TextureProxy with the given dimensions and color type. 76 sk_sp<TextureProxy> getAtlasTexture( 77 Recorder*, uint16_t width, uint16_t height, SkColorType, uint16_t identifier, 78 bool requireStorageUsage); 79 80 // This frees textures held in the atlas pool, and compacts the pages within the other 81 // atlas managers. It does not free resources that are in use or clear cached masks. 82 void freeGpuResources(); 83 84 // Push any pending uploads to atlases onto the draw context 85 void recordUploads(DrawContext*); 86 87 // Handle any post-flush work (garbage collection) 88 void compact(); 89 90 // Invalidate any cached state about what may or may not already be uploaded in the atlas. 91 void invalidateAtlases(); 92 93 private: 94 std::unique_ptr<TextAtlasManager> fTextAtlasManager; 95 96 // Accumulates atlas coverage masks generated by software rendering that are required by one or 97 // more entries in `fPendingDraws`. During the snapUploadTask step, prior to pending draws 98 // being snapped into a new DrawPass, any necessary uploads into an atlas texture are recorded 99 // for the accumulated masks. 100 // 101 // TODO: We may need a method to generate raster-generated masks in separate threads prior to 102 // upload. 103 std::unique_ptr<RasterPathAtlas> fRasterPathAtlas; 104 105 // Accumulates atlas coverage masks corresponding to an ElementList in the ClipStack. 106 std::unique_ptr<ClipAtlasManager> fClipAtlasManager; 107 108 // Allocated and cached texture proxies shared by all PathAtlas instances. It is possible for 109 // the same texture to be bound to multiple DispatchGroups and DrawPasses across flushes. The 110 // owning Recorder must guarantee that any uploads or compute dispatches are scheduled to remain 111 // coherent across flushes. 112 // TODO: This requirement might change with a more sophisticated reuse scheme for texture 113 // allocations. For now our model is simple: all PathAtlases target the same texture and only 114 // one of them will render to the texture during a given command submission. 115 std::unordered_map<uint64_t, sk_sp<TextureProxy>> fTexturePool; 116 117 PathAtlasFlagsBitMask fPathAtlasFlags = PathAtlasFlags::kNone; 118 }; 119 120 SK_MAKE_BITMASK_OPS(AtlasProvider::PathAtlasFlags) 121 122 } // namespace skgpu::graphite 123 124 #endif // skgpu_graphite_AtlasProvider_DEFINED 125