1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 
17 #include "IndexRangeCache.h"
18 
19 // This is almost literally
20 // external/angle/src/libANGLE/IndexRangeCache.cpp
21 
addRange(GLenum type,size_t offset,size_t count,bool primitiveRestartEnabled,int start,int end)22 void IndexRangeCache::addRange(GLenum type,
23                                size_t offset,
24                                size_t count,
25                                bool primitiveRestartEnabled,
26                                int start,
27                                int end) {
28     IndexRange r;
29     r.start = start;
30     r.end = end;
31     mIndexRangeCache[IndexRangeKey(type, offset, count, primitiveRestartEnabled)] = r;
32 }
33 
findRange(GLenum type,size_t offset,size_t count,bool primitiveRestartEnabled,int * start_out,int * end_out) const34 bool IndexRangeCache::findRange(GLenum type,
35                                 size_t offset,
36                                 size_t count,
37                                 bool primitiveRestartEnabled,
38                                 int* start_out,
39                                 int* end_out) const {
40     IndexRangeMap::const_iterator it =
41         mIndexRangeCache.find(
42                 IndexRangeKey(type, offset, count, primitiveRestartEnabled));
43 
44     if (it != mIndexRangeCache.end()) {
45         if (start_out) *start_out = it->second.start;
46         if (end_out) *end_out = it->second.end;
47         return true;
48     } else {
49         if (start_out) *start_out = 0;
50         if (end_out) *end_out = 0;
51         return false;
52     }
53 }
54 
55 
invalidateRange(size_t offset,size_t size)56 void IndexRangeCache::invalidateRange(size_t offset, size_t size) {
57     size_t invalidateStart = offset;
58     size_t invalidateEnd = offset + size;
59 
60     IndexRangeMap::iterator it =
61         mIndexRangeCache.lower_bound(
62                 IndexRangeKey(GL_UNSIGNED_BYTE,
63                               offset,
64                               size,
65                               false));
66 
67     while (it != mIndexRangeCache.end()) {
68         size_t rangeStart = it->first.offset;
69         size_t rangeEnd =
70             it->first.offset +
71             it->first.count * glSizeof(it->first.type);
72 
73         if (invalidateEnd < rangeStart ||
74             invalidateStart > rangeEnd) {
75             ++it;
76         } else {
77             mIndexRangeCache.erase(it++);
78         }
79     }
80 }
81 
clear()82 void IndexRangeCache::clear() {
83     mIndexRangeCache.clear();
84 }
85