Commit 1b94d432 by Jamie Madill

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/289558Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 519a5be2
......@@ -186,6 +186,9 @@ void Context::makeCurrent(egl::Surface *surface)
mHasBeenCurrent = true;
}
// TODO(jmadill): Rework this when we support ContextImpl
mState.setAllDirtyBits();
// Update default framebuffer
Framebuffer *defaultFBO = mFramebufferMap[0];
......@@ -1237,6 +1240,7 @@ bool Context::getIndexedQueryParameterInfo(GLenum target, GLenum *type, unsigned
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 @@ Error Context::drawElements(GLenum mode, GLsizei count, GLenum type,
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::initCaps(GLuint clientVersion)
}
}
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);
}
}
}
......@@ -204,6 +204,8 @@ class Context final : angle::NonCopyable
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);
......
......@@ -511,29 +511,57 @@ Error Framebuffer::invalidateSub(size_t count, const GLenum *attachments, const
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 @@ GLenum Framebuffer::getImplementationColorReadType() const
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())
{
......
......@@ -32,6 +32,7 @@ class Surface;
namespace gl
{
class Context;
class Renderbuffer;
class State;
class Texture;
......@@ -121,15 +122,23 @@ class Framebuffer
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);
......
......@@ -90,8 +90,8 @@ TEST(ImageTest, RespecificationReleasesReferences)
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 @@ TEST(ImageTest, RespecificationReleasesReferences)
.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);
......
......@@ -23,6 +23,24 @@ State::State()
{
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 @@ void State::reset()
mUnpack.pixelBuffer.set(NULL);
mProgram = NULL;
// TODO(jmadill): Is this necessary?
setAllDirtyBits();
}
const RasterizerState &State::getRasterizerState() const
......@@ -206,16 +227,19 @@ void State::setColorClearValue(float red, float green, float blue, float alpha)
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 @@ void State::setColorMask(bool red, bool green, bool blue, bool alpha)
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 @@ bool State::isRasterizerDiscardEnabled() const
void State::setRasterizerDiscard(bool enabled)
{
mRasterizer.rasterizerDiscard = enabled;
mDirtyBits.set(DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
}
bool State::isCullFaceEnabled() const
......@@ -249,16 +276,19 @@ bool State::isCullFaceEnabled() const
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 @@ bool State::isDepthTestEnabled() const
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 @@ bool State::isBlendEnabled() const
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 @@ void State::setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha
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 @@ void State::setBlendColor(float red, float green, float blue, float alpha)
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 @@ bool State::isStencilTestEnabled() const
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 @@ void State::setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stenci
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 @@ void State::setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, G
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 @@ void State::setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail
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 @@ void State::setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackP
mDepthStencil.stencilBackFail = stencilBackFail;
mDepthStencil.stencilBackPassDepthFail = stencilBackPassDepthFail;
mDepthStencil.stencilBackPassDepthPass = stencilBackPassDepthPass;
mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK);
}
GLint State::getStencilRef() const
......@@ -394,7 +438,8 @@ bool State::isPolygonOffsetFillEnabled() const
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 @@ void State::setPolygonOffsetParams(GLfloat factor, GLfloat units)
// 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 @@ bool State::isSampleAlphaToCoverageEnabled() const
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 @@ bool State::isSampleCoverageEnabled() const
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 @@ bool State::isScissorTestEnabled() const
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 @@ void State::setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height)
mScissor.y = y;
mScissor.width = width;
mScissor.height = height;
mDirtyBits.set(DIRTY_BIT_SCISSOR);
}
const Rectangle &State::getScissor() const
......@@ -471,6 +522,7 @@ bool State::isDitherEnabled() const
void State::setDither(bool enabled)
{
mBlend.dither = enabled;
mDirtyBits.set(DIRTY_BIT_DITHER_ENABLED);
}
bool State::isPrimitiveRestartEnabled() const
......@@ -481,6 +533,7 @@ bool State::isPrimitiveRestartEnabled() const
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 @@ bool State::getEnableFeature(GLenum feature)
void State::setLineWidth(GLfloat width)
{
mLineWidth = width;
mDirtyBits.set(DIRTY_BIT_LINE_WIDTH);
}
float State::getLineWidth() const
......@@ -534,11 +588,13 @@ float State::getLineWidth() const
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 @@ void State::setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height)
mViewport.y = y;
mViewport.width = width;
mViewport.height = height;
mDirtyBits.set(DIRTY_BIT_VIEWPORT);
}
const Rectangle &State::getViewport() const
......@@ -1034,6 +1091,7 @@ const void *State::getVertexAttribPointer(unsigned int attribNum) const
void State::setPackAlignment(GLint alignment)
{
mPack.alignment = alignment;
mDirtyBits.set(DIRTY_BIT_PACK_ALIGNMENT);
}
GLint State::getPackAlignment() const
......@@ -1044,6 +1102,7 @@ GLint State::getPackAlignment() const
void State::setPackReverseRowOrder(bool reverseRowOrder)
{
mPack.reverseRowOrder = reverseRowOrder;
mDirtyBits.set(DIRTY_BIT_PACK_REVERSE_ROW_ORDER);
}
bool State::getPackReverseRowOrder() const
......@@ -1064,6 +1123,7 @@ PixelPackState &State::getPackState()
void State::setUnpackAlignment(GLint alignment)
{
mUnpack.alignment = alignment;
mDirtyBits.set(DIRTY_BIT_UNPACK_ALIGNMENT);
}
GLint State::getUnpackAlignment() const
......@@ -1074,6 +1134,7 @@ GLint State::getUnpackAlignment() const
void State::setUnpackRowLength(GLint rowLength)
{
mUnpack.rowLength = rowLength;
mDirtyBits.set(DIRTY_BIT_UNPACK_ROW_LENGTH);
}
GLint State::getUnpackRowLength() const
......
......@@ -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 @@ class State : angle::NonCopyable
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 @@ class State : angle::NonCopyable
PixelPackState mPack;
bool mPrimitiveRestart;
DirtyBits mDirtyBits;
DirtyBits mUnpackStateBitMask;
DirtyBits mPackStateBitMask;
DirtyBits mClearStateBitMask;
};
}
......
......@@ -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 @@ egl::Surface *Texture::getBoundSurface() const
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 @@ Error Texture::setImage(GLenum target, size_t level, GLenum internalFormat, cons
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 @@ Error Texture::setImage(GLenum target, size_t level, GLenum internalFormat, cons
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 @@ Error Texture::setCompressedImage(GLenum target, size_t level, GLenum internalFo
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 @@ Error Texture::setCompressedImage(GLenum target, size_t level, GLenum internalFo
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);
}
......
......@@ -29,6 +29,7 @@ class Surface;
namespace gl
{
class Context;
class Framebuffer;
struct Data;
......@@ -38,8 +39,7 @@ class Texture final : public egl::ImageSibling
{
public:
Texture(rx::TextureImpl *impl, GLuint id, GLenum target);
virtual ~Texture();
~Texture();
GLenum getTarget() const;
......@@ -59,26 +59,53 @@ class Texture final : public egl::ImageSibling
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);
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);
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);
virtual Error setStorage(GLenum target, size_t levels, GLenum internalFormat, const Extents &size);
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);
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);
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);
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();
......
......@@ -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 Display;
class Surface;
}
namespace gl
{
class Buffer;
struct Data;
}
namespace rx
{
struct TranslatedIndexData;
......@@ -72,6 +67,8 @@ class Renderer : public ImplFactory
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;
......
......@@ -545,20 +545,26 @@ gl::Texture *RendererD3D::getIncompleteTexture(GLenum type)
{
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);
......
......@@ -194,6 +194,11 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
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;
......
......@@ -185,28 +185,14 @@ gl::Error FramebufferGL::invalidateSub(size_t count, const GLenum *attachments,
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::clearBufferfv(const gl::State &state, GLenum buffer, GL
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::clearBufferuiv(const gl::State &state, GLenum buffer, G
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::clearBufferiv(const gl::State &state, GLenum buffer, GL
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 @@ gl::Error FramebufferGL::readPixels(const gl::State &state, const gl::Rectangle
{
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);
......
......@@ -324,4 +324,8 @@ void RendererGL::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap* outTextureC
nativegl_gl::GenerateCaps(mFunctions, outCaps, outTextureCaps, outExtensions, &mMaxSupportedESVersion);
}
void RendererGL::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits)
{
mStateManager->syncState(state, dirtyBits);
}
}
......@@ -77,6 +77,8 @@ class RendererGL : public Renderer
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:
......
......@@ -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::bindTexture(GLenum type, GLuint texture)
}
}
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::setPixelUnpackState(GLint alignment, GLint rowLength, GLint
}
}
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::bindRenderbuffer(GLenum type, GLuint renderbuffer)
}
}
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 @@ gl::Error StateManagerGL::setGenericDrawState(const gl::Data &data)
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::setClearStencil(GLint clearStencil)
}
}
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;
}
}
}
}
......@@ -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 @@ namespace rx
class FunctionsGL;
class StateManagerGL : angle::NonCopyable
class StateManagerGL final : angle::NonCopyable
{
public:
StateManagerGL(const FunctionsGL *functions, const gl::Caps &rendererCaps);
......@@ -45,18 +46,15 @@ class StateManagerGL : angle::NonCopyable
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 @@ class StateManagerGL : angle::NonCopyable
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;
......
......@@ -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 @@ gl::Error TextureGL::setImage(GLenum target, size_t level, GLenum internalFormat
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 @@ gl::Error TextureGL::setSubImage(GLenum target, size_t level, const gl::Box &are
{
ASSERT(CompatibleTextureTarget(mTextureType, target));
SetUnpackStateForTexImage(mStateManager, unpack);
nativegl::TexSubImageFormat texSubImageFormat =
nativegl::GetTexSubImageFormat(mFunctions, mWorkarounds, format, type);
......@@ -155,8 +140,6 @@ gl::Error TextureGL::setCompressedImage(GLenum target, size_t level, GLenum inte
{
ASSERT(CompatibleTextureTarget(mTextureType, target));
SetUnpackStateForTexImage(mStateManager, unpack);
nativegl::CompressedTexImageFormat compressedTexImageFormat =
nativegl::GetCompressedTexImageFormat(mFunctions, mWorkarounds, internalFormat);
......@@ -185,8 +168,6 @@ gl::Error TextureGL::setCompressedSubImage(GLenum target, size_t level, const gl
{
ASSERT(CompatibleTextureTarget(mTextureType, target));
SetUnpackStateForTexImage(mStateManager, unpack);
nativegl::CompressedTexSubImageFormat compressedTexSubImageFormat =
nativegl::GetCompressedSubTexImageFormat(mFunctions, mWorkarounds, format);
......
......@@ -628,7 +628,7 @@ void GL_APIENTRY Clear(GLbitfield mask)
return;
}
Error error = framebufferObject->clear(context->getData(), mask);
Error error = framebufferObject->clear(context, mask);
if (error.isError())
{
context->recordError(error);
......@@ -743,8 +743,9 @@ void GL_APIENTRY CompressedTexImage2D(GLenum target, GLint level, GLenum interna
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 @@ void GL_APIENTRY CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffs
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 @@ void GL_APIENTRY ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
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 @@ void GL_APIENTRY TexImage2D(GLenum target, GLint level, GLint internalformat, GL
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 @@ void GL_APIENTRY TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint
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())
{
......
......@@ -496,7 +496,7 @@ void GL_APIENTRY ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
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);
......
......@@ -109,7 +109,7 @@ void GL_APIENTRY TexImage3D(GLenum target, GLint level, GLint internalformat, GL
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 @@ void GL_APIENTRY TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint
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 @@ void GL_APIENTRY CompressedTexImage3D(GLenum target, GLint level, GLenum interna
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 @@ void GL_APIENTRY CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffs
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 @@ void GL_APIENTRY ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint* val
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 @@ void GL_APIENTRY ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint* v
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 @@ void GL_APIENTRY ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat* v
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 @@ void GL_APIENTRY ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, G
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);
......
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