| 126 | |
| 127 | |
| 128 | void ExecuteOSLShader(const std::string & shaderName, |
| 129 | const Image & inValues, |
| 130 | const Image & outValues, |
| 131 | float threshold, |
| 132 | float minValue, |
| 133 | bool relativeComparison) |
| 134 | { |
| 135 | MyRendererServices renderer; |
| 136 | ErrorRecorder msg; |
| 137 | std::unique_ptr<OSL::ShadingSystem> shadsys(new OSL::ShadingSystem(&renderer, nullptr, &msg)); |
| 138 | |
| 139 | OSL::ShaderGroupRef mygroup = shadsys->ShaderGroupBegin("my_color_mgt"); |
| 140 | shadsys->Parameter(*mygroup, "inColor.rgb", 1.0f, /*lockgeom=*/false); |
| 141 | shadsys->Parameter(*mygroup, "inColor.a", 1.0f, /*lockgeom=*/false); |
| 142 | shadsys->Shader(*mygroup, "shader", shaderName, "layer1"); |
| 143 | shadsys->ShaderGroupEnd(*mygroup); |
| 144 | |
| 145 | const std::vector<OSL::ustring> output_names{ OSL::ustring("outColor.rgb"), OSL::ustring("outColor.a") }; |
| 146 | shadsys->attribute (mygroup.get(), "renderer_outputs", |
| 147 | OSL::TypeDesc(OSL::TypeDesc::STRING, output_names.size()), |
| 148 | output_names.data()); |
| 149 | |
| 150 | #if OSL_LIBRARY_VERSION_CODE >= 11300 |
| 151 | // Use the new symlocs API to say where to place outputs |
| 152 | OSL::SymLocationDesc outputRGB("outColor.rgb", OSL::TypePoint, false, |
| 153 | OSL::SymArena::Outputs, |
| 154 | 0 /* output arena offset of "out" */, |
| 155 | sizeof(OSL::Vec3) /* point to point stride */); |
| 156 | shadsys->add_symlocs(mygroup.get(), outputRGB); |
| 157 | |
| 158 | OSL::SymLocationDesc outputA("outColor.a", OSL::TypeFloat, false, |
| 159 | OSL::SymArena::Outputs, |
| 160 | sizeof(OSL::Vec3) /* output arena offset of "out" */, |
| 161 | sizeof(float) /* point to point stride */); |
| 162 | shadsys->add_symlocs(mygroup.get(), outputA); |
| 163 | #endif |
| 164 | |
| 165 | // Now we want to create a context in which we can execute the shader. |
| 166 | // We need one context per thread. |
| 167 | OSL::PerThreadInfo * perthread = shadsys->create_thread_info(); |
| 168 | OSL::ShadingContext * ctx = shadsys->get_context(perthread); |
| 169 | |
| 170 | // The group must already be optimized before we call find_symbol, |
| 171 | // so we force that to happen now. |
| 172 | shadsys->optimize_group(mygroup.get(), ctx); |
| 173 | |
| 174 | #if OSL_LIBRARY_VERSION_CODE < 11300 |
| 175 | // Get a ShaderSymbol* handle to the final output we care about. This |
| 176 | // will greatly speed up retrieving the value later, rather than by |
| 177 | // looking it up by name on every shade. |
| 178 | const OSL::ShaderSymbol * outsymRGB |
| 179 | = shadsys->find_symbol(*mygroup.get(), OSL::ustring("layer1"), OSL::ustring("outColor.rgb")); |
| 180 | OSL_ASSERT(outsymRGB); |
| 181 | |
| 182 | const OSL::ShaderSymbol * outsymA |
| 183 | = shadsys->find_symbol(*mygroup.get(), OSL::ustring("layer1"), OSL::ustring("outColor.a")); |
| 184 | OSL_ASSERT(outsymA); |
| 185 | #endif |