| // | |
| // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| // | |
| // Compiler.cpp: implements the gl::Compiler class. | |
| #include "libANGLE/Compiler.h" | |
| #include "common/debug.h" | |
| #include "libANGLE/Data.h" | |
| #include "libANGLE/renderer/CompilerImpl.h" | |
| #include "libANGLE/renderer/ImplFactory.h" | |
| namespace gl | |
| { | |
| namespace | |
| { | |
| // Global count of active shader compiler handles. Needed to know when to call ShInitialize and | |
| // ShFinalize. | |
| size_t activeCompilerHandles = 0; | |
| } // anonymous namespace | |
| Compiler::Compiler(rx::ImplFactory *implFactory, const gl::Data &data) | |
| : mImplementation(implFactory->createCompiler()), | |
| mSpec(data.clientVersion > 2 ? SH_GLES3_SPEC : SH_GLES2_SPEC), | |
| mOutputType(mImplementation->getTranslatorOutputType()), | |
| mResources(), | |
| mFragmentCompiler(nullptr), | |
| mVertexCompiler(nullptr) | |
| { | |
| ASSERT(data.clientVersion == 2 || data.clientVersion == 3); | |
| const gl::Caps &caps = *data.caps; | |
| const gl::Extensions &extensions = *data.extensions; | |
| ShInitBuiltInResources(&mResources); | |
| mResources.MaxVertexAttribs = caps.maxVertexAttributes; | |
| mResources.MaxVertexUniformVectors = caps.maxVertexUniformVectors; | |
| mResources.MaxVaryingVectors = caps.maxVaryingVectors; | |
| mResources.MaxVertexTextureImageUnits = caps.maxVertexTextureImageUnits; | |
| mResources.MaxCombinedTextureImageUnits = caps.maxCombinedTextureImageUnits; | |
| mResources.MaxTextureImageUnits = caps.maxTextureImageUnits; | |
| mResources.MaxFragmentUniformVectors = caps.maxFragmentUniformVectors; | |
| mResources.MaxDrawBuffers = caps.maxDrawBuffers; | |
| mResources.OES_standard_derivatives = extensions.standardDerivatives; | |
| mResources.EXT_draw_buffers = extensions.drawBuffers; | |
| mResources.EXT_shader_texture_lod = extensions.shaderTextureLOD; | |
| // TODO: disabled until the extension is actually supported. | |
| mResources.OES_EGL_image_external = 0; | |
| // TODO: use shader precision caps to determine if high precision is supported? | |
| mResources.FragmentPrecisionHigh = 1; | |
| mResources.EXT_frag_depth = extensions.fragDepth; | |
| // GLSL ES 3.0 constants | |
| mResources.MaxVertexOutputVectors = caps.maxVertexOutputComponents / 4; | |
| mResources.MaxFragmentInputVectors = caps.maxFragmentInputComponents / 4; | |
| mResources.MinProgramTexelOffset = caps.minProgramTexelOffset; | |
| mResources.MaxProgramTexelOffset = caps.maxProgramTexelOffset; | |
| } | |
| Compiler::~Compiler() | |
| { | |
| release(); | |
| SafeDelete(mImplementation); | |
| } | |
| Error Compiler::release() | |
| { | |
| if (mFragmentCompiler) | |
| { | |
| ShDestruct(mFragmentCompiler); | |
| mFragmentCompiler = nullptr; | |
| ASSERT(activeCompilerHandles > 0); | |
| activeCompilerHandles--; | |
| } | |
| if (mVertexCompiler) | |
| { | |
| ShDestruct(mVertexCompiler); | |
| mVertexCompiler = nullptr; | |
| ASSERT(activeCompilerHandles > 0); | |
| activeCompilerHandles--; | |
| } | |
| if (activeCompilerHandles == 0) | |
| { | |
| ShFinalize(); | |
| } | |
| mImplementation->release(); | |
| return gl::Error(GL_NO_ERROR); | |
| } | |
| ShHandle Compiler::getCompilerHandle(GLenum type) | |
| { | |
| ShHandle *compiler = nullptr; | |
| switch (type) | |
| { | |
| case GL_VERTEX_SHADER: | |
| compiler = &mVertexCompiler; | |
| break; | |
| case GL_FRAGMENT_SHADER: | |
| compiler = &mFragmentCompiler; | |
| break; | |
| default: | |
| UNREACHABLE(); | |
| return nullptr; | |
| } | |
| if (!(*compiler)) | |
| { | |
| if (activeCompilerHandles == 0) | |
| { | |
| ShInitialize(); | |
| } | |
| *compiler = ShConstructCompiler(type, mSpec, mOutputType, &mResources); | |
| activeCompilerHandles++; | |
| } | |
| return *compiler; | |
| } | |
| } // namespace gl |