content/canvas/src/WebGLContextExtensions.cpp

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     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/. */
     6 #include "WebGLContext.h"
     7 #include "WebGLContextUtils.h"
     8 #include "WebGLExtensions.h"
     9 #include "GLContext.h"
    11 #include "nsString.h"
    12 #include "mozilla/Preferences.h"
    13 #include "AccessCheck.h"
    15 using namespace mozilla;
    16 using namespace mozilla::gl;
    18 /* static */ const char*
    19 WebGLContext::GetExtensionString(WebGLExtensionID ext)
    20 {
    21     // must match WebGLExtensionID.
    22     // Once we can use variadic templates, EnumeratedArray should get a constructor
    23     // allowing to initialize it directly without using this auxiliary plain array.
    24     static const char *kExtensionNames[] = {
    25         "ANGLE_instanced_arrays",
    26         "EXT_color_buffer_half_float",
    27         "EXT_frag_depth",
    28         "EXT_sRGB",
    29         "EXT_texture_filter_anisotropic",
    30         "OES_element_index_uint",
    31         "OES_standard_derivatives",
    32         "OES_texture_float",
    33         "OES_texture_float_linear",
    34         "OES_texture_half_float",
    35         "OES_texture_half_float_linear",
    36         "OES_vertex_array_object",
    37         "WEBGL_color_buffer_float",
    38         "WEBGL_compressed_texture_atc",
    39         "WEBGL_compressed_texture_etc1",
    40         "WEBGL_compressed_texture_pvrtc",
    41         "WEBGL_compressed_texture_s3tc",
    42         "WEBGL_debug_renderer_info",
    43         "WEBGL_debug_shaders",
    44         "WEBGL_depth_texture",
    45         "WEBGL_draw_buffers",
    46         "WEBGL_lose_context"
    47     };
    49     typedef EnumeratedArray<WebGLExtensionID, WebGLExtensionID::Max, const char*>
    50             names_array_t;
    51     static const names_array_t kExtensionNamesEnumeratedArray(kExtensionNames);
    53     return kExtensionNamesEnumeratedArray[ext];
    54 }
    56 bool
    57 WebGLContext::IsExtensionEnabled(WebGLExtensionID ext) const {
    58     return mExtensions[ext];
    59 }
    61 bool WebGLContext::IsExtensionSupported(JSContext *cx, WebGLExtensionID ext) const
    62 {
    63     bool allowPrivilegedExts = false;
    65     // Chrome contexts need access to debug information even when
    66     // webgl.disable-extensions is set. This is used in the graphics
    67     // section of about:support.
    68     if (xpc::AccessCheck::isChrome(js::GetContextCompartment(cx)))
    69         allowPrivilegedExts = true;
    71     if (Preferences::GetBool("webgl.enable-privileged-extensions", false))
    72         allowPrivilegedExts = true;
    74     if (allowPrivilegedExts) {
    75         switch (ext) {
    76             case WebGLExtensionID::WEBGL_debug_renderer_info:
    77                 return true;
    78             case WebGLExtensionID::WEBGL_debug_shaders:
    79                 return true;
    80             default:
    81                 // For warnings-as-errors.
    82                 break;
    83         }
    84     }
    86     return IsExtensionSupported(ext);
    87 }
    89 bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const
    90 {
    91     if (mDisableExtensions) {
    92         return false;
    93     }
    95     switch (ext) {
    96         case WebGLExtensionID::OES_element_index_uint:
    97             return gl->IsSupported(GLFeature::element_index_uint);
    98         case WebGLExtensionID::OES_standard_derivatives:
    99             return gl->IsSupported(GLFeature::standard_derivatives);
   100         case WebGLExtensionID::WEBGL_lose_context:
   101             // We always support this extension.
   102             return true;
   103         case WebGLExtensionID::OES_texture_float:
   104             return gl->IsSupported(GLFeature::texture_float);
   105         case WebGLExtensionID::OES_texture_float_linear:
   106             return gl->IsSupported(GLFeature::texture_float_linear);
   107         case WebGLExtensionID::OES_texture_half_float:
   108             // If we have Feature::texture_half_float, we must not be on ES2
   109             // and need to translate HALF_FLOAT_OES -> HALF_FLOAT.  We do that
   110             // right before making the relevant calls.
   111             return gl->IsExtensionSupported(GLContext::OES_texture_half_float) ||
   112                    gl->IsSupported(GLFeature::texture_half_float);
   113         case WebGLExtensionID::OES_texture_half_float_linear:
   114             return gl->IsSupported(GLFeature::texture_half_float_linear);
   115         case WebGLExtensionID::WEBGL_color_buffer_float:
   116             return WebGLExtensionColorBufferFloat::IsSupported(this);
   117         case WebGLExtensionID::EXT_color_buffer_half_float:
   118             return WebGLExtensionColorBufferHalfFloat::IsSupported(this);
   119         case WebGLExtensionID::OES_vertex_array_object:
   120             return WebGLExtensionVertexArray::IsSupported(this);
   121         case WebGLExtensionID::EXT_texture_filter_anisotropic:
   122             return gl->IsExtensionSupported(GLContext::EXT_texture_filter_anisotropic);
   123         case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
   124             if (gl->IsExtensionSupported(GLContext::EXT_texture_compression_s3tc)) {
   125                 return true;
   126             }
   127             else if (gl->IsExtensionSupported(GLContext::EXT_texture_compression_dxt1) &&
   128                      gl->IsExtensionSupported(GLContext::ANGLE_texture_compression_dxt3) &&
   129                      gl->IsExtensionSupported(GLContext::ANGLE_texture_compression_dxt5))
   130             {
   131                 return true;
   132             }
   133             return false;
   134         case WebGLExtensionID::WEBGL_compressed_texture_atc:
   135             return gl->IsExtensionSupported(GLContext::AMD_compressed_ATC_texture);
   136         case WebGLExtensionID::WEBGL_compressed_texture_etc1:
   137             return gl->IsExtensionSupported(GLContext::OES_compressed_ETC1_RGB8_texture);
   138         case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
   139             return gl->IsExtensionSupported(GLContext::IMG_texture_compression_pvrtc);
   140         case WebGLExtensionID::WEBGL_depth_texture:
   141             // WEBGL_depth_texture supports DEPTH_STENCIL textures
   142             if (!gl->IsSupported(GLFeature::packed_depth_stencil)) {
   143                 return false;
   144             }
   145             return gl->IsSupported(GLFeature::depth_texture) ||
   146                    gl->IsExtensionSupported(GLContext::ANGLE_depth_texture);
   147         case WebGLExtensionID::ANGLE_instanced_arrays:
   148             return WebGLExtensionInstancedArrays::IsSupported(this);
   149         case WebGLExtensionID::EXT_sRGB:
   150             return WebGLExtensionSRGB::IsSupported(this);
   151         case WebGLExtensionID::WEBGL_draw_buffers:
   152             return WebGLExtensionDrawBuffers::IsSupported(this);
   153         case WebGLExtensionID::EXT_frag_depth:
   154             return WebGLExtensionFragDepth::IsSupported(this);
   155         default:
   156             // For warnings-as-errors.
   157             break;
   158     }
   159 // Uncomment this switch for any new extensions
   160 #if 0
   161     if (Preferences::GetBool("webgl.enable-draft-extensions", false) || IsWebGL2()) {
   162         switch (ext) {
   163             default:
   164                 // For warnings-as-errors.
   165                 break;
   166         }
   167     }
   168 #endif
   170     return false;
   171 }
   173 static bool
   174 CompareWebGLExtensionName(const nsACString& name, const char *other)
   175 {
   176     return name.Equals(other, nsCaseInsensitiveCStringComparator());
   177 }
   179 void
   180 WebGLContext::GetExtension(JSContext *cx, const nsAString& aName,
   181                            JS::MutableHandle<JSObject*> aRetval,
   182                            ErrorResult& rv)
   183 {
   184     if (IsContextLost()) {
   185         aRetval.set(nullptr);
   186         return;
   187     }
   189     NS_LossyConvertUTF16toASCII name(aName);
   191     WebGLExtensionID ext = WebGLExtensionID::Unknown;
   193     // step 1: figure what extension is wanted
   194     for (size_t i = 0; i < size_t(WebGLExtensionID::Max); i++)
   195     {
   196         WebGLExtensionID extension = WebGLExtensionID(i);
   198         if (CompareWebGLExtensionName(name, GetExtensionString(extension))) {
   199             ext = extension;
   200             break;
   201         }
   202     }
   204     if (ext == WebGLExtensionID::Unknown)
   205     {
   206         /**
   207          * We keep backward compatibility for these deprecated vendor-prefixed
   208          * alias. Do not add new ones anymore. Hide it behind the
   209          * webgl.enable-draft-extensions flag instead.
   210          */
   211         if (CompareWebGLExtensionName(name, "MOZ_WEBGL_lose_context")) {
   212             ext = WebGLExtensionID::WEBGL_lose_context;
   213         }
   214         else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_s3tc")) {
   215             ext = WebGLExtensionID::WEBGL_compressed_texture_s3tc;
   216         }
   217         else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_atc")) {
   218             ext = WebGLExtensionID::WEBGL_compressed_texture_atc;
   219         }
   220         else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_compressed_texture_pvrtc")) {
   221             ext = WebGLExtensionID::WEBGL_compressed_texture_pvrtc;
   222         }
   223         else if (CompareWebGLExtensionName(name, "MOZ_WEBGL_depth_texture")) {
   224             ext = WebGLExtensionID::WEBGL_depth_texture;
   225         }
   227         if (ext != WebGLExtensionID::Unknown) {
   228             GenerateWarning("getExtension('%s'): MOZ_ prefixed WebGL extension strings are deprecated. "
   229                             "Support for them will be removed in the future. Use unprefixed extension strings. "
   230                             "To get draft extensions, set the webgl.enable-draft-extensions preference.",
   231                             name.get());
   232         }
   233     }
   235     if (ext == WebGLExtensionID::Unknown) {
   236         aRetval.set(nullptr);
   237         return;
   238     }
   240     // step 2: check if the extension is supported
   241     if (!IsExtensionSupported(cx, ext)) {
   242         aRetval.set(nullptr);
   243         return;
   244     }
   246     // step 3: if the extension hadn't been previously been created, create it now, thus enabling it
   247     if (!IsExtensionEnabled(ext)) {
   248         EnableExtension(ext);
   249     }
   251     aRetval.set(WebGLObjectAsJSObject(cx, mExtensions[ext].get(), rv));
   252 }
   254 void
   255 WebGLContext::EnableExtension(WebGLExtensionID ext)
   256 {
   257     MOZ_ASSERT(IsExtensionEnabled(ext) == false);
   259     WebGLExtensionBase* obj = nullptr;
   260     switch (ext) {
   261         case WebGLExtensionID::OES_element_index_uint:
   262             obj = new WebGLExtensionElementIndexUint(this);
   263             break;
   264         case WebGLExtensionID::OES_standard_derivatives:
   265             obj = new WebGLExtensionStandardDerivatives(this);
   266             break;
   267         case WebGLExtensionID::EXT_texture_filter_anisotropic:
   268             obj = new WebGLExtensionTextureFilterAnisotropic(this);
   269             break;
   270         case WebGLExtensionID::WEBGL_lose_context:
   271             obj = new WebGLExtensionLoseContext(this);
   272             break;
   273         case WebGLExtensionID::WEBGL_compressed_texture_s3tc:
   274             obj = new WebGLExtensionCompressedTextureS3TC(this);
   275             break;
   276         case WebGLExtensionID::WEBGL_compressed_texture_atc:
   277             obj = new WebGLExtensionCompressedTextureATC(this);
   278             break;
   279         case WebGLExtensionID::WEBGL_compressed_texture_etc1:
   280             obj = new WebGLExtensionCompressedTextureETC1(this);
   281             break;
   282         case WebGLExtensionID::WEBGL_compressed_texture_pvrtc:
   283             obj = new WebGLExtensionCompressedTexturePVRTC(this);
   284             break;
   285         case WebGLExtensionID::WEBGL_debug_renderer_info:
   286             obj = new WebGLExtensionDebugRendererInfo(this);
   287             break;
   288         case WebGLExtensionID::WEBGL_debug_shaders:
   289             obj = new WebGLExtensionDebugShaders(this);
   290             break;
   291         case WebGLExtensionID::WEBGL_depth_texture:
   292             obj = new WebGLExtensionDepthTexture(this);
   293             break;
   294         case WebGLExtensionID::OES_texture_float:
   295             obj = new WebGLExtensionTextureFloat(this);
   296             break;
   297         case WebGLExtensionID::OES_texture_float_linear:
   298             obj = new WebGLExtensionTextureFloatLinear(this);
   299             break;
   300         case WebGLExtensionID::OES_texture_half_float:
   301             obj = new WebGLExtensionTextureHalfFloat(this);
   302             break;
   303         case WebGLExtensionID::OES_texture_half_float_linear:
   304             obj = new WebGLExtensionTextureHalfFloatLinear(this);
   305             break;
   306         case WebGLExtensionID::WEBGL_color_buffer_float:
   307             obj = new WebGLExtensionColorBufferFloat(this);
   308             break;
   309         case WebGLExtensionID::EXT_color_buffer_half_float:
   310             obj = new WebGLExtensionColorBufferHalfFloat(this);
   311             break;
   312         case WebGLExtensionID::WEBGL_draw_buffers:
   313             obj = new WebGLExtensionDrawBuffers(this);
   314             break;
   315         case WebGLExtensionID::OES_vertex_array_object:
   316             obj = new WebGLExtensionVertexArray(this);
   317             break;
   318         case WebGLExtensionID::ANGLE_instanced_arrays:
   319             obj = new WebGLExtensionInstancedArrays(this);
   320             break;
   321         case WebGLExtensionID::EXT_sRGB:
   322             obj = new WebGLExtensionSRGB(this);
   323             break;
   324         case WebGLExtensionID::EXT_frag_depth:
   325             obj = new WebGLExtensionFragDepth(this);
   326             break;
   327         default:
   328             MOZ_ASSERT(false, "should not get there.");
   329     }
   331     mExtensions[ext] = obj;
   332 }
   334 void
   335 WebGLContext::GetSupportedExtensions(JSContext *cx, Nullable< nsTArray<nsString> > &retval)
   336 {
   337     retval.SetNull();
   338     if (IsContextLost())
   339         return;
   341     nsTArray<nsString>& arr = retval.SetValue();
   343     for (size_t i = 0; i < size_t(WebGLExtensionID::Max); i++)
   344     {
   345         WebGLExtensionID extension = WebGLExtensionID(i);
   347         if (IsExtensionSupported(cx, extension)) {
   348             arr.AppendElement(NS_ConvertUTF8toUTF16(GetExtensionString(extension)));
   349         }
   350     }
   352     /**
   353      * We keep backward compatibility for these deprecated vendor-prefixed
   354      * alias. Do not add new ones anymore. Hide it behind the
   355      * webgl.enable-draft-extensions flag instead.
   356      */
   357     if (IsExtensionSupported(cx, WebGLExtensionID::WEBGL_lose_context))
   358         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_lose_context"));
   359     if (IsExtensionSupported(cx, WebGLExtensionID::WEBGL_compressed_texture_s3tc))
   360         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_s3tc"));
   361     if (IsExtensionSupported(cx, WebGLExtensionID::WEBGL_compressed_texture_atc))
   362         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_atc"));
   363     if (IsExtensionSupported(cx, WebGLExtensionID::WEBGL_compressed_texture_pvrtc))
   364         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_compressed_texture_pvrtc"));
   365     if (IsExtensionSupported(cx, WebGLExtensionID::WEBGL_depth_texture))
   366         arr.AppendElement(NS_LITERAL_STRING("MOZ_WEBGL_depth_texture"));
   367 }

mercurial