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