work towards implementing osl as a renderer
This commit is contained in:
@@ -43,6 +43,8 @@ find_package(OpenImageIO REQUIRED)
|
||||
|
||||
find_package(OpenShadingLanguage REQUIRED)
|
||||
|
||||
find_package(OpenEXR REQUIRED)
|
||||
|
||||
find_package(Qt5 5.6 REQUIRED
|
||||
COMPONENTS
|
||||
Core
|
||||
|
||||
+7
-3
@@ -78,15 +78,17 @@ if(MSVC)
|
||||
"$<$<CONFIG:RELEASE>:/O2>"
|
||||
)
|
||||
else()
|
||||
target_compile_options(${OLIVE_TARGET} PRIVATE -O2 -Werror -Wuninitialized -pedantic-errors -Wall -Wextra -Wconversion -Wsign-conversion)
|
||||
target_compile_options(${OLIVE_TARGET} PRIVATE -O2 -Werror -Wuninitialized -pedantic-errors -Wall -Wextra -Wsign-conversion)
|
||||
endif()
|
||||
|
||||
target_include_directories(
|
||||
${OLIVE_TARGET}
|
||||
PRIVATE
|
||||
${OPENCOLORIO_INCLUDE_DIR}
|
||||
${OIIO_INCLUDE_DIRS}
|
||||
${FFMPEG_INCLUDE_DIRS}
|
||||
${OCIO_INCLUDE_DIRS}
|
||||
${OIIO_INCLUDE_DIRS}
|
||||
${OSL_INCLUDE_DIRS}
|
||||
${OPENEXR_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(${OLIVE_TARGET}
|
||||
@@ -105,6 +107,8 @@ target_link_libraries(${OLIVE_TARGET}
|
||||
FFMPEG::swresample
|
||||
${OCIO_LIBRARIES}
|
||||
${OIIO_LIBRARIES}
|
||||
${OSL_LIBRARIES}
|
||||
${OPENEXR_LIBRARIES}
|
||||
)
|
||||
|
||||
set(OLIVE_TS_FILES
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
#include "render/colorprocessor.h"
|
||||
#include "rendercache.h"
|
||||
|
||||
using ColorProcessorCache = RenderCache<QString, ColorProcessorPtr>;
|
||||
using ColorProcessorCache = ThreadSafeRenderCache<QString, ColorProcessorPtr>;
|
||||
|
||||
#endif // COLORPROCESSORCACHE_H
|
||||
|
||||
@@ -18,6 +18,9 @@ set(OLIVE_SOURCES
|
||||
${OLIVE_SOURCES}
|
||||
render/backend/osl/oslbackend.h
|
||||
render/backend/osl/oslbackend.cpp
|
||||
render/backend/osl/oslrenderer.h
|
||||
render/backend/osl/oslrenderer.cpp
|
||||
render/backend/osl/oslshadercache.h
|
||||
render/backend/osl/oslworker.h
|
||||
render/backend/osl/oslworker.cpp
|
||||
PARENT_SCOPE
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
#include "oslbackend.h"
|
||||
|
||||
#include <OSL/oslexec.h>
|
||||
#include <OSL/oslcomp.h>
|
||||
#include <QEventLoop>
|
||||
#include <QThread>
|
||||
|
||||
#include "oslworker.h"
|
||||
|
||||
OSLBackend::OSLBackend(QObject *parent) :
|
||||
VideoRenderBackend(parent)
|
||||
VideoRenderBackend(parent),
|
||||
shading_system_(nullptr),
|
||||
renderer_(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -22,10 +24,17 @@ bool OSLBackend::InitInternal()
|
||||
return false;
|
||||
}
|
||||
|
||||
renderer_ = new OSL::SimpleRenderer();
|
||||
|
||||
shading_system_ = new OSL::ShadingSystem(renderer_);
|
||||
|
||||
// Initiate one thread per CPU core
|
||||
for (int i=0;i<threads().size();i++) {
|
||||
// Create one processor object for each thread
|
||||
OSLWorker* processor = new OSLWorker(frame_cache());
|
||||
OSLWorker* processor = new OSLWorker(frame_cache(),
|
||||
shading_system_,
|
||||
&shader_cache_,
|
||||
&color_cache_);
|
||||
processor->SetParameters(params());
|
||||
processors_.append(processor);
|
||||
}
|
||||
@@ -33,9 +42,54 @@ bool OSLBackend::InitInternal()
|
||||
return true;
|
||||
}
|
||||
|
||||
void OSLBackend::CloseInternal()
|
||||
{
|
||||
VideoRenderBackend::CloseInternal();
|
||||
|
||||
shader_cache_.Clear();
|
||||
|
||||
delete shading_system_;
|
||||
shading_system_ = nullptr;
|
||||
|
||||
delete renderer_;
|
||||
renderer_= nullptr;
|
||||
}
|
||||
|
||||
bool OSLBackend::CompileInternal()
|
||||
{
|
||||
//OSL::ShadingSystem;
|
||||
OSL::ShadingSystem* system = shading_system_;
|
||||
|
||||
OSL::OSLCompiler compiler;
|
||||
|
||||
QList<Node*> deps = viewer_node()->GetDependencies();
|
||||
foreach (Node* n, deps) {
|
||||
if (!shader_cache_.Has(n->id())) {
|
||||
if (n->IsAccelerated()) {
|
||||
// FIXME: Compile here
|
||||
|
||||
std::string oso_buffer;
|
||||
|
||||
if (!compiler.compile_buffer(n->AcceleratedCodeFragment().toStdString(),
|
||||
oso_buffer,
|
||||
std::vector<std::string>(),
|
||||
"",
|
||||
n->id().toStdString())) {
|
||||
qWarning() << "Failed to compile" << n->id();
|
||||
return false;
|
||||
}
|
||||
|
||||
OSL::ShaderGroupRef ref = system->ShaderGroupBegin(n->id().toStdString());
|
||||
system->Shader("surface", n->id().toStdString(), "layer1");
|
||||
system->ShaderGroupEnd();
|
||||
|
||||
shader_cache_.Add(n->id(), ref);
|
||||
|
||||
} else {
|
||||
// Insert null
|
||||
shader_cache_.Add(n->id(), nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
#ifndef OSLBACKEND_H
|
||||
#define OSLBACKEND_H
|
||||
|
||||
#include <OSL/oslexec.h>
|
||||
|
||||
#include "../videorenderbackend.h"
|
||||
#include "oslrenderer.h"
|
||||
#include "oslshadercache.h"
|
||||
|
||||
class OSLBackend : public VideoRenderBackend
|
||||
{
|
||||
@@ -14,12 +18,23 @@ public:
|
||||
protected:
|
||||
virtual bool InitInternal() override;
|
||||
|
||||
virtual void CloseInternal() override;
|
||||
|
||||
virtual bool CompileInternal() override;
|
||||
|
||||
virtual void DecompileInternal() override;
|
||||
|
||||
//virtual void ParamsChangedEvent() override;
|
||||
|
||||
private:
|
||||
OSL::ShadingSystem* shading_system_;
|
||||
|
||||
OSL::SimpleRenderer* renderer_;
|
||||
|
||||
OSLShaderCache shader_cache_;
|
||||
|
||||
ColorProcessorCache color_cache_;
|
||||
|
||||
};
|
||||
|
||||
#endif // OSLBACKEND_H
|
||||
|
||||
@@ -0,0 +1,456 @@
|
||||
/*
|
||||
Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Sony Pictures Imageworks nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include "oslrenderer.h"
|
||||
using namespace OSL;
|
||||
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
static ustring u_camera("camera"), u_screen("screen");
|
||||
static ustring u_NDC("NDC"), u_raster("raster");
|
||||
static ustring u_perspective("perspective");
|
||||
static ustring u_s("s"), u_t("t");
|
||||
static TypeDesc TypeFloatArray2 (TypeDesc::FLOAT, 2);
|
||||
static TypeDesc TypeFloatArray4 (TypeDesc::FLOAT, 4);
|
||||
static TypeDesc TypeIntArray2 (TypeDesc::INT, 2);
|
||||
|
||||
|
||||
|
||||
|
||||
SimpleRenderer::SimpleRenderer ()
|
||||
{
|
||||
Matrix44 M; M.makeIdentity();
|
||||
camera_params (M, u_perspective, 90.0f,
|
||||
0.1f, 1000.0f, 256, 256);
|
||||
|
||||
// Set up getters
|
||||
m_attr_getters[ustring("osl:version")] = &SimpleRenderer::get_osl_version;
|
||||
m_attr_getters[ustring("camera:resolution")] = &SimpleRenderer::get_camera_resolution;
|
||||
m_attr_getters[ustring("camera:projection")] = &SimpleRenderer::get_camera_projection;
|
||||
m_attr_getters[ustring("camera:pixelaspect")] = &SimpleRenderer::get_camera_pixelaspect;
|
||||
m_attr_getters[ustring("camera:screen_window")] = &SimpleRenderer::get_camera_screen_window;
|
||||
m_attr_getters[ustring("camera:fov")] = &SimpleRenderer::get_camera_fov;
|
||||
m_attr_getters[ustring("camera:clip")] = &SimpleRenderer::get_camera_clip;
|
||||
m_attr_getters[ustring("camera:clip_near")] = &SimpleRenderer::get_camera_clip_near;
|
||||
m_attr_getters[ustring("camera:clip_far")] = &SimpleRenderer::get_camera_clip_far;
|
||||
m_attr_getters[ustring("camera:shutter")] = &SimpleRenderer::get_camera_shutter;
|
||||
m_attr_getters[ustring("camera:shutter_open")] = &SimpleRenderer::get_camera_shutter_open;
|
||||
m_attr_getters[ustring("camera:shutter_close")] = &SimpleRenderer::get_camera_shutter_close;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
SimpleRenderer::supports (string_view) const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
SimpleRenderer::camera_params (const Matrix44 &world_to_camera,
|
||||
ustring projection, float hfov,
|
||||
float hither, float yon,
|
||||
int xres, int yres)
|
||||
{
|
||||
m_world_to_camera = world_to_camera;
|
||||
m_projection = projection;
|
||||
m_fov = hfov;
|
||||
m_pixelaspect = 1.0f; // hard-coded
|
||||
m_hither = hither;
|
||||
m_yon = yon;
|
||||
m_shutter[0] = 0.0f; m_shutter[1] = 1.0f; // hard-coded
|
||||
float frame_aspect = float(xres)/float(yres) * m_pixelaspect;
|
||||
m_screen_window[0] = -frame_aspect;
|
||||
m_screen_window[1] = -1.0f;
|
||||
m_screen_window[2] = frame_aspect;
|
||||
m_screen_window[3] = 1.0f;
|
||||
m_xres = xres;
|
||||
m_yres = yres;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_matrix (ShaderGlobals *, Matrix44 &result,
|
||||
TransformationPtr xform,
|
||||
float)
|
||||
{
|
||||
// SimpleRenderer doesn't understand motion blur and transformations
|
||||
// are just simple 4x4 matrices.
|
||||
result = *reinterpret_cast<const Matrix44*>(xform);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_matrix (ShaderGlobals *, Matrix44 &result,
|
||||
ustring from, float)
|
||||
{
|
||||
TransformMap::const_iterator found = m_named_xforms.find (from);
|
||||
if (found != m_named_xforms.end()) {
|
||||
result = *(found->second);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_matrix (ShaderGlobals *, Matrix44 &result,
|
||||
TransformationPtr xform)
|
||||
{
|
||||
// SimpleRenderer doesn't understand motion blur and transformations
|
||||
// are just simple 4x4 matrices.
|
||||
result = *reinterpret_cast<const Matrix44*>(xform);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_matrix (ShaderGlobals *, Matrix44 &result,
|
||||
ustring from)
|
||||
{
|
||||
// SimpleRenderer doesn't understand motion blur, so we never fail
|
||||
// on account of time-varying transformations.
|
||||
TransformMap::const_iterator found = m_named_xforms.find (from);
|
||||
if (found != m_named_xforms.end()) {
|
||||
result = *(found->second);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_inverse_matrix (ShaderGlobals *, Matrix44 &result,
|
||||
ustring to, float)
|
||||
{
|
||||
if (to == u_camera || to == u_screen || to == u_NDC || to == u_raster) {
|
||||
Matrix44 M = m_world_to_camera;
|
||||
if (to == u_screen || to == u_NDC || to == u_raster) {
|
||||
float depthrange = (double)m_yon-(double)m_hither;
|
||||
if (m_projection == u_perspective) {
|
||||
float tanhalffov = tanf (0.5f * m_fov * M_PI/180.0);
|
||||
Matrix44 camera_to_screen (1/tanhalffov, 0, 0, 0,
|
||||
0, 1/tanhalffov, 0, 0,
|
||||
0, 0, m_yon/depthrange, 1,
|
||||
0, 0, -m_yon*m_hither/depthrange, 0);
|
||||
M = M * camera_to_screen;
|
||||
} else {
|
||||
Matrix44 camera_to_screen (1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1/depthrange, 0,
|
||||
0, 0, -m_hither/depthrange, 1);
|
||||
M = M * camera_to_screen;
|
||||
}
|
||||
if (to == u_NDC || to == u_raster) {
|
||||
float screenleft = -1.0, screenwidth = 2.0;
|
||||
float screenbottom = -1.0, screenheight = 2.0;
|
||||
Matrix44 screen_to_ndc (1/screenwidth, 0, 0, 0,
|
||||
0, 1/screenheight, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
-screenleft/screenwidth, -screenbottom/screenheight, 0, 1);
|
||||
M = M * screen_to_ndc;
|
||||
if (to == u_raster) {
|
||||
Matrix44 ndc_to_raster (m_xres, 0, 0, 0,
|
||||
0, m_yres, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
M = M * ndc_to_raster;
|
||||
}
|
||||
}
|
||||
}
|
||||
result = M;
|
||||
return true;
|
||||
}
|
||||
|
||||
TransformMap::const_iterator found = m_named_xforms.find (to);
|
||||
if (found != m_named_xforms.end()) {
|
||||
result = *(found->second);
|
||||
result.invert();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
SimpleRenderer::name_transform (const char *name, const OSL::Matrix44 &xform)
|
||||
{
|
||||
std::shared_ptr<Transformation> M (new OSL::Matrix44 (xform));
|
||||
m_named_xforms[ustring(name)] = M;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_array_attribute (ShaderGlobals *sg, bool derivatives, ustring object,
|
||||
TypeDesc type, ustring name,
|
||||
int index, void *val)
|
||||
{
|
||||
AttrGetterMap::const_iterator g = m_attr_getters.find (name);
|
||||
if (g != m_attr_getters.end()) {
|
||||
AttrGetter getter = g->second;
|
||||
return (this->*(getter)) (sg, derivatives, object, type, name, val);
|
||||
}
|
||||
|
||||
// If no named attribute was found, allow userdata to bind to the
|
||||
// attribute request.
|
||||
if (object.empty() && index == -1)
|
||||
return get_userdata (derivatives, name, type, sg, val);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_attribute (ShaderGlobals *sg, bool derivatives, ustring object,
|
||||
TypeDesc type, ustring name, void *val)
|
||||
{
|
||||
return get_array_attribute (sg, derivatives, object,
|
||||
type, name, -1, val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_userdata (bool derivatives, ustring name, TypeDesc type,
|
||||
ShaderGlobals *sg, void *val)
|
||||
{
|
||||
// Just to illustrate how this works, respect s and t userdata, filled
|
||||
// in with the uv coordinates. In a real renderer, it would probably
|
||||
// look up something specific to the primitive, rather than have hard-
|
||||
// coded names.
|
||||
|
||||
if (name == u_s && type == TypeDesc::TypeFloat) {
|
||||
((float *)val)[0] = sg->u;
|
||||
if (derivatives) {
|
||||
((float *)val)[1] = sg->dudx;
|
||||
((float *)val)[2] = sg->dudy;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (name == u_t && type == TypeDesc::TypeFloat) {
|
||||
((float *)val)[0] = sg->v;
|
||||
if (derivatives) {
|
||||
((float *)val)[1] = sg->dvdx;
|
||||
((float *)val)[2] = sg->dvdy;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_osl_version (ShaderGlobals *, bool, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
if (type == TypeDesc::TypeInt) {
|
||||
((int *)val)[0] = OSL_VERSION;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_resolution (ShaderGlobals *, bool, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
if (type == TypeIntArray2) {
|
||||
((int *)val)[0] = m_xres;
|
||||
((int *)val)[1] = m_yres;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_projection (ShaderGlobals *, bool, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
if (type == TypeDesc::TypeString) {
|
||||
((ustring *)val)[0] = m_projection;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_fov (ShaderGlobals *, bool derivs, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
// N.B. in a real rederer, this may be time-dependent
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float *)val)[0] = m_fov;
|
||||
if (derivs)
|
||||
memset ((char *)val+type.size(), 0, 2*type.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_pixelaspect (ShaderGlobals *, bool derivs, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float *)val)[0] = m_pixelaspect;
|
||||
if (derivs)
|
||||
memset ((char *)val+type.size(), 0, 2*type.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_clip (ShaderGlobals *, bool derivs, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
if (type == TypeFloatArray2) {
|
||||
((float *)val)[0] = m_hither;
|
||||
((float *)val)[1] = m_yon;
|
||||
if (derivs)
|
||||
memset ((char *)val+type.size(), 0, 2*type.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_clip_near (ShaderGlobals *, bool derivs, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float *)val)[0] = m_hither;
|
||||
if (derivs)
|
||||
memset ((char *)val+type.size(), 0, 2*type.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_clip_far (ShaderGlobals *, bool derivs, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float *)val)[0] = m_yon;
|
||||
if (derivs)
|
||||
memset ((char *)val+type.size(), 0, 2*type.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_shutter (ShaderGlobals *, bool derivs, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
if (type == TypeFloatArray2) {
|
||||
((float *)val)[0] = m_shutter[0];
|
||||
((float *)val)[1] = m_shutter[1];
|
||||
if (derivs)
|
||||
memset ((char *)val+type.size(), 0, 2*type.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_shutter_open (ShaderGlobals *, bool derivs, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float *)val)[0] = m_shutter[0];
|
||||
if (derivs)
|
||||
memset ((char *)val+type.size(), 0, 2*type.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_shutter_close (ShaderGlobals *, bool derivs, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
if (type == TypeDesc::TypeFloat) {
|
||||
((float *)val)[0] = m_shutter[1];
|
||||
if (derivs)
|
||||
memset ((char *)val+type.size(), 0, 2*type.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
SimpleRenderer::get_camera_screen_window (ShaderGlobals *, bool derivs, ustring,
|
||||
TypeDesc type, ustring, void *val)
|
||||
{
|
||||
// N.B. in a real rederer, this may be time-dependent
|
||||
if (type == TypeFloatArray4) {
|
||||
((float *)val)[0] = m_screen_window[0];
|
||||
((float *)val)[1] = m_screen_window[1];
|
||||
((float *)val)[2] = m_screen_window[2];
|
||||
((float *)val)[3] = m_screen_window[3];
|
||||
if (derivs)
|
||||
memset ((char *)val+type.size(), 0, 2*type.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
OSL_NAMESPACE_EXIT
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
|
||||
All Rights Reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Sony Pictures Imageworks nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <OpenImageIO/ustring.h>
|
||||
#include <OSL/oslexec.h>
|
||||
|
||||
OSL_NAMESPACE_ENTER
|
||||
|
||||
class SimpleRenderer : public RendererServices
|
||||
{
|
||||
public:
|
||||
// Just use 4x4 matrix for transformations
|
||||
typedef Matrix44 Transformation;
|
||||
|
||||
SimpleRenderer ();
|
||||
~SimpleRenderer () { }
|
||||
|
||||
virtual int supports (string_view feature) const;
|
||||
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
TransformationPtr xform,
|
||||
float time);
|
||||
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
ustring from, float time);
|
||||
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
TransformationPtr xform);
|
||||
virtual bool get_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
ustring from);
|
||||
virtual bool get_inverse_matrix (ShaderGlobals *sg, Matrix44 &result,
|
||||
ustring to, float time);
|
||||
|
||||
void name_transform (const char *name, const Transformation &xform);
|
||||
|
||||
virtual bool get_array_attribute (ShaderGlobals *sg, bool derivatives,
|
||||
ustring object, TypeDesc type, ustring name,
|
||||
int index, void *val );
|
||||
virtual bool get_attribute (ShaderGlobals *sg, bool derivatives, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
virtual bool get_userdata (bool derivatives, ustring name, TypeDesc type,
|
||||
ShaderGlobals *sg, void *val);
|
||||
|
||||
// Super simple camera and display parameters. Many options not
|
||||
// available, no motion blur, etc.
|
||||
void camera_params (const Matrix44 &world_to_camera, ustring projection,
|
||||
float hfov, float hither, float yon,
|
||||
int xres, int yres);
|
||||
|
||||
private:
|
||||
// Camera parameters
|
||||
Matrix44 m_world_to_camera;
|
||||
ustring m_projection;
|
||||
float m_fov, m_pixelaspect, m_hither, m_yon;
|
||||
float m_shutter[2];
|
||||
float m_screen_window[4];
|
||||
int m_xres, m_yres;
|
||||
|
||||
// Named transforms
|
||||
typedef std::map <ustring, std::shared_ptr<Transformation> > TransformMap;
|
||||
TransformMap m_named_xforms;
|
||||
|
||||
// Attribute and userdata retrieval -- for fast dispatch, use a hash
|
||||
// table to map attribute names to functions that retrieve them. We
|
||||
// imagine this to be fairly quick, but for a performance-critical
|
||||
// renderer, we would encourage benchmarking various methods and
|
||||
// alternate data structures.
|
||||
typedef bool (SimpleRenderer::*AttrGetter)(ShaderGlobals *sg, bool derivs,
|
||||
ustring object, TypeDesc type,
|
||||
ustring name, void *val);
|
||||
typedef std::unordered_map<ustring, AttrGetter, ustringHash> AttrGetterMap;
|
||||
AttrGetterMap m_attr_getters;
|
||||
|
||||
// Attribute getters
|
||||
bool get_osl_version (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
bool get_camera_resolution (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
bool get_camera_projection (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
bool get_camera_fov (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
bool get_camera_pixelaspect (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
bool get_camera_clip (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
bool get_camera_clip_near (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
bool get_camera_clip_far (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
bool get_camera_shutter (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
bool get_camera_shutter_open (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
bool get_camera_shutter_close (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
bool get_camera_screen_window (ShaderGlobals *sg, bool derivs, ustring object,
|
||||
TypeDesc type, ustring name, void *val);
|
||||
|
||||
};
|
||||
|
||||
OSL_NAMESPACE_EXIT
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef OSLSHADERMAP_H
|
||||
#define OSLSHADERMAP_H
|
||||
|
||||
#include <OSL/oslexec.h>
|
||||
#include <QString>
|
||||
|
||||
#include "../rendercache.h"
|
||||
|
||||
using OSLShaderCache = ThreadSafeRenderCache<QString, OSL::ShaderGroupRef>;
|
||||
|
||||
#endif // OSLSHADERMAP_H
|
||||
@@ -1,5 +1,11 @@
|
||||
#include "oslworker.h"
|
||||
|
||||
#include <OpenImageIO/imagebuf.h>
|
||||
#include <QMatrix4x4>
|
||||
#include <QVector2D>
|
||||
#include <QVector3D>
|
||||
#include <QVector4D>
|
||||
|
||||
#include "common/clamp.h"
|
||||
#include "core.h"
|
||||
#include "node/block/transition/transition.h"
|
||||
@@ -7,28 +13,292 @@
|
||||
#include "render/colormanager.h"
|
||||
#include "render/pixelservice.h"
|
||||
|
||||
OSLWorker::OSLWorker(VideoRenderFrameCache *frame_cache, QObject *parent) :
|
||||
VideoRenderWorker(frame_cache, parent)
|
||||
OSLWorker::OSLWorker(VideoRenderFrameCache* frame_cache,
|
||||
OSL::ShadingSystem* shading_system,
|
||||
OSLShaderCache* shader_cache,
|
||||
ColorProcessorCache* color_cache,
|
||||
QObject* parent) :
|
||||
VideoRenderWorker(frame_cache, parent),
|
||||
shading_system_(shading_system),
|
||||
shader_cache_(shader_cache),
|
||||
color_cache_(color_cache)
|
||||
{
|
||||
}
|
||||
|
||||
void OSLWorker::FrameToValue(StreamPtr stream, FramePtr frame, NodeValueTable *table)
|
||||
{
|
||||
Q_UNUSED(stream)
|
||||
Q_UNUSED(frame)
|
||||
Q_UNUSED(table)
|
||||
// Ensure stream is video or image type
|
||||
if (stream->type() != Stream::kVideo && stream->type() != Stream::kImage) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImageStreamPtr video_stream = std::static_pointer_cast<ImageStream>(stream);
|
||||
|
||||
// Set up OCIO context
|
||||
ColorProcessorPtr color_processor = color_cache_->Get(video_stream->colorspace());
|
||||
|
||||
if (!color_processor) {
|
||||
// FIXME: We match with the colorspace string, but this won't change if the user sets a new config with a colorspace with the same string
|
||||
color_processor = ColorProcessor::Create(video_stream->footage()->project()->color_manager()->GetConfig(),
|
||||
video_stream->colorspace(),
|
||||
OCIO::ROLE_SCENE_LINEAR);
|
||||
color_cache_->Add(video_stream->colorspace(), color_processor);
|
||||
}
|
||||
|
||||
// If alpha is associated, disassociate for the color transform
|
||||
if (video_stream->premultiplied_alpha()) {
|
||||
ColorManager::DisassociateAlpha(frame);
|
||||
}
|
||||
|
||||
// Convert frame to float for OCIO
|
||||
if (frame->format() != PixelFormat::PIX_FMT_RGBA32F) {
|
||||
frame = PixelService::ConvertPixelFormat(frame, frame->format());
|
||||
}
|
||||
|
||||
// Perform color transform
|
||||
color_processor->ConvertFrame(frame);
|
||||
|
||||
// Associate alpha
|
||||
if (video_stream->premultiplied_alpha()) {
|
||||
ColorManager::ReassociateAlpha(frame);
|
||||
} else {
|
||||
ColorManager::AssociateAlpha(frame);
|
||||
}
|
||||
|
||||
table->Push(NodeParam::kTexture, QVariant::fromValue(frame));
|
||||
}
|
||||
|
||||
void OSLWorker::RunNodeAccelerated(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable *output_params)
|
||||
{
|
||||
Q_UNUSED(node)
|
||||
Q_UNUSED(range)
|
||||
Q_UNUSED(input_params)
|
||||
Q_UNUSED(output_params)
|
||||
if (!node->IsAccelerated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
OSL::ShaderGroupRef group = shader_cache_->Get(node->id());
|
||||
|
||||
if (!group) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the output textures
|
||||
QList<OpenGLTextureCache::ReferencePtr> dst_refs;
|
||||
dst_refs.append(texture_cache_.Get(ctx_, video_params_));
|
||||
GLuint iterative_input = 0;
|
||||
|
||||
// If this node requires multiple iterations, get a texture for it too
|
||||
if (node->AcceleratedCodeIterations() > 1 && node->AcceleratedCodeIterativeInput()) {
|
||||
dst_refs.append(texture_cache_.Get(ctx_, video_params_));
|
||||
}
|
||||
|
||||
foreach (NodeParam* param, node->parameters()) {
|
||||
if (param->type() == NodeParam::kInput) {
|
||||
// This variable is used in the shader, let's set it to our value
|
||||
|
||||
NodeInput* input = static_cast<NodeInput*>(param);
|
||||
|
||||
// Get value from database at this input
|
||||
const NodeValueTable& input_data = input_params[input];
|
||||
|
||||
QVariant value = node->InputValueFromTable(input, input_data);
|
||||
|
||||
switch (input->data_type()) {
|
||||
case NodeInput::kInt:
|
||||
{
|
||||
int val = value.toInt();
|
||||
shading_system_->ReParameter(*group.get(), "layer1", param->id().toStdString(), OIIO::TypeDesc::INT, &val);
|
||||
break;
|
||||
}
|
||||
case NodeInput::kFloat:
|
||||
{
|
||||
double val = value.toDouble();
|
||||
shading_system_->ReParameter(*group.get(), "layer1", param->id().toStdString(), OIIO::TypeDesc::DOUBLE, &val);
|
||||
break;
|
||||
}
|
||||
case NodeInput::kVec2:
|
||||
{
|
||||
QVector2D val = value.value<QVector2D>();
|
||||
shading_system_->ReParameter(*group.get(), "layer1", param->id().toStdString(), OIIO::TypeDesc(OIIO::TypeDesc::FLOAT, OIIO::TypeDesc::VEC2), &val);
|
||||
break;
|
||||
}
|
||||
case NodeInput::kVec3:
|
||||
{
|
||||
QVector3D val = value.value<QVector3D>();
|
||||
shading_system_->ReParameter(*group.get(), "layer1", param->id().toStdString(), OIIO::TypeDesc(OIIO::TypeDesc::FLOAT, OIIO::TypeDesc::VEC3), &val);
|
||||
break;
|
||||
}
|
||||
case NodeInput::kVec4:
|
||||
{
|
||||
QVector4D val = value.value<QVector4D>();
|
||||
shading_system_->ReParameter(*group.get(), "layer1", param->id().toStdString(), OIIO::TypeDesc(OIIO::TypeDesc::FLOAT, OIIO::TypeDesc::VEC4), &val);
|
||||
break;
|
||||
}
|
||||
case NodeInput::kMatrix:
|
||||
{
|
||||
QMatrix4x4 val = value.value<QMatrix4x4>();
|
||||
shading_system_->ReParameter(*group.get(), "layer1", param->id().toStdString(), OIIO::TypeDesc(OIIO::TypeDesc::FLOAT, OIIO::TypeDesc::MATRIX44), &val);
|
||||
break;
|
||||
}
|
||||
case NodeInput::kColor:
|
||||
{
|
||||
QVector4D val = value.value<QVector4D>();
|
||||
shading_system_->ReParameter(*group.get(), "layer1", param->id().toStdString(), OIIO::TypeDesc(OIIO::TypeDesc::FLOAT, OIIO::TypeDesc::VEC4, OIIO::TypeDesc::COLOR), &val);
|
||||
break;
|
||||
}
|
||||
case NodeInput::kBoolean:
|
||||
{
|
||||
bool val = value.toBool();
|
||||
shading_system_->ReParameter(*group.get(), "layer1", param->id().toStdString(), OIIO::TypeDesc::CHAR, &val);
|
||||
break;
|
||||
}
|
||||
case NodeInput::kFootage:
|
||||
case NodeInput::kTexture:
|
||||
case NodeInput::kBuffer:
|
||||
{
|
||||
OpenGLTextureCache::ReferencePtr texture = value.value<OpenGLTextureCache::ReferencePtr>();
|
||||
|
||||
functions_->glActiveTexture(GL_TEXTURE0 + input_texture_count);
|
||||
|
||||
GLuint tex_id = texture ? texture->texture()->texture() : 0;
|
||||
functions_->glBindTexture(GL_TEXTURE_2D, tex_id);
|
||||
|
||||
// Set value to bound texture
|
||||
shader->setUniformValue(variable_location, input_texture_count);
|
||||
|
||||
// Set enable flag if shader wants it
|
||||
int enable_param_location = shader->uniformLocation(QStringLiteral("%1_enabled").arg(input->id()));
|
||||
if (enable_param_location > -1) {
|
||||
shader->setUniformValue(enable_param_location,
|
||||
tex_id > 0);
|
||||
}
|
||||
|
||||
if (tex_id > 0) {
|
||||
// Set texture resolution if shader wants it
|
||||
int res_param_location = shader->uniformLocation(QStringLiteral("%1_resolution").arg(input->id()));
|
||||
if (res_param_location > -1) {
|
||||
shader->setUniformValue(res_param_location,
|
||||
static_cast<GLfloat>(texture->texture()->width()),
|
||||
static_cast<GLfloat>(texture->texture()->height()));
|
||||
}
|
||||
}
|
||||
|
||||
// If this texture binding is the iterative input, set it here
|
||||
if (input == node->AcceleratedCodeIterativeInput()) {
|
||||
iterative_input = input_texture_count;
|
||||
}
|
||||
|
||||
OpenGLRenderFunctions::PrepareToDraw(functions_);
|
||||
|
||||
input_texture_count++;
|
||||
break;
|
||||
}
|
||||
case NodeInput::kSamples:
|
||||
case NodeInput::kText:
|
||||
case NodeInput::kRational:
|
||||
case NodeInput::kFont:
|
||||
case NodeInput::kFile:
|
||||
case NodeInput::kDecimal:
|
||||
case NodeInput::kWholeNumber:
|
||||
case NodeInput::kNumber:
|
||||
case NodeInput::kString:
|
||||
case NodeInput::kVector:
|
||||
case NodeInput::kNone:
|
||||
case NodeInput::kAny:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Provide some standard args
|
||||
{
|
||||
QVector2D resolution(static_cast<float>(video_params().width()), static_cast<float>(video_params().height()));
|
||||
shading_system_->ReParameter(*group.get(),
|
||||
"layer1",
|
||||
"ove_resolution",
|
||||
OIIO::TypeDesc(OIIO::TypeDesc::FLOAT, OIIO::TypeDesc::VEC2),
|
||||
&resolution);
|
||||
}
|
||||
|
||||
|
||||
if (node->IsBlock() && static_cast<const Block*>(node)->type() == Block::kTransition) {
|
||||
const TransitionBlock* transition_node = static_cast<const TransitionBlock*>(node);
|
||||
|
||||
// Provides total transition progress from 0.0 (start) - 1.0 (end)
|
||||
double p = transition_node->GetTotalProgress(range.in());
|
||||
shading_system_->ReParameter(*group.get(),
|
||||
"layer1",
|
||||
"ove_tprog_all",
|
||||
OIIO::TypeDesc::DOUBLE,
|
||||
&p);
|
||||
|
||||
// Provides progress of out section from 1.0 (start) - 0.0 (end)
|
||||
p = transition_node->GetOutProgress(range.in());
|
||||
shading_system_->ReParameter(*group.get(),
|
||||
"layer1",
|
||||
"ove_tprog_out",
|
||||
OIIO::TypeDesc::DOUBLE,
|
||||
&p);
|
||||
|
||||
// Provides progress of in section from 0.0 (start) - 1.0 (end)
|
||||
p = transition_node->GetInProgress(range.in());
|
||||
shading_system_->ReParameter(*group.get(),
|
||||
"layer1",
|
||||
"ove_tprog_in",
|
||||
OIIO::TypeDesc::DOUBLE,
|
||||
&p);
|
||||
}
|
||||
|
||||
// Some nodes use multiple iterations for optimization
|
||||
OpenGLTextureCache::ReferencePtr output_tex;
|
||||
|
||||
for (int iteration=0;iteration<node->AcceleratedCodeIterations();iteration++) {
|
||||
// If this is not the first iteration, set the parameter that will receive the last iteration's texture
|
||||
OpenGLTextureCache::ReferencePtr source_tex = dst_refs.at((iteration+1)%dst_refs.size());
|
||||
OpenGLTextureCache::ReferencePtr destination_tex = dst_refs.at(iteration%dst_refs.size());
|
||||
|
||||
// Set iteration number
|
||||
shading_system_->ReParameter(*group.get(),
|
||||
"layer1",
|
||||
"ove_iteration",
|
||||
OIIO::TypeDesc::INT,
|
||||
&iteration);
|
||||
|
||||
if (iteration > 0) {
|
||||
functions_->glActiveTexture(GL_TEXTURE0 + iterative_input);
|
||||
functions_->glBindTexture(GL_TEXTURE_2D, source_tex->texture()->texture());
|
||||
}
|
||||
|
||||
destination_tex->texture(); // DESTINATION TEXTURE
|
||||
|
||||
static OIIO::array_view<OSL::ustring> outputs = {OSL::ustring("Cout")};
|
||||
|
||||
OIIO::ImageBufAlgo::parallel_image_options popt;
|
||||
#if OPENIMAGEIO_VERSION > 10902
|
||||
popt.minitems = 4096;
|
||||
popt.splitdir = OIIO::Split_Tile;
|
||||
popt.recursive = true;
|
||||
#endif
|
||||
|
||||
OIIO::ImageBuf buffer;
|
||||
|
||||
shade_image(*shading_system_,
|
||||
*group.get(),
|
||||
nullptr,
|
||||
buffer,
|
||||
outputs,
|
||||
OSL::ShadePixelCenters,
|
||||
OIIO::ROI(),
|
||||
popt);
|
||||
|
||||
// Update output reference to the last texture we wrote to
|
||||
output_tex = destination_tex;
|
||||
}
|
||||
|
||||
output_params->Push(NodeParam::kTexture, QVariant::fromValue(output_tex));
|
||||
}
|
||||
|
||||
void OSLWorker::TextureToBuffer(const QVariant &tex_in, QByteArray &buffer)
|
||||
{
|
||||
Q_UNUSED(tex_in)
|
||||
Q_UNUSED(buffer)
|
||||
FramePtr frame = tex_in.value<FramePtr>();
|
||||
|
||||
memcpy(buffer.data(), frame->data(), static_cast<size_t>(buffer.size()));
|
||||
}
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
#ifndef OSLWORKER_H
|
||||
#define OSLWORKER_H
|
||||
|
||||
#include <OpenImageIO/imagebufalgo.h>
|
||||
#include <OSL/oslexec.h>
|
||||
|
||||
#include "../videorenderworker.h"
|
||||
#include "oslshadercache.h"
|
||||
|
||||
class OSLWorker : public VideoRenderWorker
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
OSLWorker(VideoRenderFrameCache* frame_cache,
|
||||
OSL::ShadingSystem* shading_system,
|
||||
OSLShaderCache* shader_cache,
|
||||
ColorProcessorCache* color_cache,
|
||||
QObject* parent = nullptr);
|
||||
|
||||
protected:
|
||||
@@ -17,6 +24,13 @@ protected:
|
||||
|
||||
virtual void TextureToBuffer(const QVariant& texture, QByteArray& buffer) override;
|
||||
|
||||
private:
|
||||
OSL::ShadingSystem* shading_system_;
|
||||
|
||||
OSLShaderCache* shader_cache_;
|
||||
|
||||
ColorProcessorCache* color_cache_;
|
||||
|
||||
};
|
||||
|
||||
#endif // OSLWORKER_H
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
bool Has(K key) const {return values_.contains(key);}
|
||||
|
||||
private:
|
||||
QMap<K, V> values_;
|
||||
QHash<K, V> values_;
|
||||
};
|
||||
|
||||
template<class K, class V>
|
||||
@@ -55,7 +55,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
QMap<K, V> values_;
|
||||
QHash<K, V> values_;
|
||||
|
||||
QMutex lock_;
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_path(OpenEXR_INCLUDE_DIRS OpenEXR/OpenEXRConfig.h)
|
||||
find_path(OPENEXR_INCLUDE_PATHS NAMES ImfRgbaFile.h PATH_SUFFIXES OpenEXR)
|
||||
|
||||
file(STRINGS "${OpenEXR_INCLUDE_DIRS}/OpenEXR/OpenEXRConfig.h" OPENEXR_CONFIG_H)
|
||||
|
||||
string(REGEX REPLACE "^.*define OPENEXR_VERSION_MAJOR ([0-9]+).*$" "\\1" OpenEXR_VERSION_MAJOR "${OPENEXR_CONFIG_H}")
|
||||
string(REGEX REPLACE "^.*define OPENEXR_VERSION_MINOR ([0-9]+).*$" "\\1" OpenEXR_VERSION_MINOR "${OPENEXR_CONFIG_H}")
|
||||
set(OpenEXR_LIB_SUFFIX "${OpenEXR_VERSION_MAJOR}_${OpenEXR_VERSION_MINOR}")
|
||||
|
||||
include(SelectLibraryConfigurations)
|
||||
|
||||
if(NOT OpenEXR_BASE_LIBRARY)
|
||||
find_library(OpenEXR_BASE_LIBRARY_RELEASE NAMES IlmImf-${OpenEXR_LIB_SUFFIX})
|
||||
find_library(OpenEXR_BASE_LIBRARY_DEBUG NAMES IlmImf-${OpenEXR_LIB_SUFFIX}_d)
|
||||
select_library_configurations(OpenEXR_BASE)
|
||||
endif()
|
||||
|
||||
if(NOT OpenEXR_UTIL_LIBRARY)
|
||||
find_library(OpenEXR_UTIL_LIBRARY_RELEASE NAMES IlmImfUtil-${OpenEXR_LIB_SUFFIX})
|
||||
find_library(OpenEXR_UTIL_LIBRARY_DEBUG NAMES IlmImfUtil-${OpenEXR_LIB_SUFFIX}_d)
|
||||
select_library_configurations(OpenEXR_UTIL)
|
||||
endif()
|
||||
|
||||
if(NOT OpenEXR_HALF_LIBRARY)
|
||||
find_library(OpenEXR_HALF_LIBRARY_RELEASE NAMES Half-${OpenEXR_LIB_SUFFIX})
|
||||
find_library(OpenEXR_HALF_LIBRARY_DEBUG NAMES Half-${OpenEXR_LIB_SUFFIX}_d)
|
||||
select_library_configurations(OpenEXR_HALF)
|
||||
endif()
|
||||
|
||||
if(NOT OpenEXR_IEX_LIBRARY)
|
||||
find_library(OpenEXR_IEX_LIBRARY_RELEASE NAMES Iex-${OpenEXR_LIB_SUFFIX})
|
||||
find_library(OpenEXR_IEX_LIBRARY_DEBUG NAMES Iex-${OpenEXR_LIB_SUFFIX}_d)
|
||||
select_library_configurations(OpenEXR_IEX)
|
||||
endif()
|
||||
|
||||
if(NOT OpenEXR_MATH_LIBRARY)
|
||||
find_library(OpenEXR_MATH_LIBRARY_RELEASE NAMES Imath-${OpenEXR_LIB_SUFFIX})
|
||||
find_library(OpenEXR_MATH_LIBRARY_DEBUG NAMES Imath-${OpenEXR_LIB_SUFFIX}_d)
|
||||
select_library_configurations(OpenEXR_MATH)
|
||||
endif()
|
||||
|
||||
if(NOT OpenEXR_THREAD_LIBRARY)
|
||||
find_library(OpenEXR_THREAD_LIBRARY_RELEASE NAMES IlmThread-${OpenEXR_LIB_SUFFIX})
|
||||
find_library(OpenEXR_THREAD_LIBRARY_DEBUG NAMES IlmThread-${OpenEXR_LIB_SUFFIX}_d)
|
||||
select_library_configurations(OpenEXR_THREAD)
|
||||
endif()
|
||||
|
||||
if(NOT OpenEXR_IEXMATH_LIBRARY)
|
||||
find_library(OpenEXR_IEXMATH_LIBRARY_RELEASE NAMES IexMath-${OpenEXR_LIB_SUFFIX})
|
||||
find_library(OpenEXR_IEXMATH_LIBRARY_DEBUG NAMES IexMath-${OpenEXR_LIB_SUFFIX}_d)
|
||||
select_library_configurations(OpenEXR_IEXMATH)
|
||||
endif()
|
||||
|
||||
set(OPENEXR_HALF_LIBRARY "${OpenEXR_HALF_LIBRARY}")
|
||||
set(OPENEXR_Half_LIBRARY "${OpenEXR_HALF_LIBRARY}")
|
||||
set(OPENEXR_IEX_LIBRARY "${OpenEXR_IEX_LIBRARY}")
|
||||
set(OPENEXR_Iex_LIBRARY "${OpenEXR_IEX_LIBRARY}")
|
||||
set(OPENEXR_IMATH_LIBRARY "${OpenEXR_MATH_LIBRARY}")
|
||||
set(OPENEXR_ILMIMF_LIBRARY "${OpenEXR_BASE_LIBRARY}")
|
||||
set(OPENEXR_IlmImf_LIBRARY "${OpenEXR_BASE_LIBRARY}")
|
||||
set(OPENEXR_ILMIMFUTIL_LIBRARY "${OpenEXR_UTIL_LIBRARY}")
|
||||
set(OPENEXR_ILMTHREAD_LIBRARY "${OpenEXR_THREAD_LIBRARY}")
|
||||
|
||||
set(OpenEXR_LIBRARY "${OpenEXR_BASE_LIBRARY}")
|
||||
|
||||
set(OpenEXR_LIBRARIES
|
||||
${OpenEXR_LIBRARY}
|
||||
${OpenEXR_MATH_LIBRARY}
|
||||
${OpenEXR_IEXMATH_LIBRARY}
|
||||
${OpenEXR_UTIL_LIBRARY}
|
||||
${OpenEXR_HALF_LIBRARY}
|
||||
${OpenEXR_IEX_LIBRARY}
|
||||
${OpenEXR_THREAD_LIBRARY}
|
||||
)
|
||||
|
||||
set(OPENEXR_LIBRARIES
|
||||
${OPENEXR_HALF_LIBRARY}
|
||||
${OPENEXR_IEX_LIBRARY}
|
||||
${OPENEXR_IMATH_LIBRARY}
|
||||
${OPENEXR_ILMIMF_LIBRARY}
|
||||
${OPENEXR_ILMTHREAD_LIBRARY}
|
||||
)
|
||||
|
||||
set(OpenEXR_INCLUDE_DIR ${OpenEXR_INCLUDE_DIRS})
|
||||
set(OPENEXR_INCLUDE_DIRS ${OpenEXR_INCLUDE_DIRS})
|
||||
set(OPENEXR_INCLUDE_DIR ${OPENEXR_INCLUDE_PATHS})
|
||||
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(OpenEXR REQUIRED_VARS OpenEXR_LIBRARIES OpenEXR_INCLUDE_DIRS)
|
||||
|
||||
if(OpenEXR_FOUND)
|
||||
set(OPENEXR_FOUND 1)
|
||||
endif()
|
||||
Reference in New Issue
Block a user