gfx/angle/src/libGLESv2/Shader.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 #include "precompiled.h"
     2 //
     3 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
     4 // Use of this source code is governed by a BSD-style license that can be
     5 // found in the LICENSE file.
     6 //
     8 // Shader.cpp: Implements the gl::Shader class and its  derived classes
     9 // VertexShader and FragmentShader. Implements GL shader objects and related
    10 // functionality. [OpenGL ES 2.0.24] section 2.10 page 24 and section 3.8 page 84.
    12 #include "libGLESv2/Shader.h"
    14 #include <algorithm>
    16 #include "GLSLANG/ShaderLang.h"
    17 #include "libGLESv2/utilities.h"
    18 #include "libGLESv2/renderer/Renderer.h"
    19 #include "libGLESv2/Constants.h"
    20 #include "libGLESv2/ResourceManager.h"
    22 namespace gl
    23 {
    24 void *Shader::mFragmentCompiler = NULL;
    25 void *Shader::mVertexCompiler = NULL;
    27 Shader::Shader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
    28     : mHandle(handle), mRenderer(renderer), mResourceManager(manager)
    29 {
    30     mSource = NULL;
    31     mHlsl = NULL;
    32     mInfoLog = NULL;
    34     uncompile();
    35     initializeCompiler();
    37     mRefCount = 0;
    38     mDeleteStatus = false;
    39 }
    41 Shader::~Shader()
    42 {
    43     delete[] mSource;
    44     delete[] mHlsl;
    45     delete[] mInfoLog;
    46 }
    48 GLuint Shader::getHandle() const
    49 {
    50     return mHandle;
    51 }
    53 void Shader::setSource(GLsizei count, const char **string, const GLint *length)
    54 {
    55     delete[] mSource;
    56     int totalLength = 0;
    58     for (int i = 0; i < count; i++)
    59     {
    60         if (length && length[i] >= 0)
    61         {
    62             totalLength += length[i];
    63         }
    64         else
    65         {
    66             totalLength += (int)strlen(string[i]);
    67         }
    68     }
    70     mSource = new char[totalLength + 1];
    71     char *code = mSource;
    73     for (int i = 0; i < count; i++)
    74     {
    75         int stringLength;
    77         if (length && length[i] >= 0)
    78         {
    79             stringLength = length[i];
    80         }
    81         else
    82         {
    83             stringLength = (int)strlen(string[i]);
    84         }
    86         strncpy(code, string[i], stringLength);
    87         code += stringLength;
    88     }
    90     mSource[totalLength] = '\0';
    91 }
    93 int Shader::getInfoLogLength() const
    94 {
    95     if (!mInfoLog)
    96     {
    97         return 0;
    98     }
    99     else
   100     {
   101        return strlen(mInfoLog) + 1;
   102     }
   103 }
   105 void Shader::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
   106 {
   107     int index = 0;
   109     if (bufSize > 0)
   110     {
   111         if (mInfoLog)
   112         {
   113             index = std::min(bufSize - 1, (int)strlen(mInfoLog));
   114             memcpy(infoLog, mInfoLog, index);
   115         }
   117         infoLog[index] = '\0';
   118     }
   120     if (length)
   121     {
   122         *length = index;
   123     }
   124 }
   126 int Shader::getSourceLength() const
   127 {
   128     if (!mSource)
   129     {
   130         return 0;
   131     }
   132     else
   133     {
   134        return strlen(mSource) + 1;
   135     }
   136 }
   138 int Shader::getTranslatedSourceLength() const
   139 {
   140     if (!mHlsl)
   141     {
   142         return 0;
   143     }
   144     else
   145     {
   146        return strlen(mHlsl) + 1;
   147     }
   148 }
   150 void Shader::getSourceImpl(char *source, GLsizei bufSize, GLsizei *length, char *buffer)
   151 {
   152     int index = 0;
   154     if (bufSize > 0)
   155     {
   156         if (source)
   157         {
   158             index = std::min(bufSize - 1, (int)strlen(source));
   159             memcpy(buffer, source, index);
   160         }
   162         buffer[index] = '\0';
   163     }
   165     if (length)
   166     {
   167         *length = index;
   168     }
   169 }
   171 void Shader::getSource(GLsizei bufSize, GLsizei *length, char *buffer)
   172 {
   173     getSourceImpl(mSource, bufSize, length, buffer);
   174 }
   176 void Shader::getTranslatedSource(GLsizei bufSize, GLsizei *length, char *buffer)
   177 {
   178     getSourceImpl(mHlsl, bufSize, length, buffer);
   179 }
   181 const sh::ActiveUniforms &Shader::getUniforms()
   182 {
   183     return mActiveUniforms;
   184 }
   186 bool Shader::isCompiled()
   187 {
   188     return mHlsl != NULL;
   189 }
   191 const char *Shader::getHLSL()
   192 {
   193     return mHlsl;
   194 }
   196 void Shader::addRef()
   197 {
   198     mRefCount++;
   199 }
   201 void Shader::release()
   202 {
   203     mRefCount--;
   205     if (mRefCount == 0 && mDeleteStatus)
   206     {
   207         mResourceManager->deleteShader(mHandle);
   208     }
   209 }
   211 unsigned int Shader::getRefCount() const
   212 {
   213     return mRefCount;
   214 }
   216 bool Shader::isFlaggedForDeletion() const
   217 {
   218     return mDeleteStatus;
   219 }
   221 void Shader::flagForDeletion()
   222 {
   223     mDeleteStatus = true;
   224 }
   226 // Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler)
   227 void Shader::initializeCompiler()
   228 {
   229     if (!mFragmentCompiler)
   230     {
   231         int result = ShInitialize();
   233         if (result)
   234         {
   235             ShShaderOutput hlslVersion = (mRenderer->getMajorShaderModel() >= 4) ? SH_HLSL11_OUTPUT : SH_HLSL9_OUTPUT;
   237             ShBuiltInResources resources;
   238             ShInitBuiltInResources(&resources);
   240             resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS;
   241             resources.MaxVertexUniformVectors = mRenderer->getMaxVertexUniformVectors();
   242             resources.MaxVaryingVectors = mRenderer->getMaxVaryingVectors();
   243             resources.MaxVertexTextureImageUnits = mRenderer->getMaxVertexTextureImageUnits();
   244             resources.MaxCombinedTextureImageUnits = mRenderer->getMaxCombinedTextureImageUnits();
   245             resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS;
   246             resources.MaxFragmentUniformVectors = mRenderer->getMaxFragmentUniformVectors();
   247             resources.MaxDrawBuffers = mRenderer->getMaxRenderTargets();
   248             resources.OES_standard_derivatives = mRenderer->getDerivativeInstructionSupport();
   249             resources.EXT_draw_buffers = mRenderer->getMaxRenderTargets() > 1;
   250             // resources.OES_EGL_image_external = mRenderer->getShareHandleSupport() ? 1 : 0; // TODO: commented out until the extension is actually supported.
   251             resources.FragmentPrecisionHigh = 1;   // Shader Model 2+ always supports FP24 (s16e7) which corresponds to highp
   252             resources.EXT_frag_depth = 1; // Shader Model 2+ always supports explicit depth output
   254             mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
   255             mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, hlslVersion, &resources);
   256         }
   257     }
   258 }
   260 void Shader::releaseCompiler()
   261 {
   262     ShDestruct(mFragmentCompiler);
   263     ShDestruct(mVertexCompiler);
   265     mFragmentCompiler = NULL;
   266     mVertexCompiler = NULL;
   268     ShFinalize();
   269 }
   271 void Shader::parseVaryings()
   272 {
   273     if (mHlsl)
   274     {
   275         const char *input = strstr(mHlsl, "// Varyings") + 12;
   277         while(true)
   278         {
   279             char varyingType[256];
   280             char varyingName[256];
   282             int matches = sscanf(input, "static %255s %255s", varyingType, varyingName);
   284             if (matches != 2)
   285             {
   286                 break;
   287             }
   289             char *array = strstr(varyingName, "[");
   290             int size = 1;
   292             if (array)
   293             {
   294                 size = atoi(array + 1);
   295                 *array = '\0';
   296             }
   298             mVaryings.push_back(Varying(parseType(varyingType), varyingName, size, array != NULL));
   300             input = strstr(input, ";") + 2;
   301         }
   303         mUsesMultipleRenderTargets = strstr(mHlsl, "GL_USES_MRT") != NULL;
   304         mUsesFragColor = strstr(mHlsl, "GL_USES_FRAG_COLOR") != NULL;
   305         mUsesFragData = strstr(mHlsl, "GL_USES_FRAG_DATA") != NULL;
   306         mUsesFragCoord = strstr(mHlsl, "GL_USES_FRAG_COORD") != NULL;
   307         mUsesFrontFacing = strstr(mHlsl, "GL_USES_FRONT_FACING") != NULL;
   308         mUsesPointSize = strstr(mHlsl, "GL_USES_POINT_SIZE") != NULL;
   309         mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL;
   310         mUsesDepthRange = strstr(mHlsl, "GL_USES_DEPTH_RANGE") != NULL;
   311         mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL;
   312     }
   313 }
   315 void Shader::resetVaryingsRegisterAssignment()
   316 {
   317     for (VaryingList::iterator var = mVaryings.begin(); var != mVaryings.end(); var++)
   318     {
   319         var->reg = -1;
   320         var->col = -1;
   321     }
   322 }
   324 // initialize/clean up previous state
   325 void Shader::uncompile()
   326 {
   327     // set by compileToHLSL
   328     delete[] mHlsl;
   329     mHlsl = NULL;
   330     delete[] mInfoLog;
   331     mInfoLog = NULL;
   333     // set by parseVaryings
   334     mVaryings.clear();
   336     mUsesMultipleRenderTargets = false;
   337     mUsesFragColor = false;
   338     mUsesFragData = false;
   339     mUsesFragCoord = false;
   340     mUsesFrontFacing = false;
   341     mUsesPointSize = false;
   342     mUsesPointCoord = false;
   343     mUsesDepthRange = false;
   344     mUsesFragDepth = false;
   346     mActiveUniforms.clear();
   347 }
   349 void Shader::compileToHLSL(void *compiler)
   350 {
   351     // ensure we don't pass a NULL source to the compiler
   352     const char *source = "\0";
   353     if (mSource)
   354     {
   355         source = mSource;
   356     }
   358     // ensure the compiler is loaded
   359     initializeCompiler();
   361     int compileOptions = SH_OBJECT_CODE;
   362     std::string sourcePath;
   363     if (perfActive())
   364     {
   365         sourcePath = getTempPath();
   366         writeFile(sourcePath.c_str(), source, strlen(source));
   367         compileOptions |= SH_LINE_DIRECTIVES;
   368     }
   370     int result;
   371     if (sourcePath.empty())
   372     {
   373         result = ShCompile(compiler, &source, 1, compileOptions);
   374     }
   375     else
   376     {
   377         const char* sourceStrings[2] =
   378         {
   379             sourcePath.c_str(),
   380             source
   381         };
   383         result = ShCompile(compiler, sourceStrings, 2, compileOptions | SH_SOURCE_PATH);
   384     }
   386     if (result)
   387     {
   388         size_t objCodeLen = 0;
   389         ShGetInfo(compiler, SH_OBJECT_CODE_LENGTH, &objCodeLen);
   390         mHlsl = new char[objCodeLen];
   391         ShGetObjectCode(compiler, mHlsl);
   393         void *activeUniforms;
   394         ShGetInfoPointer(compiler, SH_ACTIVE_UNIFORMS_ARRAY, &activeUniforms);
   395         mActiveUniforms = *(sh::ActiveUniforms*)activeUniforms;
   396     }
   397     else
   398     {
   399         size_t infoLogLen = 0;
   400         ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen);
   401         mInfoLog = new char[infoLogLen];
   402         ShGetInfoLog(compiler, mInfoLog);
   404         TRACE("\n%s", mInfoLog);
   405     }
   406 }
   408 GLenum Shader::parseType(const std::string &type)
   409 {
   410     if (type == "float")
   411     {
   412         return GL_FLOAT;
   413     }
   414     else if (type == "float2")
   415     {
   416         return GL_FLOAT_VEC2;
   417     }
   418     else if (type == "float3")
   419     {
   420         return GL_FLOAT_VEC3;
   421     }
   422     else if (type == "float4")
   423     {
   424         return GL_FLOAT_VEC4;
   425     }
   426     else if (type == "float2x2")
   427     {
   428         return GL_FLOAT_MAT2;
   429     }
   430     else if (type == "float3x3")
   431     {
   432         return GL_FLOAT_MAT3;
   433     }
   434     else if (type == "float4x4")
   435     {
   436         return GL_FLOAT_MAT4;
   437     }
   438     else UNREACHABLE();
   440     return GL_NONE;
   441 }
   443 // true if varying x has a higher priority in packing than y
   444 bool Shader::compareVarying(const Varying &x, const Varying &y)
   445 {
   446     if(x.type == y.type)
   447     {
   448         return x.size > y.size;
   449     }
   451     switch (x.type)
   452     {
   453       case GL_FLOAT_MAT4: return true;
   454       case GL_FLOAT_MAT2:
   455         switch(y.type)
   456         {
   457           case GL_FLOAT_MAT4: return false;
   458           case GL_FLOAT_MAT2: return true;
   459           case GL_FLOAT_VEC4: return true;
   460           case GL_FLOAT_MAT3: return true;
   461           case GL_FLOAT_VEC3: return true;
   462           case GL_FLOAT_VEC2: return true;
   463           case GL_FLOAT:      return true;
   464           default: UNREACHABLE();
   465         }
   466         break;
   467       case GL_FLOAT_VEC4:
   468         switch(y.type)
   469         {
   470           case GL_FLOAT_MAT4: return false;
   471           case GL_FLOAT_MAT2: return false;
   472           case GL_FLOAT_VEC4: return true;
   473           case GL_FLOAT_MAT3: return true;
   474           case GL_FLOAT_VEC3: return true;
   475           case GL_FLOAT_VEC2: return true;
   476           case GL_FLOAT:      return true;
   477           default: UNREACHABLE();
   478         }
   479         break;
   480       case GL_FLOAT_MAT3:
   481         switch(y.type)
   482         {
   483           case GL_FLOAT_MAT4: return false;
   484           case GL_FLOAT_MAT2: return false;
   485           case GL_FLOAT_VEC4: return false;
   486           case GL_FLOAT_MAT3: return true;
   487           case GL_FLOAT_VEC3: return true;
   488           case GL_FLOAT_VEC2: return true;
   489           case GL_FLOAT:      return true;
   490           default: UNREACHABLE();
   491         }
   492         break;
   493       case GL_FLOAT_VEC3:
   494         switch(y.type)
   495         {
   496           case GL_FLOAT_MAT4: return false;
   497           case GL_FLOAT_MAT2: return false;
   498           case GL_FLOAT_VEC4: return false;
   499           case GL_FLOAT_MAT3: return false;
   500           case GL_FLOAT_VEC3: return true;
   501           case GL_FLOAT_VEC2: return true;
   502           case GL_FLOAT:      return true;
   503           default: UNREACHABLE();
   504         }
   505         break;
   506       case GL_FLOAT_VEC2:
   507         switch(y.type)
   508         {
   509           case GL_FLOAT_MAT4: return false;
   510           case GL_FLOAT_MAT2: return false;
   511           case GL_FLOAT_VEC4: return false;
   512           case GL_FLOAT_MAT3: return false;
   513           case GL_FLOAT_VEC3: return false;
   514           case GL_FLOAT_VEC2: return true;
   515           case GL_FLOAT:      return true;
   516           default: UNREACHABLE();
   517         }
   518         break;
   519       case GL_FLOAT: return false;
   520       default: UNREACHABLE();
   521     }
   523     return false;
   524 }
   526 VertexShader::VertexShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
   527     : Shader(manager, renderer, handle)
   528 {
   529 }
   531 VertexShader::~VertexShader()
   532 {
   533 }
   535 GLenum VertexShader::getType()
   536 {
   537     return GL_VERTEX_SHADER;
   538 }
   540 void VertexShader::uncompile()
   541 {
   542     Shader::uncompile();
   544     // set by ParseAttributes
   545     mAttributes.clear();
   546 }
   548 void VertexShader::compile()
   549 {
   550     uncompile();
   552     compileToHLSL(mVertexCompiler);
   553     parseAttributes();
   554     parseVaryings();
   555 }
   557 int VertexShader::getSemanticIndex(const std::string &attributeName)
   558 {
   559     if (!attributeName.empty())
   560     {
   561         int semanticIndex = 0;
   562         for (AttributeArray::iterator attribute = mAttributes.begin(); attribute != mAttributes.end(); attribute++)
   563         {
   564             if (attribute->name == attributeName)
   565             {
   566                 return semanticIndex;
   567             }
   569             semanticIndex += VariableRowCount(attribute->type);
   570         }
   571     }
   573     return -1;
   574 }
   576 void VertexShader::parseAttributes()
   577 {
   578     const char *hlsl = getHLSL();
   579     if (hlsl)
   580     {
   581         const char *input = strstr(hlsl, "// Attributes") + 14;
   583         while(true)
   584         {
   585             char attributeType[256];
   586             char attributeName[256];
   588             int matches = sscanf(input, "static %255s _%255s", attributeType, attributeName);
   590             if (matches != 2)
   591             {
   592                 break;
   593             }
   595             mAttributes.push_back(Attribute(parseType(attributeType), attributeName));
   597             input = strstr(input, ";") + 2;
   598         }
   599     }
   600 }
   602 FragmentShader::FragmentShader(ResourceManager *manager, const rx::Renderer *renderer, GLuint handle)
   603     : Shader(manager, renderer, handle)
   604 {
   605 }
   607 FragmentShader::~FragmentShader()
   608 {
   609 }
   611 GLenum FragmentShader::getType()
   612 {
   613     return GL_FRAGMENT_SHADER;
   614 }
   616 void FragmentShader::compile()
   617 {
   618     uncompile();
   620     compileToHLSL(mFragmentCompiler);
   621     parseVaryings();
   622     mVaryings.sort(compareVarying);
   623 }
   624 }

mercurial