tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit cc900f29e5c40b15e8c0fcf21d3baa6ee90f929a
parent b60c123daa3f1616689ca1c7f8a13e4c803f6042
Author: Jamie Nicol <jnicol@mozilla.com>
Date:   Wed, 15 Oct 2025 19:46:13 +0000

Bug 1983036 - Pad vertex buffers with space for an extra vertex on Xclipse GPUs. r=gfx-reviewers,nical

On devices with Samsung Xclipse GPUs running Android 15, we see broken
rendering due to attribute data residing at the end of a vertex buffer
not being read correctly. Ensuring we pad the size of vertex buffers
by an additional GL_MAX_VERTEX_ATTRIB_STRIDE bytes (i.e. definitely
enough space for one additional vertex) avoids the issue.

Differential Revision: https://phabricator.services.mozilla.com/D268727

Diffstat:
Mgfx/gl/GLContext.cpp | 10++++++++++
Mgfx/gl/GLContext.h | 13++++++++++++-
2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp @@ -885,6 +885,7 @@ bool GLContext::InitImpl() { raw_fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, &mMaxCubeMapTextureSize); raw_fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, &mMaxRenderbufferSize); raw_fGetIntegerv(LOCAL_GL_MAX_VIEWPORT_DIMS, mMaxViewportDims); + raw_fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIB_STRIDE, &mMaxVertexAttribStride); if (mWorkAroundDriverBugs) { int maxTexSize = INT32_MAX; @@ -942,6 +943,15 @@ bool GLContext::InitImpl() { mMaxTexOrRbSize = std::min(mMaxTextureSize, mMaxRenderbufferSize); +#ifdef MOZ_WIDGET_ANDROID + if (Renderer() == GLRenderer::SamsungXclipse && jni::GetAPIVersion() == 35) { + // On Samsung Xclipse GPUs on Android 15 attribute values for the final + // vertex in a buffer may be incorrect. Padding the buffer to contain + // enough space for an additional vertex avoids the issue. See bug 1983036. + mVertexBufferExtraPadding = Some(mMaxVertexAttribStride); + } +#endif + //////////////////////////////////////////////////////////////////////////// // We're ready for final setup. diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h @@ -899,7 +899,14 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr { public: void fBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage) { - raw_fBufferData(target, size, data, usage); + if (WorkAroundDriverBugs() && target == LOCAL_GL_ARRAY_BUFFER && + mVertexBufferExtraPadding) { + raw_fBufferData(target, size + *mVertexBufferExtraPadding, nullptr, + usage); + fBufferSubData(target, 0, size, data); + } else { + raw_fBufferData(target, size, data, usage); + } // bug 744888 if (WorkAroundDriverBugs() && !data && Vendor() == GLVendor::NVIDIA) { @@ -3909,10 +3916,14 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr { GLint mMaxCubeMapTextureSize = 0; GLint mMaxRenderbufferSize = 0; GLint mMaxViewportDims[2] = {}; + GLint mMaxVertexAttribStride = 0; GLsizei mMaxSamples = 0; bool mNeedsTextureSizeChecks = false; bool mNeedsFlushBeforeDeleteFB = false; bool mTextureAllocCrashesOnMapFailure = false; + // Amount of additional padding bytes that must be allocated for + // GL_ARRAY_BUFFER buffers. + Maybe<GLint> mVertexBufferExtraPadding; const bool mWorkAroundDriverBugs; mutable uint64_t mSyncGLCallCount = 0;