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