Implement dirty bits for RendererGL's basic state.
BUG=angleproject:1040
TEST=angle_end2end_tests,angle_perftests,WebGL
Change-Id: I72beaf7e178e042440337fbb8b9669638c5ad016
Reviewed-on: https://chromium-review.googlesource.com/289558
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Context.cpp b/src/libANGLE/Context.cpp
index 2a24990..3923a2e 100644
--- a/src/libANGLE/Context.cpp
+++ b/src/libANGLE/Context.cpp
@@ -186,6 +186,9 @@
mHasBeenCurrent = true;
}
+ // TODO(jmadill): Rework this when we support ContextImpl
+ mState.setAllDirtyBits();
+
// Update default framebuffer
Framebuffer *defaultFBO = mFramebufferMap[0];
@@ -1237,6 +1240,7 @@
Error Context::drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instances)
{
+ syncRendererState();
Error error = mRenderer->drawArrays(getData(), mode, first, count, instances);
if (error.isError())
{
@@ -1263,6 +1267,7 @@
const GLvoid *indices, GLsizei instances,
const RangeUI &indexRange)
{
+ syncRendererState();
return mRenderer->drawElements(getData(), mode, count, type, indices, instances, indexRange);
}
@@ -1661,4 +1666,23 @@
}
}
+void Context::syncRendererState()
+{
+ const State::DirtyBits &dirtyBits = mState.getDirtyBits();
+ if (dirtyBits.any())
+ {
+ mRenderer->syncState(mState, dirtyBits);
+ mState.clearDirtyBits();
+ }
+}
+
+void Context::syncRendererState(const State::DirtyBits &bitMask)
+{
+ const State::DirtyBits &dirtyBits = (mState.getDirtyBits() & bitMask);
+ if (dirtyBits.any())
+ {
+ mRenderer->syncState(mState, dirtyBits);
+ mState.clearDirtyBits(dirtyBits);
+ }
+}
}
diff --git a/src/libANGLE/Context.h b/src/libANGLE/Context.h
index 367a922..6ad3b78 100644
--- a/src/libANGLE/Context.h
+++ b/src/libANGLE/Context.h
@@ -204,6 +204,8 @@
const State &getState() const { return mState; }
const Data &getData() const { return mData; }
+ void syncRendererState();
+ void syncRendererState(const State::DirtyBits &bitMask);
private:
void detachBuffer(GLuint buffer);
diff --git a/src/libANGLE/Framebuffer.cpp b/src/libANGLE/Framebuffer.cpp
index 07c40f6..398c980 100644
--- a/src/libANGLE/Framebuffer.cpp
+++ b/src/libANGLE/Framebuffer.cpp
@@ -511,29 +511,57 @@
return mImpl->invalidateSub(count, attachments, area);
}
-Error Framebuffer::clear(const gl::Data &data, GLbitfield mask)
+Error Framebuffer::clear(Context *context, GLbitfield mask)
{
- return mImpl->clear(data, mask);
+ // Sync the clear state
+ context->syncRendererState(context->getState().clearStateBitMask());
+
+ return mImpl->clear(context->getData(), mask);
}
-Error Framebuffer::clearBufferfv(const State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values)
+Error Framebuffer::clearBufferfv(Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLfloat *values)
{
- return mImpl->clearBufferfv(state, buffer, drawbuffer, values);
+ // Sync the clear state
+ context->syncRendererState(context->getState().clearStateBitMask());
+
+ return mImpl->clearBufferfv(context->getState(), buffer, drawbuffer, values);
}
-Error Framebuffer::clearBufferuiv(const State &state, GLenum buffer, GLint drawbuffer, const GLuint *values)
+Error Framebuffer::clearBufferuiv(Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLuint *values)
{
- return mImpl->clearBufferuiv(state, buffer, drawbuffer, values);
+ // Sync the clear state
+ context->syncRendererState(context->getState().clearStateBitMask());
+
+ return mImpl->clearBufferuiv(context->getState(), buffer, drawbuffer, values);
}
-Error Framebuffer::clearBufferiv(const State &state, GLenum buffer, GLint drawbuffer, const GLint *values)
+Error Framebuffer::clearBufferiv(Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ const GLint *values)
{
- return mImpl->clearBufferiv(state, buffer, drawbuffer, values);
+ // Sync the clear state
+ context->syncRendererState(context->getState().clearStateBitMask());
+
+ return mImpl->clearBufferiv(context->getState(), buffer, drawbuffer, values);
}
-Error Framebuffer::clearBufferfi(const State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
+Error Framebuffer::clearBufferfi(Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil)
{
- return mImpl->clearBufferfi(state, buffer, drawbuffer, depth, stencil);
+ // Sync the clear state
+ context->syncRendererState(context->getState().clearStateBitMask());
+
+ return mImpl->clearBufferfi(context->getState(), buffer, drawbuffer, depth, stencil);
}
GLenum Framebuffer::getImplementationColorReadFormat() const
@@ -546,8 +574,17 @@
return mImpl->getImplementationColorReadType();
}
-Error Framebuffer::readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const
+Error Framebuffer::readPixels(Context *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ GLvoid *pixels) const
{
+ const State &state = context->getState();
+
+ // Sync pack state
+ context->syncRendererState(state.packStateBitMask());
+
Error error = mImpl->readPixels(state, area, format, type, pixels);
if (error.isError())
{
diff --git a/src/libANGLE/Framebuffer.h b/src/libANGLE/Framebuffer.h
index 428789c..3b132a3 100644
--- a/src/libANGLE/Framebuffer.h
+++ b/src/libANGLE/Framebuffer.h
@@ -32,6 +32,7 @@
namespace gl
{
+class Context;
class Renderbuffer;
class State;
class Texture;
@@ -121,15 +122,23 @@
Error invalidate(size_t count, const GLenum *attachments);
Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area);
- Error clear(const gl::Data &data, GLbitfield mask);
- Error clearBufferfv(const State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values);
- Error clearBufferuiv(const State &state, GLenum buffer, GLint drawbuffer, const GLuint *values);
- Error clearBufferiv(const State &state, GLenum buffer, GLint drawbuffer, const GLint *values);
- Error clearBufferfi(const State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+ Error clear(Context *context, GLbitfield mask);
+ Error clearBufferfv(Context *context, GLenum buffer, GLint drawbuffer, const GLfloat *values);
+ Error clearBufferuiv(Context *context, GLenum buffer, GLint drawbuffer, const GLuint *values);
+ Error clearBufferiv(Context *context, GLenum buffer, GLint drawbuffer, const GLint *values);
+ Error clearBufferfi(Context *context,
+ GLenum buffer,
+ GLint drawbuffer,
+ GLfloat depth,
+ GLint stencil);
GLenum getImplementationColorReadFormat() const;
GLenum getImplementationColorReadType() const;
- Error readPixels(const gl::State &state, const gl::Rectangle &area, GLenum format, GLenum type, GLvoid *pixels) const;
+ Error readPixels(Context *context,
+ const gl::Rectangle &area,
+ GLenum format,
+ GLenum type,
+ GLvoid *pixels) const;
Error blit(const gl::State &state, const gl::Rectangle &sourceArea, const gl::Rectangle &destArea,
GLbitfield mask, GLenum filter, const gl::Framebuffer *sourceFramebuffer);
diff --git a/src/libANGLE/Image_unittest.cpp b/src/libANGLE/Image_unittest.cpp
index 45614cd..c9de26f 100644
--- a/src/libANGLE/Image_unittest.cpp
+++ b/src/libANGLE/Image_unittest.cpp
@@ -90,8 +90,8 @@
EXPECT_CALL(*textureImpl, setImage(_, _, _, _, _, _, _, _))
.WillOnce(Return(gl::Error(GL_NO_ERROR)))
.RetiresOnSaturation();
- texture->setImage(GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), GL_RGBA, GL_UNSIGNED_BYTE,
- gl::PixelUnpackState(), nullptr);
+ texture->setImage(nullptr, GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), GL_RGBA,
+ GL_UNSIGNED_BYTE, nullptr);
rx::MockImageImpl *imageImpl = new rx::MockImageImpl();
egl::Image *image = new egl::Image(imageImpl, EGL_GL_TEXTURE_2D, texture, egl::AttributeMap());
@@ -110,8 +110,8 @@
.WillOnce(Return(gl::Error(GL_NO_ERROR)))
.RetiresOnSaturation();
- texture->setImage(GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), GL_RGBA, GL_UNSIGNED_BYTE,
- gl::PixelUnpackState(), nullptr);
+ texture->setImage(nullptr, GL_TEXTURE_2D, 0, GL_RGBA8, gl::Extents(1, 1, 1), GL_RGBA,
+ GL_UNSIGNED_BYTE, nullptr);
EXPECT_EQ(texture->getRefCount(), 1u);
EXPECT_EQ(image->getRefCount(), 1u);
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 6790356..3e8ec36 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -23,6 +23,24 @@
{
mMaxDrawBuffers = 0;
mMaxCombinedTextureImageUnits = 0;
+
+ // Initialize dirty bit masks
+ // TODO(jmadill): additional ES3 state
+ mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ALIGNMENT);
+ mUnpackStateBitMask.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
+ mPackStateBitMask.set(DIRTY_BIT_PACK_ALIGNMENT);
+ mPackStateBitMask.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
+ mClearStateBitMask.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
+ mClearStateBitMask.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
+ mClearStateBitMask.set(DIRTY_BIT_SCISSOR);
+ mClearStateBitMask.set(DIRTY_BIT_VIEWPORT);
+ mClearStateBitMask.set(DIRTY_BIT_CLEAR_COLOR);
+ mClearStateBitMask.set(DIRTY_BIT_CLEAR_DEPTH);
+ mClearStateBitMask.set(DIRTY_BIT_CLEAR_STENCIL);
+ mClearStateBitMask.set(DIRTY_BIT_COLOR_MASK);
+ mClearStateBitMask.set(DIRTY_BIT_DEPTH_MASK);
+ mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
+ mClearStateBitMask.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
}
State::~State()
@@ -183,6 +201,9 @@
mUnpack.pixelBuffer.set(NULL);
mProgram = NULL;
+
+ // TODO(jmadill): Is this necessary?
+ setAllDirtyBits();
}
const RasterizerState &State::getRasterizerState() const
@@ -206,16 +227,19 @@
mColorClearValue.green = green;
mColorClearValue.blue = blue;
mColorClearValue.alpha = alpha;
+ mDirtyBits.set(DIRTY_BIT_CLEAR_COLOR);
}
void State::setDepthClearValue(float depth)
{
mDepthClearValue = depth;
+ mDirtyBits.set(DIRTY_BIT_CLEAR_DEPTH);
}
void State::setStencilClearValue(int stencil)
{
mStencilClearValue = stencil;
+ mDirtyBits.set(DIRTY_BIT_CLEAR_STENCIL);
}
void State::setColorMask(bool red, bool green, bool blue, bool alpha)
@@ -224,11 +248,13 @@
mBlend.colorMaskGreen = green;
mBlend.colorMaskBlue = blue;
mBlend.colorMaskAlpha = alpha;
+ mDirtyBits.set(DIRTY_BIT_COLOR_MASK);
}
void State::setDepthMask(bool mask)
{
mDepthStencil.depthMask = mask;
+ mDirtyBits.set(DIRTY_BIT_DEPTH_MASK);
}
bool State::isRasterizerDiscardEnabled() const
@@ -239,6 +265,7 @@
void State::setRasterizerDiscard(bool enabled)
{
mRasterizer.rasterizerDiscard = enabled;
+ mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
}
bool State::isCullFaceEnabled() const
@@ -249,16 +276,19 @@
void State::setCullFace(bool enabled)
{
mRasterizer.cullFace = enabled;
+ mDirtyBits.set(DIRTY_BIT_CULL_FACE_ENABLED);
}
void State::setCullMode(GLenum mode)
{
mRasterizer.cullMode = mode;
+ mDirtyBits.set(DIRTY_BIT_CULL_FACE);
}
void State::setFrontFace(GLenum front)
{
mRasterizer.frontFace = front;
+ mDirtyBits.set(DIRTY_BIT_FRONT_FACE);
}
bool State::isDepthTestEnabled() const
@@ -269,17 +299,20 @@
void State::setDepthTest(bool enabled)
{
mDepthStencil.depthTest = enabled;
+ mDirtyBits.set(DIRTY_BIT_DEPTH_TEST_ENABLED);
}
void State::setDepthFunc(GLenum depthFunc)
{
mDepthStencil.depthFunc = depthFunc;
+ mDirtyBits.set(DIRTY_BIT_DEPTH_FUNC);
}
void State::setDepthRange(float zNear, float zFar)
{
mNearZ = zNear;
mFarZ = zFar;
+ mDirtyBits.set(DIRTY_BIT_DEPTH_RANGE);
}
float State::getNearPlane() const
@@ -300,6 +333,7 @@
void State::setBlend(bool enabled)
{
mBlend.blend = enabled;
+ mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED);
}
void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha)
@@ -308,6 +342,7 @@
mBlend.destBlendRGB = destRGB;
mBlend.sourceBlendAlpha = sourceAlpha;
mBlend.destBlendAlpha = destAlpha;
+ mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS);
}
void State::setBlendColor(float red, float green, float blue, float alpha)
@@ -316,12 +351,14 @@
mBlendColor.green = green;
mBlendColor.blue = blue;
mBlendColor.alpha = alpha;
+ mDirtyBits.set(DIRTY_BIT_BLEND_COLOR);
}
void State::setBlendEquation(GLenum rgbEquation, GLenum alphaEquation)
{
mBlend.blendEquationRGB = rgbEquation;
mBlend.blendEquationAlpha = alphaEquation;
+ mDirtyBits.set(DIRTY_BIT_BLEND_EQUATIONS);
}
const ColorF &State::getBlendColor() const
@@ -337,6 +374,7 @@
void State::setStencilTest(bool enabled)
{
mDepthStencil.stencilTest = enabled;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED);
}
void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask)
@@ -344,6 +382,7 @@
mDepthStencil.stencilFunc = stencilFunc;
mStencilRef = (stencilRef > 0) ? stencilRef : 0;
mDepthStencil.stencilMask = stencilMask;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT);
}
void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask)
@@ -351,16 +390,19 @@
mDepthStencil.stencilBackFunc = stencilBackFunc;
mStencilBackRef = (stencilBackRef > 0) ? stencilBackRef : 0;
mDepthStencil.stencilBackMask = stencilBackMask;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK);
}
void State::setStencilWritemask(GLuint stencilWritemask)
{
mDepthStencil.stencilWritemask = stencilWritemask;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
}
void State::setStencilBackWritemask(GLuint stencilBackWritemask)
{
mDepthStencil.stencilBackWritemask = stencilBackWritemask;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK);
}
void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass)
@@ -368,6 +410,7 @@
mDepthStencil.stencilFail = stencilFail;
mDepthStencil.stencilPassDepthFail = stencilPassDepthFail;
mDepthStencil.stencilPassDepthPass = stencilPassDepthPass;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT);
}
void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass)
@@ -375,6 +418,7 @@
mDepthStencil.stencilBackFail = stencilBackFail;
mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
+ mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
}
GLint State::getStencilRef() const
@@ -394,7 +438,8 @@
void State::setPolygonOffsetFill(bool enabled)
{
- mRasterizer.polygonOffsetFill = enabled;
+ mRasterizer.polygonOffsetFill = enabled;
+ mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
}
void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
@@ -402,6 +447,7 @@
// An application can pass NaN values here, so handle this gracefully
mRasterizer.polygonOffsetFactor = factor != factor ? 0.0f : factor;
mRasterizer.polygonOffsetUnits = units != units ? 0.0f : units;
+ mDirtyBits.set(DIRTY_BIT_POLYGON_OFFSET);
}
bool State::isSampleAlphaToCoverageEnabled() const
@@ -412,6 +458,7 @@
void State::setSampleAlphaToCoverage(bool enabled)
{
mBlend.sampleAlphaToCoverage = enabled;
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
}
bool State::isSampleCoverageEnabled() const
@@ -422,12 +469,14 @@
void State::setSampleCoverage(bool enabled)
{
mSampleCoverage = enabled;
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
}
void State::setSampleCoverageParams(GLclampf value, bool invert)
{
mSampleCoverageValue = value;
mSampleCoverageInvert = invert;
+ mDirtyBits.set(DIRTY_BIT_SAMPLE_COVERAGE);
}
GLclampf State::getSampleCoverageValue() const
@@ -448,6 +497,7 @@
void State::setScissorTest(bool enabled)
{
mScissorTest = enabled;
+ mDirtyBits.set(DIRTY_BIT_SCISSOR_TEST_ENABLED);
}
void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
@@ -456,6 +506,7 @@
mScissor.y = y;
mScissor.width = width;
mScissor.height = height;
+ mDirtyBits.set(DIRTY_BIT_SCISSOR);
}
const Rectangle &State::getScissor() const
@@ -471,6 +522,7 @@
void State::setDither(bool enabled)
{
mBlend.dither = enabled;
+ mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
}
bool State::isPrimitiveRestartEnabled() const
@@ -481,6 +533,7 @@
void State::setPrimitiveRestart(bool enabled)
{
mPrimitiveRestart = enabled;
+ mDirtyBits.set(DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
}
void State::setEnableFeature(GLenum feature, bool enabled)
@@ -524,6 +577,7 @@
void State::setLineWidth(GLfloat width)
{
mLineWidth = width;
+ mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
}
float State::getLineWidth() const
@@ -534,11 +588,13 @@
void State::setGenerateMipmapHint(GLenum hint)
{
mGenerateMipmapHint = hint;
+ mDirtyBits.set(DIRTY_BIT_GENERATE_MIPMAP_HINT);
}
void State::setFragmentShaderDerivativeHint(GLenum hint)
{
mFragmentShaderDerivativeHint = hint;
+ mDirtyBits.set(DIRTY_BIT_SHADER_DERIVATIVE_HINT);
// TODO: Propagate the hint to shader translator so we can write
// ddx, ddx_coarse, or ddx_fine depending on the hint.
// Ignore for now. It is valid for implementations to ignore hint.
@@ -550,6 +606,7 @@
mViewport.y = y;
mViewport.width = width;
mViewport.height = height;
+ mDirtyBits.set(DIRTY_BIT_VIEWPORT);
}
const Rectangle &State::getViewport() const
@@ -1034,6 +1091,7 @@
void State::setPackAlignment(GLint alignment)
{
mPack.alignment = alignment;
+ mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
}
GLint State::getPackAlignment() const
@@ -1044,6 +1102,7 @@
void State::setPackReverseRowOrder(bool reverseRowOrder)
{
mPack.reverseRowOrder = reverseRowOrder;
+ mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
}
bool State::getPackReverseRowOrder() const
@@ -1064,6 +1123,7 @@
void State::setUnpackAlignment(GLint alignment)
{
mUnpack.alignment = alignment;
+ mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
}
GLint State::getUnpackAlignment() const
@@ -1074,6 +1134,7 @@
void State::setUnpackRowLength(GLint rowLength)
{
mUnpack.rowLength = rowLength;
+ mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
}
GLint State::getUnpackRowLength() const
diff --git a/src/libANGLE/State.h b/src/libANGLE/State.h
index 90e757d..dad3b6e 100644
--- a/src/libANGLE/State.h
+++ b/src/libANGLE/State.h
@@ -9,15 +9,17 @@
#ifndef LIBANGLE_STATE_H_
#define LIBANGLE_STATE_H_
+#include <bitset>
+
#include "common/angleutils.h"
+#include "libANGLE/Program.h"
#include "libANGLE/RefCountObject.h"
-#include "libANGLE/angletypes.h"
-#include "libANGLE/VertexAttribute.h"
#include "libANGLE/Renderbuffer.h"
+#include "libANGLE/Sampler.h"
#include "libANGLE/Texture.h"
#include "libANGLE/TransformFeedback.h"
-#include "libANGLE/Program.h"
-#include "libANGLE/Sampler.h"
+#include "libANGLE/VertexAttribute.h"
+#include "libANGLE/angletypes.h"
namespace gl
{
@@ -252,6 +254,73 @@
bool hasMappedBuffer(GLenum target) const;
+ enum DirtyBitType
+ {
+ DIRTY_BIT_SCISSOR_TEST_ENABLED,
+ DIRTY_BIT_SCISSOR,
+ DIRTY_BIT_VIEWPORT,
+ DIRTY_BIT_DEPTH_RANGE,
+ DIRTY_BIT_BLEND_ENABLED,
+ DIRTY_BIT_BLEND_COLOR,
+ DIRTY_BIT_BLEND_FUNCS,
+ DIRTY_BIT_BLEND_EQUATIONS,
+ DIRTY_BIT_COLOR_MASK,
+ DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED,
+ DIRTY_BIT_SAMPLE_COVERAGE_ENABLED,
+ DIRTY_BIT_SAMPLE_COVERAGE,
+ DIRTY_BIT_DEPTH_TEST_ENABLED,
+ DIRTY_BIT_DEPTH_FUNC,
+ DIRTY_BIT_DEPTH_MASK,
+ DIRTY_BIT_STENCIL_TEST_ENABLED,
+ DIRTY_BIT_STENCIL_FUNCS_FRONT,
+ DIRTY_BIT_STENCIL_FUNCS_BACK,
+ DIRTY_BIT_STENCIL_OPS_FRONT,
+ DIRTY_BIT_STENCIL_OPS_BACK,
+ DIRTY_BIT_STENCIL_WRITEMASK_FRONT,
+ DIRTY_BIT_STENCIL_WRITEMASK_BACK,
+ DIRTY_BIT_CULL_FACE_ENABLED,
+ DIRTY_BIT_CULL_FACE,
+ DIRTY_BIT_FRONT_FACE,
+ DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED,
+ DIRTY_BIT_POLYGON_OFFSET,
+ DIRTY_BIT_MULTISAMPLE_ENABLED,
+ DIRTY_BIT_RASTERIZER_DISCARD_ENABLED,
+ DIRTY_BIT_LINE_WIDTH,
+ DIRTY_BIT_PRIMITIVE_RESTART_ENABLED,
+ DIRTY_BIT_CLEAR_COLOR,
+ DIRTY_BIT_CLEAR_DEPTH,
+ DIRTY_BIT_CLEAR_STENCIL,
+ DIRTY_BIT_UNPACK_ALIGNMENT,
+ DIRTY_BIT_UNPACK_ROW_LENGTH,
+ DIRTY_BIT_PACK_ALIGNMENT,
+ DIRTY_BIT_PACK_REVERSE_ROW_ORDER,
+ DIRTY_BIT_DITHER_ENABLED,
+ DIRTY_BIT_GENERATE_MIPMAP_HINT,
+ DIRTY_BIT_SHADER_DERIVATIVE_HINT,
+ DIRTY_BIT_READ_FRAMEBUFFER_BINDING,
+ DIRTY_BIT_READ_FRAMEBUFFER_OBJECT,
+ DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING,
+ DIRTY_BIT_DRAW_FRAMEBUFFER_OBJECT,
+ DIRTY_BIT_RENDERBUFFER_BINDING,
+ DIRTY_BIT_VERTEX_ARRAY_BINDING,
+ DIRTY_BIT_VERTEX_ARRAY_OBJECT,
+ DIRTY_BIT_PROGRAM_BINDING,
+ DIRTY_BIT_PROGRAM_OBJECT,
+ DIRTY_BIT_INVALID,
+ DIRTY_BIT_MAX = DIRTY_BIT_INVALID,
+ };
+
+ typedef std::bitset<DIRTY_BIT_MAX> DirtyBits;
+ const DirtyBits &getDirtyBits() const { return mDirtyBits; }
+ void clearDirtyBits() { mDirtyBits.reset(); }
+ void clearDirtyBits(const DirtyBits &bitset) { mDirtyBits &= ~bitset; }
+ void setAllDirtyBits() { mDirtyBits.set(); }
+
+ // Dirty bit masks
+ const DirtyBits &unpackStateBitMask() const { return mUnpackStateBitMask; }
+ const DirtyBits &packStateBitMask() const { return mPackStateBitMask; }
+ const DirtyBits &clearStateBitMask() const { return mClearStateBitMask; }
+
private:
// Cached values from Context's caps
GLuint mMaxDrawBuffers;
@@ -320,6 +389,11 @@
PixelPackState mPack;
bool mPrimitiveRestart;
+
+ DirtyBits mDirtyBits;
+ DirtyBits mUnpackStateBitMask;
+ DirtyBits mPackStateBitMask;
+ DirtyBits mClearStateBitMask;
};
}
diff --git a/src/libANGLE/Texture.cpp b/src/libANGLE/Texture.cpp
index 2668478..f532797 100644
--- a/src/libANGLE/Texture.cpp
+++ b/src/libANGLE/Texture.cpp
@@ -11,6 +11,7 @@
#include "common/mathutil.h"
#include "common/utilities.h"
#include "libANGLE/Config.h"
+#include "libANGLE/Context.h"
#include "libANGLE/Data.h"
#include "libANGLE/Image.h"
#include "libANGLE/Surface.h"
@@ -189,8 +190,14 @@
return mBoundSurface;
}
-Error Texture::setImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size, GLenum format, GLenum type,
- const PixelUnpackState &unpack, const uint8_t *pixels)
+Error Texture::setImage(Context *context,
+ GLenum target,
+ size_t level,
+ GLenum internalFormat,
+ const Extents &size,
+ GLenum format,
+ GLenum type,
+ const uint8_t *pixels)
{
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
@@ -198,6 +205,15 @@
releaseTexImageInternal();
orphanImages();
+ // Hack: allow nullptr for testing
+ if (context != nullptr)
+ {
+ // Sync the unpack state
+ context->syncRendererState(context->getState().unpackStateBitMask());
+ }
+
+ const PixelUnpackState &unpack =
+ context ? context->getState().getUnpackState() : PixelUnpackState();
Error error = mTexture->setImage(target, level, internalFormat, size, format, type, unpack, pixels);
if (error.isError())
{
@@ -209,16 +225,30 @@
return Error(GL_NO_ERROR);
}
-Error Texture::setSubImage(GLenum target, size_t level, const Box &area, GLenum format, GLenum type,
- const PixelUnpackState &unpack, const uint8_t *pixels)
+Error Texture::setSubImage(Context *context,
+ GLenum target,
+ size_t level,
+ const Box &area,
+ GLenum format,
+ GLenum type,
+ const uint8_t *pixels)
{
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+ // Sync the unpack state
+ context->syncRendererState(context->getState().unpackStateBitMask());
+
+ const PixelUnpackState &unpack = context->getState().getUnpackState();
return mTexture->setSubImage(target, level, area, format, type, unpack, pixels);
}
-Error Texture::setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size,
- const PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels)
+Error Texture::setCompressedImage(Context *context,
+ GLenum target,
+ size_t level,
+ GLenum internalFormat,
+ const Extents &size,
+ size_t imageSize,
+ const uint8_t *pixels)
{
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
@@ -226,6 +256,10 @@
releaseTexImageInternal();
orphanImages();
+ // Sync the unpack state
+ context->syncRendererState(context->getState().unpackStateBitMask());
+
+ const PixelUnpackState &unpack = context->getState().getUnpackState();
Error error = mTexture->setCompressedImage(target, level, internalFormat, size, unpack, imageSize, pixels);
if (error.isError())
{
@@ -237,11 +271,20 @@
return Error(GL_NO_ERROR);
}
-Error Texture::setCompressedSubImage(GLenum target, size_t level, const Box &area, GLenum format,
- const PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels)
+Error Texture::setCompressedSubImage(Context *context,
+ GLenum target,
+ size_t level,
+ const Box &area,
+ GLenum format,
+ size_t imageSize,
+ const uint8_t *pixels)
{
ASSERT(target == mTarget || (mTarget == GL_TEXTURE_CUBE_MAP && IsCubeMapTextureTarget(target)));
+ // Sync the unpack state
+ context->syncRendererState(context->getState().unpackStateBitMask());
+
+ const PixelUnpackState &unpack = context->getState().getUnpackState();
return mTexture->setCompressedSubImage(target, level, area, format, unpack, imageSize, pixels);
}
diff --git a/src/libANGLE/Texture.h b/src/libANGLE/Texture.h
index 735b6d5..c01cf00 100644
--- a/src/libANGLE/Texture.h
+++ b/src/libANGLE/Texture.h
@@ -29,6 +29,7 @@
namespace gl
{
+class Context;
class Framebuffer;
struct Data;
@@ -38,8 +39,7 @@
{
public:
Texture(rx::TextureImpl *impl, GLuint id, GLenum target);
-
- virtual ~Texture();
+ ~Texture();
GLenum getTarget() const;
@@ -59,26 +59,53 @@
bool isCubeComplete() const;
size_t getMipCompleteLevels() const;
- virtual Error setImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size, GLenum format, GLenum type,
- const PixelUnpackState &unpack, const uint8_t *pixels);
- virtual Error setSubImage(GLenum target, size_t level, const Box &area, GLenum format, GLenum type,
- const PixelUnpackState &unpack, const uint8_t *pixels);
+ Error setImage(Context *context,
+ GLenum target,
+ size_t level,
+ GLenum internalFormat,
+ const Extents &size,
+ GLenum format,
+ GLenum type,
+ const uint8_t *pixels);
+ Error setSubImage(Context *context,
+ GLenum target,
+ size_t level,
+ const Box &area,
+ GLenum format,
+ GLenum type,
+ const uint8_t *pixels);
- virtual Error setCompressedImage(GLenum target, size_t level, GLenum internalFormat, const Extents &size,
- const PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels);
- virtual Error setCompressedSubImage(GLenum target, size_t level, const Box &area, GLenum format,
- const PixelUnpackState &unpack, size_t imageSize, const uint8_t *pixels);
+ Error setCompressedImage(Context *context,
+ GLenum target,
+ size_t level,
+ GLenum internalFormat,
+ const Extents &size,
+ size_t imageSize,
+ const uint8_t *pixels);
+ Error setCompressedSubImage(Context *context,
+ GLenum target,
+ size_t level,
+ const Box &area,
+ GLenum format,
+ size_t imageSize,
+ const uint8_t *pixels);
- virtual Error copyImage(GLenum target, size_t level, const Rectangle &sourceArea, GLenum internalFormat,
- const Framebuffer *source);
- virtual Error copySubImage(GLenum target, size_t level, const Offset &destOffset, const Rectangle &sourceArea,
- const Framebuffer *source);
+ Error copyImage(GLenum target,
+ size_t level,
+ const Rectangle &sourceArea,
+ GLenum internalFormat,
+ const Framebuffer *source);
+ Error copySubImage(GLenum target,
+ size_t level,
+ const Offset &destOffset,
+ const Rectangle &sourceArea,
+ const Framebuffer *source);
- virtual Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const Extents &size);
+ Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const Extents &size);
Error setEGLImageTarget(GLenum target, egl::Image *imageTarget);
- virtual Error generateMipmaps();
+ Error generateMipmaps();
bool isImmutable() const;
GLsizei immutableLevelCount();
diff --git a/src/libANGLE/renderer/Renderer.h b/src/libANGLE/renderer/Renderer.h
index 6663455..ae12c42 100644
--- a/src/libANGLE/renderer/Renderer.h
+++ b/src/libANGLE/renderer/Renderer.h
@@ -13,6 +13,7 @@
#include "libANGLE/Caps.h"
#include "libANGLE/Error.h"
#include "libANGLE/Framebuffer.h"
+#include "libANGLE/State.h"
#include "libANGLE/Uniform.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/ImplFactory.h"
@@ -29,12 +30,6 @@
class Surface;
}
-namespace gl
-{
-class Buffer;
-struct Data;
-}
-
namespace rx
{
struct TranslatedIndexData;
@@ -72,6 +67,8 @@
virtual void pushGroupMarker(GLsizei length, const char *marker) = 0;
virtual void popGroupMarker() = 0;
+ virtual void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) = 0;
+
// Renderer capabilities
const gl::Caps &getRendererCaps() const;
const gl::TextureCapsMap &getRendererTextureCaps() const;
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.cpp b/src/libANGLE/renderer/d3d/RendererD3D.cpp
index c5c949b..4c7ebb4 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.cpp
+++ b/src/libANGLE/renderer/d3d/RendererD3D.cpp
@@ -545,20 +545,26 @@
{
const GLubyte color[] = { 0, 0, 0, 255 };
const gl::Extents colorSize(1, 1, 1);
- const gl::PixelUnpackState incompleteUnpackState(1, 0);
+ const gl::PixelUnpackState unpack(1, 0);
+ const gl::Box area(0, 0, 0, 1, 1, 1);
- gl::Texture* t = new gl::Texture(createTexture(type), std::numeric_limits<GLuint>::max(), type);
+ // Skip the API layer to avoid needing to pass the Context and mess with dirty bits.
+ gl::Texture *t =
+ new gl::Texture(createTexture(type), std::numeric_limits<GLuint>::max(), type);
+ t->setStorage(type, 1, GL_RGBA8, colorSize);
if (type == GL_TEXTURE_CUBE_MAP)
{
for (GLenum face = GL_TEXTURE_CUBE_MAP_POSITIVE_X; face <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z; face++)
{
- t->setImage(face, 0, GL_RGBA, colorSize, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ t->getImplementation()->setSubImage(face, 0, area, GL_RGBA8, GL_UNSIGNED_BYTE,
+ unpack, color);
}
}
else
{
- t->setImage(type, 0, GL_RGBA, colorSize, GL_RGBA, GL_UNSIGNED_BYTE, incompleteUnpackState, color);
+ t->getImplementation()->setSubImage(type, 0, area, GL_RGBA8, GL_UNSIGNED_BYTE, unpack,
+ color);
}
mIncompleteTextures[type].set(t);
diff --git a/src/libANGLE/renderer/d3d/RendererD3D.h b/src/libANGLE/renderer/d3d/RendererD3D.h
index 441e8bc..2397efa 100644
--- a/src/libANGLE/renderer/d3d/RendererD3D.h
+++ b/src/libANGLE/renderer/d3d/RendererD3D.h
@@ -194,6 +194,11 @@
virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget,
GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) = 0;
+ void syncState(const gl::State & /*state*/, const gl::State::DirtyBits &bitmask) override
+ {
+ // TODO(jmadill): implement state sync for D3D renderers;
+ }
+
// Device lost
void notifyDeviceLost() override;
virtual bool resetDevice() = 0;
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.cpp b/src/libANGLE/renderer/gl/FramebufferGL.cpp
index 61f55eb..6c2101a 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.cpp
+++ b/src/libANGLE/renderer/gl/FramebufferGL.cpp
@@ -185,28 +185,14 @@
gl::Error FramebufferGL::clear(const gl::Data &data, GLbitfield mask)
{
- mStateManager->setClearState(*data.state, mask);
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
mFunctions->clear(mask);
return gl::Error(GL_NO_ERROR);
}
-static GLbitfield GetClearBufferMask(GLenum buffer)
-{
- switch (buffer)
- {
- case GL_COLOR: return GL_COLOR_BUFFER_BIT;
- case GL_DEPTH: return GL_DEPTH_BUFFER_BIT;
- case GL_STENCIL: return GL_STENCIL_BUFFER_BIT;
- case GL_DEPTH_STENCIL: return GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT;
- default: UNREACHABLE(); return 0;
- }
-}
-
gl::Error FramebufferGL::clearBufferfv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLfloat *values)
{
- mStateManager->setClearState(state, GetClearBufferMask(buffer));
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
mFunctions->clearBufferfv(buffer, drawbuffer, values);
@@ -215,7 +201,6 @@
gl::Error FramebufferGL::clearBufferuiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLuint *values)
{
- mStateManager->setClearState(state, GetClearBufferMask(buffer));
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
mFunctions->clearBufferuiv(buffer, drawbuffer, values);
@@ -224,7 +209,6 @@
gl::Error FramebufferGL::clearBufferiv(const gl::State &state, GLenum buffer, GLint drawbuffer, const GLint *values)
{
- mStateManager->setClearState(state, GetClearBufferMask(buffer));
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
mFunctions->clearBufferiv(buffer, drawbuffer, values);
@@ -233,7 +217,6 @@
gl::Error FramebufferGL::clearBufferfi(const gl::State &state, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil)
{
- mStateManager->setClearState(state, GetClearBufferMask(buffer));
mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
mFunctions->clearBufferfi(buffer, drawbuffer, depth, stencil);
@@ -263,7 +246,6 @@
{
UNIMPLEMENTED();
}
- mStateManager->setPixelPackState(packState.alignment, packState.rowLength, packState.skipRows, packState.skipPixels);
mStateManager->bindFramebuffer(GL_READ_FRAMEBUFFER, mFramebufferID);
mFunctions->readPixels(area.x, area.y, area.width, area.height, format, type, pixels);
diff --git a/src/libANGLE/renderer/gl/RendererGL.cpp b/src/libANGLE/renderer/gl/RendererGL.cpp
index db8ed00..f4d6562 100644
--- a/src/libANGLE/renderer/gl/RendererGL.cpp
+++ b/src/libANGLE/renderer/gl/RendererGL.cpp
@@ -324,4 +324,8 @@
nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions, &mMaxSupportedESVersion);
}
+void RendererGL::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
+{
+ mStateManager->syncState(state, dirtyBits);
+}
}
diff --git a/src/libANGLE/renderer/gl/RendererGL.h b/src/libANGLE/renderer/gl/RendererGL.h
index 55591ec..4687a7a 100644
--- a/src/libANGLE/renderer/gl/RendererGL.h
+++ b/src/libANGLE/renderer/gl/RendererGL.h
@@ -77,6 +77,8 @@
std::string getVendorString() const override;
std::string getRendererDescription() const override;
+ void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) override;
+
const gl::Version &getMaxSupportedESVersion() const;
private:
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.cpp b/src/libANGLE/renderer/gl/StateManagerGL.cpp
index a45ab2d..87307cd 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.cpp
+++ b/src/libANGLE/renderer/gl/StateManagerGL.cpp
@@ -8,6 +8,7 @@
#include "libANGLE/renderer/gl/StateManagerGL.h"
+#include "common/BitSetIterator.h"
#include "libANGLE/Data.h"
#include "libANGLE/Framebuffer.h"
#include "libANGLE/VertexArray.h"
@@ -250,6 +251,17 @@
}
}
+void StateManagerGL::setPixelUnpackState(const gl::PixelUnpackState &unpack)
+{
+ const gl::Buffer *unpackBuffer = unpack.pixelBuffer.get();
+ if (unpackBuffer != nullptr)
+ {
+ UNIMPLEMENTED();
+ }
+ setPixelUnpackState(unpack.alignment, unpack.rowLength, unpack.skipRows, unpack.skipPixels,
+ unpack.imageHeight, unpack.skipImages);
+}
+
void StateManagerGL::setPixelUnpackState(GLint alignment, GLint rowLength, GLint skipRows, GLint skipPixels,
GLint imageHeight, GLint skipImages)
{
@@ -290,6 +302,16 @@
}
}
+void StateManagerGL::setPixelPackState(const gl::PixelPackState &pack)
+{
+ const gl::Buffer *packBuffer = pack.pixelBuffer.get();
+ if (packBuffer != nullptr)
+ {
+ UNIMPLEMENTED();
+ }
+ setPixelPackState(pack.alignment, pack.rowLength, pack.skipRows, pack.skipPixels);
+}
+
void StateManagerGL::setPixelPackState(GLint alignment, GLint rowLength, GLint skipRows, GLint skipPixels)
{
if (mPackAlignment != alignment)
@@ -351,44 +373,6 @@
}
}
-void StateManagerGL::setClearState(const gl::State &state, GLbitfield mask)
-{
- // Only apply the state required to do a clear
- const gl::RasterizerState &rasterizerState = state.getRasterizerState();
- setRasterizerDiscardEnabled(rasterizerState.rasterizerDiscard);
- if (!rasterizerState.rasterizerDiscard)
- {
- setScissorTestEnabled(state.isScissorTestEnabled());
- if (state.isScissorTestEnabled())
- {
- setScissor(state.getScissor());
- }
-
- setViewport(state.getViewport());
-
- if ((mask & GL_COLOR_BUFFER_BIT) != 0)
- {
- setClearColor(state.getColorClearValue());
-
- const gl::BlendState &blendState = state.getBlendState();
- setColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, blendState.colorMaskBlue, blendState.colorMaskAlpha);
- }
-
- if ((mask & GL_DEPTH_BUFFER_BIT) != 0)
- {
- setClearDepth(state.getDepthClearValue());
- setDepthMask(state.getDepthStencilState().depthMask);
- }
-
- if ((mask & GL_STENCIL_BUFFER_BIT) != 0)
- {
- setClearStencil(state.getStencilClearValue());
- setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask);
- setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask);
- }
- }
-}
-
gl::Error StateManagerGL::setDrawArraysState(const gl::Data &data, GLint first, GLsizei count)
{
const gl::State &state = *data.state;
@@ -489,67 +473,6 @@
const FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebufferGL->getFramebufferID());
- setScissorTestEnabled(state.isScissorTestEnabled());
- if (state.isScissorTestEnabled())
- {
- setScissor(state.getScissor());
- }
-
- setViewport(state.getViewport());
- setDepthRange(state.getNearPlane(), state.getFarPlane());
-
- const gl::BlendState &blendState = state.getBlendState();
- setBlendEnabled(blendState.blend);
- if (blendState.blend)
- {
- setBlendColor(state.getBlendColor());
- setBlendFuncs(blendState.sourceBlendRGB, blendState.destBlendRGB, blendState.sourceBlendAlpha, blendState.destBlendAlpha);
- setBlendEquations(blendState.blendEquationRGB, blendState.blendEquationAlpha);
- }
- setColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, blendState.colorMaskBlue, blendState.colorMaskAlpha);
- setSampleAlphaToCoverageEnabled(blendState.sampleAlphaToCoverage);
- setSampleCoverageEnabled(state.isSampleCoverageEnabled());
- setSampleCoverage(state.getSampleCoverageValue(), state.getSampleCoverageInvert());
-
- const gl::DepthStencilState &depthStencilState = state.getDepthStencilState();
- setDepthTestEnabled(depthStencilState.depthTest);
- if (depthStencilState.depthTest)
- {
- setDepthFunc(depthStencilState.depthFunc);
- }
- setDepthMask(depthStencilState.depthMask);
-
- setStencilTestEnabled(depthStencilState.stencilTest);
- if (depthStencilState.stencilTest)
- {
- setStencilFrontFuncs(depthStencilState.stencilFunc, state.getStencilRef(), depthStencilState.stencilMask);
- setStencilBackFuncs(depthStencilState.stencilBackFunc, state.getStencilBackRef(), depthStencilState.stencilBackMask);
- setStencilFrontOps(depthStencilState.stencilFail, depthStencilState.stencilPassDepthFail, depthStencilState.stencilPassDepthPass);
- setStencilBackOps(depthStencilState.stencilBackFail, depthStencilState.stencilBackPassDepthFail, depthStencilState.stencilBackPassDepthPass);
- }
- setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask);
- setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask);
-
- const gl::RasterizerState &rasterizerState = state.getRasterizerState();
- setCullFaceEnabled(rasterizerState.cullFace);
- if (rasterizerState.cullFace)
- {
- setCullFace(rasterizerState.cullMode);
- }
- setFrontFace(rasterizerState.frontFace);
-
- setPolygonOffsetFillEnabled(rasterizerState.polygonOffsetFill);
- if (rasterizerState.polygonOffsetFill)
- {
- setPolygonOffset(rasterizerState.polygonOffsetFactor, rasterizerState.polygonOffsetUnits);
- }
-
- setMultisampleEnabled(rasterizerState.multiSample);
- setRasterizerDiscardEnabled(rasterizerState.rasterizerDiscard);
- setLineWidth(state.getLineWidth());
-
- setPrimitiveRestartEnabled(state.isPrimitiveRestartEnabled());
-
return gl::Error(GL_NO_ERROR);
}
@@ -974,4 +897,203 @@
}
}
+void StateManagerGL::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
+{
+ for (unsigned int dirtyBit : angle::IterateBitSet(dirtyBits))
+ {
+ switch (dirtyBit)
+ {
+ case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
+ setScissorTestEnabled(state.isScissorTestEnabled());
+ break;
+ case gl::State::DIRTY_BIT_SCISSOR:
+ setScissor(state.getScissor());
+ break;
+ case gl::State::DIRTY_BIT_VIEWPORT:
+ setViewport(state.getViewport());
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_RANGE:
+ setDepthRange(state.getNearPlane(), state.getFarPlane());
+ break;
+ case gl::State::DIRTY_BIT_BLEND_ENABLED:
+ setBlendEnabled(state.isBlendEnabled());
+ break;
+ case gl::State::DIRTY_BIT_BLEND_COLOR:
+ setBlendColor(state.getBlendColor());
+ break;
+ case gl::State::DIRTY_BIT_BLEND_FUNCS:
+ {
+ const auto &blendState = state.getBlendState();
+ setBlendFuncs(blendState.sourceBlendRGB, blendState.destBlendRGB,
+ blendState.sourceBlendAlpha, blendState.destBlendAlpha);
+ break;
+ }
+ case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
+ {
+ const auto &blendState = state.getBlendState();
+ setBlendEquations(blendState.blendEquationRGB, blendState.blendEquationAlpha);
+ break;
+ }
+ case gl::State::DIRTY_BIT_COLOR_MASK:
+ {
+ const auto &blendState = state.getBlendState();
+ setColorMask(blendState.colorMaskRed, blendState.colorMaskGreen,
+ blendState.colorMaskBlue, blendState.colorMaskAlpha);
+ break;
+ }
+ case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
+ setSampleAlphaToCoverageEnabled(state.isSampleAlphaToCoverageEnabled());
+ break;
+ case gl::State::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED:
+ setSampleCoverageEnabled(state.isSampleCoverageEnabled());
+ break;
+ case gl::State::DIRTY_BIT_SAMPLE_COVERAGE:
+ setSampleCoverage(state.getSampleCoverageValue(), state.getSampleCoverageInvert());
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
+ setDepthTestEnabled(state.isDepthTestEnabled());
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_FUNC:
+ setDepthFunc(state.getDepthStencilState().depthFunc);
+ break;
+ case gl::State::DIRTY_BIT_DEPTH_MASK:
+ setDepthMask(state.getDepthStencilState().depthMask);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
+ setStencilTestEnabled(state.isStencilTestEnabled());
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
+ {
+ const auto &depthStencilState = state.getDepthStencilState();
+ setStencilFrontFuncs(depthStencilState.stencilFunc, state.getStencilRef(),
+ depthStencilState.stencilMask);
+ break;
+ }
+ case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
+ {
+ const auto &depthStencilState = state.getDepthStencilState();
+ setStencilBackFuncs(depthStencilState.stencilBackFunc, state.getStencilBackRef(),
+ depthStencilState.stencilBackMask);
+ break;
+ }
+ case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
+ {
+ const auto &depthStencilState = state.getDepthStencilState();
+ setStencilFrontOps(depthStencilState.stencilFail,
+ depthStencilState.stencilPassDepthFail,
+ depthStencilState.stencilPassDepthPass);
+ break;
+ }
+ case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
+ {
+ const auto &depthStencilState = state.getDepthStencilState();
+ setStencilBackOps(depthStencilState.stencilBackFail,
+ depthStencilState.stencilBackPassDepthFail,
+ depthStencilState.stencilBackPassDepthPass);
+ break;
+ }
+ case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
+ setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask);
+ break;
+ case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
+ setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask);
+ break;
+ case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
+ setCullFaceEnabled(state.isCullFaceEnabled());
+ break;
+ case gl::State::DIRTY_BIT_CULL_FACE:
+ setCullFace(state.getRasterizerState().cullMode);
+ break;
+ case gl::State::DIRTY_BIT_FRONT_FACE:
+ setFrontFace(state.getRasterizerState().frontFace);
+ break;
+ case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
+ setPolygonOffsetFillEnabled(state.isPolygonOffsetFillEnabled());
+ break;
+ case gl::State::DIRTY_BIT_POLYGON_OFFSET:
+ {
+ const auto &rasterizerState = state.getRasterizerState();
+ setPolygonOffset(rasterizerState.polygonOffsetFactor,
+ rasterizerState.polygonOffsetUnits);
+ break;
+ }
+ case gl::State::DIRTY_BIT_MULTISAMPLE_ENABLED:
+ setMultisampleEnabled(state.getRasterizerState().multiSample);
+ break;
+ case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
+ setRasterizerDiscardEnabled(state.isRasterizerDiscardEnabled());
+ break;
+ case gl::State::DIRTY_BIT_LINE_WIDTH:
+ setLineWidth(state.getLineWidth());
+ break;
+ case gl::State::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED:
+ setPrimitiveRestartEnabled(state.isPrimitiveRestartEnabled());
+ break;
+ case gl::State::DIRTY_BIT_CLEAR_COLOR:
+ setClearColor(state.getColorClearValue());
+ break;
+ case gl::State::DIRTY_BIT_CLEAR_DEPTH:
+ setClearDepth(state.getDepthClearValue());
+ break;
+ case gl::State::DIRTY_BIT_CLEAR_STENCIL:
+ setClearStencil(state.getStencilClearValue());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_ALIGNMENT:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_UNPACK_ROW_LENGTH:
+ // TODO(jmadill): split this
+ setPixelUnpackState(state.getUnpackState());
+ break;
+ case gl::State::DIRTY_BIT_PACK_ALIGNMENT:
+ // TODO(jmadill): split this
+ setPixelPackState(state.getPackState());
+ break;
+ case gl::State::DIRTY_BIT_PACK_REVERSE_ROW_ORDER:
+ // TODO(jmadill): split this
+ setPixelPackState(state.getPackState());
+ break;
+ case gl::State::DIRTY_BIT_DITHER_ENABLED:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_GENERATE_MIPMAP_HINT:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_SHADER_DERIVATIVE_HINT:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_READ_FRAMEBUFFER_BINDING:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_READ_FRAMEBUFFER_OBJECT:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_OBJECT:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_RENDERBUFFER_BINDING:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_VERTEX_ARRAY_OBJECT:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_PROGRAM_BINDING:
+ // TODO(jmadill): implement this
+ break;
+ case gl::State::DIRTY_BIT_PROGRAM_OBJECT:
+ // TODO(jmadill): implement this
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ }
+}
}
diff --git a/src/libANGLE/renderer/gl/StateManagerGL.h b/src/libANGLE/renderer/gl/StateManagerGL.h
index 14050f4..a38c3ec 100644
--- a/src/libANGLE/renderer/gl/StateManagerGL.h
+++ b/src/libANGLE/renderer/gl/StateManagerGL.h
@@ -11,6 +11,7 @@
#include "common/debug.h"
#include "libANGLE/Error.h"
+#include "libANGLE/State.h"
#include "libANGLE/angletypes.h"
#include "libANGLE/renderer/gl/functionsgl_typedefs.h"
@@ -28,7 +29,7 @@
class FunctionsGL;
-class StateManagerGL : angle::NonCopyable
+class StateManagerGL final : angle::NonCopyable
{
public:
StateManagerGL(const FunctionsGL *functions, const gl::Caps &rendererCaps);
@@ -45,18 +46,15 @@
void bindBuffer(GLenum type, GLuint buffer);
void activeTexture(size_t unit);
void bindTexture(GLenum type, GLuint texture);
- void setPixelUnpackState(GLint alignment, GLint rowLength, GLint skipRows, GLint skipPixels,
- GLint imageHeight, GLint skipImages);
- void setPixelPackState(GLint alignment, GLint rowLength, GLint skipRows, GLint skipPixels);
void bindFramebuffer(GLenum type, GLuint framebuffer);
void bindRenderbuffer(GLenum type, GLuint renderbuffer);
- void setClearState(const gl::State &state, GLbitfield mask);
-
gl::Error setDrawArraysState(const gl::Data &data, GLint first, GLsizei count);
gl::Error setDrawElementsState(const gl::Data &data, GLsizei count, GLenum type, const GLvoid *indices,
const GLvoid **outIndices);
+ void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits);
+
private:
gl::Error setGenericDrawState(const gl::Data &data);
@@ -103,6 +101,16 @@
void setClearDepth(float clearDepth);
void setClearStencil(GLint clearStencil);
+ void setPixelUnpackState(const gl::PixelUnpackState &unpack);
+ void setPixelUnpackState(GLint alignment,
+ GLint rowLength,
+ GLint skipRows,
+ GLint skipPixels,
+ GLint imageHeight,
+ GLint skipImages);
+ void setPixelPackState(const gl::PixelPackState &pack);
+ void setPixelPackState(GLint alignment, GLint rowLength, GLint skipRows, GLint skipPixels);
+
const FunctionsGL *mFunctions;
GLuint mProgram;
diff --git a/src/libANGLE/renderer/gl/TextureGL.cpp b/src/libANGLE/renderer/gl/TextureGL.cpp
index 590a7a8..6dca94a 100644
--- a/src/libANGLE/renderer/gl/TextureGL.cpp
+++ b/src/libANGLE/renderer/gl/TextureGL.cpp
@@ -23,17 +23,6 @@
namespace rx
{
-static void SetUnpackStateForTexImage(StateManagerGL *stateManager, const gl::PixelUnpackState &unpack)
-{
- const gl::Buffer *unpackBuffer = unpack.pixelBuffer.get();
- if (unpackBuffer != nullptr)
- {
- UNIMPLEMENTED();
- }
- stateManager->setPixelUnpackState(unpack.alignment, unpack.rowLength, unpack.skipRows,
- unpack.skipPixels, unpack.imageHeight, unpack.skipImages);
-}
-
static bool UseTexImage2D(GLenum textureType)
{
return textureType == GL_TEXTURE_2D || textureType == GL_TEXTURE_CUBE_MAP;
@@ -93,8 +82,6 @@
UNUSED_ASSERTION_VARIABLE(&CompatibleTextureTarget); // Reference this function to avoid warnings.
ASSERT(CompatibleTextureTarget(mTextureType, target));
- SetUnpackStateForTexImage(mStateManager, unpack);
-
nativegl::TexImageFormat texImageFormat =
nativegl::GetTexImageFormat(mFunctions, mWorkarounds, internalFormat, format, type);
@@ -124,8 +111,6 @@
{
ASSERT(CompatibleTextureTarget(mTextureType, target));
- SetUnpackStateForTexImage(mStateManager, unpack);
-
nativegl::TexSubImageFormat texSubImageFormat =
nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type);
@@ -155,8 +140,6 @@
{
ASSERT(CompatibleTextureTarget(mTextureType, target));
- SetUnpackStateForTexImage(mStateManager, unpack);
-
nativegl::CompressedTexImageFormat compressedTexImageFormat =
nativegl::GetCompressedTexImageFormat(mFunctions, mWorkarounds, internalFormat);
@@ -185,8 +168,6 @@
{
ASSERT(CompatibleTextureTarget(mTextureType, target));
- SetUnpackStateForTexImage(mStateManager, unpack);
-
nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat =
nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, format);
diff --git a/src/libGLESv2/entry_points_gles_2_0.cpp b/src/libGLESv2/entry_points_gles_2_0.cpp
index 2773de5..64bbdc8 100644
--- a/src/libGLESv2/entry_points_gles_2_0.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0.cpp
@@ -628,7 +628,7 @@
return;
}
- Error error = framebufferObject->clear(context->getData(), mask);
+ Error error = framebufferObject->clear(context, mask);
if (error.isError())
{
context->recordError(error);
@@ -743,8 +743,9 @@
Extents size(width, height, 1);
Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
- Error error = texture->setCompressedImage(target, level, internalformat, size, context->getState().getUnpackState(),
- imageSize, reinterpret_cast<const uint8_t *>(data));
+ Error error =
+ texture->setCompressedImage(context, target, level, internalformat, size, imageSize,
+ reinterpret_cast<const uint8_t *>(data));
if (error.isError())
{
context->recordError(error);
@@ -785,11 +786,11 @@
return;
}
-
Box area(xoffset, yoffset, 0, width, height, 1);
Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
- Error error = texture->setCompressedSubImage(target, level, area, format, context->getState().getUnpackState(),
- imageSize, reinterpret_cast<const uint8_t *>(data));
+ Error error =
+ texture->setCompressedSubImage(context, target, level, area, format, imageSize,
+ reinterpret_cast<const uint8_t *>(data));
if (error.isError())
{
context->recordError(error);
@@ -3319,7 +3320,7 @@
ASSERT(framebufferObject);
Rectangle area(x, y, width, height);
- Error error = framebufferObject->readPixels(context->getState(), area, format, type, pixels);
+ Error error = framebufferObject->readPixels(context, area, format, type, pixels);
if (error.isError())
{
context->recordError(error);
@@ -3657,7 +3658,7 @@
Extents size(width, height, 1);
Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
- Error error = texture->setImage(target, level, internalformat, size, format, type, context->getState().getUnpackState(),
+ Error error = texture->setImage(context, target, level, internalformat, size, format, type,
reinterpret_cast<const uint8_t *>(pixels));
if (error.isError())
{
@@ -3810,7 +3811,7 @@
Box area(xoffset, yoffset, 0, width, height, 1);
Texture *texture = context->getTargetTexture(IsCubeMapTextureTarget(target) ? GL_TEXTURE_CUBE_MAP : target);
- Error error = texture->setSubImage(target, level, area, format, type, context->getState().getUnpackState(),
+ Error error = texture->setSubImage(context, target, level, area, format, type,
reinterpret_cast<const uint8_t *>(pixels));
if (error.isError())
{
diff --git a/src/libGLESv2/entry_points_gles_2_0_ext.cpp b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
index 851da08..f611092 100644
--- a/src/libGLESv2/entry_points_gles_2_0_ext.cpp
+++ b/src/libGLESv2/entry_points_gles_2_0_ext.cpp
@@ -496,7 +496,7 @@
ASSERT(framebufferObject);
Rectangle area(x, y, width, height);
- Error error = framebufferObject->readPixels(context->getState(), area, format, type, data);
+ Error error = framebufferObject->readPixels(context, area, format, type, data);
if (error.isError())
{
context->recordError(error);
diff --git a/src/libGLESv2/entry_points_gles_3_0.cpp b/src/libGLESv2/entry_points_gles_3_0.cpp
index f22d520..59f736e 100644
--- a/src/libGLESv2/entry_points_gles_3_0.cpp
+++ b/src/libGLESv2/entry_points_gles_3_0.cpp
@@ -109,7 +109,7 @@
Extents size(width, height, depth);
Texture *texture = context->getTargetTexture(target);
- Error error = texture->setImage(target, level, internalformat, size, format, type, context->getState().getUnpackState(),
+ Error error = texture->setImage(context, target, level, internalformat, size, format, type,
reinterpret_cast<const uint8_t *>(pixels));
if (error.isError())
{
@@ -151,7 +151,7 @@
Box area(xoffset, yoffset, zoffset, width, height, depth);
Texture *texture = context->getTargetTexture(target);
- Error error = texture->setSubImage(target, level, area, format, type, context->getState().getUnpackState(),
+ Error error = texture->setSubImage(context, target, level, area, format, type,
reinterpret_cast<const uint8_t *>(pixels));
if (error.isError())
{
@@ -214,8 +214,9 @@
Extents size(width, height, depth);
Texture *texture = context->getTargetTexture(target);
- Error error = texture->setCompressedImage(target, level, internalformat, size, context->getState().getUnpackState(),
- imageSize, reinterpret_cast<const uint8_t *>(data));
+ Error error =
+ texture->setCompressedImage(context, target, level, internalformat, size, imageSize,
+ reinterpret_cast<const uint8_t *>(data));
if (error.isError())
{
context->recordError(error);
@@ -268,8 +269,9 @@
Box area(xoffset, yoffset, zoffset, width, height, depth);
Texture *texture = context->getTargetTexture(target);
- Error error = texture->setCompressedSubImage(target, level, area, format, context->getState().getUnpackState(),
- imageSize, reinterpret_cast<const uint8_t *>(data));
+ Error error =
+ texture->setCompressedSubImage(context, target, level, area, format, imageSize,
+ reinterpret_cast<const uint8_t *>(data));
if (error.isError())
{
context->recordError(error);
@@ -1731,7 +1733,7 @@
Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
ASSERT(framebufferObject);
- Error error = framebufferObject->clearBufferiv(context->getState(), buffer, drawbuffer, value);
+ Error error = framebufferObject->clearBufferiv(context, buffer, drawbuffer, value);
if (error.isError())
{
context->recordError(error);
@@ -1771,7 +1773,7 @@
Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
ASSERT(framebufferObject);
- Error error = framebufferObject->clearBufferuiv(context->getState(), buffer, drawbuffer, value);
+ Error error = framebufferObject->clearBufferuiv(context, buffer, drawbuffer, value);
if (error.isError())
{
context->recordError(error);
@@ -1819,7 +1821,7 @@
Framebuffer *framebufferObject = context->getState().getDrawFramebuffer();
ASSERT(framebufferObject);
- Error error = framebufferObject->clearBufferfv(context->getState(), buffer, drawbuffer, value);
+ Error error = framebufferObject->clearBufferfv(context, buffer, drawbuffer, value);
if (error.isError())
{
context->recordError(error);
@@ -1865,7 +1867,7 @@
return;
}
- Error error = framebufferObject->clearBufferfi(context->getState(), buffer, drawbuffer, depth, stencil);
+ Error error = framebufferObject->clearBufferfi(context, buffer, drawbuffer, depth, stencil);
if (error.isError())
{
context->recordError(error);