2009-09-03 04:47:49 +04:00
|
|
|
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2009-09-18 10:01:12 +04:00
|
|
|
|
2009-09-03 04:47:49 +04:00
|
|
|
#include "WebGLContext.h"
|
2014-10-23 00:57:53 +04:00
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include "angle/ShaderLang.h"
|
|
|
|
#include "CanvasUtils.h"
|
2015-10-12 06:21:03 +03:00
|
|
|
#include "gfxPrefs.h"
|
2014-10-23 00:57:53 +04:00
|
|
|
#include "GLContext.h"
|
|
|
|
#include "jsfriendapi.h"
|
|
|
|
#include "mozilla/CheckedInt.h"
|
|
|
|
#include "mozilla/Preferences.h"
|
|
|
|
#include "mozilla/Services.h"
|
|
|
|
#include "nsIObserverService.h"
|
2016-07-22 09:25:41 +03:00
|
|
|
#include "nsPrintfCString.h"
|
2015-07-15 03:37:28 +03:00
|
|
|
#include "WebGLActiveInfo.h"
|
2013-06-11 00:00:35 +04:00
|
|
|
#include "WebGLBuffer.h"
|
2014-10-23 00:57:53 +04:00
|
|
|
#include "WebGLContextUtils.h"
|
2013-06-11 00:00:35 +04:00
|
|
|
#include "WebGLFramebuffer.h"
|
2014-10-23 00:57:53 +04:00
|
|
|
#include "WebGLProgram.h"
|
2013-06-11 00:00:35 +04:00
|
|
|
#include "WebGLRenderbuffer.h"
|
2015-07-15 03:37:28 +03:00
|
|
|
#include "WebGLSampler.h"
|
2014-10-23 00:57:53 +04:00
|
|
|
#include "WebGLShader.h"
|
2013-06-11 00:00:35 +04:00
|
|
|
#include "WebGLTexture.h"
|
2014-10-23 00:57:53 +04:00
|
|
|
#include "WebGLUniformLocation.h"
|
2015-01-16 02:40:39 +03:00
|
|
|
#include "WebGLValidateStrings.h"
|
2013-06-28 01:07:21 +04:00
|
|
|
#include "WebGLVertexArray.h"
|
2014-10-23 00:57:53 +04:00
|
|
|
#include "WebGLVertexAttribData.h"
|
2012-03-03 00:42:49 +04:00
|
|
|
|
2014-10-23 00:57:53 +04:00
|
|
|
#if defined(MOZ_WIDGET_COCOA)
|
|
|
|
#include "nsCocoaFeatures.h"
|
|
|
|
#endif
|
2012-04-22 00:48:22 +04:00
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
namespace mozilla {
|
2009-09-03 04:47:49 +04:00
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
bool
|
|
|
|
WebGLContext::ValidateBlendEquationEnum(GLenum mode, const char* info)
|
2010-06-19 18:48:44 +04:00
|
|
|
{
|
|
|
|
switch (mode) {
|
2014-11-14 07:03:50 +03:00
|
|
|
case LOCAL_GL_FUNC_ADD:
|
|
|
|
case LOCAL_GL_FUNC_SUBTRACT:
|
|
|
|
case LOCAL_GL_FUNC_REVERSE_SUBTRACT:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case LOCAL_GL_MIN:
|
|
|
|
case LOCAL_GL_MAX:
|
2015-11-25 07:15:29 +03:00
|
|
|
if (IsWebGL2() ||
|
|
|
|
IsExtensionEnabled(WebGLExtensionID::EXT_blend_minmax))
|
|
|
|
{
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2015-11-25 07:15:29 +03:00
|
|
|
}
|
2014-11-14 07:03:50 +03:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
2010-06-19 18:48:44 +04:00
|
|
|
}
|
2013-07-18 19:24:23 +04:00
|
|
|
|
|
|
|
ErrorInvalidEnumInfo(info, mode);
|
|
|
|
return false;
|
2010-06-19 18:48:44 +04:00
|
|
|
}
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
bool
|
|
|
|
WebGLContext::ValidateBlendFuncDstEnum(GLenum factor, const char* info)
|
2010-06-19 18:48:44 +04:00
|
|
|
{
|
|
|
|
switch (factor) {
|
2014-11-14 07:03:50 +03:00
|
|
|
case LOCAL_GL_ZERO:
|
|
|
|
case LOCAL_GL_ONE:
|
|
|
|
case LOCAL_GL_SRC_COLOR:
|
|
|
|
case LOCAL_GL_ONE_MINUS_SRC_COLOR:
|
|
|
|
case LOCAL_GL_DST_COLOR:
|
|
|
|
case LOCAL_GL_ONE_MINUS_DST_COLOR:
|
|
|
|
case LOCAL_GL_SRC_ALPHA:
|
|
|
|
case LOCAL_GL_ONE_MINUS_SRC_ALPHA:
|
|
|
|
case LOCAL_GL_DST_ALPHA:
|
|
|
|
case LOCAL_GL_ONE_MINUS_DST_ALPHA:
|
|
|
|
case LOCAL_GL_CONSTANT_COLOR:
|
|
|
|
case LOCAL_GL_ONE_MINUS_CONSTANT_COLOR:
|
|
|
|
case LOCAL_GL_CONSTANT_ALPHA:
|
|
|
|
case LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ErrorInvalidEnumInfo(info, factor);
|
|
|
|
return false;
|
2010-06-19 18:48:44 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
bool
|
|
|
|
WebGLContext::ValidateBlendFuncSrcEnum(GLenum factor, const char* info)
|
2010-06-19 18:48:44 +04:00
|
|
|
{
|
2010-06-30 19:49:59 +04:00
|
|
|
if (factor == LOCAL_GL_SRC_ALPHA_SATURATE)
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2014-11-14 07:03:50 +03:00
|
|
|
|
|
|
|
return ValidateBlendFuncDstEnum(factor, info);
|
2010-06-19 18:48:44 +04:00
|
|
|
}
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
bool
|
|
|
|
WebGLContext::ValidateBlendFuncEnumsCompatibility(GLenum sfactor,
|
|
|
|
GLenum dfactor,
|
|
|
|
const char* info)
|
2010-12-06 14:34:35 +03:00
|
|
|
{
|
2011-09-29 10:19:26 +04:00
|
|
|
bool sfactorIsConstantColor = sfactor == LOCAL_GL_CONSTANT_COLOR ||
|
2014-11-14 07:03:50 +03:00
|
|
|
sfactor == LOCAL_GL_ONE_MINUS_CONSTANT_COLOR;
|
2011-09-29 10:19:26 +04:00
|
|
|
bool sfactorIsConstantAlpha = sfactor == LOCAL_GL_CONSTANT_ALPHA ||
|
2014-11-14 07:03:50 +03:00
|
|
|
sfactor == LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA;
|
2011-09-29 10:19:26 +04:00
|
|
|
bool dfactorIsConstantColor = dfactor == LOCAL_GL_CONSTANT_COLOR ||
|
2014-11-14 07:03:50 +03:00
|
|
|
dfactor == LOCAL_GL_ONE_MINUS_CONSTANT_COLOR;
|
2011-09-29 10:19:26 +04:00
|
|
|
bool dfactorIsConstantAlpha = dfactor == LOCAL_GL_CONSTANT_ALPHA ||
|
2014-11-14 07:03:50 +03:00
|
|
|
dfactor == LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA;
|
2010-12-06 14:34:35 +03:00
|
|
|
if ( (sfactorIsConstantColor && dfactorIsConstantAlpha) ||
|
2014-11-14 07:03:50 +03:00
|
|
|
(dfactorIsConstantColor && sfactorIsConstantAlpha) )
|
|
|
|
{
|
|
|
|
ErrorInvalidOperation("%s are mutually incompatible, see section 6.8 in"
|
|
|
|
" the WebGL 1.0 spec", info);
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2010-12-06 14:34:35 +03:00
|
|
|
}
|
2014-11-14 07:03:50 +03:00
|
|
|
|
|
|
|
return true;
|
2010-12-06 14:34:35 +03:00
|
|
|
}
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
bool
|
|
|
|
WebGLContext::ValidateComparisonEnum(GLenum target, const char* info)
|
2010-06-30 19:48:30 +04:00
|
|
|
{
|
|
|
|
switch (target) {
|
2014-11-14 07:03:50 +03:00
|
|
|
case LOCAL_GL_NEVER:
|
|
|
|
case LOCAL_GL_LESS:
|
|
|
|
case LOCAL_GL_LEQUAL:
|
|
|
|
case LOCAL_GL_GREATER:
|
|
|
|
case LOCAL_GL_GEQUAL:
|
|
|
|
case LOCAL_GL_EQUAL:
|
|
|
|
case LOCAL_GL_NOTEQUAL:
|
|
|
|
case LOCAL_GL_ALWAYS:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ErrorInvalidEnumInfo(info, target);
|
|
|
|
return false;
|
2010-06-30 19:48:30 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
bool
|
|
|
|
WebGLContext::ValidateStencilOpEnum(GLenum action, const char* info)
|
2010-06-30 19:48:30 +04:00
|
|
|
{
|
|
|
|
switch (action) {
|
2014-11-14 07:03:50 +03:00
|
|
|
case LOCAL_GL_KEEP:
|
|
|
|
case LOCAL_GL_ZERO:
|
|
|
|
case LOCAL_GL_REPLACE:
|
|
|
|
case LOCAL_GL_INCR:
|
|
|
|
case LOCAL_GL_INCR_WRAP:
|
|
|
|
case LOCAL_GL_DECR:
|
|
|
|
case LOCAL_GL_DECR_WRAP:
|
|
|
|
case LOCAL_GL_INVERT:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ErrorInvalidEnumInfo(info, action);
|
|
|
|
return false;
|
2010-06-30 19:48:30 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
bool
|
|
|
|
WebGLContext::ValidateFaceEnum(GLenum face, const char* info)
|
2010-06-30 19:48:30 +04:00
|
|
|
{
|
2010-07-16 18:31:48 +04:00
|
|
|
switch (face) {
|
2014-11-14 07:03:50 +03:00
|
|
|
case LOCAL_GL_FRONT:
|
|
|
|
case LOCAL_GL_BACK:
|
|
|
|
case LOCAL_GL_FRONT_AND_BACK:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ErrorInvalidEnumInfo(info, face);
|
|
|
|
return false;
|
2010-06-30 19:48:30 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
bool
|
|
|
|
WebGLContext::ValidateDrawModeEnum(GLenum mode, const char* info)
|
2010-07-16 18:31:48 +04:00
|
|
|
{
|
|
|
|
switch (mode) {
|
2014-11-14 07:03:50 +03:00
|
|
|
case LOCAL_GL_TRIANGLES:
|
|
|
|
case LOCAL_GL_TRIANGLE_STRIP:
|
|
|
|
case LOCAL_GL_TRIANGLE_FAN:
|
|
|
|
case LOCAL_GL_POINTS:
|
|
|
|
case LOCAL_GL_LINE_STRIP:
|
|
|
|
case LOCAL_GL_LINE_LOOP:
|
|
|
|
case LOCAL_GL_LINES:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
default:
|
|
|
|
ErrorInvalidEnumInfo(info, mode);
|
|
|
|
return false;
|
2010-07-04 02:34:07 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-16 16:17:01 +04:00
|
|
|
bool
|
2015-01-16 02:40:39 +03:00
|
|
|
WebGLContext::ValidateUniformLocation(WebGLUniformLocation* loc, const char* funcName)
|
2012-10-16 16:17:01 +04:00
|
|
|
{
|
2015-01-16 02:40:39 +03:00
|
|
|
/* GLES 2.0.25, p38:
|
|
|
|
* If the value of location is -1, the Uniform* commands will silently
|
|
|
|
* ignore the data passed in, and the current uniform values will not be
|
|
|
|
* changed.
|
|
|
|
*/
|
2015-01-13 11:07:26 +03:00
|
|
|
if (!loc)
|
2015-01-10 08:03:54 +03:00
|
|
|
return false;
|
|
|
|
|
2016-11-30 05:30:28 +03:00
|
|
|
if (!ValidateObjectAllowDeleted(funcName, *loc))
|
2015-01-13 11:07:26 +03:00
|
|
|
return false;
|
|
|
|
|
2015-01-16 02:40:39 +03:00
|
|
|
if (!mCurrentProgram) {
|
|
|
|
ErrorInvalidOperation("%s: No program is currently bound.", funcName);
|
2012-10-16 16:17:01 +04:00
|
|
|
return false;
|
|
|
|
}
|
2014-11-14 07:03:50 +03:00
|
|
|
|
2016-07-14 22:13:47 +03:00
|
|
|
return loc->ValidateForProgram(mCurrentProgram, funcName);
|
2013-03-05 04:44:31 +04:00
|
|
|
}
|
|
|
|
|
2012-10-16 16:17:01 +04:00
|
|
|
bool
|
2015-01-16 02:40:39 +03:00
|
|
|
WebGLContext::ValidateAttribArraySetter(const char* name, uint32_t setterElemSize,
|
2014-11-14 07:03:50 +03:00
|
|
|
uint32_t arrayLength)
|
2012-10-16 16:17:01 +04:00
|
|
|
{
|
2014-11-14 07:03:50 +03:00
|
|
|
if (IsContextLost())
|
2012-10-16 16:17:01 +04:00
|
|
|
return false;
|
2014-11-14 07:03:50 +03:00
|
|
|
|
2015-01-16 02:40:39 +03:00
|
|
|
if (arrayLength < setterElemSize) {
|
2016-01-09 15:20:00 +03:00
|
|
|
ErrorInvalidValue("%s: Array must have >= %d elements.", name,
|
|
|
|
setterElemSize);
|
2012-10-16 16:17:01 +04:00
|
|
|
return false;
|
|
|
|
}
|
2014-10-24 02:10:57 +04:00
|
|
|
|
2012-10-16 16:17:01 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2014-10-24 02:10:57 +04:00
|
|
|
WebGLContext::ValidateUniformSetter(WebGLUniformLocation* loc,
|
|
|
|
uint8_t setterElemSize, GLenum setterType,
|
2016-07-14 22:13:47 +03:00
|
|
|
const char* funcName)
|
2012-10-16 16:17:01 +04:00
|
|
|
{
|
2013-09-04 16:14:44 +04:00
|
|
|
if (IsContextLost())
|
2012-10-16 16:17:01 +04:00
|
|
|
return false;
|
2014-10-24 02:10:57 +04:00
|
|
|
|
2015-01-16 02:40:39 +03:00
|
|
|
if (!ValidateUniformLocation(loc, funcName))
|
2012-10-16 16:17:01 +04:00
|
|
|
return false;
|
2014-10-24 02:10:57 +04:00
|
|
|
|
2016-07-14 22:13:47 +03:00
|
|
|
if (!loc->ValidateSizeAndType(setterElemSize, setterType, funcName))
|
2012-10-16 16:17:01 +04:00
|
|
|
return false;
|
2014-10-24 02:10:57 +04:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
WebGLContext::ValidateUniformArraySetter(WebGLUniformLocation* loc,
|
2014-11-14 07:03:50 +03:00
|
|
|
uint8_t setterElemSize,
|
|
|
|
GLenum setterType,
|
2016-07-14 22:13:47 +03:00
|
|
|
uint32_t setterArraySize,
|
2015-01-16 02:40:39 +03:00
|
|
|
const char* funcName,
|
2016-07-14 22:13:47 +03:00
|
|
|
uint32_t* const out_numElementsToUpload)
|
2014-10-24 02:10:57 +04:00
|
|
|
{
|
|
|
|
if (IsContextLost())
|
2012-10-16 16:17:01 +04:00
|
|
|
return false;
|
2014-10-24 02:10:57 +04:00
|
|
|
|
2015-01-16 02:40:39 +03:00
|
|
|
if (!ValidateUniformLocation(loc, funcName))
|
2012-10-16 16:17:01 +04:00
|
|
|
return false;
|
2014-10-24 02:10:57 +04:00
|
|
|
|
2016-07-14 22:13:47 +03:00
|
|
|
if (!loc->ValidateSizeAndType(setterElemSize, setterType, funcName))
|
2014-10-24 02:10:57 +04:00
|
|
|
return false;
|
|
|
|
|
2016-07-14 22:13:47 +03:00
|
|
|
if (!loc->ValidateArrayLength(setterElemSize, setterArraySize, funcName))
|
2012-10-16 16:17:01 +04:00
|
|
|
return false;
|
2014-10-24 02:10:57 +04:00
|
|
|
|
2016-07-14 22:13:47 +03:00
|
|
|
const auto& elemCount = loc->mInfo->mActiveInfo->mElemCount;
|
|
|
|
MOZ_ASSERT(elemCount > loc->mArrayIndex);
|
|
|
|
const uint32_t uniformElemCount = elemCount - loc->mArrayIndex;
|
|
|
|
|
|
|
|
*out_numElementsToUpload = std::min(uniformElemCount,
|
|
|
|
setterArraySize / setterElemSize);
|
2012-10-16 16:17:01 +04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2014-10-24 02:10:57 +04:00
|
|
|
WebGLContext::ValidateUniformMatrixArraySetter(WebGLUniformLocation* loc,
|
2015-03-23 04:29:32 +03:00
|
|
|
uint8_t setterCols,
|
|
|
|
uint8_t setterRows,
|
2014-10-24 02:10:57 +04:00
|
|
|
GLenum setterType,
|
2016-07-14 22:13:47 +03:00
|
|
|
uint32_t setterArraySize,
|
2014-10-24 02:10:57 +04:00
|
|
|
bool setterTranspose,
|
2015-01-16 02:40:39 +03:00
|
|
|
const char* funcName,
|
2016-07-14 22:13:47 +03:00
|
|
|
uint32_t* const out_numElementsToUpload)
|
2012-10-16 16:17:01 +04:00
|
|
|
{
|
2016-07-14 22:13:47 +03:00
|
|
|
const uint8_t setterElemSize = setterCols * setterRows;
|
2014-10-24 02:10:57 +04:00
|
|
|
|
2013-09-04 16:14:44 +04:00
|
|
|
if (IsContextLost())
|
2012-10-16 16:17:01 +04:00
|
|
|
return false;
|
2014-10-24 02:10:57 +04:00
|
|
|
|
2015-01-16 02:40:39 +03:00
|
|
|
if (!ValidateUniformLocation(loc, funcName))
|
2012-10-16 16:17:01 +04:00
|
|
|
return false;
|
|
|
|
|
2016-07-14 22:13:47 +03:00
|
|
|
if (!loc->ValidateSizeAndType(setterElemSize, setterType, funcName))
|
2014-10-24 02:10:57 +04:00
|
|
|
return false;
|
|
|
|
|
2016-07-14 22:13:47 +03:00
|
|
|
if (!loc->ValidateArrayLength(setterElemSize, setterArraySize, funcName))
|
2014-10-24 02:10:57 +04:00
|
|
|
return false;
|
|
|
|
|
2015-03-23 04:29:32 +03:00
|
|
|
if (!ValidateUniformMatrixTranspose(setterTranspose, funcName))
|
2014-10-24 02:10:57 +04:00
|
|
|
return false;
|
|
|
|
|
2016-07-14 22:13:47 +03:00
|
|
|
const auto& elemCount = loc->mInfo->mActiveInfo->mElemCount;
|
|
|
|
MOZ_ASSERT(elemCount > loc->mArrayIndex);
|
|
|
|
const uint32_t uniformElemCount = elemCount - loc->mArrayIndex;
|
2016-05-25 17:28:00 +03:00
|
|
|
|
2016-07-14 22:13:47 +03:00
|
|
|
*out_numElementsToUpload = std::min(uniformElemCount,
|
|
|
|
setterArraySize / setterElemSize);
|
2014-10-24 02:10:57 +04:00
|
|
|
return true;
|
2011-02-25 01:17:34 +03:00
|
|
|
}
|
|
|
|
|
2014-06-24 04:56:21 +04:00
|
|
|
bool
|
|
|
|
WebGLContext::ValidateAttribIndex(GLuint index, const char* info)
|
|
|
|
{
|
|
|
|
bool valid = (index < MaxVertexAttribs());
|
|
|
|
|
|
|
|
if (!valid) {
|
|
|
|
if (index == GLuint(-1)) {
|
|
|
|
ErrorInvalidValue("%s: -1 is not a valid `index`. This value"
|
|
|
|
" probably comes from a getAttribLocation()"
|
|
|
|
" call, where this return value -1 means"
|
|
|
|
" that the passed name didn't correspond to"
|
|
|
|
" an active attribute in the specified"
|
|
|
|
" program.", info);
|
|
|
|
} else {
|
|
|
|
ErrorInvalidValue("%s: `index` must be less than"
|
|
|
|
" MAX_VERTEX_ATTRIBS.", info);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return valid;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
WebGLContext::ValidateAttribPointer(bool integerMode, GLuint index, GLint size, GLenum type,
|
|
|
|
WebGLboolean normalized, GLsizei stride,
|
|
|
|
WebGLintptr byteOffset, const char* info)
|
|
|
|
{
|
|
|
|
WebGLBuffer* buffer = mBoundArrayBuffer;
|
|
|
|
if (!buffer) {
|
|
|
|
ErrorInvalidOperation("%s: must have valid GL_ARRAY_BUFFER binding", info);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-07-22 09:25:41 +03:00
|
|
|
uint32_t requiredAlignment = 0;
|
2014-06-24 04:56:21 +04:00
|
|
|
if (!ValidateAttribPointerType(integerMode, type, &requiredAlignment, info))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// requiredAlignment should always be a power of two
|
2015-11-25 07:15:29 +03:00
|
|
|
MOZ_ASSERT(IsPowerOfTwo(requiredAlignment));
|
2014-06-24 04:56:21 +04:00
|
|
|
GLsizei requiredAlignmentMask = requiredAlignment - 1;
|
|
|
|
|
|
|
|
if (size < 1 || size > 4) {
|
|
|
|
ErrorInvalidValue("%s: invalid element size", info);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// see WebGL spec section 6.6 "Vertex Attribute Data Stride"
|
|
|
|
if (stride < 0 || stride > 255) {
|
|
|
|
ErrorInvalidValue("%s: negative or too large stride", info);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (byteOffset < 0) {
|
|
|
|
ErrorInvalidValue("%s: negative offset", info);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stride & requiredAlignmentMask) {
|
|
|
|
ErrorInvalidOperation("%s: stride doesn't satisfy the alignment "
|
|
|
|
"requirement of given type", info);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (byteOffset & requiredAlignmentMask) {
|
|
|
|
ErrorInvalidOperation("%s: byteOffset doesn't satisfy the alignment "
|
|
|
|
"requirement of given type", info);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
bool
|
|
|
|
WebGLContext::ValidateStencilParamsForDrawCall()
|
2011-05-20 23:53:53 +04:00
|
|
|
{
|
2014-11-14 07:03:50 +03:00
|
|
|
const char msg[] = "%s set different front and back stencil %s. Drawing in"
|
|
|
|
" this configuration is not allowed.";
|
|
|
|
|
|
|
|
if (mStencilRefFront != mStencilRefBack) {
|
|
|
|
ErrorInvalidOperation(msg, "stencilFuncSeparate", "reference values");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mStencilValueMaskFront != mStencilValueMaskBack) {
|
|
|
|
ErrorInvalidOperation(msg, "stencilFuncSeparate", "value masks");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mStencilWriteMaskFront != mStencilWriteMaskBack) {
|
|
|
|
ErrorInvalidOperation(msg, "stencilMaskSeparate", "write masks");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
2011-05-20 23:53:53 +04:00
|
|
|
}
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
static inline int32_t
|
|
|
|
FloorPOT(int32_t x)
|
2013-07-30 19:07:04 +04:00
|
|
|
{
|
|
|
|
MOZ_ASSERT(x > 0);
|
|
|
|
int32_t pot = 1;
|
|
|
|
while (pot < 0x40000000) {
|
|
|
|
if (x < pot*2)
|
|
|
|
break;
|
|
|
|
pot *= 2;
|
|
|
|
}
|
|
|
|
return pot;
|
|
|
|
}
|
|
|
|
|
2011-09-29 10:19:26 +04:00
|
|
|
bool
|
2016-06-21 06:42:10 +03:00
|
|
|
WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
|
2010-06-10 21:45:00 +04:00
|
|
|
{
|
2016-06-06 18:17:23 +03:00
|
|
|
MOZ_RELEASE_ASSERT(gl, "GFX: GL not initialized");
|
2010-06-14 22:44:12 +04:00
|
|
|
|
2015-08-04 06:39:47 +03:00
|
|
|
// Unconditionally create a new format usage authority. This is
|
|
|
|
// important when restoring contexts and extensions need to add
|
|
|
|
// formats back into the authority.
|
2015-11-25 07:15:29 +03:00
|
|
|
mFormatUsage = CreateFormatUsage(gl);
|
2016-05-12 02:45:43 +03:00
|
|
|
if (!mFormatUsage) {
|
2016-06-21 06:42:10 +03:00
|
|
|
*out_failReason = { "FEATURE_FAILURE_WEBGL_FORMAT",
|
|
|
|
"Failed to create mFormatUsage." };
|
2015-11-25 07:15:29 +03:00
|
|
|
return false;
|
2016-05-12 02:45:43 +03:00
|
|
|
}
|
2015-08-04 06:39:47 +03:00
|
|
|
|
2011-02-12 02:11:30 +03:00
|
|
|
GLenum error = gl->fGetError();
|
|
|
|
if (error != LOCAL_GL_NO_ERROR) {
|
2016-05-12 02:45:43 +03:00
|
|
|
const nsPrintfCString reason("GL error 0x%x occurred during OpenGL context"
|
|
|
|
" initialization, before WebGL initialization!",
|
|
|
|
error);
|
2016-06-21 06:42:10 +03:00
|
|
|
*out_failReason = { "FEATURE_FAILURE_WEBGL_GLERR_1", reason };
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2011-02-12 02:11:30 +03:00
|
|
|
}
|
|
|
|
|
2015-10-12 06:21:03 +03:00
|
|
|
mMinCapability = gfxPrefs::WebGLMinCapabilityMode();
|
|
|
|
mDisableExtensions = gfxPrefs::WebGLDisableExtensions();
|
|
|
|
mLoseContextOnMemoryPressure = gfxPrefs::WebGLLoseContextOnMemoryPressure();
|
|
|
|
mCanLoseContextInForeground = gfxPrefs::WebGLCanLoseContextInForeground();
|
|
|
|
mRestoreWhenVisible = gfxPrefs::WebGLRestoreWhenVisible();
|
2011-10-13 16:09:22 +04:00
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
if (MinCapabilityMode())
|
|
|
|
mDisableFragHighP = true;
|
2013-05-16 01:50:52 +04:00
|
|
|
|
2014-04-18 00:15:41 +04:00
|
|
|
// These are the default values, see 6.2 State tables in the
|
|
|
|
// OpenGL ES 2.0.25 spec.
|
|
|
|
mColorWriteMask[0] = 1;
|
|
|
|
mColorWriteMask[1] = 1;
|
|
|
|
mColorWriteMask[2] = 1;
|
|
|
|
mColorWriteMask[3] = 1;
|
|
|
|
mDepthWriteMask = 1;
|
|
|
|
mColorClearValue[0] = 0.f;
|
|
|
|
mColorClearValue[1] = 0.f;
|
|
|
|
mColorClearValue[2] = 0.f;
|
|
|
|
mColorClearValue[3] = 0.f;
|
|
|
|
mDepthClearValue = 1.f;
|
|
|
|
mStencilClearValue = 0;
|
|
|
|
mStencilRefFront = 0;
|
|
|
|
mStencilRefBack = 0;
|
2014-05-22 06:03:09 +04:00
|
|
|
|
2016-09-28 06:54:46 +03:00
|
|
|
mLineWidth = 1.0;
|
|
|
|
|
2014-05-22 06:03:09 +04:00
|
|
|
/*
|
|
|
|
// Technically, we should be setting mStencil[...] values to
|
|
|
|
// `allOnes`, but either ANGLE breaks or the SGX540s on Try break.
|
|
|
|
GLuint stencilBits = 0;
|
|
|
|
gl->GetUIntegerv(LOCAL_GL_STENCIL_BITS, &stencilBits);
|
|
|
|
GLuint allOnes = ~(UINT32_MAX << stencilBits);
|
|
|
|
mStencilValueMaskFront = allOnes;
|
|
|
|
mStencilValueMaskBack = allOnes;
|
|
|
|
mStencilWriteMaskFront = allOnes;
|
|
|
|
mStencilWriteMaskBack = allOnes;
|
|
|
|
*/
|
|
|
|
|
|
|
|
gl->GetUIntegerv(LOCAL_GL_STENCIL_VALUE_MASK, &mStencilValueMaskFront);
|
|
|
|
gl->GetUIntegerv(LOCAL_GL_STENCIL_BACK_VALUE_MASK, &mStencilValueMaskBack);
|
|
|
|
gl->GetUIntegerv(LOCAL_GL_STENCIL_WRITEMASK, &mStencilWriteMaskFront);
|
|
|
|
gl->GetUIntegerv(LOCAL_GL_STENCIL_BACK_WRITEMASK, &mStencilWriteMaskBack);
|
|
|
|
|
|
|
|
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_VALUE_MASK, mStencilValueMaskFront);
|
|
|
|
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_VALUE_MASK, mStencilValueMaskBack);
|
|
|
|
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_WRITEMASK, mStencilWriteMaskFront);
|
|
|
|
AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_WRITEMASK, mStencilWriteMaskBack);
|
|
|
|
|
|
|
|
mDitherEnabled = true;
|
|
|
|
mRasterizerDiscardEnabled = false;
|
|
|
|
mScissorTestEnabled = false;
|
2014-04-18 00:15:41 +04:00
|
|
|
|
|
|
|
// Bindings, etc.
|
2010-06-14 22:44:12 +04:00
|
|
|
mActiveTexture = 0;
|
2015-11-25 07:15:29 +03:00
|
|
|
mDefaultFB_DrawBuffer0 = LOCAL_GL_BACK;
|
|
|
|
|
2014-03-08 01:16:34 +04:00
|
|
|
mEmitContextLostErrorOnce = true;
|
2011-07-08 04:01:16 +04:00
|
|
|
mWebGLError = LOCAL_GL_NO_ERROR;
|
2014-03-08 01:16:34 +04:00
|
|
|
mUnderlyingGLError = LOCAL_GL_NO_ERROR;
|
2010-06-14 22:44:12 +04:00
|
|
|
|
|
|
|
mBound2DTextures.Clear();
|
|
|
|
mBoundCubeMapTextures.Clear();
|
2014-10-14 03:42:20 +04:00
|
|
|
mBound3DTextures.Clear();
|
2015-11-25 07:15:29 +03:00
|
|
|
mBound2DArrayTextures.Clear();
|
2015-06-09 03:18:19 +03:00
|
|
|
mBoundSamplers.Clear();
|
2010-06-14 22:44:12 +04:00
|
|
|
|
2012-07-30 18:20:58 +04:00
|
|
|
mBoundArrayBuffer = nullptr;
|
|
|
|
mCurrentProgram = nullptr;
|
2010-06-14 22:44:12 +04:00
|
|
|
|
2015-01-13 02:05:21 +03:00
|
|
|
mBoundDrawFramebuffer = nullptr;
|
|
|
|
mBoundReadFramebuffer = nullptr;
|
2012-07-30 18:20:58 +04:00
|
|
|
mBoundRenderbuffer = nullptr;
|
2010-06-14 22:44:12 +04:00
|
|
|
|
2010-07-19 09:01:14 +04:00
|
|
|
MakeContextCurrent();
|
2010-06-10 21:45:00 +04:00
|
|
|
|
2015-02-13 06:00:41 +03:00
|
|
|
// For OpenGL compat. profiles, we always keep vertex attrib 0 array enabled.
|
|
|
|
if (gl->IsCompatibilityProfile())
|
2010-09-02 18:34:08 +04:00
|
|
|
gl->fEnableVertexAttribArray(0);
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
if (MinCapabilityMode())
|
2011-10-13 16:09:22 +04:00
|
|
|
mGLMaxVertexAttribs = MINVALUE_GL_MAX_VERTEX_ATTRIBS;
|
2014-11-14 07:03:50 +03:00
|
|
|
else
|
2011-10-13 16:09:22 +04:00
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &mGLMaxVertexAttribs);
|
2014-11-14 07:03:50 +03:00
|
|
|
|
2010-07-15 07:52:34 +04:00
|
|
|
if (mGLMaxVertexAttribs < 8) {
|
2016-05-12 02:45:43 +03:00
|
|
|
const nsPrintfCString reason("GL_MAX_VERTEX_ATTRIBS: %d is < 8!",
|
|
|
|
mGLMaxVertexAttribs);
|
2016-06-21 06:42:10 +03:00
|
|
|
*out_failReason = { "FEATURE_FAILURE_WEBGL_V_ATRB", reason };
|
2011-10-13 16:09:22 +04:00
|
|
|
return false;
|
2010-06-10 21:45:00 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Note: GL_MAX_TEXTURE_UNITS is fixed at 4 for most desktop hardware,
|
|
|
|
// even though the hardware supports much more. The
|
2010-07-15 07:52:34 +04:00
|
|
|
// GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS value is the accurate value.
|
2014-11-14 07:03:50 +03:00
|
|
|
if (MinCapabilityMode())
|
2011-10-13 16:09:22 +04:00
|
|
|
mGLMaxTextureUnits = MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS;
|
2014-11-14 07:03:50 +03:00
|
|
|
else
|
2011-10-13 16:09:22 +04:00
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGLMaxTextureUnits);
|
2014-11-14 07:03:50 +03:00
|
|
|
|
2010-07-15 07:52:34 +04:00
|
|
|
if (mGLMaxTextureUnits < 8) {
|
2016-05-12 02:45:43 +03:00
|
|
|
const nsPrintfCString reason("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %d is < 8!",
|
|
|
|
mGLMaxTextureUnits);
|
2016-06-21 06:42:10 +03:00
|
|
|
*out_failReason = { "FEATURE_FAILURE_WEBGL_T_UNIT", reason };
|
2011-10-13 16:09:22 +04:00
|
|
|
return false;
|
2010-06-10 21:45:00 +04:00
|
|
|
}
|
|
|
|
|
2010-07-15 07:52:34 +04:00
|
|
|
mBound2DTextures.SetLength(mGLMaxTextureUnits);
|
|
|
|
mBoundCubeMapTextures.SetLength(mGLMaxTextureUnits);
|
2014-10-14 03:42:20 +04:00
|
|
|
mBound3DTextures.SetLength(mGLMaxTextureUnits);
|
2015-11-25 07:15:29 +03:00
|
|
|
mBound2DArrayTextures.SetLength(mGLMaxTextureUnits);
|
2015-06-09 03:18:19 +03:00
|
|
|
mBoundSamplers.SetLength(mGLMaxTextureUnits);
|
2010-07-15 07:52:34 +04:00
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
////////////////
|
|
|
|
|
2011-10-13 16:09:22 +04:00
|
|
|
if (MinCapabilityMode()) {
|
2015-11-25 07:15:29 +03:00
|
|
|
mImplMaxTextureSize = MINVALUE_GL_MAX_TEXTURE_SIZE;
|
|
|
|
mImplMaxCubeMapTextureSize = MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE;
|
|
|
|
mImplMaxRenderbufferSize = MINVALUE_GL_MAX_RENDERBUFFER_SIZE;
|
|
|
|
|
|
|
|
mImplMax3DTextureSize = MINVALUE_GL_MAX_3D_TEXTURE_SIZE;
|
|
|
|
mImplMaxArrayTextureLayers = MINVALUE_GL_MAX_ARRAY_TEXTURE_LAYERS;
|
|
|
|
|
2011-10-13 16:09:22 +04:00
|
|
|
mGLMaxTextureImageUnits = MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS;
|
|
|
|
mGLMaxVertexTextureImageUnits = MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS;
|
|
|
|
} else {
|
2015-11-25 07:15:29 +03:00
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, (GLint*)&mImplMaxTextureSize);
|
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*)&mImplMaxCubeMapTextureSize);
|
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, (GLint*)&mImplMaxRenderbufferSize);
|
|
|
|
|
|
|
|
if (!gl->GetPotentialInteger(LOCAL_GL_MAX_3D_TEXTURE_SIZE, (GLint*)&mImplMax3DTextureSize))
|
|
|
|
mImplMax3DTextureSize = 0;
|
|
|
|
if (!gl->GetPotentialInteger(LOCAL_GL_MAX_ARRAY_TEXTURE_LAYERS, (GLint*)&mImplMaxArrayTextureLayers))
|
|
|
|
mImplMaxArrayTextureLayers = 0;
|
|
|
|
|
2011-10-13 16:09:22 +04:00
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS, &mGLMaxTextureImageUnits);
|
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGLMaxVertexTextureImageUnits);
|
|
|
|
}
|
2010-07-15 07:52:34 +04:00
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
// If we don't support a target, its max size is 0. We should only floor-to-POT if the
|
|
|
|
// value if it's non-zero. (NB log2(0) is -Inf, so zero isn't an integer power-of-two)
|
|
|
|
const auto fnFloorPOTIfSupported = [](uint32_t& val) {
|
|
|
|
if (val) {
|
|
|
|
val = FloorPOT(val);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
fnFloorPOTIfSupported(mImplMaxTextureSize);
|
|
|
|
fnFloorPOTIfSupported(mImplMaxCubeMapTextureSize);
|
|
|
|
fnFloorPOTIfSupported(mImplMaxRenderbufferSize);
|
|
|
|
|
|
|
|
fnFloorPOTIfSupported(mImplMax3DTextureSize);
|
|
|
|
fnFloorPOTIfSupported(mImplMaxArrayTextureLayers);
|
|
|
|
|
|
|
|
////////////////
|
|
|
|
|
|
|
|
mGLMaxColorAttachments = 1;
|
|
|
|
mGLMaxDrawBuffers = 1;
|
|
|
|
gl->GetPotentialInteger(LOCAL_GL_MAX_COLOR_ATTACHMENTS,
|
|
|
|
(GLint*)&mGLMaxColorAttachments);
|
|
|
|
gl->GetPotentialInteger(LOCAL_GL_MAX_DRAW_BUFFERS, (GLint*)&mGLMaxDrawBuffers);
|
|
|
|
|
|
|
|
if (MinCapabilityMode()) {
|
|
|
|
mGLMaxColorAttachments = std::min(mGLMaxColorAttachments,
|
|
|
|
kMinMaxColorAttachments);
|
|
|
|
mGLMaxDrawBuffers = std::min(mGLMaxDrawBuffers, kMinMaxDrawBuffers);
|
2014-09-03 23:17:18 +04:00
|
|
|
}
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
if (IsWebGL2()) {
|
|
|
|
mImplMaxColorAttachments = mGLMaxColorAttachments;
|
|
|
|
mImplMaxDrawBuffers = std::min(mGLMaxDrawBuffers, mImplMaxColorAttachments);
|
|
|
|
} else {
|
|
|
|
mImplMaxColorAttachments = 1;
|
|
|
|
mImplMaxDrawBuffers = 1;
|
2014-09-03 23:17:18 +04:00
|
|
|
}
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
////////////////
|
2013-07-30 19:07:04 +04:00
|
|
|
|
2011-10-13 16:09:22 +04:00
|
|
|
if (MinCapabilityMode()) {
|
|
|
|
mGLMaxFragmentUniformVectors = MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS;
|
|
|
|
mGLMaxVertexUniformVectors = MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS;
|
|
|
|
mGLMaxVaryingVectors = MINVALUE_GL_MAX_VARYING_VECTORS;
|
2010-07-29 01:24:09 +04:00
|
|
|
} else {
|
2013-08-22 21:42:05 +04:00
|
|
|
if (gl->IsSupported(gl::GLFeature::ES2_compatibility)) {
|
2011-10-13 16:09:22 +04:00
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGLMaxFragmentUniformVectors);
|
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS, &mGLMaxVertexUniformVectors);
|
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &mGLMaxVaryingVectors);
|
|
|
|
} else {
|
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &mGLMaxFragmentUniformVectors);
|
|
|
|
mGLMaxFragmentUniformVectors /= 4;
|
|
|
|
gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS, &mGLMaxVertexUniformVectors);
|
|
|
|
mGLMaxVertexUniformVectors /= 4;
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
/* We are now going to try to read GL_MAX_VERTEX_OUTPUT_COMPONENTS
|
|
|
|
* and GL_MAX_FRAGMENT_INPUT_COMPONENTS, however these constants
|
|
|
|
* only entered the OpenGL standard at OpenGL 3.2. So we will try
|
|
|
|
* reading, and check OpenGL error for INVALID_ENUM.
|
|
|
|
*
|
|
|
|
* On the public_webgl list, "problematic GetParameter pnames"
|
|
|
|
* thread, the following formula was given:
|
|
|
|
* maxVaryingVectors = min(GL_MAX_VERTEX_OUTPUT_COMPONENTS,
|
|
|
|
* GL_MAX_FRAGMENT_INPUT_COMPONENTS) / 4
|
|
|
|
*/
|
2014-10-24 05:55:49 +04:00
|
|
|
GLint maxVertexOutputComponents = 0;
|
|
|
|
GLint maxFragmentInputComponents = 0;
|
|
|
|
|
|
|
|
const bool ok = (gl->GetPotentialInteger(LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS,
|
|
|
|
&maxVertexOutputComponents) &&
|
|
|
|
gl->GetPotentialInteger(LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS,
|
|
|
|
&maxFragmentInputComponents));
|
|
|
|
|
|
|
|
if (ok) {
|
|
|
|
mGLMaxVaryingVectors = std::min(maxVertexOutputComponents,
|
|
|
|
maxFragmentInputComponents) / 4;
|
|
|
|
} else {
|
|
|
|
mGLMaxVaryingVectors = 16;
|
2014-11-14 07:03:50 +03:00
|
|
|
// 16 = 64/4, and 64 is the min value for
|
|
|
|
// maxVertexOutputComponents in the OpenGL 3.2 spec.
|
2013-08-20 19:36:20 +04:00
|
|
|
}
|
2011-02-12 02:11:30 +03:00
|
|
|
}
|
2010-07-29 01:24:09 +04:00
|
|
|
}
|
2010-06-10 21:45:00 +04:00
|
|
|
|
2015-02-13 06:00:41 +03:00
|
|
|
if (gl->IsCompatibilityProfile()) {
|
2013-07-03 00:50:34 +04:00
|
|
|
gl->fEnable(LOCAL_GL_POINT_SPRITE);
|
2010-07-29 01:24:09 +04:00
|
|
|
}
|
2010-07-15 07:52:34 +04:00
|
|
|
|
2016-09-30 10:34:56 +03:00
|
|
|
if (!gl->IsGLES()) {
|
|
|
|
gl->fEnable(LOCAL_GL_PROGRAM_POINT_SIZE);
|
|
|
|
}
|
|
|
|
|
2012-07-05 18:13:46 +04:00
|
|
|
#ifdef XP_MACOSX
|
|
|
|
if (gl->WorkAroundDriverBugs() &&
|
2014-10-23 00:57:53 +04:00
|
|
|
gl->Vendor() == gl::GLVendor::ATI &&
|
2014-11-11 06:15:22 +03:00
|
|
|
!nsCocoaFeatures::IsAtLeastVersion(10,9))
|
2014-10-23 00:57:53 +04:00
|
|
|
{
|
2014-11-14 07:03:50 +03:00
|
|
|
// The Mac ATI driver, in all known OSX version up to and including
|
|
|
|
// 10.8, renders points sprites upside-down. (Apple bug 11778921)
|
|
|
|
gl->fPointParameterf(LOCAL_GL_POINT_SPRITE_COORD_ORIGIN,
|
|
|
|
LOCAL_GL_LOWER_LEFT);
|
2012-07-05 18:13:46 +04:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-02-12 04:57:25 +03:00
|
|
|
if (gl->IsSupported(gl::GLFeature::seamless_cube_map_opt_in)) {
|
|
|
|
gl->fEnable(LOCAL_GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
|
|
|
}
|
|
|
|
|
2010-08-20 06:50:38 +04:00
|
|
|
// Check the shader validator pref
|
2015-10-12 06:21:03 +03:00
|
|
|
mBypassShaderValidation = gfxPrefs::WebGLBypassShaderValidator();
|
2010-08-10 10:51:56 +04:00
|
|
|
|
2010-08-20 06:50:38 +04:00
|
|
|
// initialize shader translator
|
2015-01-16 02:40:39 +03:00
|
|
|
if (!ShInitialize()) {
|
2016-06-21 06:42:10 +03:00
|
|
|
*out_failReason = { "FEATURE_FAILURE_WEBGL_GLSL",
|
|
|
|
"GLSL translator initialization failed!" };
|
2015-01-16 02:40:39 +03:00
|
|
|
return false;
|
2010-08-10 10:51:56 +04:00
|
|
|
}
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
// Mesa can only be detected with the GL_VERSION string, of the form
|
|
|
|
// "2.1 Mesa 7.11.0"
|
|
|
|
const char* versionStr = (const char*)(gl->fGetString(LOCAL_GL_VERSION));
|
|
|
|
mIsMesa = strstr(versionStr, "Mesa");
|
2012-08-10 06:30:17 +04:00
|
|
|
|
2014-10-25 03:52:35 +04:00
|
|
|
// Notice that the point of calling fGetError here is not only to check for
|
|
|
|
// errors, but also to reset the error flags so that a subsequent WebGL
|
|
|
|
// getError call will give the correct result.
|
|
|
|
error = gl->fGetError();
|
2010-09-16 20:45:01 +04:00
|
|
|
if (error != LOCAL_GL_NO_ERROR) {
|
2016-05-12 02:45:43 +03:00
|
|
|
const nsPrintfCString reason("GL error 0x%x occurred during WebGL context"
|
|
|
|
" initialization!",
|
|
|
|
error);
|
2016-06-21 06:42:10 +03:00
|
|
|
*out_failReason = { "FEATURE_FAILURE_WEBGL_GLERR_2", reason };
|
2011-10-17 18:59:28 +04:00
|
|
|
return false;
|
2010-09-16 20:45:01 +04:00
|
|
|
}
|
|
|
|
|
2013-07-17 20:13:38 +04:00
|
|
|
if (IsWebGL2() &&
|
2016-06-21 06:42:10 +03:00
|
|
|
!InitWebGL2(out_failReason))
|
2013-07-17 20:13:38 +04:00
|
|
|
{
|
2013-08-07 01:23:46 +04:00
|
|
|
// Todo: Bug 898404: Only allow WebGL2 on GL>=3.0 on desktop GL.
|
2013-07-17 20:13:38 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-06-13 00:27:19 +04:00
|
|
|
// Default value for all disabled vertex attributes is [0, 0, 0, 1]
|
2015-07-20 10:56:17 +03:00
|
|
|
mVertexAttribType = MakeUnique<GLenum[]>(mGLMaxVertexAttribs);
|
2014-06-13 00:27:19 +04:00
|
|
|
for (int32_t index = 0; index < mGLMaxVertexAttribs; ++index) {
|
2015-07-20 10:56:17 +03:00
|
|
|
mVertexAttribType[index] = LOCAL_GL_FLOAT;
|
2014-06-13 00:27:19 +04:00
|
|
|
VertexAttrib4f(index, 0, 0, 0, 1);
|
|
|
|
}
|
|
|
|
|
2014-06-06 03:38:27 +04:00
|
|
|
mDefaultVertexArray = WebGLVertexArray::Create(this);
|
2013-10-11 17:16:44 +04:00
|
|
|
mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
|
2013-06-28 01:07:21 +04:00
|
|
|
mBoundVertexArray = mDefaultVertexArray;
|
|
|
|
|
2015-01-29 08:29:43 +03:00
|
|
|
// OpenGL core profiles remove the default VAO object from version
|
|
|
|
// 4.0.0. We create a default VAO for all core profiles,
|
|
|
|
// regardless of version.
|
|
|
|
//
|
|
|
|
// GL Spec 4.0.0:
|
|
|
|
// (https://www.opengl.org/registry/doc/glspec40.core.20100311.pdf)
|
|
|
|
// in Section E.2.2 "Removed Features", pg 397: "[...] The default
|
|
|
|
// vertex array object (the name zero) is also deprecated. [...]"
|
|
|
|
|
|
|
|
if (gl->IsCoreProfile()) {
|
|
|
|
mDefaultVertexArray->GenVertexArray();
|
|
|
|
mDefaultVertexArray->BindVertexArray();
|
|
|
|
}
|
|
|
|
|
2015-11-25 07:15:29 +03:00
|
|
|
mPixelStore_FlipY = false;
|
|
|
|
mPixelStore_PremultiplyAlpha = false;
|
|
|
|
mPixelStore_ColorspaceConversion = BROWSER_DEFAULT_WEBGL;
|
|
|
|
|
|
|
|
// GLES 3.0.4, p259:
|
|
|
|
mPixelStore_UnpackImageHeight = 0;
|
|
|
|
mPixelStore_UnpackSkipImages = 0;
|
|
|
|
mPixelStore_UnpackRowLength = 0;
|
|
|
|
mPixelStore_UnpackSkipRows = 0;
|
|
|
|
mPixelStore_UnpackSkipPixels = 0;
|
|
|
|
mPixelStore_UnpackAlignment = 4;
|
|
|
|
mPixelStore_PackRowLength = 0;
|
|
|
|
mPixelStore_PackSkipRows = 0;
|
|
|
|
mPixelStore_PackSkipPixels = 0;
|
|
|
|
mPixelStore_PackAlignment = 4;
|
|
|
|
|
2016-07-27 06:05:45 +03:00
|
|
|
mPrimRestartTypeBytes = 0;
|
|
|
|
|
2011-10-17 18:59:28 +04:00
|
|
|
return true;
|
2010-06-10 21:45:00 +04:00
|
|
|
}
|
2014-11-14 07:03:50 +03:00
|
|
|
|
2015-01-13 02:05:21 +03:00
|
|
|
bool
|
|
|
|
WebGLContext::ValidateFramebufferTarget(GLenum target,
|
|
|
|
const char* const info)
|
|
|
|
{
|
|
|
|
bool isValid = true;
|
|
|
|
switch (target) {
|
|
|
|
case LOCAL_GL_FRAMEBUFFER:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LOCAL_GL_DRAW_FRAMEBUFFER:
|
|
|
|
case LOCAL_GL_READ_FRAMEBUFFER:
|
|
|
|
isValid = IsWebGL2();
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
isValid = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (MOZ_LIKELY(isValid)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
ErrorInvalidEnum("%s: Invalid target: %s (0x%04x).", info, EnumName(target),
|
|
|
|
target);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2014-11-14 07:03:50 +03:00
|
|
|
} // namespace mozilla
|