Commit 603ad164 by Lingfeng Yang Committed by Commit Bot

GLES1: dirty bit pass

This CL introduces a coarse layer of dirty bits and on-demand sending of some uniforms to the underlying driver, instead of sending all uniforms every draw, which should improve performance in cases where not much is changing between draws. BUG=angleproject:2306 Change-Id: I530515dfad2e4be74c73d8659acd4fe5decaa8b0 Reviewed-on: https://chromium-review.googlesource.com/c/1361222Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Lingfeng Yang <lfy@google.com>
parent f9cc785c
...@@ -173,16 +173,20 @@ void GLES1State::initialize(const Context *context, const State *state) ...@@ -173,16 +173,20 @@ void GLES1State::initialize(const Context *context, const State *state)
// The user-specified point size, GL_POINT_SIZE_MAX, // The user-specified point size, GL_POINT_SIZE_MAX,
// is initially equal to the implementation maximum. // is initially equal to the implementation maximum.
mPointParameters.pointSizeMax = caps.maxAliasedPointSize; mPointParameters.pointSizeMax = caps.maxAliasedPointSize;
mDirtyBits.set();
} }
void GLES1State::setAlphaFunc(AlphaTestFunc func, GLfloat ref) void GLES1State::setAlphaFunc(AlphaTestFunc func, GLfloat ref)
{ {
setDirty(DIRTY_GLES1_ALPHA_TEST);
mAlphaTestFunc = func; mAlphaTestFunc = func;
mAlphaTestRef = ref; mAlphaTestRef = ref;
} }
void GLES1State::setClientTextureUnit(unsigned int unit) void GLES1State::setClientTextureUnit(unsigned int unit)
{ {
setDirty(DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE);
mClientActiveTexture = unit; mClientActiveTexture = unit;
} }
...@@ -193,6 +197,7 @@ unsigned int GLES1State::getClientTextureUnit() const ...@@ -193,6 +197,7 @@ unsigned int GLES1State::getClientTextureUnit() const
void GLES1State::setCurrentColor(const ColorF &color) void GLES1State::setCurrentColor(const ColorF &color)
{ {
setDirty(DIRTY_GLES1_CURRENT_VECTOR);
mCurrentColor = color; mCurrentColor = color;
} }
...@@ -203,6 +208,7 @@ const ColorF &GLES1State::getCurrentColor() const ...@@ -203,6 +208,7 @@ const ColorF &GLES1State::getCurrentColor() const
void GLES1State::setCurrentNormal(const angle::Vector3 &normal) void GLES1State::setCurrentNormal(const angle::Vector3 &normal)
{ {
setDirty(DIRTY_GLES1_CURRENT_VECTOR);
mCurrentNormal = normal; mCurrentNormal = normal;
} }
...@@ -213,6 +219,7 @@ const angle::Vector3 &GLES1State::getCurrentNormal() const ...@@ -213,6 +219,7 @@ const angle::Vector3 &GLES1State::getCurrentNormal() const
void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords) void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords)
{ {
setDirty(DIRTY_GLES1_CURRENT_VECTOR);
mCurrentTextureCoords[unit] = coords; mCurrentTextureCoords[unit] = coords;
} }
...@@ -223,6 +230,7 @@ const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) cons ...@@ -223,6 +230,7 @@ const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) cons
void GLES1State::setMatrixMode(MatrixType mode) void GLES1State::setMatrixMode(MatrixType mode)
{ {
setDirty(DIRTY_GLES1_MATRICES);
mMatrixMode = mode; mMatrixMode = mode;
} }
...@@ -249,18 +257,21 @@ GLint GLES1State::getCurrentMatrixStackDepth(GLenum queryType) const ...@@ -249,18 +257,21 @@ GLint GLES1State::getCurrentMatrixStackDepth(GLenum queryType) const
void GLES1State::pushMatrix() void GLES1State::pushMatrix()
{ {
setDirty(DIRTY_GLES1_MATRICES);
auto &stack = currentMatrixStack(); auto &stack = currentMatrixStack();
stack.push_back(stack.back()); stack.push_back(stack.back());
} }
void GLES1State::popMatrix() void GLES1State::popMatrix()
{ {
setDirty(DIRTY_GLES1_MATRICES);
auto &stack = currentMatrixStack(); auto &stack = currentMatrixStack();
stack.pop_back(); stack.pop_back();
} }
GLES1State::MatrixStack &GLES1State::currentMatrixStack() GLES1State::MatrixStack &GLES1State::currentMatrixStack()
{ {
setDirty(DIRTY_GLES1_MATRICES);
switch (mMatrixMode) switch (mMatrixMode)
{ {
case MatrixType::Modelview: case MatrixType::Modelview:
...@@ -298,22 +309,26 @@ const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const ...@@ -298,22 +309,26 @@ const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const
void GLES1State::loadMatrix(const angle::Mat4 &m) void GLES1State::loadMatrix(const angle::Mat4 &m)
{ {
setDirty(DIRTY_GLES1_MATRICES);
currentMatrixStack().back() = m; currentMatrixStack().back() = m;
} }
void GLES1State::multMatrix(const angle::Mat4 &m) void GLES1State::multMatrix(const angle::Mat4 &m)
{ {
setDirty(DIRTY_GLES1_MATRICES);
angle::Mat4 currentMatrix = currentMatrixStack().back(); angle::Mat4 currentMatrix = currentMatrixStack().back();
currentMatrixStack().back() = currentMatrix.product(m); currentMatrixStack().back() = currentMatrix.product(m);
} }
void GLES1State::setLogicOp(LogicalOperation opcodePacked) void GLES1State::setLogicOp(LogicalOperation opcodePacked)
{ {
setDirty(DIRTY_GLES1_LOGIC_OP);
mLogicOp = opcodePacked; mLogicOp = opcodePacked;
} }
void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable) void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable)
{ {
setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
switch (clientState) switch (clientState)
{ {
case ClientVertexArrayType::Vertex: case ClientVertexArrayType::Vertex:
...@@ -339,6 +354,7 @@ void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool e ...@@ -339,6 +354,7 @@ void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool e
void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable) void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable)
{ {
setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
mTexCoordArrayEnabled[unit] = enable; mTexCoordArrayEnabled[unit] = enable;
} }
...@@ -375,6 +391,7 @@ bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType typ ...@@ -375,6 +391,7 @@ bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType typ
LightModelParameters &GLES1State::lightModelParameters() LightModelParameters &GLES1State::lightModelParameters()
{ {
setDirty(DIRTY_GLES1_LIGHTS);
return mLightModel; return mLightModel;
} }
...@@ -385,6 +402,7 @@ const LightModelParameters &GLES1State::lightModelParameters() const ...@@ -385,6 +402,7 @@ const LightModelParameters &GLES1State::lightModelParameters() const
LightParameters &GLES1State::lightParameters(unsigned int light) LightParameters &GLES1State::lightParameters(unsigned int light)
{ {
setDirty(DIRTY_GLES1_LIGHTS);
return mLights[light]; return mLights[light];
} }
...@@ -395,6 +413,7 @@ const LightParameters &GLES1State::lightParameters(unsigned int light) const ...@@ -395,6 +413,7 @@ const LightParameters &GLES1State::lightParameters(unsigned int light) const
MaterialParameters &GLES1State::materialParameters() MaterialParameters &GLES1State::materialParameters()
{ {
setDirty(DIRTY_GLES1_MATERIAL);
return mMaterial; return mMaterial;
} }
...@@ -410,11 +429,13 @@ bool GLES1State::isColorMaterialEnabled() const ...@@ -410,11 +429,13 @@ bool GLES1State::isColorMaterialEnabled() const
void GLES1State::setShadeModel(ShadingModel model) void GLES1State::setShadeModel(ShadingModel model)
{ {
setDirty(DIRTY_GLES1_SHADE_MODEL);
mShadeModel = model; mShadeModel = model;
} }
void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation) void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation)
{ {
setDirty(DIRTY_GLES1_CLIP_PLANES);
assert(plane < mClipPlanes.size()); assert(plane < mClipPlanes.size());
mClipPlanes[plane].equation[0] = equation[0]; mClipPlanes[plane].equation[0] = equation[0];
mClipPlanes[plane].equation[1] = equation[1]; mClipPlanes[plane].equation[1] = equation[1];
...@@ -433,6 +454,7 @@ void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const ...@@ -433,6 +454,7 @@ void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const
FogParameters &GLES1State::fogParameters() FogParameters &GLES1State::fogParameters()
{ {
setDirty(DIRTY_GLES1_FOG);
return mFog; return mFog;
} }
...@@ -443,6 +465,7 @@ const FogParameters &GLES1State::fogParameters() const ...@@ -443,6 +465,7 @@ const FogParameters &GLES1State::fogParameters() const
TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit)
{ {
setDirty(DIRTY_GLES1_TEXTURE_ENVIRONMENT);
assert(unit < mTextureEnvironments.size()); assert(unit < mTextureEnvironments.size());
return mTextureEnvironments[unit]; return mTextureEnvironments[unit];
} }
...@@ -455,6 +478,7 @@ const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int ...@@ -455,6 +478,7 @@ const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int
PointParameters &GLES1State::pointParameters() PointParameters &GLES1State::pointParameters()
{ {
setDirty(DIRTY_GLES1_POINT_PARAMETERS);
return mPointParameters; return mPointParameters;
} }
...@@ -490,6 +514,7 @@ AttributesMask GLES1State::getVertexArraysAttributeMask() const ...@@ -490,6 +514,7 @@ AttributesMask GLES1State::getVertexArraysAttributeMask() const
void GLES1State::setHint(GLenum target, GLenum mode) void GLES1State::setHint(GLenum target, GLenum mode)
{ {
setDirty(DIRTY_GLES1_HINT_SETTING);
HintSetting setting = FromGLenum<HintSetting>(mode); HintSetting setting = FromGLenum<HintSetting>(mode);
switch (target) switch (target)
{ {
...@@ -527,4 +552,25 @@ GLenum GLES1State::getHint(GLenum target) ...@@ -527,4 +552,25 @@ GLenum GLES1State::getHint(GLenum target)
return 0; return 0;
} }
} }
void GLES1State::setDirty(DirtyGles1Type type)
{
mDirtyBits.set(type);
}
void GLES1State::setAllDirty()
{
mDirtyBits.set();
}
void GLES1State::clearDirty()
{
mDirtyBits.reset();
}
bool GLES1State::isDirty(DirtyGles1Type type) const
{
return mDirtyBits.test(type);
}
} // namespace gl } // namespace gl
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "common/FixedVector.h" #include "common/FixedVector.h"
#include "common/angleutils.h" #include "common/angleutils.h"
#include "common/bitset_utils.h"
#include "common/matrix_utils.h" #include "common/matrix_utils.h"
#include "common/vector_utils.h" #include "common/vector_utils.h"
#include "libANGLE/Caps.h" #include "libANGLE/Caps.h"
...@@ -225,6 +226,34 @@ class GLES1State final : angle::NonCopyable ...@@ -225,6 +226,34 @@ class GLES1State final : angle::NonCopyable
// Back pointer for reading from State. // Back pointer for reading from State.
const State *mGLState; const State *mGLState;
enum DirtyGles1Type
{
DIRTY_GLES1_TEXTURE_UNIT_ENABLE = 0,
DIRTY_GLES1_CLIENT_STATE_ENABLE,
DIRTY_GLES1_FEATURE_ENABLE,
DIRTY_GLES1_CURRENT_VECTOR,
DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE,
DIRTY_GLES1_MATRICES,
DIRTY_GLES1_TEXTURE_ENVIRONMENT,
DIRTY_GLES1_MATERIAL,
DIRTY_GLES1_LIGHTS,
DIRTY_GLES1_FOG,
DIRTY_GLES1_SHADE_MODEL,
DIRTY_GLES1_POINT_PARAMETERS,
DIRTY_GLES1_ALPHA_TEST,
DIRTY_GLES1_LOGIC_OP,
DIRTY_GLES1_CLIP_PLANES,
DIRTY_GLES1_HINT_SETTING,
DIRTY_GLES1_MAX,
};
using DirtyBits = angle::BitSet<DIRTY_GLES1_MAX>;
DirtyBits mDirtyBits;
void setDirty(DirtyGles1Type type);
void setAllDirty();
void clearDirty();
bool isDirty(DirtyGles1Type type) const;
// All initial state values come from the // All initial state values come from the
// OpenGL ES 1.1 spec. // OpenGL ES 1.1 spec.
std::vector<angle::PackedEnumBitSet<TextureType>> mTexUnitEnables; std::vector<angle::PackedEnumBitSet<TextureType>> mTexUnitEnables;
......
...@@ -59,6 +59,7 @@ angle_end2end_tests_sources = [ ...@@ -59,6 +59,7 @@ angle_end2end_tests_sources = [
"gl_tests/gles1/MatrixStackTest.cpp", "gl_tests/gles1/MatrixStackTest.cpp",
"gl_tests/gles1/LightsTest.cpp", "gl_tests/gles1/LightsTest.cpp",
"gl_tests/gles1/PointParameterTest.cpp", "gl_tests/gles1/PointParameterTest.cpp",
"gl_tests/gles1/PointSpriteTest.cpp",
"gl_tests/gles1/ShadeModelTest.cpp", "gl_tests/gles1/ShadeModelTest.cpp",
"gl_tests/gles1/TextureEnvTest.cpp", "gl_tests/gles1/TextureEnvTest.cpp",
"gl_tests/gles1/TextureParameterTest.cpp", "gl_tests/gles1/TextureParameterTest.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.
//
// PointSpriteTest.cpp: Tests basic usage of GLES1 point sprites.
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"
#include "util/random_utils.h"
#include <stdint.h>
using namespace angle;
class PointSpriteTest : public ANGLETest
{
protected:
PointSpriteTest()
{
setWindowWidth(1);
setWindowHeight(1);
setConfigRedBits(8);
setConfigGreenBits(8);
setConfigBlueBits(8);
setConfigAlphaBits(8);
setConfigDepthBits(24);
}
};
// Checks that triangles are not treated as point sprites, and that cached state
// is properly invalidated when the primitive mode changes.
TEST_P(PointSpriteTest, TrianglesNotTreatedAsPointSprites)
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_POINT_SPRITE_OES);
glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
glEnable(GL_TEXTURE_2D);
GLuint tex;
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
// A 3x3 texture where the top right corner is green. Rendered with
// triangles + texture coordinate 1,1 this is always green, but rendered as
// a point sprite, red will be used as we are using nearest filtering and we
// would be favoring only the red parts of the image in point coordinates.
GLubyte texture[] = {
0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00,
0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
};
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 3, 3, 0, GL_RGB, GL_UNSIGNED_BYTE, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
// The first coordinate, 0.9f 0.9f should be sufficiently shifted to the right
// that the green part of the point sprite is hidden.
std::vector<float> mPositions = {
0.9f, 0.9f, -0.9f, 0.9f, 0.9f, -0.9f,
};
glEnableClientState(GL_VERTEX_ARRAY);
glMultiTexCoord4f(GL_TEXTURE0, 1.0f, 1.0f, 0.0f, 0.0f);
glVertexPointer(2, GL_FLOAT, 0, mPositions.data());
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 3);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_POINTS, 0, 1);
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}
ANGLE_INSTANTIATE_TEST(PointSpriteTest, ES1_D3D11(), ES1_OPENGL(), ES1_OPENGLES());
\ No newline at end of file
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