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 |