Home | History | Annotate | Download | only in libshaderc_util
      1 // Copyright 2015 The Shaderc Authors. All rights reserved.
      2 //
      3 // Licensed under the Apache License, Version 2.0 (the "License");
      4 // you may not use this file except in compliance with the License.
      5 // You may obtain a copy of the License at
      6 //
      7 //     http://www.apache.org/licenses/LICENSE-2.0
      8 //
      9 // Unless required by applicable law or agreed to in writing, software
     10 // distributed under the License is distributed on an "AS IS" BASIS,
     11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 // See the License for the specific language governing permissions and
     13 // limitations under the License.
     14 
     15 #ifndef LIBSHADERC_UTIL_COUNTING_INCLUDER_H
     16 #define LIBSHADERC_UTIL_COUNTING_INCLUDER_H
     17 
     18 #include <atomic>
     19 
     20 #include "glslang/Public/ShaderLang.h"
     21 
     22 namespace shaderc_util {
     23 
     24 // An Includer that counts how many #include directives it saw.
     25 class CountingIncluder : public glslang::TShader::Includer {
     26  public:
     27   // Done as .store(0) instead of in the initializer list for the following
     28   // reasons:
     29   // Clang > 3.6 will complain about it if it is written as ({0}).
     30   // VS2013 fails if it is written as {0}.
     31   // G++-4.8 does not correctly support std::atomic_init.
     32   CountingIncluder() {
     33     num_include_directives_.store(0);
     34   }
     35 
     36   enum class IncludeType {
     37     System,  // Only do < > include search
     38     Local,   // Only do " " include search
     39   };
     40 
     41   // Resolves an include request for a source by name, type, and name of the
     42   // requesting source.  For the semantics of the result, see the base class.
     43   // Also increments num_include_directives and returns the results of
     44   // include_delegate(filename).  Subclasses should override include_delegate()
     45   // instead of this method.
     46   glslang::TShader::Includer::IncludeResult* includeSystem(
     47       const char* requested_source, const char* requesting_source,
     48       size_t include_depth) final {
     49     ++num_include_directives_;
     50     return include_delegate(requested_source, requesting_source,
     51                             IncludeType::System, include_depth);
     52   }
     53 
     54   // Like includeSystem, but for "local" include search.
     55   glslang::TShader::Includer::IncludeResult* includeLocal(
     56       const char* requested_source, const char* requesting_source,
     57       size_t include_depth) final {
     58     ++num_include_directives_;
     59     return include_delegate(requested_source, requesting_source,
     60                             IncludeType::Local, include_depth);
     61   }
     62 
     63   // Releases the given IncludeResult.
     64   void releaseInclude(glslang::TShader::Includer::IncludeResult* result) final {
     65     release_delegate(result);
     66   }
     67 
     68   int num_include_directives() const { return num_include_directives_.load(); }
     69 
     70  private:
     71 
     72   // Invoked by this class to provide results to
     73   // glslang::TShader::Includer::include.
     74   virtual glslang::TShader::Includer::IncludeResult* include_delegate(
     75       const char* requested_source, const char* requesting_source,
     76       IncludeType type, size_t include_depth) = 0;
     77 
     78   // Release the given IncludeResult.
     79   virtual void release_delegate(
     80       glslang::TShader::Includer::IncludeResult* result) = 0;
     81 
     82   // The number of #include directive encountered.
     83   std::atomic_int num_include_directives_;
     84 };
     85 }
     86 
     87 #endif  // LIBSHADERC_UTIL_COUNTING_INCLUDER_H
     88