OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #ifndef GrBatchAtlas_DEFINED | 8 #ifndef GrBatchAtlas_DEFINED |
9 #define GrBatchAtlas_DEFINED | 9 #define GrBatchAtlas_DEFINED |
10 | 10 |
(...skipping 22 matching lines...) Expand all Loading... |
33 // the eviction | 33 // the eviction |
34 typedef void (*EvictionFunc)(GrBatchAtlas::AtlasID, void*); | 34 typedef void (*EvictionFunc)(GrBatchAtlas::AtlasID, void*); |
35 | 35 |
36 GrBatchAtlas(GrTexture*, int numPlotsX, int numPlotsY); | 36 GrBatchAtlas(GrTexture*, int numPlotsX, int numPlotsY); |
37 ~GrBatchAtlas(); | 37 ~GrBatchAtlas(); |
38 | 38 |
39 // Adds a width x height subimage to the atlas. Upon success it returns | 39 // Adds a width x height subimage to the atlas. Upon success it returns |
40 // the containing GrPlot and absolute location in the backing texture. | 40 // the containing GrPlot and absolute location in the backing texture. |
41 // NULL is returned if the subimage cannot fit in the atlas. | 41 // NULL is returned if the subimage cannot fit in the atlas. |
42 // If provided, the image data will be written to the CPU-side backing bitma
p. | 42 // If provided, the image data will be written to the CPU-side backing bitma
p. |
| 43 // NOTE: If the client intends to refer to the atlas, they should immediatel
y call 'setUseToken' |
| 44 // with the currentToken from the batch target, otherwise the next call to a
ddToAtlas might |
| 45 // cause an eviction |
43 bool addToAtlas(AtlasID*, GrBatchTarget*, int width, int height, const void*
image, | 46 bool addToAtlas(AtlasID*, GrBatchTarget*, int width, int height, const void*
image, |
44 SkIPoint16* loc); | 47 SkIPoint16* loc); |
45 | 48 |
46 GrTexture* getTexture() const { return fTexture; } | 49 GrTexture* getTexture() const { return fTexture; } |
47 | 50 |
48 uint64_t atlasGeneration() const { return fAtlasGeneration; } | 51 uint64_t atlasGeneration() const { return fAtlasGeneration; } |
49 bool hasID(AtlasID id); | 52 bool hasID(AtlasID id); |
50 void setLastRefToken(AtlasID id, BatchToken batchToken); | 53 |
| 54 // To ensure the atlas does not evict a given entry, the client must set the
last use token |
| 55 void setLastUseToken(AtlasID id, BatchToken batchToken); |
51 void registerEvictionCallback(EvictionFunc func, void* userData) { | 56 void registerEvictionCallback(EvictionFunc func, void* userData) { |
52 EvictionData* data = fEvictionCallbacks.append(); | 57 EvictionData* data = fEvictionCallbacks.append(); |
53 data->fFunc = func; | 58 data->fFunc = func; |
54 data->fData = userData; | 59 data->fData = userData; |
55 } | 60 } |
56 | 61 |
| 62 /* |
| 63 * A class which can be handed back to GrBatchAtlas for updating in bulk las
t use tokens. The |
| 64 * current max number of plots the GrBatchAtlas can handle is 32, if in the
future this is |
| 65 * insufficient then we can move to a 64 bit int |
| 66 */ |
| 67 class BulkUseTokenUpdater { |
| 68 public: |
| 69 BulkUseTokenUpdater() : fPlotAlreadyUpdated(0), fCount(0), fAllocated(kM
inItems) {} |
| 70 void add(AtlasID id) { |
| 71 int index = GrBatchAtlas::GetIndexFromID(id); |
| 72 if (!this->find(index)) { |
| 73 this->set(index); |
| 74 } |
| 75 } |
| 76 |
| 77 void reset() { |
| 78 fPlotsToUpdate.reset(kMinItems); |
| 79 fAllocated = kMinItems; |
| 80 fCount = 0; |
| 81 fPlotAlreadyUpdated = 0; |
| 82 } |
| 83 |
| 84 private: |
| 85 bool find(int index) const { |
| 86 SkASSERT(index < kMaxPlots); |
| 87 return (fPlotAlreadyUpdated >> index) & 1; |
| 88 } |
| 89 |
| 90 void set(int index) { |
| 91 SkASSERT(!this->find(index)); |
| 92 fPlotAlreadyUpdated = fPlotAlreadyUpdated | (1 << index); |
| 93 if (fCount < fAllocated) { |
| 94 fPlotsToUpdate[fCount++] = index; |
| 95 } else { |
| 96 // This case will almost never happen |
| 97 fAllocated = fCount << 1; |
| 98 fPlotsToUpdate.realloc(fAllocated); |
| 99 fPlotsToUpdate[fCount++] = index; |
| 100 } |
| 101 } |
| 102 |
| 103 static const int kMinItems = 4; |
| 104 static const int kMaxPlots = 32; |
| 105 uint32_t fPlotAlreadyUpdated; |
| 106 SkAutoSTMalloc<kMinItems, int> fPlotsToUpdate; |
| 107 int fCount; |
| 108 int fAllocated; |
| 109 |
| 110 friend class GrBatchAtlas; |
| 111 }; |
| 112 |
| 113 void setLastUseTokenBulk(const BulkUseTokenUpdater& reffer, BatchToken); |
| 114 |
57 private: | 115 private: |
58 int getIndexFromID(AtlasID id) { | 116 static int GetIndexFromID(AtlasID id) { |
59 return id & 0xffff; | 117 return id & 0xffff; |
60 } | 118 } |
61 | 119 |
62 int getGenerationFromID(AtlasID id) { | 120 static int GetGenerationFromID(AtlasID id) { |
63 return (id >> 16) & 0xffff; | 121 return (id >> 16) & 0xffff; |
64 } | 122 } |
65 | 123 |
66 inline void updatePlot(GrBatchTarget*, AtlasID*, BatchPlot*); | 124 inline void updatePlot(GrBatchTarget*, AtlasID*, BatchPlot*); |
67 | 125 |
68 inline void makeMRU(BatchPlot* plot); | 126 inline void makeMRU(BatchPlot* plot); |
69 | 127 |
70 inline void processEviction(AtlasID); | 128 inline void processEviction(AtlasID); |
71 | 129 |
72 GrTexture* fTexture; | 130 GrTexture* fTexture; |
(...skipping 10 matching lines...) Expand all Loading... |
83 }; | 141 }; |
84 | 142 |
85 SkTDArray<EvictionData> fEvictionCallbacks; | 143 SkTDArray<EvictionData> fEvictionCallbacks; |
86 // allocated array of GrBatchPlots | 144 // allocated array of GrBatchPlots |
87 SkAutoTUnref<BatchPlot>* fPlotArray; | 145 SkAutoTUnref<BatchPlot>* fPlotArray; |
88 // LRU list of GrPlots (MRU at head - LRU at tail) | 146 // LRU list of GrPlots (MRU at head - LRU at tail) |
89 GrBatchPlotList fPlotList; | 147 GrBatchPlotList fPlotList; |
90 }; | 148 }; |
91 | 149 |
92 #endif | 150 #endif |
OLD | NEW |