| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2010 Google Inc. | 3 * Copyright 2010 Google Inc. |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "GrGpuResourcePriv.h" |
| 9 #include "GrLayerAtlas.h" | 10 #include "GrLayerAtlas.h" |
| 10 #include "GrRectanizer.h" | 11 #include "GrRectanizer.h" |
| 11 #include "GrTextureProvider.h" | 12 #include "GrTextureProvider.h" |
| 12 | 13 |
| 13 /////////////////////////////////////////////////////////////////////////////// | 14 /////////////////////////////////////////////////////////////////////////////// |
| 14 GrLayerAtlas::Plot::Plot() | 15 GrLayerAtlas::Plot::Plot() |
| 15 : fID(-1) | 16 : fID(-1) |
| 16 , fRects(nullptr) { | 17 , fRects(nullptr) { |
| 17 fOffset.set(0, 0); | 18 fOffset.set(0, 0); |
| 18 } | 19 } |
| (...skipping 17 matching lines...) Expand all Loading... |
| 36 loc->fY += fOffset.fY; | 37 loc->fY += fOffset.fY; |
| 37 return true; | 38 return true; |
| 38 } | 39 } |
| 39 | 40 |
| 40 void GrLayerAtlas::Plot::reset() { | 41 void GrLayerAtlas::Plot::reset() { |
| 41 SkASSERT(fRects); | 42 SkASSERT(fRects); |
| 42 fRects->reset(); | 43 fRects->reset(); |
| 43 } | 44 } |
| 44 | 45 |
| 45 /////////////////////////////////////////////////////////////////////////////// | 46 /////////////////////////////////////////////////////////////////////////////// |
| 47 GR_DECLARE_STATIC_UNIQUE_KEY(gLayerAtlasKey); |
| 48 static const GrUniqueKey& get_layer_atlas_key() { |
| 49 GR_DEFINE_STATIC_UNIQUE_KEY(gLayerAtlasKey); |
| 50 return gLayerAtlasKey; |
| 51 } |
| 52 |
| 53 bool GrLayerAtlas::reattachBackingTexture() { |
| 54 SkASSERT(!fTexture); |
| 55 |
| 56 fTexture.reset(fTexProvider->findAndRefTextureByUniqueKey(get_layer_atlas_ke
y())); |
| 57 return SkToBool(fTexture); |
| 58 } |
| 59 |
| 60 void GrLayerAtlas::createBackingTexture() { |
| 61 SkASSERT(!fTexture); |
| 62 |
| 63 GrSurfaceDesc desc; |
| 64 desc.fFlags = fFlags; |
| 65 desc.fWidth = fBackingTextureSize.width(); |
| 66 desc.fHeight = fBackingTextureSize.height(); |
| 67 desc.fConfig = fPixelConfig; |
| 68 |
| 69 fTexture.reset(fTexProvider->createTexture(desc, true, nullptr, 0)); |
| 70 |
| 71 fTexture->resourcePriv().setUniqueKey(get_layer_atlas_key()); |
| 72 } |
| 46 | 73 |
| 47 GrLayerAtlas::GrLayerAtlas(GrTextureProvider* texProvider, GrPixelConfig config,
| 74 GrLayerAtlas::GrLayerAtlas(GrTextureProvider* texProvider, GrPixelConfig config,
|
| 48 GrSurfaceFlags flags, | 75 GrSurfaceFlags flags, |
| 49 const SkISize& backingTextureSize, | 76 const SkISize& backingTextureSize, |
| 50 int numPlotsX, int numPlotsY) { | 77 int numPlotsX, int numPlotsY) { |
| 51 fTexProvider = texProvider; | 78 fTexProvider = texProvider; |
| 52 fPixelConfig = config; | 79 fPixelConfig = config; |
| 53 fFlags = flags; | 80 fFlags = flags; |
| 54 fBackingTextureSize = backingTextureSize; | 81 fBackingTextureSize = backingTextureSize; |
| 55 fTexture = nullptr; | |
| 56 | 82 |
| 57 int textureWidth = fBackingTextureSize.width(); | 83 int textureWidth = fBackingTextureSize.width(); |
| 58 int textureHeight = fBackingTextureSize.height(); | 84 int textureHeight = fBackingTextureSize.height(); |
| 59 | 85 |
| 60 int plotWidth = textureWidth / numPlotsX; | 86 int plotWidth = textureWidth / numPlotsX; |
| 61 int plotHeight = textureHeight / numPlotsY; | 87 int plotHeight = textureHeight / numPlotsY; |
| 62 | 88 |
| 63 SkASSERT(plotWidth * numPlotsX == textureWidth); | 89 SkASSERT(plotWidth * numPlotsX == textureWidth); |
| 64 SkASSERT(plotHeight * numPlotsY == textureHeight); | 90 SkASSERT(plotHeight * numPlotsY == textureHeight); |
| 65 | 91 |
| 66 // We currently do not support compressed atlases... | 92 // We currently do not support compressed atlases... |
| 67 SkASSERT(!GrPixelConfigIsCompressed(config)); | 93 SkASSERT(!GrPixelConfigIsCompressed(config)); |
| 68 | 94 |
| 69 // set up allocated plots | 95 // set up allocated plots |
| 70 fPlotArray = new Plot[numPlotsX * numPlotsY]; | 96 fPlotArray = new Plot[numPlotsX * numPlotsY]; |
| 71 | 97 |
| 72 Plot* currPlot = fPlotArray; | 98 Plot* currPlot = fPlotArray; |
| 73 for (int y = numPlotsY-1; y >= 0; --y) { | 99 for (int y = numPlotsY-1; y >= 0; --y) { |
| 74 for (int x = numPlotsX-1; x >= 0; --x) { | 100 for (int x = numPlotsX-1; x >= 0; --x) { |
| 75 currPlot->init(y*numPlotsX+x, x, y, plotWidth, plotHeight); | 101 currPlot->init(y*numPlotsX+x, x, y, plotWidth, plotHeight); |
| 76 | 102 |
| 77 // build LRU list | 103 // build LRU list |
| 78 fPlotList.addToHead(currPlot); | 104 fPlotList.addToHead(currPlot); |
| 79 ++currPlot; | 105 ++currPlot; |
| 80 } | 106 } |
| 81 } | 107 } |
| 82 } | 108 } |
| 83 | 109 |
| 110 void GrLayerAtlas::resetPlots() { |
| 111 PlotIter iter; |
| 112 for (Plot* plot = iter.init(fPlotList, PlotIter::kHead_IterStart); plot; plo
t = iter.next()) { |
| 113 plot->reset(); |
| 114 } |
| 115 } |
| 116 |
| 84 GrLayerAtlas::~GrLayerAtlas() { | 117 GrLayerAtlas::~GrLayerAtlas() { |
| 85 SkSafeUnref(fTexture); | |
| 86 delete[] fPlotArray; | 118 delete[] fPlotArray; |
| 87 } | 119 } |
| 88 | 120 |
| 89 void GrLayerAtlas::makeMRU(Plot* plot) { | 121 void GrLayerAtlas::makeMRU(Plot* plot) { |
| 90 if (fPlotList.head() == plot) { | 122 if (fPlotList.head() == plot) { |
| 91 return; | 123 return; |
| 92 } | 124 } |
| 93 | 125 |
| 94 fPlotList.remove(plot); | 126 fPlotList.remove(plot); |
| 95 fPlotList.addToHead(plot); | 127 fPlotList.addToHead(plot); |
| 96 }; | 128 }; |
| 97 | 129 |
| 98 GrLayerAtlas::Plot* GrLayerAtlas::addToAtlas(ClientPlotUsage* usage, | 130 GrLayerAtlas::Plot* GrLayerAtlas::addToAtlas(ClientPlotUsage* usage, |
| 99 int width, int height, SkIPoint16*
loc) { | 131 int width, int height, SkIPoint16*
loc) { |
| 100 // Iterate through the plots currently being used by this client and see if
we can find a hole. | 132 // Iterate through the plots currently being used by this client and see if
we can find a hole. |
| 101 // The last one was most recently added and probably most empty. | 133 // The last one was most recently added and probably most empty. |
| 102 // We want to consolidate the uses from individual clients to the same plot(
s) so that | 134 // We want to consolidate the uses from individual clients to the same plot(
s) so that |
| 103 // when a specific client goes away they are more likely to completely empty
a plot. | 135 // when a specific client goes away they are more likely to completely empty
a plot. |
| 104 for (int i = usage->numPlots()-1; i >= 0; --i) { | 136 for (int i = usage->numPlots()-1; i >= 0; --i) { |
| 105 Plot* plot = usage->plot(i); | 137 Plot* plot = usage->plot(i); |
| 106 if (plot->allocateRect(width, height, loc)) { | 138 if (plot->allocateRect(width, height, loc)) { |
| 107 this->makeMRU(plot); | 139 this->makeMRU(plot); |
| 108 return plot; | 140 return plot; |
| 109 } | 141 } |
| 110 } | 142 } |
| 111 | 143 |
| 112 // before we get a new plot, make sure we have a backing texture | 144 // before we get a new plot, make sure we have a backing texture |
| 113 if (nullptr == fTexture) { | 145 if (nullptr == fTexture) { |
| 114 // TODO: Update this to use the cache rather than directly creating a te
xture. | 146 this->createBackingTexture(); |
| 115 GrSurfaceDesc desc; | |
| 116 desc.fFlags = fFlags; | |
| 117 desc.fWidth = fBackingTextureSize.width(); | |
| 118 desc.fHeight = fBackingTextureSize.height(); | |
| 119 desc.fConfig = fPixelConfig; | |
| 120 | |
| 121 fTexture = fTexProvider->createTexture(desc, true, nullptr, 0); | |
| 122 if (nullptr == fTexture) { | 147 if (nullptr == fTexture) { |
| 123 return nullptr; | 148 return nullptr; |
| 124 } | 149 } |
| 125 } | 150 } |
| 126 | 151 |
| 127 // Now look through all allocated plots for one we can share, in MRU order | 152 // Now look through all allocated plots for one we can share, in MRU order |
| 128 // TODO: its seems like traversing from emptiest to fullest would make more
sense | 153 // TODO: its seems like traversing from emptiest to fullest would make more
sense |
| 129 PlotList::Iter plotIter; | 154 PlotList::Iter plotIter; |
| 130 plotIter.init(fPlotList, PlotList::Iter::kHead_IterStart); | 155 plotIter.init(fPlotList, PlotList::Iter::kHead_IterStart); |
| 131 Plot* plot; | 156 Plot* plot; |
| 132 while ((plot = plotIter.get())) { | 157 while ((plot = plotIter.get())) { |
| 133 if (plot->allocateRect(width, height, loc)) { | 158 if (plot->allocateRect(width, height, loc)) { |
| 134 this->makeMRU(plot); | 159 this->makeMRU(plot); |
| 135 // new plot for atlas, put at end of array | 160 // new plot for atlas, put at end of array |
| 136 usage->appendPlot(plot); | 161 usage->appendPlot(plot); |
| 137 return plot; | 162 return plot; |
| 138 } | 163 } |
| 139 plotIter.next(); | 164 plotIter.next(); |
| 140 } | 165 } |
| 141 | 166 |
| 142 // If the above fails, then the current plot list has no room | 167 // If the above fails, then the current plot list has no room |
| 143 return nullptr; | 168 return nullptr; |
| 144 } | 169 } |
| 145 | 170 |
| OLD | NEW |