Bug 1289655 - Add primitive restart for WebGL 2. - r=mtseng
MozReview-Commit-ID: 6SfI8yfROGI
--- a/dom/canvas/WebGL2Context.cpp
+++ b/dom/canvas/WebGL2Context.cpp
@@ -128,16 +128,19 @@ WebGLContext::InitWebGL2(FailureReason*
#ifdef XP_MACOSX
// On OSX, GL core profile is used. This requires texture swizzle
// support to emulate legacy texture formats: ALPHA, LUMINANCE,
// and LUMINANCE_ALPHA.
fnGatherMissing(gl::GLFeature::texture_swizzle);
#endif
+ fnGatherMissing2(gl::GLFeature::prim_restart_fixed,
+ gl::GLFeature::prim_restart);
+
////
if (missingList.size()) {
nsAutoCString exts;
for (auto itr = missingList.begin(); itr != missingList.end(); ++itr) {
exts.AppendLiteral("\n ");
exts.Append(gl::GLContext::GetFeatureName(*itr));
}
@@ -156,23 +159,31 @@ WebGLContext::InitWebGL2(FailureReason*
&mGLMaxUniformBufferBindings);
mBoundTransformFeedbackBuffers.SetLength(mGLMaxTransformFeedbackSeparateAttribs);
mBoundUniformBuffers.SetLength(mGLMaxUniformBufferBindings);
mDefaultTransformFeedback = new WebGLTransformFeedback(this, 0);
mBoundTransformFeedback = mDefaultTransformFeedback;
+ ////
+
if (!gl->IsGLES()) {
// Desktop OpenGL requires the following to be enabled in order to
// support sRGB operations on framebuffers.
- gl->MakeCurrent();
gl->fEnable(LOCAL_GL_FRAMEBUFFER_SRGB_EXT);
}
+ if (gl->IsSupported(gl::GLFeature::prim_restart_fixed)) {
+ gl->fEnable(LOCAL_GL_PRIMITIVE_RESTART_FIXED_INDEX);
+ } else {
+ MOZ_ASSERT(gl->IsSupported(gl::GLFeature::prim_restart));
+ gl->fEnable(LOCAL_GL_PRIMITIVE_RESTART);
+ }
+
//////
static const GLenum kWebGL2_CompressedFormats[] = {
LOCAL_GL_COMPRESSED_R11_EAC,
LOCAL_GL_COMPRESSED_SIGNED_R11_EAC,
LOCAL_GL_COMPRESSED_RG11_EAC,
LOCAL_GL_COMPRESSED_SIGNED_RG11_EAC,
LOCAL_GL_COMPRESSED_RGB8_ETC2,
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -914,16 +914,18 @@ protected:
WebGLTexture** const out_texture,
WebGLTexture::ImageInfo** const out_imageInfo);
bool ValidateUnpackInfo(const char* funcName, bool usePBOs, GLenum format,
GLenum type, webgl::PackingInfo* const out);
// -----------------------------------------------------------------------------
// Vertices Feature (WebGLContextVertices.cpp)
+ GLenum mPrimRestartTypeBytes;
+
public:
void DrawArrays(GLenum mode, GLint first, GLsizei count);
void DrawArraysInstanced(GLenum mode, GLint first, GLsizei count,
GLsizei primcount);
void DrawElements(GLenum mode, GLsizei count, GLenum type,
WebGLintptr byteOffset);
void DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type,
WebGLintptr byteOffset, GLsizei primcount);
--- a/dom/canvas/WebGLContextDraw.cpp
+++ b/dom/canvas/WebGLContextDraw.cpp
@@ -253,16 +253,25 @@ WebGLContext::DrawArrays_check(GLint fir
ErrorInvalidValue("%s: negative primcount", info);
return false;
}
if (!ValidateStencilParamsForDrawCall()) {
return false;
}
+ if (IsWebGL2() && !gl->IsSupported(gl::GLFeature::prim_restart_fixed)) {
+ MOZ_ASSERT(gl->IsSupported(gl::GLFeature::prim_restart));
+ if (mPrimRestartTypeBytes) {
+ mPrimRestartTypeBytes = 0;
+
+ gl->fPrimitiveRestartIndex(0);
+ }
+ }
+
// If count is 0, there's nothing to do.
if (count == 0 || primcount == 0) {
return false;
}
if (!ValidateBufferFetching(info)) {
return false;
}
@@ -409,16 +418,30 @@ WebGLContext::DrawElements_check(GLsizei
}
if (byteOffset % bytesPerElem != 0) {
ErrorInvalidOperation("%s: `byteOffset` must be a multiple of the size of `type`",
info);
return false;
}
+ ////
+
+ if (IsWebGL2() && !gl->IsSupported(gl::GLFeature::prim_restart_fixed)) {
+ MOZ_ASSERT(gl->IsSupported(gl::GLFeature::prim_restart));
+ if (mPrimRestartTypeBytes != bytesPerElem) {
+ mPrimRestartTypeBytes = bytesPerElem;
+
+ const uint32_t ones = UINT32_MAX >> (4 - mPrimRestartTypeBytes);
+ gl->fPrimitiveRestartIndex(ones);
+ }
+ }
+
+ ////
+
const GLsizei first = byteOffset / bytesPerElem;
const CheckedUint32 checked_byteCount = bytesPerElem * CheckedUint32(count);
if (!checked_byteCount.isValid()) {
ErrorInvalidValue("%s: overflow in byteCount", info);
return false;
}
--- a/dom/canvas/WebGLContextValidate.cpp
+++ b/dom/canvas/WebGLContextValidate.cpp
@@ -996,16 +996,18 @@ WebGLContext::InitAndValidateGL(FailureR
mPixelStore_UnpackSkipRows = 0;
mPixelStore_UnpackSkipPixels = 0;
mPixelStore_UnpackAlignment = 4;
mPixelStore_PackRowLength = 0;
mPixelStore_PackSkipRows = 0;
mPixelStore_PackSkipPixels = 0;
mPixelStore_PackAlignment = 4;
+ mPrimRestartTypeBytes = 0;
+
return true;
}
bool
WebGLContext::ValidateFramebufferTarget(GLenum target,
const char* const info)
{
bool isValid = true;