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