Hash :
b4d84458
Author :
Date :
2025-05-23T18:08:19
Move Buffer from VertexBinding to VertexArray In later CL we will not taking shared context lock for certain VertexArray API calls. VertexArray itself is per context, so this sounds reasonable to do. The main challenge here is a lot of VertexArray function end up accessing gl::Buffer object, which could be modified by other shared contexts. In order to safely not taking the shared context lock, we need to separate out Buffer object out of VertexArray itself so that these lockless APIs will take VertexArray that does not have access to buffer. In this CL, VertexArray is split into two classes: VertexArrayPrivate is everything in VertexArray except buffers. VertexArray is a subclass of VertexArrayPrivate and owns all the buffers. Buffer is removed from gl::VertexBinding class. In order to let back end access to buffers, VertexArrayImpl holds a weak reference to VertexArray::mVertexArrayBuffers (which is a vector of buffers). Further, VertexArrayBufferBindingMask mBufferBindingMask is moved from VertexArrayState into VertexArray class well, since it tracks which index has a non-null buffer. The bulk of change are due to the VertexARrayImpl constructor change, since it now takes vertexArrayBuffers argument. Other bulk of changes are due to VertexBinding no long has the buffer, but you need to get it directly from VertexArray or VertexArrayImpl. This CL also reverts some of the change in crrev.com/c/6758215 that mVertexBindings no longer contains kElementArrayBufferIndex. BYPASS_LARGE_CHANGE_WARNING Bug: b/433331119 Change-Id: I15f4576f7c5c8d8f4d9c9c07d38a60ce539bfeea Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/6774702 Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Amirali Abdolrashidi <abdolrashidi@google.com> Commit-Queue: Charlie Lao <cclao@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
//
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// VertexAttribImpl.h: Defines the abstract rx::VertexAttribImpl class.
#ifndef LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_
#define LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_
#include "common/angleutils.h"
#include "libANGLE/Buffer.h"
#include "libANGLE/VertexArray.h"
#include "libANGLE/angletypes.h"
// This is a helper X macro for iterating over all dirty attribs/bindings. Useful for dirty bits.
static_assert(gl::MAX_VERTEX_ATTRIBS == 16, "Invalid max vertex attribs");
static_assert(gl::MAX_VERTEX_ATTRIB_BINDINGS == 16, "Invalid max vertex bindings");
#define ANGLE_VERTEX_INDEX_CASES(FUNC) \
FUNC(0) \
FUNC(1) \
FUNC(2) \
FUNC(3) \
FUNC(4) \
FUNC(5) FUNC(6) FUNC(7) FUNC(8) FUNC(9) FUNC(10) FUNC(11) FUNC(12) FUNC(13) FUNC(14) FUNC(15)
namespace rx
{
class ContextImpl;
class VertexArrayImpl : angle::NonCopyable
{
public:
VertexArrayImpl(const gl::VertexArrayState &state,
const gl::VertexArrayBuffers &vertexArrayBuffers)
: mState(state), mVertexArrayBuffers(vertexArrayBuffers)
{
// ElementBuffer always observe the buffer content change.
mContentsObserverBindingsMask.set(gl::kElementArrayBufferIndex);
}
// This gives backend an opportunity to check buffers to see if buffer has been modified that
// requires VertexArray sync.
virtual gl::VertexArray::DirtyBits checkBufferForDirtyBits(
const gl::Context *context,
const gl::VertexArrayBufferBindingMask bufferBindingMask);
// It's up to the implementation to reset the attrib and binding dirty bits.
// This is faster than the front-end having to clear all the bits after they have been scanned.
virtual angle::Result syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits,
gl::VertexArray::DirtyAttribBitsArray *attribBits,
gl::VertexArray::DirtyBindingBitsArray *bindingBits);
virtual void destroy(const gl::Context *context) {}
virtual ~VertexArrayImpl() {}
const gl::VertexArrayState &getState() const { return mState; }
gl::VertexArrayBufferBindingMask getContentObserversBindingMask() const
{
return mContentsObserverBindingsMask;
}
virtual angle::Result onLabelUpdate(const gl::Context *context);
gl::Buffer *getElementArrayBuffer() const
{
return mVertexArrayBuffers[gl::kElementArrayBufferIndex].get();
}
gl::Buffer *getVertexArrayBuffer(size_t bindingIndex) const
{
ASSERT(bindingIndex != gl::kElementArrayBufferIndex);
return mVertexArrayBuffers[bindingIndex].get();
}
const gl::BindingPointer<gl::Buffer> &getBufferBindingPointer(size_t bindingIndex) const
{
return mVertexArrayBuffers[bindingIndex];
}
protected:
const gl::VertexArrayState &mState;
const gl::VertexArrayBuffers &mVertexArrayBuffers;
// Tracks back end's needs for buffer content change at each binding index. If the bit is set,
// current context's VertexArray will be notified when a related buffer data has changed along
// with this bit mask.
gl::VertexArrayBufferBindingMask mContentsObserverBindingsMask;
};
inline gl::VertexArray::DirtyBits VertexArrayImpl::checkBufferForDirtyBits(
const gl::Context *context,
const gl::VertexArrayBufferBindingMask bufferBindingMask)
{
// For now we just simply assume buffer storage has changed and always dirty all
// binding points.
uint64_t bits = bufferBindingMask.bits();
bits <<= gl::VertexArray::DIRTY_BIT_BINDING_0;
return gl::VertexArray::DirtyBits(bits);
}
inline angle::Result VertexArrayImpl::syncState(const gl::Context *context,
const gl::VertexArray::DirtyBits &dirtyBits,
gl::VertexArray::DirtyAttribBitsArray *attribBits,
gl::VertexArray::DirtyBindingBitsArray *bindingBits)
{
return angle::Result::Continue;
}
} // namespace rx
#endif // LIBANGLE_RENDERER_VERTEXARRAYIMPL_H_