Commit ef4ac5b1 by Jamie Madill

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/219834Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarBrandon Jones <bajones@chromium.org>
parent e611b064
...@@ -54,4 +54,90 @@ ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn) ...@@ -54,4 +54,90 @@ ImageIndex::ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn)
layerIndex(layerIndexIn) 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());
}
} }
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#define LIBGLESV2_IMAGE_INDEX_H_ #define LIBGLESV2_IMAGE_INDEX_H_
#include "angle_gl.h" #include "angle_gl.h"
#include "common/mathutil.h"
namespace gl namespace gl
{ {
...@@ -20,6 +21,7 @@ struct ImageIndex ...@@ -20,6 +21,7 @@ struct ImageIndex
GLint mipIndex; GLint mipIndex;
GLint layerIndex; GLint layerIndex;
ImageIndex(GLenum typeIn, GLint mipIndexIn, GLint layerIndexIn);
ImageIndex(const ImageIndex &other); ImageIndex(const ImageIndex &other);
ImageIndex &operator=(const ImageIndex &other); ImageIndex &operator=(const ImageIndex &other);
...@@ -31,9 +33,33 @@ struct ImageIndex ...@@ -31,9 +33,33 @@ struct ImageIndex
static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL); static ImageIndex Make3D(GLint mipIndex, GLint layerIndex = ENTIRE_LEVEL);
static const GLint ENTIRE_LEVEL = static_cast<GLint>(-1); 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: 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;
}; };
} }
......
...@@ -739,6 +739,10 @@ void TextureD3D_2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsize ...@@ -739,6 +739,10 @@ void TextureD3D_2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsize
} }
} }
gl::ImageIndexIterator TextureD3D_2D::imageIterator() const
{
return gl::ImageIndexIterator::Make2D(0, mTexStorage->getLevelCount());
}
TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer) TextureD3D_Cube::TextureD3D_Cube(Renderer *renderer)
: TextureD3D(renderer), : TextureD3D(renderer),
...@@ -1245,6 +1249,10 @@ void TextureD3D_Cube::commitRect(int faceIndex, GLint level, GLint xoffset, GLin ...@@ -1245,6 +1249,10 @@ void TextureD3D_Cube::commitRect(int faceIndex, GLint level, GLint xoffset, GLin
} }
} }
gl::ImageIndexIterator TextureD3D_Cube::imageIterator() const
{
return gl::ImageIndexIterator::MakeCube(0, mTexStorage->getLevelCount());
}
TextureD3D_3D::TextureD3D_3D(Renderer *renderer) TextureD3D_3D::TextureD3D_3D(Renderer *renderer)
: TextureD3D(renderer), : TextureD3D(renderer),
...@@ -1739,6 +1747,11 @@ void TextureD3D_3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint ...@@ -1739,6 +1747,11 @@ void TextureD3D_3D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLint
} }
} }
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_2DArray::TextureD3D_2DArray(Renderer *renderer)
: TextureD3D(renderer), : TextureD3D(renderer),
...@@ -2257,4 +2270,9 @@ void TextureD3D_2DArray::commitRect(GLint level, GLint xoffset, GLint yoffset, G ...@@ -2257,4 +2270,9 @@ void TextureD3D_2DArray::commitRect(GLint level, GLint xoffset, GLint yoffset, G
} }
} }
gl::ImageIndexIterator TextureD3D_2DArray::imageIterator() const
{
return gl::ImageIndexIterator::Make2DArray(0, mTexStorage->getLevelCount(), mLayerCounts);
}
} }
...@@ -51,6 +51,9 @@ class TextureD3D : public TextureImpl ...@@ -51,6 +51,9 @@ class TextureD3D : public TextureImpl
virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0; virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index) = 0;
virtual unsigned int getRenderTargetSerial(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: protected:
void setImage(const gl::PixelUnpackState &unpack, GLenum type, const void *pixels, Image *image); 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, bool subImage(GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth,
...@@ -115,6 +118,8 @@ class TextureD3D_2D : public TextureD3D ...@@ -115,6 +118,8 @@ class TextureD3D_2D : public TextureD3D
virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
virtual gl::ImageIndexIterator imageIterator() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D); DISALLOW_COPY_AND_ASSIGN(TextureD3D_2D);
...@@ -172,6 +177,8 @@ class TextureD3D_Cube : public TextureD3D ...@@ -172,6 +177,8 @@ class TextureD3D_Cube : public TextureD3D
virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
virtual gl::ImageIndexIterator imageIterator() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube); DISALLOW_COPY_AND_ASSIGN(TextureD3D_Cube);
...@@ -229,6 +236,8 @@ class TextureD3D_3D : public TextureD3D ...@@ -229,6 +236,8 @@ class TextureD3D_3D : public TextureD3D
virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
virtual gl::ImageIndexIterator imageIterator() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_3D); DISALLOW_COPY_AND_ASSIGN(TextureD3D_3D);
...@@ -285,6 +294,8 @@ class TextureD3D_2DArray : public TextureD3D ...@@ -285,6 +294,8 @@ class TextureD3D_2DArray : public TextureD3D
virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index); virtual RenderTarget *getRenderTarget(const gl::ImageIndex &index);
virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index); virtual unsigned int getRenderTargetSerial(const gl::ImageIndex &index);
virtual gl::ImageIndexIterator imageIterator() const;
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureD3D_2DArray); DISALLOW_COPY_AND_ASSIGN(TextureD3D_2DArray);
......
//
// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "libGLESv2/ImageIndex.h"
#include "libGLESv2/Texture.h"
using namespace gl;
namespace
{
static const GLint minMip = 0;
static const GLint maxMip = 4;
static const GLint minLayer = 1;
static const GLint maxLayer = 3;
TEST(ImageIndexTest, Iterator2D)
{
ImageIndexIterator iter = ImageIndexIterator::Make2D(minMip, maxMip);
for (GLint mip = minMip; mip < maxMip; mip++)
{
EXPECT_TRUE(iter.hasNext());
ImageIndex current = iter.current();
ImageIndex nextIndex = iter.next();
EXPECT_EQ(GL_TEXTURE_2D, nextIndex.type);
EXPECT_EQ(mip, nextIndex.mipIndex);
EXPECT_FALSE(nextIndex.hasLayer());
// Also test current
EXPECT_EQ(current.type, nextIndex.type);
EXPECT_EQ(current.mipIndex, nextIndex.mipIndex);
EXPECT_EQ(current.layerIndex, nextIndex.layerIndex);
}
}
TEST(ImageIndexTest, IteratorCube)
{
testing::InSequence seq;
ImageIndexIterator iter = ImageIndexIterator::MakeCube(0, 4);
for (GLint mip = minMip; mip < maxMip; mip++)
{
for (GLint layer = 0; layer < 6; layer++)
{
EXPECT_TRUE(iter.hasNext());
ImageIndex nextIndex = iter.next();
GLenum cubeTarget = TextureCubeMap::layerIndexToTarget(layer);
EXPECT_EQ(cubeTarget, nextIndex.type);
EXPECT_EQ(mip, nextIndex.mipIndex);
EXPECT_EQ(layer, nextIndex.layerIndex);
EXPECT_TRUE(nextIndex.hasLayer());
}
}
}
TEST(ImageIndexTest, Iterator3D)
{
testing::InSequence seq;
ImageIndexIterator iter = ImageIndexIterator::Make3D(minMip, maxMip, minLayer, maxLayer);
for (GLint mip = minMip; mip < maxMip; mip++)
{
for (GLint layer = minLayer; layer < maxLayer; layer++)
{
EXPECT_TRUE(iter.hasNext());
ImageIndex nextIndex = iter.next();
EXPECT_EQ(GL_TEXTURE_3D, nextIndex.type);
EXPECT_EQ(mip, nextIndex.mipIndex);
EXPECT_EQ(layer, nextIndex.layerIndex);
EXPECT_TRUE(nextIndex.hasLayer());
}
}
}
TEST(ImageIndexTest, Iterator2DArray)
{
testing::InSequence seq;
GLsizei layerCounts[] = { 1, 3, 5 };
ImageIndexIterator iter = ImageIndexIterator::Make2DArray(minMip, maxMip, layerCounts);
for (GLint mip = minMip; mip < maxMip; mip++)
{
for (GLint layer = 0; layer < layerCounts[mip]; layer++)
{
EXPECT_TRUE(iter.hasNext());
ImageIndex nextIndex = iter.next();
EXPECT_EQ(GL_TEXTURE_2D_ARRAY, nextIndex.type);
EXPECT_EQ(mip, nextIndex.mipIndex);
EXPECT_EQ(layer, nextIndex.layerIndex);
EXPECT_TRUE(nextIndex.hasLayer());
}
}
}
} // namespace
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment