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)
// The user-specified point size, GL_POINT_SIZE_MAX,
// is initially equal to the implementation maximum.
mPointParameters.pointSizeMax = caps.maxAliasedPointSize;
mDirtyBits.set();
}
void GLES1State::setAlphaFunc(AlphaTestFunc func, GLfloat ref)
{
setDirty(DIRTY_GLES1_ALPHA_TEST);
mAlphaTestFunc = func;
mAlphaTestRef = ref;
}
void GLES1State::setClientTextureUnit(unsigned int unit)
{
setDirty(DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE);
mClientActiveTexture = unit;
}
......@@ -193,6 +197,7 @@ unsigned int GLES1State::getClientTextureUnit() const
void GLES1State::setCurrentColor(const ColorF &color)
{
setDirty(DIRTY_GLES1_CURRENT_VECTOR);
mCurrentColor = color;
}
......@@ -203,6 +208,7 @@ const ColorF &GLES1State::getCurrentColor() const
void GLES1State::setCurrentNormal(const angle::Vector3 &normal)
{
setDirty(DIRTY_GLES1_CURRENT_VECTOR);
mCurrentNormal = normal;
}
......@@ -213,6 +219,7 @@ const angle::Vector3 &GLES1State::getCurrentNormal() const
void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords)
{
setDirty(DIRTY_GLES1_CURRENT_VECTOR);
mCurrentTextureCoords[unit] = coords;
}
......@@ -223,6 +230,7 @@ const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) cons
void GLES1State::setMatrixMode(MatrixType mode)
{
setDirty(DIRTY_GLES1_MATRICES);
mMatrixMode = mode;
}
......@@ -249,18 +257,21 @@ GLint GLES1State::getCurrentMatrixStackDepth(GLenum queryType) const
void GLES1State::pushMatrix()
{
setDirty(DIRTY_GLES1_MATRICES);
auto &stack = currentMatrixStack();
stack.push_back(stack.back());
}
void GLES1State::popMatrix()
{
setDirty(DIRTY_GLES1_MATRICES);
auto &stack = currentMatrixStack();
stack.pop_back();
}
GLES1State::MatrixStack &GLES1State::currentMatrixStack()
{
setDirty(DIRTY_GLES1_MATRICES);
switch (mMatrixMode)
{
case MatrixType::Modelview:
......@@ -298,22 +309,26 @@ const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const
void GLES1State::loadMatrix(const angle::Mat4 &m)
{
setDirty(DIRTY_GLES1_MATRICES);
currentMatrixStack().back() = m;
}
void GLES1State::multMatrix(const angle::Mat4 &m)
{
setDirty(DIRTY_GLES1_MATRICES);
angle::Mat4 currentMatrix = currentMatrixStack().back();
currentMatrixStack().back() = currentMatrix.product(m);
}
void GLES1State::setLogicOp(LogicalOperation opcodePacked)
{
setDirty(DIRTY_GLES1_LOGIC_OP);
mLogicOp = opcodePacked;
}
void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable)
{
setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
switch (clientState)
{
case ClientVertexArrayType::Vertex:
......@@ -339,6 +354,7 @@ void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool e
void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable)
{
setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
mTexCoordArrayEnabled[unit] = enable;
}
......@@ -375,6 +391,7 @@ bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType typ
LightModelParameters &GLES1State::lightModelParameters()
{
setDirty(DIRTY_GLES1_LIGHTS);
return mLightModel;
}
......@@ -385,6 +402,7 @@ const LightModelParameters &GLES1State::lightModelParameters() const
LightParameters &GLES1State::lightParameters(unsigned int light)
{
setDirty(DIRTY_GLES1_LIGHTS);
return mLights[light];
}
......@@ -395,6 +413,7 @@ const LightParameters &GLES1State::lightParameters(unsigned int light) const
MaterialParameters &GLES1State::materialParameters()
{
setDirty(DIRTY_GLES1_MATERIAL);
return mMaterial;
}
......@@ -410,11 +429,13 @@ bool GLES1State::isColorMaterialEnabled() const
void GLES1State::setShadeModel(ShadingModel model)
{
setDirty(DIRTY_GLES1_SHADE_MODEL);
mShadeModel = model;
}
void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation)
{
setDirty(DIRTY_GLES1_CLIP_PLANES);
assert(plane < mClipPlanes.size());
mClipPlanes[plane].equation[0] = equation[0];
mClipPlanes[plane].equation[1] = equation[1];
......@@ -433,6 +454,7 @@ void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const
FogParameters &GLES1State::fogParameters()
{
setDirty(DIRTY_GLES1_FOG);
return mFog;
}
......@@ -443,6 +465,7 @@ const FogParameters &GLES1State::fogParameters() const
TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit)
{
setDirty(DIRTY_GLES1_TEXTURE_ENVIRONMENT);
assert(unit < mTextureEnvironments.size());
return mTextureEnvironments[unit];
}
......@@ -455,6 +478,7 @@ const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int
PointParameters &GLES1State::pointParameters()
{
setDirty(DIRTY_GLES1_POINT_PARAMETERS);
return mPointParameters;
}
......@@ -490,6 +514,7 @@ AttributesMask GLES1State::getVertexArraysAttributeMask() const
void GLES1State::setHint(GLenum target, GLenum mode)
{
setDirty(DIRTY_GLES1_HINT_SETTING);
HintSetting setting = FromGLenum<HintSetting>(mode);
switch (target)
{
......@@ -527,4 +552,25 @@ GLenum GLES1State::getHint(GLenum target)
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
......@@ -14,6 +14,7 @@
#include "common/FixedVector.h"
#include "common/angleutils.h"
#include "common/bitset_utils.h"
#include "common/matrix_utils.h"
#include "common/vector_utils.h"
#include "libANGLE/Caps.h"
......@@ -225,6 +226,34 @@ class GLES1State final : angle::NonCopyable
// Back pointer for reading from State.
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
// OpenGL ES 1.1 spec.
std::vector<angle::PackedEnumBitSet<TextureType>> mTexUnitEnables;
......
......@@ -59,6 +59,7 @@ angle_end2end_tests_sources = [
"gl_tests/gles1/MatrixStackTest.cpp",
"gl_tests/gles1/LightsTest.cpp",
"gl_tests/gles1/PointParameterTest.cpp",
"gl_tests/gles1/PointSpriteTest.cpp",
"gl_tests/gles1/ShadeModelTest.cpp",
"gl_tests/gles1/TextureEnvTest.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