LCOV - code coverage report
Current view: top level - dom/canvas - WebGLContextTextures.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 163 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: 4; 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             : #include "WebGLContextUtils.h"
       8             : #include "WebGLBuffer.h"
       9             : #include "WebGLVertexAttribData.h"
      10             : #include "WebGLShader.h"
      11             : #include "WebGLProgram.h"
      12             : #include "WebGLUniformLocation.h"
      13             : #include "WebGLFramebuffer.h"
      14             : #include "WebGLRenderbuffer.h"
      15             : #include "WebGLShaderPrecisionFormat.h"
      16             : #include "WebGLTexture.h"
      17             : #include "WebGLExtensions.h"
      18             : #include "WebGLVertexArray.h"
      19             : 
      20             : #include "nsString.h"
      21             : #include "nsDebug.h"
      22             : #include "nsReadableUtils.h"
      23             : 
      24             : #include "gfxContext.h"
      25             : #include "gfxPlatform.h"
      26             : #include "GLContext.h"
      27             : 
      28             : #include "nsContentUtils.h"
      29             : #include "nsError.h"
      30             : #include "nsLayoutUtils.h"
      31             : 
      32             : #include "CanvasUtils.h"
      33             : #include "gfxUtils.h"
      34             : 
      35             : #include "jsfriendapi.h"
      36             : 
      37             : #include "WebGLTexelConversions.h"
      38             : #include "WebGLValidateStrings.h"
      39             : #include <algorithm>
      40             : 
      41             : // needed to check if current OS is lower than 10.7
      42             : #if defined(MOZ_WIDGET_COCOA)
      43             : #include "nsCocoaFeatures.h"
      44             : #endif
      45             : 
      46             : #include "mozilla/DebugOnly.h"
      47             : #include "mozilla/dom/BindingUtils.h"
      48             : #include "mozilla/dom/ImageData.h"
      49             : #include "mozilla/dom/ToJSValue.h"
      50             : #include "mozilla/EndianUtils.h"
      51             : 
      52             : namespace mozilla {
      53             : 
      54             : static bool
      55           0 : IsValidTexTarget(WebGLContext* webgl, uint8_t funcDims, GLenum rawTexTarget,
      56             :                  TexTarget* const out)
      57             : {
      58             :     uint8_t targetDims;
      59             : 
      60           0 :     switch (rawTexTarget) {
      61             :     case LOCAL_GL_TEXTURE_2D:
      62             :     case LOCAL_GL_TEXTURE_CUBE_MAP:
      63           0 :         targetDims = 2;
      64           0 :         break;
      65             : 
      66             :     case LOCAL_GL_TEXTURE_3D:
      67             :     case LOCAL_GL_TEXTURE_2D_ARRAY:
      68           0 :         if (!webgl->IsWebGL2())
      69           0 :             return false;
      70             : 
      71           0 :         targetDims = 3;
      72           0 :         break;
      73             : 
      74             :     default:
      75           0 :         return false;
      76             :     }
      77             : 
      78             :     // Some funcs (like GenerateMipmap) doesn't know the dimension, so don't check it.
      79           0 :     if (funcDims && targetDims != funcDims)
      80           0 :         return false;
      81             : 
      82           0 :     *out = rawTexTarget;
      83           0 :     return true;
      84             : }
      85             : 
      86             : static bool
      87           0 : IsValidTexImageTarget(WebGLContext* webgl, uint8_t funcDims, GLenum rawTexImageTarget,
      88             :                       TexImageTarget* const out)
      89             : {
      90             :     uint8_t targetDims;
      91             : 
      92           0 :     switch (rawTexImageTarget) {
      93             :     case LOCAL_GL_TEXTURE_2D:
      94             :     case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X:
      95             :     case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
      96             :     case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
      97             :     case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
      98             :     case LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
      99             :     case LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
     100           0 :         targetDims = 2;
     101           0 :         break;
     102             : 
     103             :     case LOCAL_GL_TEXTURE_3D:
     104             :     case LOCAL_GL_TEXTURE_2D_ARRAY:
     105           0 :         if (!webgl->IsWebGL2())
     106           0 :             return false;
     107             : 
     108           0 :         targetDims = 3;
     109           0 :         break;
     110             : 
     111             :     default:
     112           0 :         return false;
     113             :     }
     114             : 
     115           0 :     if (targetDims != funcDims)
     116           0 :         return false;
     117             : 
     118           0 :     *out = rawTexImageTarget;
     119           0 :     return true;
     120             : }
     121             : 
     122             : bool
     123           0 : ValidateTexTarget(WebGLContext* webgl, const char* funcName, uint8_t funcDims,
     124             :                   GLenum rawTexTarget, TexTarget* const out_texTarget,
     125             :                   WebGLTexture** const out_tex)
     126             : {
     127           0 :     if (webgl->IsContextLost())
     128           0 :         return false;
     129             : 
     130           0 :     TexTarget texTarget;
     131           0 :     if (!IsValidTexTarget(webgl, funcDims, rawTexTarget, &texTarget)) {
     132           0 :         webgl->ErrorInvalidEnum("%s: Invalid texTarget.", funcName);
     133           0 :         return false;
     134             :     }
     135             : 
     136           0 :     WebGLTexture* tex = webgl->ActiveBoundTextureForTarget(texTarget);
     137           0 :     if (!tex) {
     138           0 :         webgl->ErrorInvalidOperation("%s: No texture is bound to this target.", funcName);
     139           0 :         return false;
     140             :     }
     141             : 
     142           0 :     *out_texTarget = texTarget;
     143           0 :     *out_tex = tex;
     144           0 :     return true;
     145             : }
     146             : 
     147             : bool
     148           0 : ValidateTexImageTarget(WebGLContext* webgl, const char* funcName, uint8_t funcDims,
     149             :                        GLenum rawTexImageTarget, TexImageTarget* const out_texImageTarget,
     150             :                        WebGLTexture** const out_tex)
     151             : {
     152           0 :     if (webgl->IsContextLost())
     153           0 :         return false;
     154             : 
     155           0 :     TexImageTarget texImageTarget;
     156           0 :     if (!IsValidTexImageTarget(webgl, funcDims, rawTexImageTarget, &texImageTarget)) {
     157           0 :         webgl->ErrorInvalidEnum("%s: Invalid texImageTarget.", funcName);
     158           0 :         return false;
     159             :     }
     160             : 
     161           0 :     WebGLTexture* tex = webgl->ActiveBoundTextureForTexImageTarget(texImageTarget);
     162           0 :     if (!tex) {
     163           0 :         webgl->ErrorInvalidOperation("%s: No texture is bound to this target.", funcName);
     164           0 :         return false;
     165             :     }
     166             : 
     167           0 :     *out_texImageTarget = texImageTarget;
     168           0 :     *out_tex = tex;
     169           0 :     return true;
     170             : }
     171             : 
     172             : /*virtual*/ bool
     173           0 : WebGLContext::IsTexParamValid(GLenum pname) const
     174             : {
     175           0 :     switch (pname) {
     176             :     case LOCAL_GL_TEXTURE_MIN_FILTER:
     177             :     case LOCAL_GL_TEXTURE_MAG_FILTER:
     178             :     case LOCAL_GL_TEXTURE_WRAP_S:
     179             :     case LOCAL_GL_TEXTURE_WRAP_T:
     180           0 :         return true;
     181             : 
     182             :     case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
     183           0 :         return IsExtensionEnabled(WebGLExtensionID::EXT_texture_filter_anisotropic);
     184             : 
     185             :     default:
     186           0 :         return false;
     187             :     }
     188             : }
     189             : 
     190             : void
     191           0 : WebGLContext::InvalidateResolveCacheForTextureWithTexUnit(const GLuint texUnit)
     192             : {
     193           0 :     if (mBound2DTextures[texUnit])
     194           0 :         mBound2DTextures[texUnit]->InvalidateResolveCache();
     195           0 :     if (mBoundCubeMapTextures[texUnit])
     196           0 :         mBoundCubeMapTextures[texUnit]->InvalidateResolveCache();
     197           0 :     if (mBound3DTextures[texUnit])
     198           0 :         mBound3DTextures[texUnit]->InvalidateResolveCache();
     199           0 :     if (mBound2DArrayTextures[texUnit])
     200           0 :         mBound2DArrayTextures[texUnit]->InvalidateResolveCache();
     201           0 : }
     202             : 
     203             : //////////////////////////////////////////////////////////////////////////////////////////
     204             : // GL calls
     205             : 
     206             : void
     207           0 : WebGLContext::BindTexture(GLenum rawTarget, WebGLTexture* newTex)
     208             : {
     209           0 :     if (IsContextLost())
     210           0 :         return;
     211             : 
     212           0 :      if (newTex && !ValidateObject("bindTexture", *newTex))
     213           0 :         return;
     214             : 
     215             :     // Need to check rawTarget first before comparing against newTex->Target() as
     216             :     // newTex->Target() returns a TexTarget, which will assert on invalid value.
     217           0 :     WebGLRefPtr<WebGLTexture>* currentTexPtr = nullptr;
     218           0 :     switch (rawTarget) {
     219             :     case LOCAL_GL_TEXTURE_2D:
     220           0 :         currentTexPtr = &mBound2DTextures[mActiveTexture];
     221           0 :         break;
     222             : 
     223             :    case LOCAL_GL_TEXTURE_CUBE_MAP:
     224           0 :         currentTexPtr = &mBoundCubeMapTextures[mActiveTexture];
     225           0 :         break;
     226             : 
     227             :    case LOCAL_GL_TEXTURE_3D:
     228           0 :         if (IsWebGL2())
     229           0 :             currentTexPtr = &mBound3DTextures[mActiveTexture];
     230           0 :         break;
     231             : 
     232             :    case LOCAL_GL_TEXTURE_2D_ARRAY:
     233           0 :         if (IsWebGL2())
     234           0 :             currentTexPtr = &mBound2DArrayTextures[mActiveTexture];
     235           0 :         break;
     236             :     }
     237             : 
     238           0 :     if (!currentTexPtr) {
     239           0 :         ErrorInvalidEnumInfo("bindTexture: target", rawTarget);
     240           0 :         return;
     241             :     }
     242             : 
     243           0 :     const TexTarget texTarget(rawTarget);
     244             : 
     245           0 :     MakeContextCurrent();
     246             : 
     247           0 :     if (newTex) {
     248           0 :         if (!newTex->BindTexture(texTarget))
     249           0 :             return;
     250             :     } else {
     251           0 :         gl->fBindTexture(texTarget.get(), 0);
     252             :     }
     253             : 
     254           0 :     *currentTexPtr = newTex;
     255             : }
     256             : 
     257             : void
     258           0 : WebGLContext::GenerateMipmap(GLenum rawTexTarget)
     259             : {
     260           0 :     const char funcName[] = "generateMipmap";
     261           0 :     const uint8_t funcDims = 0;
     262             : 
     263           0 :     TexTarget texTarget;
     264             :     WebGLTexture* tex;
     265           0 :     if (!ValidateTexTarget(this, funcName, funcDims, rawTexTarget, &texTarget, &tex))
     266           0 :         return;
     267             : 
     268           0 :     tex->GenerateMipmap(texTarget);
     269             : }
     270             : 
     271             : JS::Value
     272           0 : WebGLContext::GetTexParameter(GLenum rawTexTarget, GLenum pname)
     273             : {
     274           0 :     const char funcName[] = "getTexParameter";
     275           0 :     const uint8_t funcDims = 0;
     276             : 
     277           0 :     TexTarget texTarget;
     278             :     WebGLTexture* tex;
     279           0 :     if (!ValidateTexTarget(this, funcName, funcDims, rawTexTarget, &texTarget, &tex))
     280           0 :         return JS::NullValue();
     281             : 
     282           0 :     if (!IsTexParamValid(pname)) {
     283           0 :         ErrorInvalidEnumInfo("getTexParameter: pname", pname);
     284           0 :         return JS::NullValue();
     285             :     }
     286             : 
     287           0 :     return tex->GetTexParameter(texTarget, pname);
     288             : }
     289             : 
     290             : bool
     291           0 : WebGLContext::IsTexture(WebGLTexture* tex)
     292             : {
     293           0 :     if (!ValidateIsObject("isTexture", tex))
     294           0 :         return false;
     295             : 
     296           0 :     return tex->IsTexture();
     297             : }
     298             : 
     299             : void
     300           0 : WebGLContext::TexParameter_base(GLenum rawTexTarget, GLenum pname,
     301             :                                 const FloatOrInt& param)
     302             : {
     303           0 :     const char funcName[] = "texParameter";
     304           0 :     const uint8_t funcDims = 0;
     305             : 
     306           0 :     TexTarget texTarget;
     307             :     WebGLTexture* tex;
     308           0 :     if (!ValidateTexTarget(this, funcName, funcDims, rawTexTarget, &texTarget, &tex))
     309           0 :         return;
     310             : 
     311           0 :     tex->TexParameter(texTarget, pname, param);
     312             : }
     313             : 
     314             : //////////////////////////////////////////////////////////////////////////////////////////
     315             : // Uploads
     316             : 
     317             : void
     318           0 : WebGLContext::CompressedTexImage(const char* funcName, uint8_t funcDims, GLenum rawTarget,
     319             :                                  GLint level, GLenum internalFormat, GLsizei width,
     320             :                                  GLsizei height, GLsizei depth, GLint border,
     321             :                                  const TexImageSource& src)
     322             : {
     323           0 :     TexImageTarget target;
     324             :     WebGLTexture* tex;
     325           0 :     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
     326           0 :         return;
     327             : 
     328           0 :     tex->CompressedTexImage(funcName, target, level, internalFormat, width, height, depth,
     329           0 :                             border, src);
     330             : }
     331             : 
     332             : void
     333           0 : WebGLContext::CompressedTexSubImage(const char* funcName, uint8_t funcDims,
     334             :                                     GLenum rawTarget, GLint level, GLint xOffset,
     335             :                                     GLint yOffset, GLint zOffset, GLsizei width,
     336             :                                     GLsizei height, GLsizei depth, GLenum unpackFormat,
     337             :                                     const TexImageSource& src)
     338             : {
     339           0 :     TexImageTarget target;
     340             :     WebGLTexture* tex;
     341           0 :     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
     342           0 :         return;
     343             : 
     344           0 :     tex->CompressedTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, width,
     345           0 :                                height, depth, unpackFormat, src);
     346             : }
     347             : 
     348             : ////
     349             : 
     350             : void
     351           0 : WebGLContext::CopyTexImage2D(GLenum rawTarget, GLint level, GLenum internalFormat,
     352             :                              GLint x, GLint y, GLsizei width, GLsizei height,
     353             :                              GLint border)
     354             : {
     355           0 :     const char funcName[] = "copyTexImage2D";
     356           0 :     const uint8_t funcDims = 2;
     357             : 
     358           0 :     TexImageTarget target;
     359             :     WebGLTexture* tex;
     360           0 :     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
     361           0 :         return;
     362             : 
     363           0 :     tex->CopyTexImage2D(target, level, internalFormat, x, y, width, height, border);
     364             : }
     365             : 
     366             : void
     367           0 : WebGLContext::CopyTexSubImage(const char* funcName, uint8_t funcDims, GLenum rawTarget,
     368             :                               GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
     369             :                               GLint x, GLint y, GLsizei width, GLsizei height)
     370             : {
     371           0 :     TexImageTarget target;
     372             :     WebGLTexture* tex;
     373           0 :     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
     374           0 :         return;
     375             : 
     376           0 :     tex->CopyTexSubImage(funcName, target, level, xOffset, yOffset, zOffset, x, y, width,
     377           0 :                          height);
     378             : }
     379             : 
     380             : ////
     381             : 
     382             : void
     383           0 : WebGLContext::TexImage(const char* funcName, uint8_t funcDims, GLenum rawTarget,
     384             :                        GLint level, GLenum internalFormat, GLsizei width, GLsizei height,
     385             :                        GLsizei depth, GLint border, GLenum unpackFormat,
     386             :                        GLenum unpackType, const TexImageSource& src)
     387             : {
     388           0 :     TexImageTarget target;
     389             :     WebGLTexture* tex;
     390           0 :     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
     391           0 :         return;
     392             : 
     393           0 :     const webgl::PackingInfo pi = {unpackFormat, unpackType};
     394           0 :     tex->TexImage(funcName, target, level, internalFormat, width, height, depth, border,
     395           0 :                   pi, src);
     396             : }
     397             : 
     398             : void
     399           0 : WebGLContext::TexSubImage(const char* funcName, uint8_t funcDims, GLenum rawTarget,
     400             :                           GLint level, GLint xOffset, GLint yOffset, GLint zOffset,
     401             :                           GLsizei width, GLsizei height, GLsizei depth,
     402             :                           GLenum unpackFormat, GLenum unpackType,
     403             :                           const TexImageSource& src)
     404             : {
     405           0 :     TexImageTarget target;
     406             :     WebGLTexture* tex;
     407           0 :     if (!ValidateTexImageTarget(this, funcName, funcDims, rawTarget, &target, &tex))
     408           0 :         return;
     409             : 
     410           0 :     const webgl::PackingInfo pi = {unpackFormat, unpackType};
     411           0 :     tex->TexSubImage(funcName, target, level, xOffset, yOffset, zOffset, width, height,
     412           0 :                      depth, pi, src);
     413             : }
     414             : 
     415             : } // namespace mozilla

Generated by: LCOV version 1.13