LCOV - code coverage report
Current view: top level - dom/canvas - WebGLContextValidate.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 327 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #include "WebGLContext.h"
       7             : 
       8             : #include <algorithm>
       9             : #include "angle/ShaderLang.h"
      10             : #include "CanvasUtils.h"
      11             : #include "gfxPrefs.h"
      12             : #include "GLContext.h"
      13             : #include "jsfriendapi.h"
      14             : #include "mozilla/CheckedInt.h"
      15             : #include "mozilla/Preferences.h"
      16             : #include "mozilla/Services.h"
      17             : #include "nsIObserverService.h"
      18             : #include "nsPrintfCString.h"
      19             : #include "WebGLActiveInfo.h"
      20             : #include "WebGLBuffer.h"
      21             : #include "WebGLContextUtils.h"
      22             : #include "WebGLFramebuffer.h"
      23             : #include "WebGLProgram.h"
      24             : #include "WebGLRenderbuffer.h"
      25             : #include "WebGLSampler.h"
      26             : #include "WebGLShader.h"
      27             : #include "WebGLTexture.h"
      28             : #include "WebGLUniformLocation.h"
      29             : #include "WebGLValidateStrings.h"
      30             : #include "WebGLVertexArray.h"
      31             : #include "WebGLVertexAttribData.h"
      32             : 
      33             : #if defined(MOZ_WIDGET_COCOA)
      34             : #include "nsCocoaFeatures.h"
      35             : #endif
      36             : 
      37             : namespace mozilla {
      38             : 
      39             : bool
      40           0 : WebGLContext::ValidateBlendEquationEnum(GLenum mode, const char* info)
      41             : {
      42           0 :     switch (mode) {
      43             :     case LOCAL_GL_FUNC_ADD:
      44             :     case LOCAL_GL_FUNC_SUBTRACT:
      45             :     case LOCAL_GL_FUNC_REVERSE_SUBTRACT:
      46           0 :         return true;
      47             : 
      48             :     case LOCAL_GL_MIN:
      49             :     case LOCAL_GL_MAX:
      50           0 :         if (IsWebGL2() ||
      51           0 :             IsExtensionEnabled(WebGLExtensionID::EXT_blend_minmax))
      52             :         {
      53           0 :             return true;
      54             :         }
      55             : 
      56           0 :         break;
      57             : 
      58             :     default:
      59           0 :         break;
      60             :     }
      61             : 
      62           0 :     ErrorInvalidEnumInfo(info, mode);
      63           0 :     return false;
      64             : }
      65             : 
      66             : bool
      67           0 : WebGLContext::ValidateBlendFuncDstEnum(GLenum factor, const char* info)
      68             : {
      69           0 :     switch (factor) {
      70             :     case LOCAL_GL_ZERO:
      71             :     case LOCAL_GL_ONE:
      72             :     case LOCAL_GL_SRC_COLOR:
      73             :     case LOCAL_GL_ONE_MINUS_SRC_COLOR:
      74             :     case LOCAL_GL_DST_COLOR:
      75             :     case LOCAL_GL_ONE_MINUS_DST_COLOR:
      76             :     case LOCAL_GL_SRC_ALPHA:
      77             :     case LOCAL_GL_ONE_MINUS_SRC_ALPHA:
      78             :     case LOCAL_GL_DST_ALPHA:
      79             :     case LOCAL_GL_ONE_MINUS_DST_ALPHA:
      80             :     case LOCAL_GL_CONSTANT_COLOR:
      81             :     case LOCAL_GL_ONE_MINUS_CONSTANT_COLOR:
      82             :     case LOCAL_GL_CONSTANT_ALPHA:
      83             :     case LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA:
      84           0 :         return true;
      85             : 
      86             :     default:
      87           0 :         ErrorInvalidEnumInfo(info, factor);
      88           0 :         return false;
      89             :     }
      90             : }
      91             : 
      92             : bool
      93           0 : WebGLContext::ValidateBlendFuncSrcEnum(GLenum factor, const char* info)
      94             : {
      95           0 :     if (factor == LOCAL_GL_SRC_ALPHA_SATURATE)
      96           0 :         return true;
      97             : 
      98           0 :     return ValidateBlendFuncDstEnum(factor, info);
      99             : }
     100             : 
     101             : bool
     102           0 : WebGLContext::ValidateBlendFuncEnumsCompatibility(GLenum sfactor,
     103             :                                                   GLenum dfactor,
     104             :                                                   const char* info)
     105             : {
     106           0 :     bool sfactorIsConstantColor = sfactor == LOCAL_GL_CONSTANT_COLOR ||
     107           0 :                                   sfactor == LOCAL_GL_ONE_MINUS_CONSTANT_COLOR;
     108           0 :     bool sfactorIsConstantAlpha = sfactor == LOCAL_GL_CONSTANT_ALPHA ||
     109           0 :                                   sfactor == LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA;
     110           0 :     bool dfactorIsConstantColor = dfactor == LOCAL_GL_CONSTANT_COLOR ||
     111           0 :                                   dfactor == LOCAL_GL_ONE_MINUS_CONSTANT_COLOR;
     112           0 :     bool dfactorIsConstantAlpha = dfactor == LOCAL_GL_CONSTANT_ALPHA ||
     113           0 :                                   dfactor == LOCAL_GL_ONE_MINUS_CONSTANT_ALPHA;
     114           0 :     if ( (sfactorIsConstantColor && dfactorIsConstantAlpha) ||
     115           0 :          (dfactorIsConstantColor && sfactorIsConstantAlpha) )
     116             :     {
     117             :         ErrorInvalidOperation("%s are mutually incompatible, see section 6.8 in"
     118           0 :                               " the WebGL 1.0 spec", info);
     119           0 :         return false;
     120             :     }
     121             : 
     122           0 :     return true;
     123             : }
     124             : 
     125             : bool
     126           0 : WebGLContext::ValidateComparisonEnum(GLenum target, const char* info)
     127             : {
     128           0 :     switch (target) {
     129             :     case LOCAL_GL_NEVER:
     130             :     case LOCAL_GL_LESS:
     131             :     case LOCAL_GL_LEQUAL:
     132             :     case LOCAL_GL_GREATER:
     133             :     case LOCAL_GL_GEQUAL:
     134             :     case LOCAL_GL_EQUAL:
     135             :     case LOCAL_GL_NOTEQUAL:
     136             :     case LOCAL_GL_ALWAYS:
     137           0 :         return true;
     138             : 
     139             :     default:
     140           0 :         ErrorInvalidEnumInfo(info, target);
     141           0 :         return false;
     142             :     }
     143             : }
     144             : 
     145             : bool
     146           0 : WebGLContext::ValidateStencilOpEnum(GLenum action, const char* info)
     147             : {
     148           0 :     switch (action) {
     149             :     case LOCAL_GL_KEEP:
     150             :     case LOCAL_GL_ZERO:
     151             :     case LOCAL_GL_REPLACE:
     152             :     case LOCAL_GL_INCR:
     153             :     case LOCAL_GL_INCR_WRAP:
     154             :     case LOCAL_GL_DECR:
     155             :     case LOCAL_GL_DECR_WRAP:
     156             :     case LOCAL_GL_INVERT:
     157           0 :         return true;
     158             : 
     159             :     default:
     160           0 :         ErrorInvalidEnumInfo(info, action);
     161           0 :         return false;
     162             :     }
     163             : }
     164             : 
     165             : bool
     166           0 : WebGLContext::ValidateFaceEnum(GLenum face, const char* info)
     167             : {
     168           0 :     switch (face) {
     169             :     case LOCAL_GL_FRONT:
     170             :     case LOCAL_GL_BACK:
     171             :     case LOCAL_GL_FRONT_AND_BACK:
     172           0 :         return true;
     173             : 
     174             :     default:
     175           0 :         ErrorInvalidEnumInfo(info, face);
     176           0 :         return false;
     177             :     }
     178             : }
     179             : 
     180             : bool
     181           0 : WebGLContext::ValidateDrawModeEnum(GLenum mode, const char* info)
     182             : {
     183           0 :     switch (mode) {
     184             :     case LOCAL_GL_TRIANGLES:
     185             :     case LOCAL_GL_TRIANGLE_STRIP:
     186             :     case LOCAL_GL_TRIANGLE_FAN:
     187             :     case LOCAL_GL_POINTS:
     188             :     case LOCAL_GL_LINE_STRIP:
     189             :     case LOCAL_GL_LINE_LOOP:
     190             :     case LOCAL_GL_LINES:
     191           0 :         return true;
     192             : 
     193             :     default:
     194           0 :         ErrorInvalidEnumInfo(info, mode);
     195           0 :         return false;
     196             :     }
     197             : }
     198             : 
     199             : bool
     200           0 : WebGLContext::ValidateUniformLocation(WebGLUniformLocation* loc, const char* funcName)
     201             : {
     202             :     /* GLES 2.0.25, p38:
     203             :      *   If the value of location is -1, the Uniform* commands will silently
     204             :      *   ignore the data passed in, and the current uniform values will not be
     205             :      *   changed.
     206             :      */
     207           0 :     if (!loc)
     208           0 :         return false;
     209             : 
     210           0 :     if (!ValidateObjectAllowDeleted(funcName, *loc))
     211           0 :         return false;
     212             : 
     213           0 :     if (!mCurrentProgram) {
     214           0 :         ErrorInvalidOperation("%s: No program is currently bound.", funcName);
     215           0 :         return false;
     216             :     }
     217             : 
     218           0 :     return loc->ValidateForProgram(mCurrentProgram, funcName);
     219             : }
     220             : 
     221             : bool
     222           0 : WebGLContext::ValidateAttribArraySetter(const char* name, uint32_t setterElemSize,
     223             :                                         uint32_t arrayLength)
     224             : {
     225           0 :     if (IsContextLost())
     226           0 :         return false;
     227             : 
     228           0 :     if (arrayLength < setterElemSize) {
     229             :         ErrorInvalidValue("%s: Array must have >= %d elements.", name,
     230           0 :                           setterElemSize);
     231           0 :         return false;
     232             :     }
     233             : 
     234           0 :     return true;
     235             : }
     236             : 
     237             : bool
     238           0 : WebGLContext::ValidateUniformSetter(WebGLUniformLocation* loc,
     239             :                                     uint8_t setterElemSize, GLenum setterType,
     240             :                                     const char* funcName)
     241             : {
     242           0 :     if (IsContextLost())
     243           0 :         return false;
     244             : 
     245           0 :     if (!ValidateUniformLocation(loc, funcName))
     246           0 :         return false;
     247             : 
     248           0 :     if (!loc->ValidateSizeAndType(setterElemSize, setterType, funcName))
     249           0 :         return false;
     250             : 
     251           0 :     return true;
     252             : }
     253             : 
     254             : bool
     255           0 : WebGLContext::ValidateUniformArraySetter(WebGLUniformLocation* loc,
     256             :                                          uint8_t setterElemSize,
     257             :                                          GLenum setterType,
     258             :                                          uint32_t setterArraySize,
     259             :                                          const char* funcName,
     260             :                                          uint32_t* const out_numElementsToUpload)
     261             : {
     262           0 :     if (IsContextLost())
     263           0 :         return false;
     264             : 
     265           0 :     if (!ValidateUniformLocation(loc, funcName))
     266           0 :         return false;
     267             : 
     268           0 :     if (!loc->ValidateSizeAndType(setterElemSize, setterType, funcName))
     269           0 :         return false;
     270             : 
     271           0 :     if (!loc->ValidateArrayLength(setterElemSize, setterArraySize, funcName))
     272           0 :         return false;
     273             : 
     274           0 :     const auto& elemCount = loc->mInfo->mActiveInfo->mElemCount;
     275           0 :     MOZ_ASSERT(elemCount > loc->mArrayIndex);
     276           0 :     const uint32_t uniformElemCount = elemCount - loc->mArrayIndex;
     277             : 
     278           0 :     *out_numElementsToUpload = std::min(uniformElemCount,
     279           0 :                                         setterArraySize / setterElemSize);
     280           0 :     return true;
     281             : }
     282             : 
     283             : bool
     284           0 : WebGLContext::ValidateUniformMatrixArraySetter(WebGLUniformLocation* loc,
     285             :                                                uint8_t setterCols,
     286             :                                                uint8_t setterRows,
     287             :                                                GLenum setterType,
     288             :                                                uint32_t setterArraySize,
     289             :                                                bool setterTranspose,
     290             :                                                const char* funcName,
     291             :                                                uint32_t* const out_numElementsToUpload)
     292             : {
     293           0 :     const uint8_t setterElemSize = setterCols * setterRows;
     294             : 
     295           0 :     if (IsContextLost())
     296           0 :         return false;
     297             : 
     298           0 :     if (!ValidateUniformLocation(loc, funcName))
     299           0 :         return false;
     300             : 
     301           0 :     if (!loc->ValidateSizeAndType(setterElemSize, setterType, funcName))
     302           0 :         return false;
     303             : 
     304           0 :     if (!loc->ValidateArrayLength(setterElemSize, setterArraySize, funcName))
     305           0 :         return false;
     306             : 
     307           0 :     if (setterTranspose && !IsWebGL2()) {
     308           0 :         ErrorInvalidValue("%s: `transpose` must be false.", funcName);
     309           0 :         return false;
     310             :     }
     311             : 
     312           0 :     const auto& elemCount = loc->mInfo->mActiveInfo->mElemCount;
     313           0 :     MOZ_ASSERT(elemCount > loc->mArrayIndex);
     314           0 :     const uint32_t uniformElemCount = elemCount - loc->mArrayIndex;
     315             : 
     316           0 :     *out_numElementsToUpload = std::min(uniformElemCount,
     317           0 :                                         setterArraySize / setterElemSize);
     318           0 :     return true;
     319             : }
     320             : 
     321             : bool
     322           0 : WebGLContext::ValidateAttribIndex(GLuint index, const char* info)
     323             : {
     324           0 :     bool valid = (index < MaxVertexAttribs());
     325             : 
     326           0 :     if (!valid) {
     327           0 :         if (index == GLuint(-1)) {
     328             :             ErrorInvalidValue("%s: -1 is not a valid `index`. This value"
     329             :                               " probably comes from a getAttribLocation()"
     330             :                               " call, where this return value -1 means"
     331             :                               " that the passed name didn't correspond to"
     332             :                               " an active attribute in the specified"
     333           0 :                               " program.", info);
     334             :         } else {
     335             :             ErrorInvalidValue("%s: `index` must be less than"
     336           0 :                               " MAX_VERTEX_ATTRIBS.", info);
     337             :         }
     338             :     }
     339             : 
     340           0 :     return valid;
     341             : }
     342             : 
     343             : bool
     344           0 : WebGLContext::ValidateStencilParamsForDrawCall()
     345             : {
     346             :     const char msg[] = "%s set different front and back stencil %s. Drawing in"
     347           0 :                        " this configuration is not allowed.";
     348             : 
     349           0 :     if (mStencilRefFront != mStencilRefBack) {
     350           0 :         ErrorInvalidOperation(msg, "stencilFuncSeparate", "reference values");
     351           0 :         return false;
     352             :     }
     353             : 
     354           0 :     if (mStencilValueMaskFront != mStencilValueMaskBack) {
     355           0 :         ErrorInvalidOperation(msg, "stencilFuncSeparate", "value masks");
     356           0 :         return false;
     357             :     }
     358             : 
     359           0 :     if (mStencilWriteMaskFront != mStencilWriteMaskBack) {
     360           0 :         ErrorInvalidOperation(msg, "stencilMaskSeparate", "write masks");
     361           0 :         return false;
     362             :     }
     363             : 
     364           0 :     return true;
     365             : }
     366             : 
     367             : static inline int32_t
     368             : FloorPOT(int32_t x)
     369             : {
     370             :     MOZ_ASSERT(x > 0);
     371             :     int32_t pot = 1;
     372             :     while (pot < 0x40000000) {
     373             :         if (x < pot*2)
     374             :             break;
     375             :         pot *= 2;
     376             :     }
     377             :     return pot;
     378             : }
     379             : 
     380             : bool
     381           0 : WebGLContext::InitAndValidateGL(FailureReason* const out_failReason)
     382             : {
     383           0 :     MOZ_RELEASE_ASSERT(gl, "GFX: GL not initialized");
     384             : 
     385             :     // Unconditionally create a new format usage authority. This is
     386             :     // important when restoring contexts and extensions need to add
     387             :     // formats back into the authority.
     388           0 :     mFormatUsage = CreateFormatUsage(gl);
     389           0 :     if (!mFormatUsage) {
     390             :         *out_failReason = { "FEATURE_FAILURE_WEBGL_FORMAT",
     391           0 :                             "Failed to create mFormatUsage." };
     392           0 :         return false;
     393             :     }
     394             : 
     395           0 :     GLenum error = gl->fGetError();
     396           0 :     if (error != LOCAL_GL_NO_ERROR) {
     397             :         const nsPrintfCString reason("GL error 0x%x occurred during OpenGL context"
     398             :                                      " initialization, before WebGL initialization!",
     399           0 :                                      error);
     400           0 :         *out_failReason = { "FEATURE_FAILURE_WEBGL_GLERR_1", reason };
     401           0 :         return false;
     402             :     }
     403             : 
     404           0 :     mMinCapability = gfxPrefs::WebGLMinCapabilityMode();
     405           0 :     mDisableExtensions = gfxPrefs::WebGLDisableExtensions();
     406           0 :     mLoseContextOnMemoryPressure = gfxPrefs::WebGLLoseContextOnMemoryPressure();
     407           0 :     mCanLoseContextInForeground = gfxPrefs::WebGLCanLoseContextInForeground();
     408           0 :     mRestoreWhenVisible = gfxPrefs::WebGLRestoreWhenVisible();
     409             : 
     410           0 :     if (MinCapabilityMode())
     411           0 :         mDisableFragHighP = true;
     412             : 
     413             :     // These are the default values, see 6.2 State tables in the
     414             :     // OpenGL ES 2.0.25 spec.
     415           0 :     mColorWriteMask[0] = 1;
     416           0 :     mColorWriteMask[1] = 1;
     417           0 :     mColorWriteMask[2] = 1;
     418           0 :     mColorWriteMask[3] = 1;
     419           0 :     mDepthWriteMask = 1;
     420           0 :     mColorClearValue[0] = 0.f;
     421           0 :     mColorClearValue[1] = 0.f;
     422           0 :     mColorClearValue[2] = 0.f;
     423           0 :     mColorClearValue[3] = 0.f;
     424           0 :     mDepthClearValue = 1.f;
     425           0 :     mStencilClearValue = 0;
     426           0 :     mStencilRefFront = 0;
     427           0 :     mStencilRefBack = 0;
     428             : 
     429           0 :     mLineWidth = 1.0;
     430             : 
     431             :     /*
     432             :     // Technically, we should be setting mStencil[...] values to
     433             :     // `allOnes`, but either ANGLE breaks or the SGX540s on Try break.
     434             :     GLuint stencilBits = 0;
     435             :     gl->GetUIntegerv(LOCAL_GL_STENCIL_BITS, &stencilBits);
     436             :     GLuint allOnes = ~(UINT32_MAX << stencilBits);
     437             :     mStencilValueMaskFront = allOnes;
     438             :     mStencilValueMaskBack  = allOnes;
     439             :     mStencilWriteMaskFront = allOnes;
     440             :     mStencilWriteMaskBack  = allOnes;
     441             :     */
     442             : 
     443           0 :     gl->GetUIntegerv(LOCAL_GL_STENCIL_VALUE_MASK,      &mStencilValueMaskFront);
     444           0 :     gl->GetUIntegerv(LOCAL_GL_STENCIL_BACK_VALUE_MASK, &mStencilValueMaskBack);
     445           0 :     gl->GetUIntegerv(LOCAL_GL_STENCIL_WRITEMASK,       &mStencilWriteMaskFront);
     446           0 :     gl->GetUIntegerv(LOCAL_GL_STENCIL_BACK_WRITEMASK,  &mStencilWriteMaskBack);
     447             : 
     448           0 :     AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_VALUE_MASK,      mStencilValueMaskFront);
     449           0 :     AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_VALUE_MASK, mStencilValueMaskBack);
     450           0 :     AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_WRITEMASK,       mStencilWriteMaskFront);
     451           0 :     AssertUintParamCorrect(gl, LOCAL_GL_STENCIL_BACK_WRITEMASK,  mStencilWriteMaskBack);
     452             : 
     453           0 :     mDitherEnabled = true;
     454           0 :     mRasterizerDiscardEnabled = false;
     455           0 :     mScissorTestEnabled = false;
     456           0 :     mDepthTestEnabled = 0;
     457           0 :     mStencilTestEnabled = 0;
     458           0 :     mGenerateMipmapHint = LOCAL_GL_DONT_CARE;
     459             : 
     460             :     // Bindings, etc.
     461           0 :     mActiveTexture = 0;
     462           0 :     mDefaultFB_DrawBuffer0 = LOCAL_GL_BACK;
     463             : 
     464           0 :     mEmitContextLostErrorOnce = true;
     465           0 :     mWebGLError = LOCAL_GL_NO_ERROR;
     466           0 :     mUnderlyingGLError = LOCAL_GL_NO_ERROR;
     467             : 
     468           0 :     mBound2DTextures.Clear();
     469           0 :     mBoundCubeMapTextures.Clear();
     470           0 :     mBound3DTextures.Clear();
     471           0 :     mBound2DArrayTextures.Clear();
     472           0 :     mBoundSamplers.Clear();
     473             : 
     474           0 :     mBoundArrayBuffer = nullptr;
     475           0 :     mCurrentProgram = nullptr;
     476             : 
     477           0 :     mBoundDrawFramebuffer = nullptr;
     478           0 :     mBoundReadFramebuffer = nullptr;
     479           0 :     mBoundRenderbuffer = nullptr;
     480             : 
     481           0 :     MakeContextCurrent();
     482             : 
     483           0 :     if (MinCapabilityMode())
     484           0 :         mGLMaxVertexAttribs = MINVALUE_GL_MAX_VERTEX_ATTRIBS;
     485             :     else
     486           0 :         gl->GetUIntegerv(LOCAL_GL_MAX_VERTEX_ATTRIBS, &mGLMaxVertexAttribs);
     487             : 
     488           0 :     if (mGLMaxVertexAttribs < 8) {
     489             :         const nsPrintfCString reason("GL_MAX_VERTEX_ATTRIBS: %d is < 8!",
     490           0 :                                      mGLMaxVertexAttribs);
     491           0 :         *out_failReason = { "FEATURE_FAILURE_WEBGL_V_ATRB", reason };
     492           0 :         return false;
     493             :     }
     494             : 
     495             :     // Note: GL_MAX_TEXTURE_UNITS is fixed at 4 for most desktop hardware,
     496             :     // even though the hardware supports much more.  The
     497             :     // GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS value is the accurate value.
     498           0 :     if (MinCapabilityMode())
     499           0 :         mGLMaxTextureUnits = MINVALUE_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS;
     500             :     else
     501           0 :         gl->fGetIntegerv(LOCAL_GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &mGLMaxTextureUnits);
     502             : 
     503           0 :     if (mGLMaxTextureUnits < 8) {
     504             :         const nsPrintfCString reason("GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: %d is < 8!",
     505           0 :                                      mGLMaxTextureUnits);
     506           0 :         *out_failReason = { "FEATURE_FAILURE_WEBGL_T_UNIT", reason };
     507           0 :         return false;
     508             :     }
     509             : 
     510           0 :     mBound2DTextures.SetLength(mGLMaxTextureUnits);
     511           0 :     mBoundCubeMapTextures.SetLength(mGLMaxTextureUnits);
     512           0 :     mBound3DTextures.SetLength(mGLMaxTextureUnits);
     513           0 :     mBound2DArrayTextures.SetLength(mGLMaxTextureUnits);
     514           0 :     mBoundSamplers.SetLength(mGLMaxTextureUnits);
     515             : 
     516           0 :     gl->fGetIntegerv(LOCAL_GL_MAX_VIEWPORT_DIMS, (GLint*)mImplMaxViewportDims);
     517             : 
     518             :     ////////////////
     519             : 
     520           0 :     if (MinCapabilityMode()) {
     521           0 :         mImplMaxTextureSize = MINVALUE_GL_MAX_TEXTURE_SIZE;
     522           0 :         mImplMaxCubeMapTextureSize = MINVALUE_GL_MAX_CUBE_MAP_TEXTURE_SIZE;
     523           0 :         mImplMaxRenderbufferSize = MINVALUE_GL_MAX_RENDERBUFFER_SIZE;
     524             : 
     525           0 :         mImplMax3DTextureSize = MINVALUE_GL_MAX_3D_TEXTURE_SIZE;
     526           0 :         mImplMaxArrayTextureLayers = MINVALUE_GL_MAX_ARRAY_TEXTURE_LAYERS;
     527             : 
     528           0 :         mGLMaxTextureImageUnits = MINVALUE_GL_MAX_TEXTURE_IMAGE_UNITS;
     529           0 :         mGLMaxVertexTextureImageUnits = MINVALUE_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS;
     530             :     } else {
     531           0 :         gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, (GLint*)&mImplMaxTextureSize);
     532           0 :         gl->fGetIntegerv(LOCAL_GL_MAX_CUBE_MAP_TEXTURE_SIZE, (GLint*)&mImplMaxCubeMapTextureSize);
     533           0 :         gl->fGetIntegerv(LOCAL_GL_MAX_RENDERBUFFER_SIZE, (GLint*)&mImplMaxRenderbufferSize);
     534             : 
     535           0 :         if (!gl->GetPotentialInteger(LOCAL_GL_MAX_3D_TEXTURE_SIZE, (GLint*)&mImplMax3DTextureSize))
     536           0 :             mImplMax3DTextureSize = 0;
     537           0 :         if (!gl->GetPotentialInteger(LOCAL_GL_MAX_ARRAY_TEXTURE_LAYERS, (GLint*)&mImplMaxArrayTextureLayers))
     538           0 :             mImplMaxArrayTextureLayers = 0;
     539             : 
     540           0 :         gl->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_IMAGE_UNITS, &mGLMaxTextureImageUnits);
     541           0 :         gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS, &mGLMaxVertexTextureImageUnits);
     542             :     }
     543             : 
     544             :     ////////////////
     545             : 
     546           0 :     mGLMaxColorAttachments = 1;
     547           0 :     mGLMaxDrawBuffers = 1;
     548           0 :     gl->GetPotentialInteger(LOCAL_GL_MAX_COLOR_ATTACHMENTS,
     549           0 :                             (GLint*)&mGLMaxColorAttachments);
     550           0 :     gl->GetPotentialInteger(LOCAL_GL_MAX_DRAW_BUFFERS, (GLint*)&mGLMaxDrawBuffers);
     551             : 
     552           0 :     if (MinCapabilityMode()) {
     553           0 :         mGLMaxColorAttachments = std::min(mGLMaxColorAttachments,
     554           0 :                                           kMinMaxColorAttachments);
     555           0 :         mGLMaxDrawBuffers = std::min(mGLMaxDrawBuffers, kMinMaxDrawBuffers);
     556             :     }
     557             : 
     558           0 :     if (IsWebGL2()) {
     559           0 :         mImplMaxColorAttachments = mGLMaxColorAttachments;
     560           0 :         mImplMaxDrawBuffers = std::min(mGLMaxDrawBuffers, mImplMaxColorAttachments);
     561             :     } else {
     562           0 :         mImplMaxColorAttachments = 1;
     563           0 :         mImplMaxDrawBuffers = 1;
     564             :     }
     565             : 
     566             :     ////////////////
     567             : 
     568           0 :     if (MinCapabilityMode()) {
     569           0 :         mGLMaxFragmentUniformVectors = MINVALUE_GL_MAX_FRAGMENT_UNIFORM_VECTORS;
     570           0 :         mGLMaxVertexUniformVectors = MINVALUE_GL_MAX_VERTEX_UNIFORM_VECTORS;
     571           0 :         mGLMaxVaryingVectors = MINVALUE_GL_MAX_VARYING_VECTORS;
     572             :     } else {
     573           0 :         if (gl->IsSupported(gl::GLFeature::ES2_compatibility)) {
     574           0 :             gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_VECTORS, &mGLMaxFragmentUniformVectors);
     575           0 :             gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_VECTORS, &mGLMaxVertexUniformVectors);
     576           0 :             gl->fGetIntegerv(LOCAL_GL_MAX_VARYING_VECTORS, &mGLMaxVaryingVectors);
     577             :         } else {
     578           0 :             gl->fGetIntegerv(LOCAL_GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &mGLMaxFragmentUniformVectors);
     579           0 :             mGLMaxFragmentUniformVectors /= 4;
     580           0 :             gl->fGetIntegerv(LOCAL_GL_MAX_VERTEX_UNIFORM_COMPONENTS, &mGLMaxVertexUniformVectors);
     581           0 :             mGLMaxVertexUniformVectors /= 4;
     582             : 
     583             :             /* We are now going to try to read GL_MAX_VERTEX_OUTPUT_COMPONENTS
     584             :              * and GL_MAX_FRAGMENT_INPUT_COMPONENTS, however these constants
     585             :              * only entered the OpenGL standard at OpenGL 3.2. So we will try
     586             :              * reading, and check OpenGL error for INVALID_ENUM.
     587             :              *
     588             :              * On the public_webgl list, "problematic GetParameter pnames"
     589             :              * thread, the following formula was given:
     590             :              *   maxVaryingVectors = min(GL_MAX_VERTEX_OUTPUT_COMPONENTS,
     591             :              *                           GL_MAX_FRAGMENT_INPUT_COMPONENTS) / 4
     592             :              */
     593           0 :             GLint maxVertexOutputComponents = 0;
     594           0 :             GLint maxFragmentInputComponents = 0;
     595             : 
     596           0 :             const bool ok = (gl->GetPotentialInteger(LOCAL_GL_MAX_VERTEX_OUTPUT_COMPONENTS,
     597           0 :                                                      &maxVertexOutputComponents) &&
     598           0 :                              gl->GetPotentialInteger(LOCAL_GL_MAX_FRAGMENT_INPUT_COMPONENTS,
     599           0 :                                                      &maxFragmentInputComponents));
     600             : 
     601           0 :             if (ok) {
     602           0 :                 mGLMaxVaryingVectors = std::min(maxVertexOutputComponents,
     603           0 :                                                 maxFragmentInputComponents) / 4;
     604             :             } else {
     605           0 :                 mGLMaxVaryingVectors = 16;
     606             :                 // 16 = 64/4, and 64 is the min value for
     607             :                 // maxVertexOutputComponents in the OpenGL 3.2 spec.
     608             :             }
     609             :         }
     610             :     }
     611             : 
     612           0 :     if (gl->IsCompatibilityProfile()) {
     613           0 :         gl->fEnable(LOCAL_GL_POINT_SPRITE);
     614             :     }
     615             : 
     616           0 :     if (!gl->IsGLES()) {
     617           0 :         gl->fEnable(LOCAL_GL_PROGRAM_POINT_SIZE);
     618             :     }
     619             : 
     620             : #ifdef XP_MACOSX
     621             :     if (gl->WorkAroundDriverBugs() &&
     622             :         gl->Vendor() == gl::GLVendor::ATI &&
     623             :         !nsCocoaFeatures::IsAtLeastVersion(10,9))
     624             :     {
     625             :         // The Mac ATI driver, in all known OSX version up to and including
     626             :         // 10.8, renders points sprites upside-down. (Apple bug 11778921)
     627             :         gl->fPointParameterf(LOCAL_GL_POINT_SPRITE_COORD_ORIGIN,
     628             :                              LOCAL_GL_LOWER_LEFT);
     629             :     }
     630             : #endif
     631             : 
     632           0 :     if (gl->IsSupported(gl::GLFeature::seamless_cube_map_opt_in)) {
     633           0 :         gl->fEnable(LOCAL_GL_TEXTURE_CUBE_MAP_SEAMLESS);
     634             :     }
     635             : 
     636             :     // Check the shader validator pref
     637           0 :     mBypassShaderValidation = gfxPrefs::WebGLBypassShaderValidator();
     638             : 
     639             :     // initialize shader translator
     640           0 :     if (!ShInitialize()) {
     641             :         *out_failReason = { "FEATURE_FAILURE_WEBGL_GLSL",
     642           0 :                             "GLSL translator initialization failed!" };
     643           0 :         return false;
     644             :     }
     645             : 
     646             :     // Mesa can only be detected with the GL_VERSION string, of the form
     647             :     // "2.1 Mesa 7.11.0"
     648           0 :     const char* versionStr = (const char*)(gl->fGetString(LOCAL_GL_VERSION));
     649           0 :     mIsMesa = strstr(versionStr, "Mesa");
     650             : 
     651             :     // Notice that the point of calling fGetError here is not only to check for
     652             :     // errors, but also to reset the error flags so that a subsequent WebGL
     653             :     // getError call will give the correct result.
     654           0 :     error = gl->fGetError();
     655           0 :     if (error != LOCAL_GL_NO_ERROR) {
     656             :         const nsPrintfCString reason("GL error 0x%x occurred during WebGL context"
     657             :                                      " initialization!",
     658           0 :                                      error);
     659           0 :         *out_failReason = { "FEATURE_FAILURE_WEBGL_GLERR_2", reason };
     660           0 :         return false;
     661             :     }
     662             : 
     663           0 :     if (IsWebGL2() &&
     664           0 :         !InitWebGL2(out_failReason))
     665             :     {
     666             :         // Todo: Bug 898404: Only allow WebGL2 on GL>=3.0 on desktop GL.
     667           0 :         return false;
     668             :     }
     669             : 
     670           0 :     mDefaultVertexArray = WebGLVertexArray::Create(this);
     671           0 :     mDefaultVertexArray->mAttribs.SetLength(mGLMaxVertexAttribs);
     672           0 :     mBoundVertexArray = mDefaultVertexArray;
     673             : 
     674             :     // OpenGL core profiles remove the default VAO object from version
     675             :     // 4.0.0. We create a default VAO for all core profiles,
     676             :     // regardless of version.
     677             :     //
     678             :     // GL Spec 4.0.0:
     679             :     // (https://www.opengl.org/registry/doc/glspec40.core.20100311.pdf)
     680             :     // in Section E.2.2 "Removed Features", pg 397: "[...] The default
     681             :     // vertex array object (the name zero) is also deprecated. [...]"
     682             : 
     683           0 :     if (gl->IsCoreProfile()) {
     684           0 :         mDefaultVertexArray->GenVertexArray();
     685           0 :         mDefaultVertexArray->BindVertexArray();
     686             :     }
     687             : 
     688           0 :     mPixelStore_FlipY = false;
     689           0 :     mPixelStore_PremultiplyAlpha = false;
     690           0 :     mPixelStore_ColorspaceConversion = BROWSER_DEFAULT_WEBGL;
     691           0 :     mPixelStore_RequireFastPath = false;
     692             : 
     693             :     // GLES 3.0.4, p259:
     694           0 :     mPixelStore_UnpackImageHeight = 0;
     695           0 :     mPixelStore_UnpackSkipImages = 0;
     696           0 :     mPixelStore_UnpackRowLength = 0;
     697           0 :     mPixelStore_UnpackSkipRows = 0;
     698           0 :     mPixelStore_UnpackSkipPixels = 0;
     699           0 :     mPixelStore_UnpackAlignment = 4;
     700           0 :     mPixelStore_PackRowLength = 0;
     701           0 :     mPixelStore_PackSkipRows = 0;
     702           0 :     mPixelStore_PackSkipPixels = 0;
     703           0 :     mPixelStore_PackAlignment = 4;
     704             : 
     705           0 :     mPrimRestartTypeBytes = 0;
     706             : 
     707           0 :     mGenericVertexAttribTypes.reset(new GLenum[mGLMaxVertexAttribs]);
     708           0 :     std::fill_n(mGenericVertexAttribTypes.get(), mGLMaxVertexAttribs, LOCAL_GL_FLOAT);
     709             : 
     710             :     static const float kDefaultGenericVertexAttribData[4] = { 0, 0, 0, 1 };
     711           0 :     memcpy(mGenericVertexAttrib0Data, kDefaultGenericVertexAttribData,
     712           0 :            sizeof(mGenericVertexAttrib0Data));
     713             : 
     714           0 :     mFakeVertexAttrib0BufferObject = 0;
     715             : 
     716           0 :     mNeedsIndexValidation = !gl->IsSupported(gl::GLFeature::robust_buffer_access_behavior);
     717           0 :     if (gfxPrefs::WebGLForceIndexValidation()) {
     718           0 :         mNeedsIndexValidation = true;
     719             :     }
     720             : 
     721           0 :     return true;
     722             : }
     723             : 
     724             : bool
     725           0 : WebGLContext::ValidateFramebufferTarget(GLenum target,
     726             :                                         const char* const info)
     727             : {
     728           0 :     bool isValid = true;
     729           0 :     switch (target) {
     730             :     case LOCAL_GL_FRAMEBUFFER:
     731           0 :         break;
     732             : 
     733             :     case LOCAL_GL_DRAW_FRAMEBUFFER:
     734             :     case LOCAL_GL_READ_FRAMEBUFFER:
     735           0 :         isValid = IsWebGL2();
     736           0 :         break;
     737             : 
     738             :     default:
     739           0 :         isValid = false;
     740           0 :         break;
     741             :     }
     742             : 
     743           0 :     if (MOZ_LIKELY(isValid)) {
     744           0 :         return true;
     745             :     }
     746             : 
     747           0 :     ErrorInvalidEnumArg(info, "target", target);
     748           0 :     return false;
     749             : }
     750             : 
     751             : } // namespace mozilla

Generated by: LCOV version 1.13