Add ImageIndexIterator.
We can use image index iterators to iterate over all images in a
Texture. This allows us to do some operations in TextureD3D rather
than in the typed subclasses and save on some repeated code.
BUG=angle:729
Change-Id: I3ba47b2eebad2cfca313117fd501ff76d5107044
Reviewed-on: https://chromium-review.googlesource.com/219834
Tested-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Brandon Jones <bajones@chromium.org>
diff --git a/src/libGLESv2/ImageIndex.cpp b/src/libGLESv2/ImageIndex.cpp
index 3522b99..684c5bf 100644
--- a/src/libGLESv2/ImageIndex.cpp
+++ b/src/libGLESv2/ImageIndex.cpp
@@ -54,4 +54,90 @@
layerIndex(layerIndexIn)
{}
+ImageIndexIterator ImageIndexIterator::Make2D(GLint minMip, GLint maxMip)
+{
+ return ImageIndexIterator(GL_TEXTURE_2D, rx::Range<GLint>(minMip, maxMip),
+ rx::Range<GLint>(ImageIndex::ENTIRE_LEVEL, ImageIndex::ENTIRE_LEVEL), NULL);
+}
+
+ImageIndexIterator ImageIndexIterator::MakeCube(GLint minMip, GLint maxMip)
+{
+ return ImageIndexIterator(GL_TEXTURE_CUBE_MAP, rx::Range<GLint>(minMip, maxMip), rx::Range<GLint>(0, 6), NULL);
+}
+
+ImageIndexIterator ImageIndexIterator::Make3D(GLint minMip, GLint maxMip,
+ GLint minLayer, GLint maxLayer)
+{
+ return ImageIndexIterator(GL_TEXTURE_3D, rx::Range<GLint>(minMip, maxMip), rx::Range<GLint>(minLayer, maxLayer), NULL);
+}
+
+ImageIndexIterator ImageIndexIterator::Make2DArray(GLint minMip, GLint maxMip,
+ const GLsizei *layerCounts)
+{
+ return ImageIndexIterator(GL_TEXTURE_2D_ARRAY, rx::Range<GLint>(minMip, maxMip),
+ rx::Range<GLint>(0, IMPLEMENTATION_MAX_2D_ARRAY_TEXTURE_LAYERS), layerCounts);
+}
+
+ImageIndexIterator::ImageIndexIterator(GLenum type, const rx::Range<GLint> &mipRange,
+ const rx::Range<GLint> &layerRange, const GLsizei *layerCounts)
+ : mType(type),
+ mMipRange(mipRange),
+ mLayerRange(layerRange),
+ mLayerCounts(layerCounts),
+ mCurrentMip(mipRange.start),
+ mCurrentLayer(layerRange.start)
+{}
+
+GLint ImageIndexIterator::maxLayer() const
+{
+ return (mLayerCounts ? static_cast<GLint>(mLayerCounts[mCurrentMip]) : mLayerRange.end);
+}
+
+ImageIndex ImageIndexIterator::next()
+{
+ ASSERT(hasNext());
+
+ ImageIndex value = current();
+
+ // Iterate layers in the inner loop for now. We can add switchable
+ // layer or mip iteration if we need it.
+
+ if (mCurrentLayer != ImageIndex::ENTIRE_LEVEL)
+ {
+ if (mCurrentLayer < maxLayer()-1)
+ {
+ mCurrentLayer++;
+ }
+ else if (mCurrentMip < mMipRange.end-1)
+ {
+ mCurrentMip++;
+ mCurrentLayer = mLayerRange.start;
+ }
+ }
+ else if (mCurrentMip < mMipRange.end-1)
+ {
+ mCurrentMip++;
+ mCurrentLayer = mLayerRange.start;
+ }
+
+ return value;
+}
+
+ImageIndex ImageIndexIterator::current() const
+{
+ ImageIndex value(mType, mCurrentMip, mCurrentLayer);
+
+ if (mType == GL_TEXTURE_CUBE_MAP)
+ {
+ value.type = TextureCubeMap::layerIndexToTarget(mCurrentLayer);
+ }
+
+ return value;
+}
+
+bool ImageIndexIterator::hasNext() const
+{
+ return (mCurrentMip < mMipRange.end || mCurrentLayer < maxLayer());
+}
+
}
diff --git a/src/libGLESv2/ImageIndex.h b/src/libGLESv2/ImageIndex.h
index 9f2df88..c16c36a 100644
--- a/src/libGLESv2/ImageIndex.h
+++ b/src/libGLESv2/ImageIndex.h
@@ -10,6 +10,7 @@
#define LIBGLESV2_IMAGE_INDEX_H_
#include "angle_gl.h"
+#include "common/mathutil.h"
namespace gl
{
@@ -20,6 +21,7 @@
GLint mipIndex;
GLint layerIndex;
+ ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
ImageIndex(const ImageIndex &other);
ImageIndex &operator=(const ImageIndex &other);
@@ -31,9 +33,33 @@
static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL);
static const GLint ENTIRE_LEVEL = static_cast<GLint>(-1);
+};
+
+class ImageIndexIterator
+{
+ public:
+ static ImageIndexIterator Make2D(GLint minMip, GLint maxMip);
+ static ImageIndexIterator MakeCube(GLint minMip, GLint maxMip);
+ static ImageIndexIterator Make3D(GLint minMip, GLint maxMip, GLint minLayer, GLint maxLayer);
+ static ImageIndexIterator Make2DArray(GLint minMip, GLint maxMip, const GLsizei *layerCounts);
+
+ ImageIndex next();
+ ImageIndex current() const;
+ bool hasNext() const;
private:
- ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
+
+ ImageIndexIterator(GLenum type, const rx::Range<GLint> &mipRange,
+ const rx::Range<GLint> &layerRange, const GLsizei *layerCounts);
+
+ GLint maxLayer() const;
+
+ GLenum mType;
+ rx::Range<GLint> mMipRange;
+ rx::Range<GLint> mLayerRange;
+ const GLsizei *mLayerCounts;
+ GLint mCurrentMip;
+ GLint mCurrentLayer;
};
}
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.cpp b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
index 7bb6947..e522b85 100644
--- a/src/libGLESv2/renderer/d3d/TextureD3D.cpp
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.cpp
@@ -739,6 +739,10 @@
}
}
+gl::ImageIndexIterator TextureD3D_2D::imageIterator() const
+{
+ return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount());
+}
TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer)
: TextureD3D(renderer),
@@ -1245,6 +1249,10 @@
}
}
+gl::ImageIndexIterator TextureD3D_Cube::imageIterator() const
+{
+ return gl::ImageIndexIterator::MakeCube(0, mTexStorage->getLevelCount());
+}
TextureD3D_3D::TextureD3D_3D(Renderer *renderer)
: TextureD3D(renderer),
@@ -1739,6 +1747,11 @@
}
}
+gl::ImageIndexIterator TextureD3D_3D::imageIterator() const
+{
+ return gl::ImageIndexIterator::Make3D(0, mTexStorage->getLevelCount(),
+ gl::ImageIndex::ENTIRE_LEVEL, gl::ImageIndex::ENTIRE_LEVEL);
+}
TextureD3D_2DArray::TextureD3D_2DArray(Renderer *renderer)
: TextureD3D(renderer),
@@ -2257,4 +2270,9 @@
}
}
+gl::ImageIndexIterator TextureD3D_2DArray::imageIterator() const
+{
+ return gl::ImageIndexIterator::Make2DArray(0, mTexStorage->getLevelCount(), mLayerCounts);
+}
+
}
diff --git a/src/libGLESv2/renderer/d3d/TextureD3D.h b/src/libGLESv2/renderer/d3d/TextureD3D.h
index 41c7318..a60d57a 100644
--- a/src/libGLESv2/renderer/d3d/TextureD3D.h
+++ b/src/libGLESv2/renderer/d3d/TextureD3D.h
@@ -51,6 +51,9 @@
virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index) = 0;
+ // Returns an iterator over all "Images" for this particular Texture.
+ virtual gl::ImageIndexIterator imageIterator() const = 0;
+
protected:
void setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image);
bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
@@ -115,6 +118,8 @@
virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D);
@@ -172,6 +177,8 @@
virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube);
@@ -229,6 +236,8 @@
virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_3D);
@@ -285,6 +294,8 @@
virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
+ virtual gl::ImageIndexIterator imageIterator() const;
+
private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2DArray);