blob: b37cbc1556e2fbbb0dd4bbddacaa6e31a177928f [file] [log] [blame]
Chris Daltona550cf22020-02-07 13:35:31 -07001/*
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
14class GrOnFlushResourceProvider;
15class GrRenderTargetContext;
16class GrResourceProvider;
17struct SkIPoint16;
18struct 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 */
25class GrDynamicAtlas {
26public:
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
49 GrTextureProxy* textureProxy() const { return fTextureProxy.get(); }
50 bool isInstantiated() const { return fTextureProxy->isInstantiated(); }
51 int currentWidth() const { return fWidth; }
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);
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
69private:
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