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