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