tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

DirectiveHandler.cpp (10577B)


      1 //
      2 // Copyright 2012 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 #include "compiler/translator/DirectiveHandler.h"
      8 
      9 #include <sstream>
     10 
     11 #include "angle_gl.h"
     12 #include "common/debug.h"
     13 #include "compiler/translator/Common.h"
     14 #include "compiler/translator/Diagnostics.h"
     15 
     16 namespace sh
     17 {
     18 
     19 static TBehavior getBehavior(const std::string &str)
     20 {
     21    const char kRequire[] = "require";
     22    const char kEnable[]  = "enable";
     23    const char kDisable[] = "disable";
     24    const char kWarn[]    = "warn";
     25 
     26    if (str == kRequire)
     27        return EBhRequire;
     28    else if (str == kEnable)
     29        return EBhEnable;
     30    else if (str == kDisable)
     31        return EBhDisable;
     32    else if (str == kWarn)
     33        return EBhWarn;
     34    return EBhUndefined;
     35 }
     36 
     37 TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
     38                                     TDiagnostics &diagnostics,
     39                                     int &shaderVersion,
     40                                     sh::GLenum shaderType)
     41    : mExtensionBehavior(extBehavior),
     42      mDiagnostics(diagnostics),
     43      mShaderVersion(shaderVersion),
     44      mShaderType(shaderType)
     45 {}
     46 
     47 TDirectiveHandler::~TDirectiveHandler() {}
     48 
     49 void TDirectiveHandler::handleError(const angle::pp::SourceLocation &loc, const std::string &msg)
     50 {
     51    mDiagnostics.error(loc, msg.c_str(), "");
     52 }
     53 
     54 void TDirectiveHandler::handlePragma(const angle::pp::SourceLocation &loc,
     55                                     const std::string &name,
     56                                     const std::string &value,
     57                                     bool stdgl)
     58 {
     59    if (stdgl)
     60    {
     61        const char kInvariant[] = "invariant";
     62        const char kAll[]       = "all";
     63 
     64        if (name == kInvariant && value == kAll)
     65        {
     66            if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
     67            {
     68                // ESSL 3.00.4 section 4.6.1
     69                mDiagnostics.error(
     70                    loc, "#pragma STDGL invariant(all) can not be used in fragment shader",
     71                    name.c_str());
     72            }
     73            mPragma.stdgl.invariantAll = true;
     74        }
     75        // The STDGL pragma is used to reserve pragmas for use by future
     76        // revisions of GLSL.  Do not generate an error on unexpected
     77        // name and value.
     78        return;
     79    }
     80    else
     81    {
     82        const char kOptimize[] = "optimize";
     83        const char kDebug[]    = "debug";
     84        const char kOn[]       = "on";
     85        const char kOff[]      = "off";
     86 
     87        bool invalidValue = false;
     88        if (name == kOptimize)
     89        {
     90            if (value == kOn)
     91                mPragma.optimize = true;
     92            else if (value == kOff)
     93                mPragma.optimize = false;
     94            else
     95                invalidValue = true;
     96        }
     97        else if (name == kDebug)
     98        {
     99            if (value == kOn)
    100                mPragma.debug = true;
    101            else if (value == kOff)
    102                mPragma.debug = false;
    103            else
    104                invalidValue = true;
    105        }
    106        else
    107        {
    108            mDiagnostics.report(angle::pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
    109            return;
    110        }
    111 
    112        if (invalidValue)
    113        {
    114            mDiagnostics.error(loc, "invalid pragma value - 'on' or 'off' expected", value.c_str());
    115        }
    116    }
    117 }
    118 
    119 void TDirectiveHandler::handleExtension(const angle::pp::SourceLocation &loc,
    120                                        const std::string &name,
    121                                        const std::string &behavior)
    122 {
    123    const char kExtAll[] = "all";
    124 
    125    TBehavior behaviorVal = getBehavior(behavior);
    126    if (behaviorVal == EBhUndefined)
    127    {
    128        mDiagnostics.error(loc, "behavior invalid", name.c_str());
    129        return;
    130    }
    131 
    132    if (name == kExtAll)
    133    {
    134        if (behaviorVal == EBhRequire)
    135        {
    136            mDiagnostics.error(loc, "extension cannot have 'require' behavior", name.c_str());
    137        }
    138        else if (behaviorVal == EBhEnable)
    139        {
    140            mDiagnostics.error(loc, "extension cannot have 'enable' behavior", name.c_str());
    141        }
    142        else
    143        {
    144            for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
    145                 iter != mExtensionBehavior.end(); ++iter)
    146                iter->second = behaviorVal;
    147        }
    148        return;
    149    }
    150 
    151    TExtensionBehavior::iterator iter = mExtensionBehavior.find(GetExtensionByName(name.c_str()));
    152    if (iter != mExtensionBehavior.end())
    153    {
    154        iter->second = behaviorVal;
    155        // OVR_multiview is implicitly enabled when OVR_multiview2 is enabled
    156        if (name == "GL_OVR_multiview2")
    157        {
    158            constexpr char kMultiviewExtName[] = "GL_OVR_multiview";
    159            iter = mExtensionBehavior.find(GetExtensionByName(kMultiviewExtName));
    160            if (iter != mExtensionBehavior.end())
    161            {
    162                iter->second = behaviorVal;
    163            }
    164        }
    165        // All the extensions listed in the spec here:
    166        // https://www.khronos.org/registry/OpenGL/extensions/ANDROID/ANDROID_extension_pack_es31a.txt
    167        // are implicitly enabled when GL_ANDROID_extension_pack_es31a is enabled
    168        if (name == "GL_ANDROID_extension_pack_es31a")
    169        {
    170            constexpr char kGeometryShaderExtName[]      = "GL_EXT_geometry_shader";
    171            constexpr char kTessellationShaderExtName[]  = "GL_EXT_tessellation_shader";
    172            constexpr char kGpuShader5ExtName[]          = "GL_EXT_gpu_shader5";
    173            constexpr char kTextureBufferExtName[]       = "GL_EXT_texture_buffer";
    174            constexpr char kTextureCubeMapArrayExtName[] = "GL_EXT_texture_cube_map_array";
    175            constexpr char kSampleVariablesExtName[]     = "GL_OES_sample_variables";
    176            constexpr char kShaderMultisampleInterpolationExtName[] =
    177                "GL_OES_shader_multisample_interpolation";
    178            constexpr char kShaderImageAtomicExtName[] = "GL_OES_shader_image_atomic";
    179            constexpr char kTextureStorageMultisample2dArrayExtName[] =
    180                "GL_OES_texture_storage_multisample_2d_array";
    181            iter = mExtensionBehavior.find(GetExtensionByName(kGeometryShaderExtName));
    182            if (iter != mExtensionBehavior.end())
    183            {
    184                iter->second = behaviorVal;
    185            }
    186 
    187            iter = mExtensionBehavior.find(GetExtensionByName(kTessellationShaderExtName));
    188            if (iter != mExtensionBehavior.end())
    189            {
    190                iter->second = behaviorVal;
    191            }
    192 
    193            iter = mExtensionBehavior.find(GetExtensionByName(kGpuShader5ExtName));
    194            if (iter != mExtensionBehavior.end())
    195            {
    196                iter->second = behaviorVal;
    197            }
    198 
    199            iter = mExtensionBehavior.find(GetExtensionByName(kTextureBufferExtName));
    200            if (iter != mExtensionBehavior.end())
    201            {
    202                iter->second = behaviorVal;
    203            }
    204 
    205            iter = mExtensionBehavior.find(GetExtensionByName(kTextureCubeMapArrayExtName));
    206            if (iter != mExtensionBehavior.end())
    207            {
    208                iter->second = behaviorVal;
    209            }
    210 
    211            iter = mExtensionBehavior.find(GetExtensionByName(kSampleVariablesExtName));
    212            if (iter != mExtensionBehavior.end())
    213            {
    214                iter->second = behaviorVal;
    215            }
    216 
    217            iter =
    218                mExtensionBehavior.find(GetExtensionByName(kShaderMultisampleInterpolationExtName));
    219            if (iter != mExtensionBehavior.end())
    220            {
    221                iter->second = behaviorVal;
    222            }
    223 
    224            iter = mExtensionBehavior.find(GetExtensionByName(kShaderImageAtomicExtName));
    225            if (iter != mExtensionBehavior.end())
    226            {
    227                iter->second = behaviorVal;
    228            }
    229 
    230            iter = mExtensionBehavior.find(
    231                GetExtensionByName(kTextureStorageMultisample2dArrayExtName));
    232            if (iter != mExtensionBehavior.end())
    233            {
    234                iter->second = behaviorVal;
    235            }
    236        }
    237        // EXT_shader_io_blocks is implicitly enabled when EXT_geometry_shader or
    238        // EXT_tessellation_shader is enabled.
    239        if (name == "GL_EXT_geometry_shader" || name == "GL_EXT_tessellation_shader")
    240        {
    241            constexpr char kIOBlocksExtName[] = "GL_EXT_shader_io_blocks";
    242            iter = mExtensionBehavior.find(GetExtensionByName(kIOBlocksExtName));
    243            if (iter != mExtensionBehavior.end())
    244            {
    245                iter->second = behaviorVal;
    246            }
    247        }
    248        // GL_APPLE_clip_distance is implicitly enabled when GL_EXT_clip_cull_distance is enabled
    249        else if (name == "GL_EXT_clip_cull_distance")
    250        {
    251            // This extension only can be enabled on greater than ESSL 300
    252            if (mShaderVersion < 300)
    253            {
    254                mDiagnostics.error(loc, "extension can be enabled on greater than ESSL 300",
    255                                   name.c_str());
    256                return;
    257            }
    258 
    259            constexpr char kAPPLEClipDistanceEXTName[] = "GL_APPLE_clip_distance";
    260            iter = mExtensionBehavior.find(GetExtensionByName(kAPPLEClipDistanceEXTName));
    261            if (iter != mExtensionBehavior.end())
    262            {
    263                iter->second = behaviorVal;
    264            }
    265        }
    266        return;
    267    }
    268 
    269    switch (behaviorVal)
    270    {
    271        case EBhRequire:
    272            mDiagnostics.error(loc, "extension is not supported", name.c_str());
    273            break;
    274        case EBhEnable:
    275        case EBhWarn:
    276        case EBhDisable:
    277            mDiagnostics.warning(loc, "extension is not supported", name.c_str());
    278            break;
    279        default:
    280            UNREACHABLE();
    281            break;
    282    }
    283 }
    284 
    285 void TDirectiveHandler::handleVersion(const angle::pp::SourceLocation &loc,
    286                                      int version,
    287                                      ShShaderSpec spec)
    288 {
    289    if (((version == 100 || version == 300 || version == 310 || version == 320) &&
    290         !IsDesktopGLSpec(spec)) ||
    291        IsDesktopGLSpec(spec))
    292    {
    293        mShaderVersion = version;
    294    }
    295    else
    296    {
    297        std::stringstream stream = sh::InitializeStream<std::stringstream>();
    298        stream << version;
    299        std::string str = stream.str();
    300        mDiagnostics.error(loc, "client/version number not supported", str.c_str());
    301    }
    302 }
    303 
    304 }  // namespace sh