Home | History | Annotate | Download | only in renderer
      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 }
    129