mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 1879178 - Add UninitializedBufferData_SizeOnly for unitialized orphaning of WebGL buffers. r=jgilbert
Currently BufferData when supplied null data, a pattern explicitly recommended in OpenGL for orphaning buffer before they are subsequently filled with BufferSubData, currently causes zero data to be calloc'd and uploaded to the buffer, which can be expensive. In trusted code that only directly accesses WebGLContext, we can add an UninitializedBufferData_SizeOnly call that can be used for this initialization, with the understanding that subsequent BufferSubData calls will fill in relevant sections of the buffer before they are ever used. Differential Revision: https://phabricator.services.mozilla.com/D201176
This commit is contained in:
parent
96f3f29b27
commit
2590ec2804
@ -1256,9 +1256,9 @@ static const float kRectVertexData[12] = {0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f,
|
||||
// buffers.
|
||||
void SharedContextWebgl::ResetPathVertexBuffer(bool aChanged) {
|
||||
mWebgl->BindBuffer(LOCAL_GL_ARRAY_BUFFER, mPathVertexBuffer.get());
|
||||
mWebgl->BufferData(
|
||||
mWebgl->UninitializedBufferData_SizeOnly(
|
||||
LOCAL_GL_ARRAY_BUFFER,
|
||||
std::max(size_t(mPathVertexCapacity), sizeof(kRectVertexData)), nullptr,
|
||||
std::max(size_t(mPathVertexCapacity), sizeof(kRectVertexData)),
|
||||
LOCAL_GL_DYNAMIC_DRAW);
|
||||
mWebgl->BufferSubData(LOCAL_GL_ARRAY_BUFFER, 0, sizeof(kRectVertexData),
|
||||
(const uint8_t*)kRectVertexData);
|
||||
|
@ -75,7 +75,8 @@ static bool ValidateBufferUsageEnum(WebGLContext* webgl, GLenum usage) {
|
||||
}
|
||||
|
||||
void WebGLBuffer::BufferData(const GLenum target, const uint64_t size,
|
||||
const void* const maybeData, const GLenum usage) {
|
||||
const void* const maybeData, const GLenum usage,
|
||||
bool allowUninitialized) {
|
||||
// The driver knows only GLsizeiptr, which is int32_t on 32bit!
|
||||
bool sizeValid = CheckedInt<GLsizeiptr>(size).isValid();
|
||||
|
||||
@ -104,7 +105,7 @@ void WebGLBuffer::BufferData(const GLenum target, const uint64_t size,
|
||||
|
||||
const void* uploadData = maybeData;
|
||||
UniqueBuffer maybeCalloc;
|
||||
if (!uploadData) {
|
||||
if (!uploadData && !allowUninitialized) {
|
||||
maybeCalloc = UniqueBuffer::Take(calloc(1, AssertedCast<size_t>(size)));
|
||||
if (!maybeCalloc) {
|
||||
mContext->ErrorOutOfMemory("Failed to alloc zeros.");
|
||||
@ -112,7 +113,7 @@ void WebGLBuffer::BufferData(const GLenum target, const uint64_t size,
|
||||
}
|
||||
uploadData = maybeCalloc.get();
|
||||
}
|
||||
MOZ_ASSERT(uploadData);
|
||||
MOZ_ASSERT(uploadData || allowUninitialized);
|
||||
|
||||
UniqueBuffer newIndexCache;
|
||||
const bool needsIndexCache = mContext->mNeedsIndexValidation ||
|
||||
|
@ -41,7 +41,8 @@ class WebGLBuffer final : public WebGLContextBoundObject {
|
||||
bool ValidateRange(size_t byteOffset, size_t byteLen) const;
|
||||
|
||||
bool ValidateCanBindToTarget(GLenum target);
|
||||
void BufferData(GLenum target, uint64_t size, const void* data, GLenum usage);
|
||||
void BufferData(GLenum target, uint64_t size, const void* data, GLenum usage,
|
||||
bool allowUninitialized = false);
|
||||
void BufferSubData(GLenum target, uint64_t dstByteOffset, uint64_t dataLen,
|
||||
const void* data, bool unsynchronized = false) const;
|
||||
|
||||
|
@ -685,6 +685,8 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr {
|
||||
|
||||
void BufferData(GLenum target, uint64_t dataLen, const uint8_t* data,
|
||||
GLenum usage) const;
|
||||
void UninitializedBufferData_SizeOnly(GLenum target, uint64_t dataLen,
|
||||
GLenum usage) const;
|
||||
// The unsynchronized flag may allow for better performance when
|
||||
// interleaving buffer updates with draw calls. However, care must
|
||||
// be taken. This has similar semantics to glMapBufferRange's
|
||||
|
@ -251,6 +251,18 @@ void WebGLContext::BufferData(GLenum target, uint64_t dataLen,
|
||||
buffer->BufferData(target, dataLen, data, usage);
|
||||
}
|
||||
|
||||
void WebGLContext::UninitializedBufferData_SizeOnly(GLenum target,
|
||||
uint64_t dataLen,
|
||||
GLenum usage) const {
|
||||
const FuncScope funcScope(*this, "bufferData");
|
||||
if (IsContextLost()) return;
|
||||
|
||||
const auto& buffer = ValidateBufferSelection(target);
|
||||
if (!buffer) return;
|
||||
|
||||
buffer->BufferData(target, dataLen, nullptr, usage, true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
|
||||
void WebGLContext::BufferSubData(GLenum target, uint64_t dstByteOffset,
|
||||
|
Loading…
Reference in New Issue
Block a user