• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2020 Google Inc.
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 GrDynamicAtlas_DEFINED
9 #define GrDynamicAtlas_DEFINED
10 
11 #include "src/core/SkArenaAlloc.h"
12 #include "src/gpu/GrTextureProxy.h"
13 
14 class GrOnFlushResourceProvider;
15 class GrResourceProvider;
16 struct SkIPoint16;
17 struct SkIRect;
18 
19 /**
20  * This class implements a dynamic size GrRectanizer that grows until it reaches the implementation-
21  * dependent max texture size. When finalized, it also creates and stores a GrTextureProxy for the
22  * underlying atlas.
23  */
24 class GrDynamicAtlas {
25 public:
26     // As long as GrSurfaceOrigin exists, we just have to decide on one for the atlas texture.
27     inline static constexpr GrSurfaceOrigin kTextureOrigin = kTopLeft_GrSurfaceOrigin;
28     inline static constexpr int kPadding = 1;  // Amount of padding below and to the right of each
29                                                // path.
30 
31     using LazyAtlasDesc = GrSurfaceProxy::LazySurfaceDesc;
32     using LazyInstantiateAtlasCallback = GrSurfaceProxy::LazyInstantiateCallback;
33 
34     enum class InternalMultisample : bool {
35         kNo = false,
36         kYes = true
37     };
38 
39     static sk_sp<GrTextureProxy> MakeLazyAtlasProxy(LazyInstantiateAtlasCallback&&,
40                                                     GrColorType colorType,
41                                                     InternalMultisample,
42                                                     const GrCaps&,
43                                                     GrSurfaceProxy::UseAllocator);
44 
45     enum class RectanizerAlgorithm {
46         kSkyline,
47         kPow2
48     };
49 
50     GrDynamicAtlas(GrColorType colorType, InternalMultisample, SkISize initialSize,
51                    int maxAtlasSize, const GrCaps&,
52                    RectanizerAlgorithm = RectanizerAlgorithm::kSkyline);
53     virtual ~GrDynamicAtlas();
54 
55     void reset(SkISize initialSize, const GrCaps& desc);
56 
colorType()57     GrColorType colorType() const { return fColorType; }
maxAtlasSize()58     int maxAtlasSize() const { return fMaxAtlasSize; }
textureProxy()59     GrTextureProxy* textureProxy() const { return fTextureProxy.get(); }
60     GrSurfaceProxyView readView(const GrCaps&) const;
61     GrSurfaceProxyView writeView(const GrCaps&) const;
isInstantiated()62     bool isInstantiated() const { return fTextureProxy->isInstantiated(); }
63 
64     // Attempts to add a rect to the atlas. Returns true if successful, along with the rect's
65     // top-left location in the atlas.
66     bool addRect(int width, int height, SkIPoint16* location);
drawBounds()67     const SkISize& drawBounds() { return fDrawBounds; }
68 
69     // Instantiates our texture proxy for the atlas. After this call, it is no longer valid to call
70     // addRect(), setUserBatchID(), or this method again.
71     //
72     // 'backingTexture', if provided, is a renderable texture with which to instantiate our proxy.
73     // If null then we will create a texture using the resource provider. The purpose of this param
74     // is to provide a guaranteed way to recycle textures from previous atlases.
75     void instantiate(GrOnFlushResourceProvider*, sk_sp<GrTexture> backingTexture = nullptr);
76 
77 private:
78     class Node;
79 
80     Node* makeNode(Node* previous, int l, int t, int r, int b);
81     bool internalPlaceRect(int w, int h, SkIPoint16* loc);
82 
83     const GrColorType fColorType;
84     const InternalMultisample fInternalMultisample;
85     const int fMaxAtlasSize;
86     const RectanizerAlgorithm fRectanizerAlgorithm;
87     int fWidth;
88     int fHeight;
89     SkISize fDrawBounds;
90 
91     SkSTArenaAllocWithReset<512> fNodeAllocator;
92     Node* fTopNode = nullptr;
93 
94     sk_sp<GrTextureProxy> fTextureProxy;
95     sk_sp<GrTexture> fBackingTexture;
96 };
97 
98 #endif
99