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 GrSurfaceDrawContext; 16 class GrResourceProvider; 17 struct SkIPoint16; 18 struct SkIRect; 19 20 /** 21 * This class implements a dynamic size GrRectanizer that grows until it reaches the implementation- 22 * dependent max texture size. When finalized, it also creates and stores a GrTextureProxy for the 23 * 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 static constexpr GrSurfaceOrigin kTextureOrigin = kTopLeft_GrSurfaceOrigin; 29 static constexpr int kPadding = 1; // Amount of padding below and to the right of each 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 maxAtlasSize()57 int maxAtlasSize() const { return fMaxAtlasSize; } textureProxy()58 GrTextureProxy* textureProxy() const { return fTextureProxy.get(); } isInstantiated()59 bool isInstantiated() const { return fTextureProxy->isInstantiated(); } currentWidth()60 int currentWidth() const { return fWidth; } currentHeight()61 int currentHeight() const { return fHeight; } 62 63 // Attempts to add a rect to the atlas. Returns true if successful, along with the rect's 64 // top-left location in the atlas. 65 bool addRect(int width, int height, SkIPoint16* location); drawBounds()66 const SkISize& drawBounds() { return fDrawBounds; } 67 68 // Instantiates our texture proxy for the atlas and returns a pre-cleared GrSurfaceDrawContext 69 // that the caller may use to render the content. 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 a stashed atlas texture from a previous flush. 75 std::unique_ptr<GrSurfaceDrawContext> instantiate( 76 GrOnFlushResourceProvider*, sk_sp<GrTexture> backingTexture = nullptr); 77 78 private: 79 class Node; 80 81 Node* makeNode(Node* previous, int l, int t, int r, int b); 82 bool internalPlaceRect(int w, int h, SkIPoint16* loc); 83 84 const GrColorType fColorType; 85 const InternalMultisample fInternalMultisample; 86 const int fMaxAtlasSize; 87 const RectanizerAlgorithm fRectanizerAlgorithm; 88 int fWidth; 89 int fHeight; 90 SkISize fDrawBounds; 91 92 SkSTArenaAllocWithReset<512> fNodeAllocator; 93 Node* fTopNode = nullptr; 94 95 sk_sp<GrTextureProxy> fTextureProxy; 96 sk_sp<GrTexture> fBackingTexture; 97 }; 98 99 #endif 100