Commit 8e34494f by Jamie Madill

Share data between VertexArray and Impl.

Using the same design as for the Framebuffer::Data helper, we can use a struct to share between the object and the Impl. This also gives the Impl access to the maxEnabledAttrib, and saves some duplicated storage. BUG=angleproject:1040 TEST=WebGL CTS, end2end_tests, unittests Change-Id: I55c91e8a5f3dcae302cab441182320aafd5375ef Reviewed-on: https://chromium-review.googlesource.com/283930Tested-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarCorentin Wallez <cwallez@chromium.org> Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org>
parent 0d208976
......@@ -284,7 +284,7 @@ GLuint Context::createVertexArray()
// Although the spec states VAO state is not initialized until the object is bound,
// we create it immediately. The resulting behaviour is transparent to the application,
// since it's not currently possible to access the state until the object is bound.
VertexArray *vertexArray = new VertexArray(mRenderer->createVertexArray(), handle, MAX_VERTEX_ATTRIBS);
VertexArray *vertexArray = new VertexArray(mRenderer, handle, MAX_VERTEX_ATTRIBS);
mVertexArrayMap[handle] = vertexArray;
return handle;
}
......@@ -588,7 +588,7 @@ void Context::bindVertexArray(GLuint vertexArray)
{
if (!getVertexArray(vertexArray))
{
VertexArray *vertexArrayObject = new VertexArray(mRenderer->createVertexArray(), vertexArray, MAX_VERTEX_ATTRIBS);
VertexArray *vertexArrayObject = new VertexArray(mRenderer, vertexArray, MAX_VERTEX_ATTRIBS);
mVertexArrayMap[vertexArray] = vertexArrayObject;
}
......
......@@ -38,7 +38,7 @@ class RefCountObject : angle::NonCopyable
template <class ObjectType>
class BindingPointer
{
public:
public:
BindingPointer()
: mObject(nullptr)
{
......
......@@ -982,7 +982,7 @@ Buffer *State::getTargetBuffer(GLenum target) const
case GL_ARRAY_BUFFER: return mArrayBuffer.get();
case GL_COPY_READ_BUFFER: return mCopyReadBuffer.get();
case GL_COPY_WRITE_BUFFER: return mCopyWriteBuffer.get();
case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer();
case GL_ELEMENT_ARRAY_BUFFER: return getVertexArray()->getElementArrayBuffer().get();
case GL_PIXEL_PACK_BUFFER: return mPack.pixelBuffer.get();
case GL_PIXEL_UNPACK_BUFFER: return mUnpack.pixelBuffer.get();
case GL_TRANSFORM_FEEDBACK_BUFFER: return mTransformFeedback->getGenericBuffer().get();
......@@ -1174,7 +1174,7 @@ void State::getIntegerv(const gl::Data &data, GLenum pname, GLint *params)
switch (pname)
{
case GL_ARRAY_BUFFER_BINDING: *params = mArrayBuffer.id(); break;
case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBufferId(); break;
case GL_ELEMENT_ARRAY_BUFFER_BINDING: *params = getVertexArray()->getElementArrayBuffer().id(); break;
//case GL_FRAMEBUFFER_BINDING: // now equivalent to GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
case GL_DRAW_FRAMEBUFFER_BINDING_ANGLE: *params = mDrawFramebuffer->id(); break;
case GL_READ_FRAMEBUFFER_BINDING_ANGLE: *params = mReadFramebuffer->id(); break;
......@@ -1413,7 +1413,7 @@ bool State::hasMappedBuffer(GLenum target) const
{
const VertexArray *vao = getVertexArray();
const auto &vertexAttribs = vao->getVertexAttributes();
unsigned int maxEnabledAttrib = vao->getMaxEnabledAttribute();
size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
for (size_t attribIndex = 0; attribIndex < maxEnabledAttrib; attribIndex++)
{
const gl::VertexAttribute &vertexAttrib = vertexAttribs[attribIndex];
......
......@@ -8,29 +8,38 @@
#include "libANGLE/VertexArray.h"
#include "libANGLE/Buffer.h"
#include "libANGLE/renderer/ImplFactory.h"
#include "libANGLE/renderer/VertexArrayImpl.h"
namespace gl
{
VertexArray::VertexArray(rx::VertexArrayImpl *impl, GLuint id, size_t maxAttribs)
: mId(id),
mVertexArray(impl),
mVertexAttributes(maxAttribs),
VertexArray::Data::Data(size_t maxAttribs)
: mVertexAttributes(maxAttribs),
mMaxEnabledAttribute(0)
{
ASSERT(impl != NULL);
}
VertexArray::~VertexArray()
VertexArray::Data::~Data()
{
SafeDelete(mVertexArray);
for (size_t i = 0; i < getMaxAttribs(); i++)
{
mVertexAttributes[i].buffer.set(NULL);
mVertexAttributes[i].buffer.set(nullptr);
}
mElementArrayBuffer.set(NULL);
mElementArrayBuffer.set(nullptr);
}
VertexArray::VertexArray(rx::ImplFactory *factory, GLuint id, size_t maxAttribs)
: mId(id),
mVertexArray(factory->createVertexArray(mData)),
mData(maxAttribs)
{
ASSERT(mVertexArray != nullptr);
}
VertexArray::~VertexArray()
{
SafeDelete(mVertexArray);
}
GLuint VertexArray::id() const
......@@ -42,75 +51,74 @@ void VertexArray::detachBuffer(GLuint bufferName)
{
for (size_t attribute = 0; attribute < getMaxAttribs(); attribute++)
{
if (mVertexAttributes[attribute].buffer.id() == bufferName)
if (mData.mVertexAttributes[attribute].buffer.id() == bufferName)
{
mVertexAttributes[attribute].buffer.set(nullptr);
mVertexArray->setAttribute(attribute, mVertexAttributes[attribute]);
mData.mVertexAttributes[attribute].buffer.set(nullptr);
mVertexArray->setAttribute(attribute, mData.mVertexAttributes[attribute]);
}
}
if (mElementArrayBuffer.id() == bufferName)
if (mData.mElementArrayBuffer.id() == bufferName)
{
mElementArrayBuffer.set(nullptr);
mData.mElementArrayBuffer.set(nullptr);
mVertexArray->setElementArrayBuffer(nullptr);
}
}
const VertexAttribute& VertexArray::getVertexAttribute(size_t attributeIndex) const
const VertexAttribute &VertexArray::getVertexAttribute(size_t attributeIndex) const
{
ASSERT(attributeIndex < getMaxAttribs());
return mVertexAttributes[attributeIndex];
return mData.mVertexAttributes[attributeIndex];
}
const std::vector<VertexAttribute> &VertexArray::getVertexAttributes() const
{
return mVertexAttributes;
}
void VertexArray::setVertexAttribDivisor(GLuint index, GLuint divisor)
void VertexArray::setVertexAttribDivisor(size_t index, GLuint divisor)
{
ASSERT(index < getMaxAttribs());
mVertexAttributes[index].divisor = divisor;
mData.mVertexAttributes[index].divisor = divisor;
mVertexArray->setAttributeDivisor(index, divisor);
}
void VertexArray::enableAttribute(unsigned int attributeIndex, bool enabledState)
void VertexArray::enableAttribute(size_t attributeIndex, bool enabledState)
{
ASSERT(attributeIndex < getMaxAttribs());
mVertexAttributes[attributeIndex].enabled = enabledState;
mData.mVertexAttributes[attributeIndex].enabled = enabledState;
mVertexArray->enableAttribute(attributeIndex, enabledState);
// Update state cache
if (enabledState)
{
mMaxEnabledAttribute = std::max(attributeIndex, mMaxEnabledAttribute);
mData.mMaxEnabledAttribute = std::max(attributeIndex, mData.mMaxEnabledAttribute);
}
else if (mMaxEnabledAttribute == attributeIndex)
else if (mData.mMaxEnabledAttribute == attributeIndex)
{
while (mMaxEnabledAttribute > 0 && !mVertexAttributes[mMaxEnabledAttribute].enabled)
while (mData.mMaxEnabledAttribute > 0 && !mData.mVertexAttributes[mData.mMaxEnabledAttribute].enabled)
{
--mMaxEnabledAttribute;
--mData.mMaxEnabledAttribute;
}
}
}
void VertexArray::setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type,
void VertexArray::setAttributeState(size_t attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, bool pureInteger, GLsizei stride, const void *pointer)
{
ASSERT(attributeIndex < getMaxAttribs());
mVertexAttributes[attributeIndex].buffer.set(boundBuffer);
mVertexAttributes[attributeIndex].size = size;
mVertexAttributes[attributeIndex].type = type;
mVertexAttributes[attributeIndex].normalized = normalized;
mVertexAttributes[attributeIndex].pureInteger = pureInteger;
mVertexAttributes[attributeIndex].stride = stride;
mVertexAttributes[attributeIndex].pointer = pointer;
mVertexArray->setAttribute(attributeIndex, mVertexAttributes[attributeIndex]);
VertexAttribute *attrib = &mData.mVertexAttributes[attributeIndex];
attrib->buffer.set(boundBuffer);
attrib->size = size;
attrib->type = type;
attrib->normalized = normalized;
attrib->pureInteger = pureInteger;
attrib->stride = stride;
attrib->pointer = pointer;
mVertexArray->setAttribute(attributeIndex, *attrib);
}
void VertexArray::setElementArrayBuffer(Buffer *buffer)
{
mElementArrayBuffer.set(buffer);
mData.mElementArrayBuffer.set(buffer);
mVertexArray->setElementArrayBuffer(buffer);
}
......
......@@ -21,6 +21,7 @@
namespace rx
{
class ImplFactory;
class VertexArrayImpl;
}
......@@ -31,37 +32,54 @@ class Buffer;
class VertexArray
{
public:
VertexArray(rx::VertexArrayImpl *impl, GLuint id, size_t maxAttribs);
VertexArray(rx::ImplFactory *factory, GLuint id, size_t maxAttribs);
~VertexArray();
GLuint id() const;
const VertexAttribute& getVertexAttribute(size_t attributeIndex) const;
const std::vector<VertexAttribute> &getVertexAttributes() const;
const VertexAttribute &getVertexAttribute(size_t attributeIndex) const;
void detachBuffer(GLuint bufferName);
void setVertexAttribDivisor(GLuint index, GLuint divisor);
void enableAttribute(unsigned int attributeIndex, bool enabledState);
void setAttributeState(unsigned int attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type,
void setVertexAttribDivisor(size_t index, GLuint divisor);
void enableAttribute(size_t attributeIndex, bool enabledState);
void setAttributeState(size_t attributeIndex, gl::Buffer *boundBuffer, GLint size, GLenum type,
bool normalized, bool pureInteger, GLsizei stride, const void *pointer);
Buffer *getElementArrayBuffer() const { return mElementArrayBuffer.get(); }
void setElementArrayBuffer(Buffer *buffer);
GLuint getElementArrayBufferId() const { return mElementArrayBuffer.id(); }
size_t getMaxAttribs() const { return mVertexAttributes.size(); }
const BindingPointer<Buffer> &getElementArrayBuffer() const { return mData.getElementArrayBuffer(); }
size_t getMaxAttribs() const { return mData.getVertexAttributes().size(); }
const std::vector<VertexAttribute> &getVertexAttributes() const { return mData.getVertexAttributes(); }
rx::VertexArrayImpl *getImplementation() { return mVertexArray; }
const rx::VertexArrayImpl *getImplementation() const { return mVertexArray; }
unsigned int getMaxEnabledAttribute() const { return mMaxEnabledAttribute; }
size_t getMaxEnabledAttribute() const { return mData.getMaxEnabledAttribute(); }
class Data final : public angle::NonCopyable
{
public:
explicit Data(size_t maxAttribs);
~Data();
const BindingPointer<Buffer> &getElementArrayBuffer() const { return mElementArrayBuffer; }
size_t getMaxAttribs() const { return mVertexAttributes.size(); }
size_t getMaxEnabledAttribute() const { return mMaxEnabledAttribute; }
const std::vector<VertexAttribute> &getVertexAttributes() const { return mVertexAttributes; }
private:
friend class VertexArray;
std::vector<VertexAttribute> mVertexAttributes;
BindingPointer<Buffer> mElementArrayBuffer;
size_t mMaxEnabledAttribute;
};
private:
GLuint mId;
rx::VertexArrayImpl *mVertexArray;
std::vector<VertexAttribute> mVertexAttributes;
BindingPointer<Buffer> mElementArrayBuffer;
unsigned int mMaxEnabledAttribute;
Data mData;
};
}
......
......@@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_IMPLFACTORY_H_
#include "libANGLE/Framebuffer.h"
#include "libANGLE/VertexArray.h"
namespace rx
{
......@@ -52,7 +53,7 @@ class ImplFactory : angle::NonCopyable
virtual BufferImpl *createBuffer() = 0;
// Vertex Array creation
virtual VertexArrayImpl *createVertexArray() = 0;
virtual VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) = 0;
// Query and Fence creation
virtual QueryImpl *createQuery(GLenum type) = 0;
......
......@@ -11,7 +11,7 @@
#include "common/angleutils.h"
#include "libANGLE/Buffer.h"
#include "libANGLE/VertexAttribute.h"
#include "libANGLE/VertexArray.h"
namespace rx
{
......@@ -19,12 +19,16 @@ namespace rx
class VertexArrayImpl : angle::NonCopyable
{
public:
VertexArrayImpl(const gl::VertexArray::Data &data) : mData(data) { }
virtual ~VertexArrayImpl() { }
virtual void setElementArrayBuffer(const gl::Buffer *buffer) = 0;
virtual void setAttribute(size_t idx, const gl::VertexAttribute &attr) = 0;
virtual void setAttributeDivisor(size_t idx, GLuint divisor) = 0;
virtual void enableAttribute(size_t idx, bool enabledState) = 0;
protected:
const gl::VertexArray::Data &mData;
};
}
......
......@@ -111,7 +111,7 @@ gl::Error RendererD3D::drawElements(const gl::Data &data,
SourceIndexData sourceIndexInfo;
error = applyIndexBuffer(indices, vao->getElementArrayBuffer(), count, mode, type, &indexInfo, &sourceIndexInfo);
error = applyIndexBuffer(indices, vao->getElementArrayBuffer().get(), count, mode, type, &indexInfo, &sourceIndexInfo);
if (error.isError())
{
return error;
......@@ -149,7 +149,7 @@ gl::Error RendererD3D::drawElements(const gl::Data &data,
if (!skipDraw(data, mode))
{
error = drawElements(mode, count, type, indices, vao->getElementArrayBuffer(), indexInfo, instances, program->usesPointSize());
error = drawElements(mode, count, type, indices, vao->getElementArrayBuffer().get(), indexInfo, instances, program->usesPointSize());
if (error.isError())
{
return error;
......
......@@ -3162,9 +3162,9 @@ BufferImpl *Renderer11::createBuffer()
return new Buffer11(this);
}
VertexArrayImpl *Renderer11::createVertexArray()
VertexArrayImpl *Renderer11::createVertexArray(const gl::VertexArray::Data &data)
{
return new VertexArray11(this);
return new VertexArray11(data);
}
QueryImpl *Renderer11::createQuery(GLenum type)
......
......@@ -220,7 +220,7 @@ class Renderer11 : public RendererD3D
virtual IndexBuffer *createIndexBuffer();
// Vertex Array creation
virtual VertexArrayImpl *createVertexArray();
VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override;
// Query and Fence creation
virtual QueryImpl *createQuery(GLenum type);
......
......@@ -19,8 +19,8 @@ class Renderer11;
class VertexArray11 : public VertexArrayImpl
{
public:
VertexArray11(Renderer11 *renderer)
: VertexArrayImpl()
VertexArray11(const gl::VertexArray::Data &data)
: VertexArrayImpl(data)
{
}
virtual ~VertexArray11() { }
......
......@@ -714,9 +714,9 @@ BufferImpl *Renderer9::createBuffer()
return new Buffer9(this);
}
VertexArrayImpl *Renderer9::createVertexArray()
VertexArrayImpl *Renderer9::createVertexArray(const gl::VertexArray::Data &data)
{
return new VertexArray9(this);
return new VertexArray9(data);
}
QueryImpl *Renderer9::createQuery(GLenum type)
......
......@@ -206,7 +206,7 @@ class Renderer9 : public RendererD3D
virtual IndexBuffer *createIndexBuffer();
// Vertex Array creation
virtual VertexArrayImpl *createVertexArray();
VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override;
// Query and Fence creation
virtual QueryImpl *createQuery(GLenum type);
......
......@@ -19,8 +19,8 @@ class Renderer9;
class VertexArray9 : public VertexArrayImpl
{
public:
VertexArray9(Renderer9 *renderer)
: VertexArrayImpl()
VertexArray9(const gl::VertexArray::Data &data)
: VertexArrayImpl(data)
{
}
......
......@@ -205,9 +205,9 @@ BufferImpl *RendererGL::createBuffer()
return new BufferGL(mFunctions, mStateManager);
}
VertexArrayImpl *RendererGL::createVertexArray()
VertexArrayImpl *RendererGL::createVertexArray(const gl::VertexArray::Data &data)
{
return new VertexArrayGL(mFunctions, mStateManager);
return new VertexArrayGL(data, mFunctions, mStateManager);
}
QueryImpl *RendererGL::createQuery(GLenum type)
......
......@@ -51,7 +51,7 @@ class RendererGL : public Renderer
BufferImpl *createBuffer() override;
// Vertex Array creation
VertexArrayImpl *createVertexArray() override;
VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override;
// Query and Fence creation
QueryImpl *createQuery(GLenum type) override;
......
......@@ -20,7 +20,7 @@ class StateManagerGL;
class VertexArrayGL : public VertexArrayImpl
{
public:
VertexArrayGL(const FunctionsGL *functions, StateManagerGL *stateManager);
VertexArrayGL(const gl::VertexArray::Data &data, const FunctionsGL *functions, StateManagerGL *stateManager);
~VertexArrayGL() override;
void setElementArrayBuffer(const gl::Buffer *buffer) override;
......@@ -57,9 +57,6 @@ class VertexArrayGL : public VertexArrayImpl
GLuint mVertexArrayID;
BindingPointer<const gl::Buffer> mElementArrayBuffer;
std::vector<gl::VertexAttribute> mAttributes;
mutable GLuint mAppliedElementArrayBuffer;
mutable std::vector<gl::VertexAttribute> mAppliedAttributes;
......
......@@ -1406,7 +1406,7 @@ static bool ValidateDrawBase(Context *context, GLenum mode, GLsizei count, GLsiz
const VertexArray *vao = state.getVertexArray();
const auto &vertexAttribs = vao->getVertexAttributes();
const int *semanticIndexes = program->getSemanticIndexes();
unsigned int maxEnabledAttrib = vao->getMaxEnabledAttribute();
size_t maxEnabledAttrib = vao->getMaxEnabledAttribute();
for (size_t attributeIndex = 0; attributeIndex < maxEnabledAttrib; ++attributeIndex)
{
const VertexAttribute &attrib = vertexAttribs[attributeIndex];
......@@ -1601,7 +1601,7 @@ bool ValidateDrawElements(Context *context, GLenum mode, GLsizei count, GLenum t
}
const gl::VertexArray *vao = state.getVertexArray();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer();
gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get();
if (!indices && !elementArrayBuffer)
{
context->recordError(Error(GL_INVALID_OPERATION));
......
......@@ -39,7 +39,7 @@ class NullFactory : public ImplFactory
BufferImpl *createBuffer() override { return nullptr; }
// Vertex Array creation
VertexArrayImpl *createVertexArray() override { return nullptr; }
VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override { return nullptr; }
// Query and Fence creation
QueryImpl *createQuery(GLenum type) override { return nullptr; }
......
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