| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2014 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 SkOffsetTable_DEFINED | |
| 9 #define SkOffsetTable_DEFINED | |
| 10 | |
| 11 #include "SkRefCnt.h" | |
| 12 #include "SkTDArray.h" | |
| 13 | |
| 14 // A 2D table of skp offsets. Each row is indexed by an int. This is used | |
| 15 // to store the command offsets that reference a particular bitmap using | |
| 16 // the bitmap's index in the bitmap heap as the 'id' here. It has to be | |
| 17 // ref-countable so SkPicturePlayback can take ownership of it. | |
| 18 // Note that this class assumes that the ids are densely packed. | |
| 19 | |
| 20 // TODO: This needs to be sped up. We could replace the offset table with | |
| 21 // a hash table. | |
| 22 class SkOffsetTable : public SkRefCnt { | |
| 23 public: | |
| 24 SkOffsetTable() {} | |
| 25 ~SkOffsetTable() { | |
| 26 fOffsetArrays.deleteAll(); | |
| 27 } | |
| 28 | |
| 29 // Record that this 'id' is used by the command starting at this 'offset'. | |
| 30 // Offsets for a given 'id' should always be added in increasing order. | |
| 31 void add(int id, size_t offset) { | |
| 32 if (id >= fOffsetArrays.count()) { | |
| 33 int oldCount = fOffsetArrays.count(); | |
| 34 fOffsetArrays.setCount(id+1); | |
| 35 for (int i = oldCount; i <= id; ++i) { | |
| 36 fOffsetArrays[i] = NULL; | |
| 37 } | |
| 38 } | |
| 39 | |
| 40 if (NULL == fOffsetArrays[id]) { | |
| 41 fOffsetArrays[id] = SkNEW(OffsetArray); | |
| 42 } | |
| 43 fOffsetArrays[id]->add(offset); | |
| 44 } | |
| 45 | |
| 46 int numIDs() const { | |
| 47 return fOffsetArrays.count(); | |
| 48 } | |
| 49 | |
| 50 // Do the offsets of any commands referencing this ID fall in the | |
| 51 // range [min, max] (both inclusive) | |
| 52 bool overlap(int id, size_t min, size_t max) { | |
| 53 SkASSERT(id < fOffsetArrays.count()); | |
| 54 | |
| 55 if (NULL == fOffsetArrays[id]) { | |
| 56 return false; | |
| 57 } | |
| 58 | |
| 59 // If this id has an offset array it should have at least one use | |
| 60 SkASSERT(fOffsetArrays[id]->count() > 0); | |
| 61 if (max < fOffsetArrays[id]->min() || min > fOffsetArrays[id]->max()) { | |
| 62 return false; | |
| 63 } | |
| 64 | |
| 65 return true; | |
| 66 } | |
| 67 | |
| 68 bool includes(int id, size_t offset) { | |
| 69 SkASSERT(id < fOffsetArrays.count()); | |
| 70 | |
| 71 OffsetArray* array = fOffsetArrays[id]; | |
| 72 | |
| 73 for (int i = 0; i < array->fOffsets.count(); ++i) { | |
| 74 if (array->fOffsets[i] == offset) { | |
| 75 return true; | |
| 76 } else if (array->fOffsets[i] > offset) { | |
| 77 return false; | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 // Calls to 'includes' should be gaurded by an overlap() call, so we | |
| 82 // should always find something. | |
| 83 SkASSERT(0); | |
| 84 return false; | |
| 85 } | |
| 86 | |
| 87 protected: | |
| 88 class OffsetArray { | |
| 89 public: | |
| 90 void add(size_t offset) { | |
| 91 SkASSERT(fOffsets.count() == 0 || offset > this->max()); | |
| 92 *fOffsets.append() = offset; | |
| 93 } | |
| 94 size_t min() const { | |
| 95 SkASSERT(fOffsets.count() > 0); | |
| 96 return fOffsets[0]; | |
| 97 } | |
| 98 size_t max() const { | |
| 99 SkASSERT(fOffsets.count() > 0); | |
| 100 return fOffsets[fOffsets.count()-1]; | |
| 101 } | |
| 102 int count() const { | |
| 103 return fOffsets.count(); | |
| 104 } | |
| 105 | |
| 106 SkTDArray<size_t> fOffsets; | |
| 107 }; | |
| 108 | |
| 109 SkTDArray<OffsetArray*> fOffsetArrays; | |
| 110 | |
| 111 private: | |
| 112 typedef SkRefCnt INHERITED; | |
| 113 }; | |
| 114 | |
| 115 #endif | |
| OLD | NEW |