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/gpu/GrAllocator.h" 12 #include "src/gpu/GrTextureProxy.h" 13 14 class GrOnFlushResourceProvider; 15 class GrRenderTargetContext; 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 LazyInstantiateAtlasCallback = std::function<GrSurfaceProxy::LazyCallbackResult( 32 GrResourceProvider*, const GrBackendFormat&, int sampleCount)>; 33 34 enum class InternalMultisample : bool { 35 kNo = false, 36 kYes = true 37 }; 38 39 static sk_sp<GrTextureProxy> MakeLazyAtlasProxy(const LazyInstantiateAtlasCallback&, 40 GrColorType colorType, InternalMultisample, 41 const GrCaps&, GrSurfaceProxy::UseAllocator); 42 43 GrDynamicAtlas(GrColorType colorType, InternalMultisample, SkISize initialSize, 44 int maxAtlasSize, const GrCaps&); 45 virtual ~GrDynamicAtlas(); 46 47 void reset(SkISize initialSize, const GrCaps& caps); 48 textureProxy()49 GrTextureProxy* textureProxy() const { return fTextureProxy.get(); } isInstantiated()50 bool isInstantiated() const { return fTextureProxy->isInstantiated(); } currentWidth()51 int currentWidth() const { return fWidth; } currentHeight()52 int currentHeight() const { return fHeight; } 53 54 // Attempts to add a rect to the atlas. If successful, returns the integer offset from 55 // device-space pixels where the path will be drawn, to atlas pixels where its mask resides. 56 bool addRect(const SkIRect& devIBounds, SkIVector* atlasOffset); drawBounds()57 const SkISize& drawBounds() { return fDrawBounds; } 58 59 // Instantiates our texture proxy for the atlas and returns a pre-cleared GrRenderTargetContext 60 // that the caller may use to render the content. After this call, it is no longer valid to call 61 // addRect(), setUserBatchID(), or this method again. 62 // 63 // 'backingTexture', if provided, is a renderable texture with which to instantiate our proxy. 64 // If null then we will create a texture using the resource provider. The purpose of this param 65 // is to provide a guaranteed way to recycle a stashed atlas texture from a previous flush. 66 std::unique_ptr<GrRenderTargetContext> instantiate( 67 GrOnFlushResourceProvider*, sk_sp<GrTexture> backingTexture = nullptr); 68 69 private: 70 class Node; 71 72 bool internalPlaceRect(int w, int h, SkIPoint16* loc); 73 74 const GrColorType fColorType; 75 const InternalMultisample fInternalMultisample; 76 const int fMaxAtlasSize; 77 int fWidth; 78 int fHeight; 79 std::unique_ptr<Node> fTopNode; 80 SkISize fDrawBounds; 81 82 sk_sp<GrTextureProxy> fTextureProxy; 83 sk_sp<GrTexture> fBackingTexture; 84 }; 85 86 #endif 87