• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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