content/canvas/src/WebGLProgram.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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/. */
     6 #include "WebGLContext.h"
     7 #include "WebGLShader.h"
     8 #include "WebGLProgram.h"
     9 #include "mozilla/dom/WebGLRenderingContextBinding.h"
    10 #include "GLContext.h"
    12 using namespace mozilla;
    14 /** Takes an ASCII string like "foo[i]", turns it into "foo" and returns "[i]" in bracketPart
    15   * 
    16   * \param string input/output: the string to split, becomes the string without the bracket part
    17   * \param bracketPart output: gets the bracket part.
    18   * 
    19   * Notice that if there are multiple brackets like "foo[i].bar[j]", only the last bracket is split.
    20   */
    21 static bool SplitLastSquareBracket(nsACString& string, nsCString& bracketPart)
    22 {
    23     MOZ_ASSERT(bracketPart.IsEmpty(), "SplitLastSquareBracket must be called with empty bracketPart string");
    25     if (string.IsEmpty())
    26         return false;
    28     char *string_start = string.BeginWriting();
    29     char *s = string_start + string.Length() - 1;
    31     if (*s != ']')
    32         return false;
    34     while (*s != '[' && s != string_start)
    35         s--;
    37     if (*s != '[')
    38         return false;
    40     bracketPart.Assign(s);
    41     *s = 0;
    42     string.EndWriting();
    43     string.SetLength(s - string_start);
    44     return true;
    45 }
    47 JSObject*
    48 WebGLProgram::WrapObject(JSContext *cx) {
    49     return dom::WebGLProgramBinding::Wrap(cx, this);
    50 }
    52 WebGLProgram::WebGLProgram(WebGLContext *context)
    53     : WebGLContextBoundObject(context)
    54     , mLinkStatus(false)
    55     , mGeneration(0)
    56     , mAttribMaxNameLength(0)
    57 {
    58     SetIsDOMBinding();
    59     mContext->MakeContextCurrent();
    60     mGLName = mContext->gl->fCreateProgram();
    61     mContext->mPrograms.insertBack(this);
    62 }
    64 void
    65 WebGLProgram::Delete() {
    66     DetachShaders();
    67     mContext->MakeContextCurrent();
    68     mContext->gl->fDeleteProgram(mGLName);
    69     LinkedListElement<WebGLProgram>::removeFrom(mContext->mPrograms);
    70 }
    72 bool
    73 WebGLProgram::AttachShader(WebGLShader *shader) {
    74     if (ContainsShader(shader))
    75         return false;
    76     mAttachedShaders.AppendElement(shader);
    78     mContext->MakeContextCurrent();
    79     mContext->gl->fAttachShader(GLName(), shader->GLName());
    81     return true;
    82 }
    84 bool
    85 WebGLProgram::DetachShader(WebGLShader *shader) {
    86     if (!mAttachedShaders.RemoveElement(shader))
    87         return false;
    89     mContext->MakeContextCurrent();
    90     mContext->gl->fDetachShader(GLName(), shader->GLName());
    92     return true;
    93 }
    95 bool
    96 WebGLProgram::HasAttachedShaderOfType(GLenum shaderType) {
    97     for (uint32_t i = 0; i < mAttachedShaders.Length(); ++i) {
    98         if (mAttachedShaders[i] && mAttachedShaders[i]->ShaderType() == shaderType) {
    99             return true;
   100         }
   101     }
   102     return false;
   103 }
   105 bool
   106 WebGLProgram::HasBadShaderAttached() {
   107     for (uint32_t i = 0; i < mAttachedShaders.Length(); ++i) {
   108         if (mAttachedShaders[i] && !mAttachedShaders[i]->CompileStatus()) {
   109             return true;
   110         }
   111     }
   112     return false;
   113 }
   115 size_t
   116 WebGLProgram::UpperBoundNumSamplerUniforms() {
   117     size_t numSamplerUniforms = 0;
   118     for (size_t i = 0; i < mAttachedShaders.Length(); ++i) {
   119         const WebGLShader *shader = mAttachedShaders[i];
   120         if (!shader)
   121             continue;
   122         for (size_t j = 0; j < shader->mUniformInfos.Length(); ++j) {
   123             WebGLUniformInfo u = shader->mUniformInfos[j];
   124             if (u.type == SH_SAMPLER_2D ||
   125                 u.type == SH_SAMPLER_CUBE)
   126             {
   127                 numSamplerUniforms += u.arraySize;
   128             }
   129         }
   130     }
   131     return numSamplerUniforms;
   132 }
   134 void
   135 WebGLProgram::MapIdentifier(const nsACString& name, nsCString *mappedName) {
   136     if (!mIdentifierMap) {
   137         // if the identifier map doesn't exist yet, build it now
   138         mIdentifierMap = new CStringMap;
   139         for (size_t i = 0; i < mAttachedShaders.Length(); i++) {
   140             for (size_t j = 0; j < mAttachedShaders[i]->mAttributes.Length(); j++) {
   141                 const WebGLMappedIdentifier& attrib = mAttachedShaders[i]->mAttributes[j];
   142                 mIdentifierMap->Put(attrib.original, attrib.mapped);
   143             }
   144             for (size_t j = 0; j < mAttachedShaders[i]->mUniforms.Length(); j++) {
   145                 const WebGLMappedIdentifier& uniform = mAttachedShaders[i]->mUniforms[j];
   146                 mIdentifierMap->Put(uniform.original, uniform.mapped);
   147             }
   148         }
   149     }
   151     nsCString mutableName(name);
   152     nsCString bracketPart;
   153     bool hadBracketPart = SplitLastSquareBracket(mutableName, bracketPart);
   154     if (hadBracketPart)
   155         mutableName.AppendLiteral("[0]");
   157     if (mIdentifierMap->Get(mutableName, mappedName)) {
   158         if (hadBracketPart) {
   159             nsCString mappedBracketPart;
   160             bool mappedHadBracketPart = SplitLastSquareBracket(*mappedName, mappedBracketPart);
   161             if (mappedHadBracketPart)
   162                 mappedName->Append(bracketPart);
   163         }
   164         return;
   165     }
   167     // not found? We might be in the situation we have a uniform array name and the GL's glGetActiveUniform
   168     // returned its name without [0], as is allowed by desktop GL but not in ES. Let's then try with [0].
   169     mutableName.AppendLiteral("[0]");
   170     if (mIdentifierMap->Get(mutableName, mappedName))
   171         return;
   173     // not found? return name unchanged. This case happens e.g. on bad user input, or when
   174     // we're not using identifier mapping, or if we didn't store an identifier in the map because
   175     // e.g. its mapping is trivial (as happens for short identifiers)
   176     mappedName->Assign(name);
   177 }
   179 void
   180 WebGLProgram::ReverseMapIdentifier(const nsACString& name, nsCString *reverseMappedName) {
   181     if (!mIdentifierReverseMap) {
   182         // if the identifier reverse map doesn't exist yet, build it now
   183         mIdentifierReverseMap = new CStringMap;
   184         for (size_t i = 0; i < mAttachedShaders.Length(); i++) {
   185             for (size_t j = 0; j < mAttachedShaders[i]->mAttributes.Length(); j++) {
   186                 const WebGLMappedIdentifier& attrib = mAttachedShaders[i]->mAttributes[j];
   187                 mIdentifierReverseMap->Put(attrib.mapped, attrib.original);
   188             }
   189             for (size_t j = 0; j < mAttachedShaders[i]->mUniforms.Length(); j++) {
   190                 const WebGLMappedIdentifier& uniform = mAttachedShaders[i]->mUniforms[j];
   191                 mIdentifierReverseMap->Put(uniform.mapped, uniform.original);
   192             }
   193         }
   194     }
   196     nsCString mutableName(name);
   197     nsCString bracketPart;
   198     bool hadBracketPart = SplitLastSquareBracket(mutableName, bracketPart);
   199     if (hadBracketPart)
   200         mutableName.AppendLiteral("[0]");
   202     if (mIdentifierReverseMap->Get(mutableName, reverseMappedName)) {
   203         if (hadBracketPart) {
   204             nsCString reverseMappedBracketPart;
   205             bool reverseMappedHadBracketPart = SplitLastSquareBracket(*reverseMappedName, reverseMappedBracketPart);
   206             if (reverseMappedHadBracketPart)
   207                 reverseMappedName->Append(bracketPart);
   208         }
   209         return;
   210     }
   212     // not found? We might be in the situation we have a uniform array name and the GL's glGetActiveUniform
   213     // returned its name without [0], as is allowed by desktop GL but not in ES. Let's then try with [0].
   214     mutableName.AppendLiteral("[0]");
   215     if (mIdentifierReverseMap->Get(mutableName, reverseMappedName))
   216         return;
   218     // not found? return name unchanged. This case happens e.g. on bad user input, or when
   219     // we're not using identifier mapping, or if we didn't store an identifier in the map because
   220     // e.g. its mapping is trivial (as happens for short identifiers)
   221     reverseMappedName->Assign(name);
   222 }
   224 WebGLUniformInfo
   225 WebGLProgram::GetUniformInfoForMappedIdentifier(const nsACString& name) {
   226     nsCString mutableName(name);
   227     nsCString bracketPart;
   228     bool hadBracketPart = SplitLastSquareBracket(mutableName, bracketPart);
   229     // if there is a bracket, we're either an array or an entry in an array.
   230     if (hadBracketPart)
   231         mutableName.AppendLiteral("[0]");
   233     WebGLUniformInfo info;
   234     mUniformInfoMap->Get(mutableName, &info);
   235     // we don't check if that Get failed, as if it did, it left info with default values
   237     return info;
   238 }
   240 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(WebGLProgram, mAttachedShaders)
   242 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLProgram, AddRef)
   243 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLProgram, Release)

mercurial