OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2010 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 GrLayerAtlas_DEFINED | |
9 #define GrLayerAtlas_DEFINED | |
10 | |
11 #include "GrTexture.h" | |
12 | |
13 #include "SkPoint.h" | |
14 #include "SkTDArray.h" | |
15 #include "SkTInternalLList.h" | |
16 | |
17 class GrLayerAtlas; | |
18 class GrTextureProvider; | |
19 class GrRectanizer; | |
20 | |
21 // The backing GrTexture for a GrLayerAtlas is broken into a spatial grid of Plo
ts. When | |
22 // the atlas needs space on the texture (i.e., in response to an addToAtlas call
), it | |
23 // iterates through the plots in use by the requesting client looking for space
and, | |
24 // if no space is found, opens up a new Plot for that client. The Plots keep tra
ck of | |
25 // subimage placement via their GrRectanizer. | |
26 // | |
27 // If all Plots are full, the replacement strategy is up to the client. The Plot
::reset | |
28 // call will remove a Plot's knowledge of any allocated rects - freeing its spac
e for reuse. | |
29 | |
30 class GrLayerAtlas { | |
31 public: | |
32 class Plot { | |
33 SK_DECLARE_INTERNAL_LLIST_INTERFACE(Plot); // In an MRU llist | |
34 | |
35 public: | |
36 // This returns a plot ID unique to each plot in the atlas. They are | |
37 // consecutive and start at 0. | |
38 int id() const { return fID; } | |
39 | |
40 void reset(); | |
41 | |
42 private: | |
43 friend class GrLayerAtlas; | |
44 | |
45 Plot(); | |
46 ~Plot(); // does not try to delete the fNext field | |
47 | |
48 void init(int id, int offX, int offY, int width, int height); | |
49 | |
50 bool allocateRect(int width, int height, SkIPoint16*); | |
51 | |
52 int fID; | |
53 GrRectanizer* fRects; | |
54 SkIPoint16 fOffset; // the offset of the plot in the
backing texture | |
55 }; | |
56 | |
57 // This class allows each client to independently track the Plots in | |
58 // which its data is stored. | |
59 // For example, multiple pictures may simultaneously store their layers in t
he | |
60 // layer atlas. When a picture goes away it can use the ClientPlotUsage to r
emove itself | |
61 // from those plots. | |
62 class ClientPlotUsage { | |
63 public: | |
64 ClientPlotUsage(int maxPlots) | |
65 SkDEBUGCODE(: fMaxPlots(maxPlots)) { | |
66 fPlots.setReserve(maxPlots); | |
67 } | |
68 | |
69 bool isEmpty() const { return 0 == fPlots.count(); } | |
70 | |
71 int numPlots() const { return fPlots.count(); } | |
72 Plot* plot(int index) { return fPlots[index]; } | |
73 | |
74 void appendPlot(Plot* plot) { | |
75 SkASSERT(fPlots.count() <= fMaxPlots); | |
76 SkASSERT(!fPlots.contains(plot)); | |
77 *fPlots.append() = plot; | |
78 } | |
79 | |
80 // remove reference to 'plot' | |
81 void removePlot(const Plot* plot) { | |
82 int index = fPlots.find(const_cast<Plot*>(plot)); | |
83 if (index >= 0) { | |
84 fPlots.remove(index); | |
85 } | |
86 } | |
87 | |
88 #ifdef SK_DEBUG | |
89 bool contains(const Plot* plot) const { | |
90 return fPlots.contains(const_cast<Plot*>(plot)); | |
91 } | |
92 #endif | |
93 | |
94 private: | |
95 SkTDArray<Plot*> fPlots; | |
96 SkDEBUGCODE(int fMaxPlots;) | |
97 }; | |
98 | |
99 GrLayerAtlas(GrTextureProvider*, GrPixelConfig, GrSurfaceFlags flags, | |
100 const SkISize& backingTextureSize, | |
101 int numPlotsX, int numPlotsY); | |
102 ~GrLayerAtlas(); | |
103 | |
104 // Requests a width x height block in the atlas. Upon success it returns | |
105 // the containing Plot and absolute location in the backing texture. | |
106 // nullptr is returned if there is no more space in the atlas. | |
107 Plot* addToAtlas(ClientPlotUsage*, int width, int height, SkIPoint16* loc); | |
108 | |
109 GrTexture* getTextureOrNull() const { | |
110 return fTexture; | |
111 } | |
112 | |
113 GrTexture* getTexture() const { | |
114 SkASSERT(fTexture); | |
115 return fTexture; | |
116 } | |
117 | |
118 bool reattachBackingTexture(); | |
119 | |
120 void detachBackingTexture() { | |
121 fTexture.reset(nullptr); | |
122 } | |
123 | |
124 void resetPlots(); | |
125 | |
126 enum IterOrder { | |
127 kLRUFirst_IterOrder, | |
128 kMRUFirst_IterOrder | |
129 }; | |
130 | |
131 typedef SkTInternalLList<Plot> PlotList; | |
132 typedef PlotList::Iter PlotIter; | |
133 Plot* iterInit(PlotIter* iter, IterOrder order) { | |
134 return iter->init(fPlotList, kLRUFirst_IterOrder == order | |
135 ? PlotList::Iter::kTail_I
terStart | |
136 : PlotList::Iter::kHead_I
terStart); | |
137 } | |
138 | |
139 private: | |
140 void createBackingTexture(); | |
141 | |
142 void makeMRU(Plot* plot); | |
143 | |
144 GrTextureProvider* fTexProvider; | |
145 GrPixelConfig fPixelConfig; | |
146 GrSurfaceFlags fFlags; | |
147 SkAutoTUnref<GrTexture> fTexture; | |
148 | |
149 SkISize fBackingTextureSize; | |
150 | |
151 // allocated array of Plots | |
152 Plot* fPlotArray; | |
153 // LRU list of Plots (MRU at head - LRU at tail) | |
154 PlotList fPlotList; | |
155 }; | |
156 | |
157 #endif | |
OLD | NEW |