1 
2 //
3 // This source file is part of appleseed.
4 // Visit https://appleseedhq.net/ for additional information and resources.
5 //
6 // This software is released under the MIT license.
7 //
8 // Copyright (c) 2017-2018 Esteban Tovagliari, The appleseedhq Organization
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to deal
12 // in the Software without restriction, including without limitation the rights
13 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 // copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 // THE SOFTWARE.
27 //
28 
29 // Interface header.
30 #include "shadercompiler.h"
31 
32 // appleseed.renderer headers.
33 #include "renderer/kernel/rendering/oiioerrorhandler.h"
34 
35 // appleseed.foundation headers.
36 #include "foundation/utility/api/apistring.h"
37 
38 // OSL headers.
39 #include "foundation/platform/_beginoslheaders.h"
40 #include "OSL/oslcomp.h"
41 #include "foundation/platform/_endoslheaders.h"
42 
43 // Standard headers.
44 #include <string>
45 #include <vector>
46 
47 using namespace foundation;
48 using namespace std;
49 
50 namespace renderer
51 {
52 
53 //
54 // ShaderCompiler class implementation.
55 //
56 
57 struct ShaderCompiler::Impl
58 {
Implrenderer::ShaderCompiler::Impl59     Impl(const char* stdosl_path)
60       : m_stdosl_path(stdosl_path)
61     {
62         m_error_handler = new OIIOErrorHandler();
63     #ifndef NDEBUG
64         m_error_handler->verbosity(OIIO::ErrorHandler::VERBOSE);
65     #endif
66 
67         m_compiler = new OSL::OSLCompiler(m_error_handler);
68     }
69 
~Implrenderer::ShaderCompiler::Impl70     ~Impl()
71     {
72         delete m_compiler;
73         delete m_error_handler;
74     }
75 
76     string              m_stdosl_path;
77     OSL::OSLCompiler*   m_compiler;
78     OIIOErrorHandler*   m_error_handler;
79     vector<string>      m_options;
80 };
81 
ShaderCompiler(const char * stdosl_path)82 ShaderCompiler::ShaderCompiler(const char* stdosl_path)
83   : impl(new Impl(stdosl_path))
84 {
85 }
86 
~ShaderCompiler()87 ShaderCompiler::~ShaderCompiler()
88 {
89     delete impl;
90 }
91 
release()92 void ShaderCompiler::release()
93 {
94     delete this;
95 }
96 
clear_options()97 void ShaderCompiler::clear_options()
98 {
99     impl->m_options.clear();
100 }
101 
add_option(const char * option)102 void ShaderCompiler::add_option(const char* option)
103 {
104     impl->m_options.push_back(option);
105 }
106 
compile_buffer(const char * source_code,APIString & result) const107 bool ShaderCompiler::compile_buffer(
108     const char* source_code,
109     APIString&  result) const
110 {
111     string buffer;
112     const bool ok = impl->m_compiler->compile_buffer(
113         source_code,
114         buffer,
115         impl->m_options,
116         impl->m_stdosl_path.c_str());
117 
118     if (ok)
119         result = APIString(buffer.c_str());
120 
121     return ok;
122 }
123 
124 
125 //
126 // ShaderCompilerFactory class implementation.
127 //
128 
create(const char * stdosl_path)129 auto_release_ptr<ShaderCompiler> ShaderCompilerFactory::create(
130     const char* stdosl_path)
131 {
132     return auto_release_ptr<ShaderCompiler>(new ShaderCompiler(stdosl_path));
133 }
134 
135 }   // namespace renderer
136