blob: 697c8d18eb82774d1fad01d2a943a5fc6f80501c [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 -040015namespace rx
16{
17
Jamie Madill2b976812014-08-25 15:47:49 -040018template <class IndexType>
19static RangeUI ComputeTypedRange(const IndexType *indices, GLsizei count)
20{
21 unsigned int minIndex = indices[0];
22 unsigned int maxIndex = indices[0];
23
24 for (GLsizei i = 1; i < count; i++)
25 {
26 if (minIndex > indices[i]) minIndex = indices[i];
27 if (maxIndex < indices[i]) maxIndex = indices[i];
28 }
29
30 return RangeUI(minIndex, maxIndex);
31}
32
33RangeUI IndexRangeCache::ComputeRange(GLenum type, const GLvoid *indices, GLsizei count)
34{
35 switch (type)
36 {
37 case GL_UNSIGNED_BYTE:
38 return ComputeTypedRange(static_cast<const GLubyte*>(indices), count);
39 case GL_UNSIGNED_INT:
40 return ComputeTypedRange(static_cast<const GLuint*>(indices), count);
41 case GL_UNSIGNED_SHORT:
42 return ComputeTypedRange(static_cast<const GLushort*>(indices), count);
43 default:
44 UNREACHABLE();
45 return RangeUI();
46 }
47}
48
Jamie Madill39b43462014-08-18 16:39:50 -040049void IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range,
Geoff Langf23eb282013-07-22 10:52:19 -040050 unsigned int streamOffset)
51{
Jamie Madill39b43462014-08-18 16:39:50 -040052 mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(range, streamOffset);
Geoff Langf23eb282013-07-22 10:52:19 -040053}
54
55void IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size)
56{
57 unsigned int invalidateStart = offset;
58 unsigned int invalidateEnd = offset + size;
59
60 IndexRangeMap::iterator i = mIndexRangeCache.begin();
61 while (i != mIndexRangeCache.end())
62 {
63 unsigned int rangeStart = i->second.streamOffset;
Geoff Lang5d601382014-07-22 15:14:06 -040064 unsigned int rangeEnd = i->second.streamOffset + (gl::GetTypeInfo(i->first.type).bytes * i->first.count);
Geoff Langf23eb282013-07-22 10:52:19 -040065
66 if (invalidateEnd < rangeStart || invalidateStart > rangeEnd)
67 {
68 ++i;
69 }
70 else
71 {
Jamie Madill2bd2a422015-01-05 13:26:05 -050072 mIndexRangeCache.erase(i++);
Geoff Langf23eb282013-07-22 10:52:19 -040073 }
74 }
75}
76
Jamie Madill39b43462014-08-18 16:39:50 -040077bool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count,
78 RangeUI *outRange, unsigned int *outStreamOffset) const
Geoff Langf23eb282013-07-22 10:52:19 -040079{
80 IndexRangeMap::const_iterator i = mIndexRangeCache.find(IndexRange(type, offset, count));
81 if (i != mIndexRangeCache.end())
82 {
Jamie Madill39b43462014-08-18 16:39:50 -040083 if (outRange) *outRange = i->second.range;
Geoff Langf23eb282013-07-22 10:52:19 -040084 if (outStreamOffset) *outStreamOffset = i->second.streamOffset;
85 return true;
86 }
87 else
88 {
Jamie Madill39b43462014-08-18 16:39:50 -040089 if (outRange) *outRange = RangeUI(0, 0);
Geoff Langf23eb282013-07-22 10:52:19 -040090 if (outStreamOffset) *outStreamOffset = 0;
91 return false;
92 }
93}
94
95void IndexRangeCache::clear()
96{
97 mIndexRangeCache.clear();
98}
99
100IndexRangeCache::IndexRange::IndexRange()
101 : type(GL_NONE), offset(0), count(0)
102{
103}
104
105IndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c)
106 : type(typ), offset(off), count(c)
107{
108}
109
110bool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const
111{
Jamie Madill3897cd12015-01-05 13:15:15 -0500112 if (type != rhs.type) return type < rhs.type;
113 if (offset != rhs.offset) return offset < rhs.offset;
114 return count < rhs.count;
Geoff Langf23eb282013-07-22 10:52:19 -0400115}
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}