1f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang//
2f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
3f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang// Use of this source code is governed by a BSD-style license that can be
4f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang// found in the LICENSE file.
5f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang//
6f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
7f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang// IndexRangeCache.cpp: Defines the rx::IndexRangeCache class which stores information about
8f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang// ranges of indices.
9f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
10f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang#include "libGLESv2/renderer/IndexRangeCache.h"
11f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang#include "libGLESv2/formatutils.h"
120b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang
13f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang#include "common/debug.h"
140b7eef7c469bf717f7e1b57c6273f00d88e8b1d9Geoff Lang
15f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang#include <tuple>
16f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
17f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Langnamespace rx
18f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang{
19f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
202b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madilltemplate <class IndexType>
212b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madillstatic RangeUI ComputeTypedRange(const IndexType *indices, GLsizei count)
222b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill{
232b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    unsigned int minIndex = indices[0];
242b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    unsigned int maxIndex = indices[0];
252b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill
262b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    for (GLsizei i = 1; i < count; i++)
272b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    {
282b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        if (minIndex > indices[i]) minIndex = indices[i];
292b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        if (maxIndex < indices[i]) maxIndex = indices[i];
302b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    }
312b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill
322b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    return RangeUI(minIndex, maxIndex);
332b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill}
342b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill
352b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie MadillRangeUI IndexRangeCache::ComputeRange(GLenum type, const GLvoid *indices, GLsizei count)
362b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill{
372b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    switch (type)
382b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    {
392b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill      case GL_UNSIGNED_BYTE:
402b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        return ComputeTypedRange(static_cast<const GLubyte*>(indices), count);
412b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill      case GL_UNSIGNED_INT:
422b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        return ComputeTypedRange(static_cast<const GLuint*>(indices), count);
432b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill      case GL_UNSIGNED_SHORT:
442b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        return ComputeTypedRange(static_cast<const GLushort*>(indices), count);
452b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill      default:
462b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        UNREACHABLE();
472b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill        return RangeUI();
482b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill    }
492b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill}
502b97681b9ac01909bc60f5c6caecef3599b2acf9Jamie Madill
5139b434637523ef3a8f6b3e984979022af8379d10Jamie Madillvoid IndexRangeCache::addRange(GLenum type, unsigned int offset, GLsizei count, const RangeUI &range,
52f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang                               unsigned int streamOffset)
53f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang{
5439b434637523ef3a8f6b3e984979022af8379d10Jamie Madill    mIndexRangeCache[IndexRange(type, offset, count)] = IndexBounds(range, streamOffset);
55f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang}
56f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
57f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Langvoid IndexRangeCache::invalidateRange(unsigned int offset, unsigned int size)
58f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang{
59f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    unsigned int invalidateStart = offset;
60f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    unsigned int invalidateEnd = offset + size;
61f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
62f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    IndexRangeMap::iterator i = mIndexRangeCache.begin();
63f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    while (i != mIndexRangeCache.end())
64f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    {
65f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang        unsigned int rangeStart = i->second.streamOffset;
665d601382b51c29d1670b58c01360416bd929842dGeoff Lang        unsigned int rangeEnd = i->second.streamOffset + (gl::GetTypeInfo(i->first.type).bytes * i->first.count);
67f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
68f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang        if (invalidateEnd < rangeStart || invalidateStart > rangeEnd)
69f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang        {
70f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang            ++i;
71f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang        }
72f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang        else
73f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang        {
74f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang            i = mIndexRangeCache.erase(i);
75f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang        }
76f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    }
77f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang}
78f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
7939b434637523ef3a8f6b3e984979022af8379d10Jamie Madillbool IndexRangeCache::findRange(GLenum type, unsigned int offset, GLsizei count,
8039b434637523ef3a8f6b3e984979022af8379d10Jamie Madill                                RangeUI *outRange, unsigned int *outStreamOffset) const
81f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang{
82f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    IndexRangeMap::const_iterator i = mIndexRangeCache.find(IndexRange(type, offset, count));
83f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    if (i != mIndexRangeCache.end())
84f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    {
8539b434637523ef3a8f6b3e984979022af8379d10Jamie Madill        if (outRange)        *outRange = i->second.range;
86f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang        if (outStreamOffset) *outStreamOffset = i->second.streamOffset;
87f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang        return true;
88f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    }
89f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    else
90f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    {
9139b434637523ef3a8f6b3e984979022af8379d10Jamie Madill        if (outRange)        *outRange = RangeUI(0, 0);
92f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang        if (outStreamOffset) *outStreamOffset = 0;
93f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang        return false;
94f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    }
95f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang}
96f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
97f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Langvoid IndexRangeCache::clear()
98f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang{
99f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    mIndexRangeCache.clear();
100f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang}
101f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
102f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff LangIndexRangeCache::IndexRange::IndexRange()
103f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    : type(GL_NONE), offset(0), count(0)
104f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang{
105f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang}
106f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
107f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff LangIndexRangeCache::IndexRange::IndexRange(GLenum typ, intptr_t off, GLsizei c)
108f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    : type(typ), offset(off), count(c)
109f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang{
110f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang}
111f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
112f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Langbool IndexRangeCache::IndexRange::operator<(const IndexRange& rhs) const
113f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang{
114f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang    return std::make_tuple(type, offset, count) < std::make_tuple(rhs.type, rhs.offset, rhs.count);
115f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang}
116f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
117f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff LangIndexRangeCache::IndexBounds::IndexBounds()
11839b434637523ef3a8f6b3e984979022af8379d10Jamie Madill    : range(0, 0),
11939b434637523ef3a8f6b3e984979022af8379d10Jamie Madill      streamOffset(0)
120f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang{
121f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang}
122f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
12339b434637523ef3a8f6b3e984979022af8379d10Jamie MadillIndexRangeCache::IndexBounds::IndexBounds(const RangeUI &rangeIn, unsigned int offset)
12439b434637523ef3a8f6b3e984979022af8379d10Jamie Madill    : range(rangeIn), streamOffset(offset)
125f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang{
126f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang}
127f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang
128f23eb28c3ad98344e340b97dcad268a7ec362e8bGeoff Lang}
129