Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / libGLESv2 / renderer / IndexRangeCache.cpp
1 //
2 // Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // IndexRangeCache.cpp: Defines the rx::IndexRangeCache class which stores information about
8 // ranges of indices.
9
10 #include "libGLESv2/renderer/IndexRangeCache.h"
11 #include "libGLESv2/formatutils.h"
12
13 #include "common/debug.h"
14
15 #include <tuple>
16
17 namespace rx
18 {
19
20 template <class IndexType>
21 static RangeUI ComputeTypedRange(const IndexType *indices, GLsizei count)
22 {
23     unsigned int minIndex = indices[0];
24     unsigned int maxIndex = indices[0];
25
26     for (GLsizei i = 1; i < count; i++)
27     {
28         if (minIndex > indices[i]) minIndex = indices[i];
29         if (maxIndex < indices[i]) maxIndex = indices[i];
30     }
31
32     return RangeUI(minIndex, maxIndex);
33 }
34
35 RangeUI IndexRangeCache::ComputeRange(GLenum type, const GLvoid *indices, GLsizei count)
36 {
37     switch (type)
38     {
39       case GL_UNSIGNED_BYTE:
40         return ComputeTypedRange(static_cast<const GLubyte*>(indices), count);
41       case GL_UNSIGNED_INT:
42         return ComputeTypedRange(static_cast<const GLuint*>(indices), count);
43       case GL_UNSIGNED_SHORT:
44         return ComputeTypedRange(static_cast<const GLushort*>(indices), count);
45       default:
46         UNREACHABLE();
47         return RangeUI();
48     }
49 }
50
51 void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range,
52                                unsigned int streamOffset)
53 {
54     mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(range, streamOffset);
55 }
56
57 void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size)
58 {
59     unsigned int invalidateStart = offset;
60     unsigned int invalidateEnd = offset + size;
61
62     IndexRangeMap::iterator i = mIndexRangeCache.begin();
63     while (i != mIndexRangeCache.end())
64     {
65         unsigned int rangeStart = i->second.streamOffset;
66         unsigned int rangeEnd = i->second.streamOffset + (gl::GetTypeInfo(i->first.type).bytes * i->first.count);
67
68         if (invalidateEnd < rangeStart || invalidateStart > rangeEnd)
69         {
70             ++i;
71         }
72         else
73         {
74             i = mIndexRangeCache.erase(i);
75         }
76     }
77 }
78
79 bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count,
80                                 RangeUI *outRange, unsigned int *outStreamOffset) const
81 {
82     IndexRangeMap::const_iterator i = mIndexRangeCache.find(IndexRange(type, offset, count));
83     if (i != mIndexRangeCache.end())
84     {
85         if (outRange)        *outRange = i->second.range;
86         if (outStreamOffset) *outStreamOffset = i->second.streamOffset;
87         return true;
88     }
89     else
90     {
91         if (outRange)        *outRange = RangeUI(0, 0);
92         if (outStreamOffset) *outStreamOffset = 0;
93         return false;
94     }
95 }
96
97 void IndexRangeCache::clear()
98 {
99     mIndexRangeCache.clear();
100 }
101
102 IndexRangeCache::IndexRange::IndexRange()
103     : type(GL_NONE), offset(0), count(0)
104 {
105 }
106
107 IndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c)
108     : type(typ), offset(off), count(c)
109 {
110 }
111
112 bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const
113 {
114     return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count);
115 }
116
117 IndexRangeCache::IndexBounds::IndexBounds()
118     : range(0, 0),
119       streamOffset(0)
120 {
121 }
122
123 IndexRangeCache::IndexBounds::IndexBounds(const RangeUI &rangeIn, unsigned int offset)
124     : range(rangeIn), streamOffset(offset)
125 {
126 }
127
128 }