blob: 78dfb2f08c2d2807d4f70a76482839047d305279 [file] [log] [blame]
Geoff Langf23eb282013-07-22 10:52:19 -04001//
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
Geoff Lang2b5420c2014-11-19 14:20:15 -050010#include "libANGLE/renderer/IndexRangeCache.h"
11#include "libANGLE/formatutils.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040012
Geoff Langf23eb282013-07-22 10:52:19 -040013#include "common/debug.h"
Geoff Lang0b7eef72014-06-12 14:10:47 -040014
Geoff Langf23eb282013-07-22 10:52:19 -040015#include <tuple>
16
17namespace rx
18{
19
Jamie Madill2b976812014-08-25 15:47:49 -040020template <class IndexType>
21static 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
35RangeUI 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
Jamie Madill39b43462014-08-18 16:39:50 -040051void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range,
Geoff Langf23eb282013-07-22 10:52:19 -040052 unsigned int streamOffset)
53{
Jamie Madill39b43462014-08-18 16:39:50 -040054 mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(range, streamOffset);
Geoff Langf23eb282013-07-22 10:52:19 -040055}
56
57void 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;
Geoff Lang5d601382014-07-22 15:14:06 -040066 unsigned int rangeEnd = i->second.streamOffset + (gl::GetTypeInfo(i->first.type).bytes * i->first.count);
Geoff Langf23eb282013-07-22 10:52:19 -040067
68 if (invalidateEnd < rangeStart || invalidateStart > rangeEnd)
69 {
70 ++i;
71 }
72 else
73 {
74 i = mIndexRangeCache.erase(i);
75 }
76 }
77}
78
Jamie Madill39b43462014-08-18 16:39:50 -040079bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count,
80 RangeUI *outRange, unsigned int *outStreamOffset) const
Geoff Langf23eb282013-07-22 10:52:19 -040081{
82 IndexRangeMap::const_iterator i = mIndexRangeCache.find(IndexRange(type, offset, count));
83 if (i != mIndexRangeCache.end())
84 {
Jamie Madill39b43462014-08-18 16:39:50 -040085 if (outRange) *outRange = i->second.range;
Geoff Langf23eb282013-07-22 10:52:19 -040086 if (outStreamOffset) *outStreamOffset = i->second.streamOffset;
87 return true;
88 }
89 else
90 {
Jamie Madill39b43462014-08-18 16:39:50 -040091 if (outRange) *outRange = RangeUI(0, 0);
Geoff Langf23eb282013-07-22 10:52:19 -040092 if (outStreamOffset) *outStreamOffset = 0;
93 return false;
94 }
95}
96
97void IndexRangeCache::clear()
98{
99 mIndexRangeCache.clear();
100}
101
102IndexRangeCache::IndexRange::IndexRange()
103 : type(GL_NONE), offset(0), count(0)
104{
105}
106
107IndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c)
108 : type(typ), offset(off), count(c)
109{
110}
111
112bool 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
117IndexRangeCache::IndexBounds::IndexBounds()
Jamie Madill39b43462014-08-18 16:39:50 -0400118 : range(0, 0),
119 streamOffset(0)
Geoff Langf23eb282013-07-22 10:52:19 -0400120{
121}
122
Jamie Madill39b43462014-08-18 16:39:50 -0400123IndexRangeCache::IndexBounds::IndexBounds(const RangeUI &rangeIn, unsigned int offset)
124 : range(rangeIn), streamOffset(offset)
Geoff Langf23eb282013-07-22 10:52:19 -0400125{
126}
127
128}