| 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 |