Commit e547aac7 by Lingfeng Yang Committed by Commit Bot

GLES1: gl(Push|Pop)Matrix

BUG=angleproject:2306 Change-Id: I96498aebbbc62ebd53e5320db17ef6a54d20d2dc Reviewed-on: https://chromium-review.googlesource.com/998308 Commit-Queue: Lingfeng Yang <lfy@google.com> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 8957e832
......@@ -589,6 +589,7 @@ struct Caps
GLuint maxMultitextureUnits;
GLuint maxClipPlanes;
GLuint maxLights;
static constexpr int GlobalMatrixStackDepth = 16;
GLuint maxModelviewMatrixStackDepth;
GLuint maxProjectionMatrixStackDepth;
GLuint maxTextureMatrixStackDepth;
......
......@@ -1647,6 +1647,15 @@ void Context::getIntegervImpl(GLenum pname, GLint *params)
case GL_MAX_TEXTURE_UNITS:
*params = mCaps.maxMultitextureUnits;
break;
case GL_MAX_MODELVIEW_STACK_DEPTH:
*params = mCaps.maxModelviewMatrixStackDepth;
break;
case GL_MAX_PROJECTION_STACK_DEPTH:
*params = mCaps.maxProjectionMatrixStackDepth;
break;
case GL_MAX_TEXTURE_STACK_DEPTH:
*params = mCaps.maxTextureMatrixStackDepth;
break;
default:
handleError(mGLState.getIntegerv(this, pname, params));
break;
......@@ -2860,9 +2869,9 @@ void Context::initCaps(const egl::DisplayExtensions &displayExtensions, bool rob
mCaps.maxMultitextureUnits = 4;
mCaps.maxClipPlanes = 6;
mCaps.maxLights = 8;
mCaps.maxModelviewMatrixStackDepth = 16;
mCaps.maxProjectionMatrixStackDepth = 16;
mCaps.maxTextureMatrixStackDepth = 16;
mCaps.maxModelviewMatrixStackDepth = Caps::GlobalMatrixStackDepth;
mCaps.maxProjectionMatrixStackDepth = Caps::GlobalMatrixStackDepth;
mCaps.maxTextureMatrixStackDepth = Caps::GlobalMatrixStackDepth;
}
mExtensions = mImplementation->getNativeExtensions();
......@@ -6845,6 +6854,12 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
switch (pname)
{
case GL_ALPHA_TEST_FUNC:
case GL_CLIENT_ACTIVE_TEXTURE:
case GL_MATRIX_MODE:
case GL_MAX_TEXTURE_UNITS:
case GL_MAX_MODELVIEW_STACK_DEPTH:
case GL_MAX_PROJECTION_STACK_DEPTH:
case GL_MAX_TEXTURE_STACK_DEPTH:
*type = GL_INT;
*numParams = 1;
return true;
......@@ -6852,15 +6867,8 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
*type = GL_FLOAT;
*numParams = 1;
return true;
case GL_MAX_TEXTURE_UNITS:
*type = GL_INT;
*numParams = 1;
return true;
case GL_CLIENT_ACTIVE_TEXTURE:
*type = GL_INT;
*numParams = 1;
return true;
case GL_CURRENT_COLOR:
case GL_CURRENT_TEXTURE_COORDS:
*type = GL_FLOAT;
*numParams = 4;
return true;
......@@ -6868,14 +6876,6 @@ bool Context::getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *nu
*type = GL_FLOAT;
*numParams = 3;
return true;
case GL_CURRENT_TEXTURE_COORDS:
*type = GL_FLOAT;
*numParams = 4;
return true;
case GL_MATRIX_MODE:
*type = GL_INT;
*numParams = 1;
return true;
}
}
......
......@@ -359,12 +359,12 @@ void Context::polygonOffsetx(GLfixed factor, GLfixed units)
void Context::popMatrix()
{
UNIMPLEMENTED();
mGLState.gles1().popMatrix();
}
void Context::pushMatrix()
{
UNIMPLEMENTED();
mGLState.gles1().pushMatrix();
}
void Context::rotatef(float angle, float x, float y, float z)
......
......@@ -128,6 +128,8 @@ ERRMSG(InvalidVertexAttrSize, "Vertex attribute size must be 1, 2, 3, or 4.");
ERRMSG(InvalidWidth, "Invalid width.");
ERRMSG(InvalidWrapModeTexture, "Invalid wrap mode for texture type.");
ERRMSG(LevelNotZero, "Texture level must be zero.");
ERRMSG(MatrixStackOverflow, "Current matrix stack is full.");
ERRMSG(MatrixStackUnderflow, "Current matrix stack has only a single matrix.");
ERRMSG(MismatchedByteCountType, "Buffer size does not align with data type.");
ERRMSG(MismatchedFormat, "Format must match internal format.");
ERRMSG(MismatchedTargetAndFormat, "Invalid texture target and format combination.");
......
......@@ -26,7 +26,8 @@ bool TextureCoordF::operator==(const TextureCoordF &other) const
}
GLES1State::GLES1State()
: mVertexArrayEnabled(false),
: mGLState(nullptr),
mVertexArrayEnabled(false),
mNormalArrayEnabled(false),
mColorArrayEnabled(false),
mPointSizeArrayEnabled(false),
......@@ -59,8 +60,10 @@ GLES1State::GLES1State()
GLES1State::~GLES1State() = default;
// Taken from the GLES 1.x spec which specifies all initial state values.
void GLES1State::initialize(const Context *context)
void GLES1State::initialize(const Context *context, const State *state)
{
mGLState = state;
const Caps &caps = context->getCaps();
mTexUnitEnables.resize(caps.maxMultitextureUnits);
......@@ -97,12 +100,12 @@ void GLES1State::initialize(const Context *context)
mTextureEnvironments.resize(caps.maxMultitextureUnits);
mProjMatrices.resize(caps.maxProjectionMatrixStackDepth);
mModelviewMatrices.resize(caps.maxModelviewMatrixStackDepth);
mModelviewMatrices.push_back(angle::Mat4());
mProjectionMatrices.push_back(angle::Mat4());
mTextureMatrices.resize(caps.maxMultitextureUnits);
for (auto &textureMatrixStack : mTextureMatrices)
for (auto &stack : mTextureMatrices)
{
textureMatrixStack.resize(caps.maxTextureMatrixStackDepth);
stack.push_back(angle::Mat4());
}
mMaterial.ambient = {0.2f, 0.2f, 0.2f, 1.0f};
......@@ -210,4 +213,48 @@ MatrixType GLES1State::getMatrixMode() const
return mMatrixMode;
}
void GLES1State::pushMatrix()
{
auto &stack = currentMatrixStack();
stack.push_back(stack.back());
}
void GLES1State::popMatrix()
{
auto &stack = currentMatrixStack();
stack.pop_back();
}
GLES1State::MatrixStack &GLES1State::currentMatrixStack()
{
switch (mMatrixMode)
{
case MatrixType::Modelview:
return mModelviewMatrices;
case MatrixType::Projection:
return mProjectionMatrices;
case MatrixType::Texture:
return mTextureMatrices[mGLState->getActiveSampler()];
default:
UNREACHABLE();
return mModelviewMatrices;
}
}
const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const
{
switch (mMatrixMode)
{
case MatrixType::Modelview:
return mModelviewMatrices;
case MatrixType::Projection:
return mProjectionMatrices;
case MatrixType::Texture:
return mTextureMatrices[mGLState->getActiveSampler()];
default:
UNREACHABLE();
return mModelviewMatrices;
}
}
} // namespace gl
......@@ -12,9 +12,11 @@
#include <unordered_set>
#include "common/FixedVector.h"
#include "common/angleutils.h"
#include "common/matrix_utils.h"
#include "common/vector_utils.h"
#include "libANGLE/Caps.h"
#include "libANGLE/angletypes.h"
namespace gl
......@@ -120,7 +122,7 @@ class GLES1State final : angle::NonCopyable
GLES1State();
~GLES1State();
void initialize(const Context *context);
void initialize(const Context *context, const State *state);
void setAlphaFunc(AlphaTestFunc func, GLfloat ref);
void setClientTextureUnit(unsigned int unit);
......@@ -138,9 +140,19 @@ class GLES1State final : angle::NonCopyable
void setMatrixMode(MatrixType mode);
MatrixType getMatrixMode() const;
void pushMatrix();
void popMatrix();
using MatrixStack = angle::FixedVector<angle::Mat4, Caps::GlobalMatrixStackDepth>;
MatrixStack &currentMatrixStack();
const MatrixStack &currentMatrixStack() const;
private:
friend class State;
// Back pointer for reading from State.
const State *mGLState;
// All initial state values come from the
// OpenGL ES 1.1 spec.
struct TextureEnables
......@@ -181,9 +193,8 @@ class GLES1State final : angle::NonCopyable
unsigned int mClientActiveTexture;
// Table 6.7
using MatrixStack = std::vector<angle::Mat4>;
MatrixType mMatrixMode;
MatrixStack mProjMatrices;
MatrixStack mProjectionMatrices;
MatrixStack mModelviewMatrices;
std::vector<MatrixStack> mTextureMatrices;
......
......@@ -246,7 +246,7 @@ void State::initialize(const Context *context,
// applies
if (clientVersion < Version(2, 0))
{
mGLES1State.initialize(context);
mGLES1State.initialize(context, this);
}
}
......
......@@ -504,13 +504,25 @@ bool ValidatePolygonOffsetx(Context *context, GLfixed factor, GLfixed units)
bool ValidatePopMatrix(Context *context)
{
UNIMPLEMENTED();
ANGLE_VALIDATE_IS_GLES1(context);
const auto &stack = context->getGLState().gles1().currentMatrixStack();
if (stack.size() == 1)
{
ANGLE_VALIDATION_ERR(context, StackUnderflow(), MatrixStackUnderflow);
return false;
}
return true;
}
bool ValidatePushMatrix(Context *context)
{
UNIMPLEMENTED();
ANGLE_VALIDATE_IS_GLES1(context);
const auto &stack = context->getGLState().gles1().currentMatrixStack();
if (stack.size() == stack.max_size())
{
ANGLE_VALIDATION_ERR(context, StackOverflow(), MatrixStackOverflow);
return false;
}
return true;
}
......
......@@ -53,6 +53,7 @@
'<(angle_path)/src/tests/gl_tests/gles1/CurrentNormalTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/CurrentTextureCoordsTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/MatrixModeTest.cpp',
'<(angle_path)/src/tests/gl_tests/gles1/MatrixStackTest.cpp',
'<(angle_path)/src/tests/gl_tests/GLSLTest.cpp',
'<(angle_path)/src/tests/gl_tests/ImageTest.cpp',
'<(angle_path)/src/tests/gl_tests/IncompleteTextureTest.cpp',
......
//
// Copyright 2018 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.
//
// MatrixStackTest.cpp: Tests basic usage of gl(Push|Pop)Matrix.
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include <vector>
using namespace angle;
class MatrixStackTest : public ANGLETest
{
protected:
MatrixStackTest()
{
setWindowWidth(32);
setWindowHeight(32);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
setConfigDepthBits(24);
}
};
// State query: Checks the initial state is correct; that there is only one matrix on the stack.
TEST_P(MatrixStackTest, InitialState)
{
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
EXPECT_GL_ERROR(GL_STACK_UNDERFLOW);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
EXPECT_GL_ERROR(GL_STACK_UNDERFLOW);
glMatrixMode(GL_TEXTURE);
glPopMatrix();
EXPECT_GL_ERROR(GL_STACK_UNDERFLOW);
}
// Tests that caps are greater than or equal to spec minimums and that we can actually push them
// that much.
TEST_P(MatrixStackTest, Limits)
{
GLint modelviewMatrixMax;
GLint projectionMatrixMax;
GLint textureMatrixMax;
GLint textureUnits; // For iterating over texture matrices
glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &modelviewMatrixMax);
glGetIntegerv(GL_MAX_PROJECTION_STACK_DEPTH, &projectionMatrixMax);
glGetIntegerv(GL_MAX_TEXTURE_STACK_DEPTH, &textureMatrixMax);
glGetIntegerv(GL_MAX_TEXTURE_UNITS, &textureUnits);
EXPECT_GE(modelviewMatrixMax, 16);
EXPECT_GE(projectionMatrixMax, 2);
EXPECT_GE(textureMatrixMax, 2);
glMatrixMode(GL_MODELVIEW);
for (int i = 0; i < modelviewMatrixMax; i++)
{
glPushMatrix();
if (i == modelviewMatrixMax - 1)
{
EXPECT_GL_ERROR(GL_STACK_OVERFLOW);
}
else
{
EXPECT_GL_NO_ERROR();
}
}
glMatrixMode(GL_PROJECTION);
for (int i = 0; i < projectionMatrixMax; i++)
{
glPushMatrix();
if (i == projectionMatrixMax - 1)
{
EXPECT_GL_ERROR(GL_STACK_OVERFLOW);
}
else
{
EXPECT_GL_NO_ERROR();
}
}
glMatrixMode(GL_TEXTURE);
for (int i = 0; i < textureUnits; i++)
{
glActiveTexture(GL_TEXTURE0 + i);
for (int j = 0; j < textureMatrixMax; j++)
{
glPushMatrix();
if (j == textureMatrixMax - 1)
{
EXPECT_GL_ERROR(GL_STACK_OVERFLOW);
}
else
{
EXPECT_GL_NO_ERROR();
}
}
}
}
ANGLE_INSTANTIATE_TEST(MatrixStackTest, ES1_D3D11(), ES1_OPENGL(), ES1_OPENGLES());
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