OpenColorIO: cache multiple shaders instead of just one.
Fixes constant shader and texture rebuilding when doing animation playback with multiple editors that use different view transforms.
This commit is contained in:
@@ -59,13 +59,19 @@ using namespace OCIO_NAMESPACE;
|
|||||||
#include "ocio_impl.h"
|
#include "ocio_impl.h"
|
||||||
|
|
||||||
static const int LUT3D_EDGE_SIZE = 64;
|
static const int LUT3D_EDGE_SIZE = 64;
|
||||||
|
static const int SHADER_CACHE_SIZE = 4;
|
||||||
|
|
||||||
extern "C" char datatoc_gpu_shader_display_transform_glsl[];
|
extern "C" char datatoc_gpu_shader_display_transform_glsl[];
|
||||||
extern "C" char datatoc_gpu_shader_display_transform_vertex_glsl[];
|
extern "C" char datatoc_gpu_shader_display_transform_vertex_glsl[];
|
||||||
|
|
||||||
/* **** OpenGL drawing routines using GLSL for color space transform ***** */
|
/* **** OpenGL drawing routines using GLSL for color space transform ***** */
|
||||||
|
|
||||||
typedef struct OCIO_GLSLDrawState {
|
typedef struct OCIO_GLSLShader {
|
||||||
|
/* Cache ID */
|
||||||
|
std::string lut3dCacheID;
|
||||||
|
std::string shaderCacheID;
|
||||||
|
|
||||||
|
/* LUT */
|
||||||
bool lut3d_texture_allocated; /* boolean flag indicating whether
|
bool lut3d_texture_allocated; /* boolean flag indicating whether
|
||||||
* lut texture is allocated
|
* lut texture is allocated
|
||||||
*/
|
*/
|
||||||
@@ -75,25 +81,29 @@ typedef struct OCIO_GLSLDrawState {
|
|||||||
|
|
||||||
float *lut3d; /* 3D LUT table */
|
float *lut3d; /* 3D LUT table */
|
||||||
|
|
||||||
bool dither_used;
|
/* Dither */
|
||||||
|
bool use_dither;
|
||||||
|
|
||||||
bool curve_mapping_used;
|
/* Curve Mapping */
|
||||||
|
bool use_curve_mapping;
|
||||||
bool curve_mapping_texture_allocated;
|
bool curve_mapping_texture_allocated;
|
||||||
bool curve_mapping_texture_valid;
|
bool curve_mapping_texture_valid;
|
||||||
GLuint curve_mapping_texture;
|
GLuint curve_mapping_texture;
|
||||||
size_t curve_mapping_cache_id;
|
size_t curve_mapping_cache_id;
|
||||||
|
|
||||||
bool predivide_used;
|
/* Alpha Predivide */
|
||||||
|
bool use_predivide;
|
||||||
/* Cache */
|
|
||||||
std::string lut3dcacheid;
|
|
||||||
std::string shadercacheid;
|
|
||||||
|
|
||||||
/* GLSL stuff */
|
/* GLSL stuff */
|
||||||
GLuint ocio_shader;
|
GLuint ocio_shader;
|
||||||
GLuint vert_shader;
|
GLuint vert_shader;
|
||||||
GLuint program;
|
GLuint program;
|
||||||
Gwn_ShaderInterface *shader_interface;
|
Gwn_ShaderInterface *shader_interface;
|
||||||
|
} GLSLDrawState;
|
||||||
|
|
||||||
|
typedef struct OCIO_GLSLDrawState {
|
||||||
|
/* Shader Cache */
|
||||||
|
OCIO_GLSLShader *shader_cache[SHADER_CACHE_SIZE];
|
||||||
|
|
||||||
/* Previous OpenGL state. */
|
/* Previous OpenGL state. */
|
||||||
GLint last_texture, last_texture_unit;
|
GLint last_texture, last_texture_unit;
|
||||||
@@ -150,33 +160,24 @@ static GLuint linkShaders(GLuint ocio_shader, GLuint vert_shader)
|
|||||||
|
|
||||||
static OCIO_GLSLDrawState *allocateOpenGLState(void)
|
static OCIO_GLSLDrawState *allocateOpenGLState(void)
|
||||||
{
|
{
|
||||||
OCIO_GLSLDrawState *state;
|
return (OCIO_GLSLDrawState *) MEM_callocN(sizeof(OCIO_GLSLDrawState),
|
||||||
|
"OCIO OpenGL State struct");
|
||||||
/* Allocate memory for state. */
|
|
||||||
state = (OCIO_GLSLDrawState *) MEM_callocN(sizeof(OCIO_GLSLDrawState),
|
|
||||||
"OCIO OpenGL State struct");
|
|
||||||
|
|
||||||
/* Call constructors on new memory. */
|
|
||||||
new (&state->lut3dcacheid) std::string("");
|
|
||||||
new (&state->shadercacheid) std::string("");
|
|
||||||
|
|
||||||
return state;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure LUT texture and array are allocated */
|
/* Ensure LUT texture and array are allocated */
|
||||||
static bool ensureLUT3DAllocated(OCIO_GLSLDrawState *state)
|
static bool ensureLUT3DAllocated(OCIO_GLSLShader *shader)
|
||||||
{
|
{
|
||||||
int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE;
|
int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE;
|
||||||
|
|
||||||
if (state->lut3d_texture_allocated)
|
if (shader->lut3d_texture_allocated)
|
||||||
return state->lut3d_texture_valid;
|
return shader->lut3d_texture_valid;
|
||||||
|
|
||||||
glGenTextures(1, &state->lut3d_texture);
|
glGenTextures(1, &shader->lut3d_texture);
|
||||||
|
|
||||||
state->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT");
|
shader->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT");
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
|
glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
|
||||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
@@ -188,27 +189,27 @@ static bool ensureLUT3DAllocated(OCIO_GLSLDrawState *state)
|
|||||||
|
|
||||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB,
|
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB,
|
||||||
LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
|
LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
|
||||||
0, GL_RGB, GL_FLOAT, state->lut3d);
|
0, GL_RGB, GL_FLOAT, shader->lut3d);
|
||||||
|
|
||||||
state->lut3d_texture_allocated = true;
|
shader->lut3d_texture_allocated = true;
|
||||||
|
|
||||||
/* GL_RGB16F_ARB could be not supported at some drivers
|
/* GL_RGB16F_ARB could be not supported at some drivers
|
||||||
* in this case we could not use GLSL display
|
* in this case we could not use GLSL display
|
||||||
*/
|
*/
|
||||||
state->lut3d_texture_valid = glGetError() == GL_NO_ERROR;
|
shader->lut3d_texture_valid = glGetError() == GL_NO_ERROR;
|
||||||
|
|
||||||
return state->lut3d_texture_valid;
|
return shader->lut3d_texture_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ensureCurveMappingAllocated(OCIO_GLSLDrawState *state, OCIO_CurveMappingSettings *curve_mapping_settings)
|
static bool ensureCurveMappingAllocated(OCIO_GLSLShader *shader, OCIO_CurveMappingSettings *curve_mapping_settings)
|
||||||
{
|
{
|
||||||
if (state->curve_mapping_texture_allocated)
|
if (shader->curve_mapping_texture_allocated)
|
||||||
return state->curve_mapping_texture_valid;
|
return shader->curve_mapping_texture_valid;
|
||||||
|
|
||||||
glGenTextures(1, &state->curve_mapping_texture);
|
glGenTextures(1, &shader->curve_mapping_texture);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_1D, state->curve_mapping_texture);
|
glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
|
||||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
@@ -221,16 +222,51 @@ static bool ensureCurveMappingAllocated(OCIO_GLSLDrawState *state, OCIO_CurveMap
|
|||||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16F, curve_mapping_settings->lut_size,
|
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16F, curve_mapping_settings->lut_size,
|
||||||
0, GL_RGBA, GL_FLOAT, curve_mapping_settings->lut);
|
0, GL_RGBA, GL_FLOAT, curve_mapping_settings->lut);
|
||||||
|
|
||||||
state->curve_mapping_texture_allocated = true;
|
shader->curve_mapping_texture_allocated = true;
|
||||||
|
|
||||||
/* GL_RGB16F_ARB could be not supported at some drivers
|
/* GL_RGB16F_ARB could be not supported at some drivers
|
||||||
* in this case we could not use GLSL display
|
* in this case we could not use GLSL display
|
||||||
*/
|
*/
|
||||||
state->curve_mapping_texture_valid = glGetError() == GL_NO_ERROR;
|
shader->curve_mapping_texture_valid = glGetError() == GL_NO_ERROR;
|
||||||
|
|
||||||
return state->curve_mapping_texture_valid;
|
return shader->curve_mapping_texture_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void freeGLSLShader(OCIO_GLSLShader *shader)
|
||||||
|
{
|
||||||
|
if (shader->curve_mapping_texture_allocated) {
|
||||||
|
glDeleteTextures(1, &shader->curve_mapping_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shader->lut3d_texture_allocated) {
|
||||||
|
glDeleteTextures(1, &shader->lut3d_texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shader->lut3d) {
|
||||||
|
MEM_freeN(shader->lut3d);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shader->program) {
|
||||||
|
glDeleteProgram(shader->program);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shader->shader_interface) {
|
||||||
|
GWN_shaderinterface_discard(shader->shader_interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shader->ocio_shader) {
|
||||||
|
glDeleteShader(shader->ocio_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
shader->lut3dCacheID.~string();
|
||||||
|
shader->shaderCacheID.~string();
|
||||||
|
|
||||||
|
MEM_freeN(shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Detect if we can support GLSL drawing */
|
/* Detect if we can support GLSL drawing */
|
||||||
bool OCIOImpl::supportGLSLDraw()
|
bool OCIOImpl::supportGLSLDraw()
|
||||||
{
|
{
|
||||||
@@ -265,135 +301,154 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc
|
|||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &state->last_texture);
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &state->last_texture);
|
||||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit);
|
glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit);
|
||||||
|
|
||||||
if (!ensureLUT3DAllocated(state)) {
|
/* Compute cache IDs. */
|
||||||
glActiveTexture(state->last_texture_unit);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, state->last_texture);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_curve_mapping) {
|
|
||||||
if (!ensureCurveMappingAllocated(state, curve_mapping_settings)) {
|
|
||||||
glActiveTexture(state->last_texture_unit);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, state->last_texture);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (state->curve_mapping_texture_allocated) {
|
|
||||||
glDeleteTextures(1, &state->curve_mapping_texture);
|
|
||||||
state->curve_mapping_texture_allocated = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Step 1: Create a GPU Shader Description */
|
|
||||||
GpuShaderDesc shaderDesc;
|
GpuShaderDesc shaderDesc;
|
||||||
shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_3);
|
shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_3);
|
||||||
shaderDesc.setFunctionName("OCIODisplay");
|
shaderDesc.setFunctionName("OCIODisplay");
|
||||||
shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);
|
shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);
|
||||||
|
|
||||||
if (use_curve_mapping) {
|
std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc);
|
||||||
if (state->curve_mapping_cache_id != curve_mapping_settings->cache_id) {
|
std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc);
|
||||||
|
|
||||||
|
/* Find matching cached shader. */
|
||||||
|
OCIO_GLSLShader *shader = NULL;
|
||||||
|
for (int i = 0; i < SHADER_CACHE_SIZE; i++) {
|
||||||
|
OCIO_GLSLShader *cached_shader = state->shader_cache[i];
|
||||||
|
if (cached_shader == NULL) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cached_shader->lut3dCacheID == lut3dCacheID &&
|
||||||
|
cached_shader->shaderCacheID == shaderCacheID &&
|
||||||
|
cached_shader->use_predivide == use_predivide &&
|
||||||
|
cached_shader->use_curve_mapping == use_curve_mapping &&
|
||||||
|
cached_shader->use_dither == use_dither)
|
||||||
|
{
|
||||||
|
/* LRU cache, so move to front. */
|
||||||
|
for (int j = i; j > 0; j--) {
|
||||||
|
state->shader_cache[j] = state->shader_cache[j - 1];
|
||||||
|
}
|
||||||
|
state->shader_cache[0] = cached_shader;
|
||||||
|
|
||||||
|
shader = cached_shader;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shader == NULL) {
|
||||||
|
/* LRU cache, shift other items back so we can insert at the front. */
|
||||||
|
OCIO_GLSLShader *last_shader = state->shader_cache[SHADER_CACHE_SIZE - 1];
|
||||||
|
if (last_shader) {
|
||||||
|
freeGLSLShader(last_shader);
|
||||||
|
}
|
||||||
|
for (int j = SHADER_CACHE_SIZE - 1; j > 0; j--) {
|
||||||
|
state->shader_cache[j] = state->shader_cache[j - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate memory for shader. */
|
||||||
|
shader = (OCIO_GLSLShader *) MEM_callocN(sizeof(OCIO_GLSLShader),
|
||||||
|
"OCIO GLSL Shader");
|
||||||
|
state->shader_cache[0] = shader;
|
||||||
|
|
||||||
|
new (&shader->lut3dCacheID) std::string();
|
||||||
|
new (&shader->shaderCacheID) std::string();
|
||||||
|
|
||||||
|
shader->lut3dCacheID = lut3dCacheID;
|
||||||
|
shader->shaderCacheID = shaderCacheID;
|
||||||
|
shader->use_curve_mapping = use_curve_mapping;
|
||||||
|
shader->use_dither = use_dither;
|
||||||
|
shader->use_predivide = use_predivide;
|
||||||
|
|
||||||
|
bool valid = true;
|
||||||
|
|
||||||
|
/* Compute 3D LUT. */
|
||||||
|
if (valid && ensureLUT3DAllocated(shader)) {
|
||||||
|
ocio_processor->getGpuLut3D(shader->lut3d, shaderDesc);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
|
||||||
|
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0,
|
||||||
|
LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
|
||||||
|
GL_RGB, GL_FLOAT, shader->lut3d);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Allocate curve mapping texture. */
|
||||||
|
if (valid && use_curve_mapping) {
|
||||||
|
if (!ensureCurveMappingAllocated(shader, curve_mapping_settings)) {
|
||||||
|
valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid) {
|
||||||
|
/* Vertex shader */
|
||||||
|
std::ostringstream osv;
|
||||||
|
|
||||||
|
osv << "#version 330\n";
|
||||||
|
osv << datatoc_gpu_shader_display_transform_vertex_glsl;
|
||||||
|
|
||||||
|
shader->vert_shader = compileShaderText(GL_VERTEX_SHADER, osv.str().c_str());
|
||||||
|
|
||||||
|
/* Fragment shader */
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
os << "#version 330\n";
|
||||||
|
|
||||||
|
/* Work around OpenColorIO not supporting latest GLSL yet. */
|
||||||
|
os << "#define texture2D texture\n";
|
||||||
|
os << "#define texture3D texture\n";
|
||||||
|
|
||||||
|
if (use_predivide) {
|
||||||
|
os << "#define USE_PREDIVIDE\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_dither) {
|
||||||
|
os << "#define USE_DITHER\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_curve_mapping) {
|
||||||
|
os << "#define USE_CURVE_MAPPING\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
os << ocio_processor->getGpuShaderText(shaderDesc) << "\n";
|
||||||
|
os << datatoc_gpu_shader_display_transform_glsl;
|
||||||
|
|
||||||
|
shader->ocio_shader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
|
||||||
|
|
||||||
|
/* Program */
|
||||||
|
if (shader->ocio_shader && shader->vert_shader) {
|
||||||
|
shader->program = linkShaders(shader->ocio_shader, shader->vert_shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shader->program) {
|
||||||
|
if (shader->shader_interface) {
|
||||||
|
GWN_shaderinterface_discard(shader->shader_interface);
|
||||||
|
}
|
||||||
|
shader->shader_interface = GWN_shaderinterface_create(shader->program);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update curve mapping texture. */
|
||||||
|
if (use_curve_mapping && shader->curve_mapping_texture_allocated) {
|
||||||
|
if (shader->curve_mapping_cache_id != curve_mapping_settings->cache_id) {
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_1D, state->curve_mapping_texture);
|
glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
|
||||||
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, curve_mapping_settings->lut_size,
|
glTexSubImage1D(GL_TEXTURE_1D, 0, 0, curve_mapping_settings->lut_size,
|
||||||
GL_RGBA, GL_FLOAT, curve_mapping_settings->lut);
|
GL_RGBA, GL_FLOAT, curve_mapping_settings->lut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Step 2: Compute the 3D LUT */
|
/* Bind Shader. */
|
||||||
std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc);
|
if (shader->program) {
|
||||||
if (lut3dCacheID != state->lut3dcacheid) {
|
|
||||||
state->lut3dcacheid = lut3dCacheID;
|
|
||||||
ocio_processor->getGpuLut3D(state->lut3d, shaderDesc);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
|
glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture);
|
||||||
glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0,
|
|
||||||
LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
|
|
||||||
GL_RGB, GL_FLOAT, state->lut3d);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Step 3: Compute the Shader */
|
|
||||||
std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc);
|
|
||||||
if (state->program == 0 ||
|
|
||||||
shaderCacheID != state->shadercacheid ||
|
|
||||||
use_predivide != state->predivide_used ||
|
|
||||||
use_curve_mapping != state->curve_mapping_used ||
|
|
||||||
use_dither != state->dither_used)
|
|
||||||
{
|
|
||||||
state->shadercacheid = shaderCacheID;
|
|
||||||
|
|
||||||
if (state->program) {
|
|
||||||
glDeleteProgram(state->program);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->ocio_shader) {
|
|
||||||
glDeleteShader(state->ocio_shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->vert_shader) {
|
|
||||||
glDeleteShader(state->vert_shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Vertex shader */
|
|
||||||
std::ostringstream osv;
|
|
||||||
|
|
||||||
osv << "#version 330\n";
|
|
||||||
osv << datatoc_gpu_shader_display_transform_vertex_glsl;
|
|
||||||
|
|
||||||
state->vert_shader = compileShaderText(GL_VERTEX_SHADER, osv.str().c_str());
|
|
||||||
|
|
||||||
/* Fragment shader */
|
|
||||||
std::ostringstream os;
|
|
||||||
|
|
||||||
os << "#version 330\n";
|
|
||||||
|
|
||||||
/* Work around OpenColorIO not supporting latest GLSL yet. */
|
|
||||||
os << "#define texture2D texture\n";
|
|
||||||
os << "#define texture3D texture\n";
|
|
||||||
|
|
||||||
if (use_predivide) {
|
|
||||||
os << "#define USE_PREDIVIDE\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_dither) {
|
|
||||||
os << "#define USE_DITHER\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_curve_mapping) {
|
|
||||||
os << "#define USE_CURVE_MAPPING\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
os << ocio_processor->getGpuShaderText(shaderDesc) << "\n";
|
|
||||||
os << datatoc_gpu_shader_display_transform_glsl;
|
|
||||||
|
|
||||||
state->ocio_shader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
|
|
||||||
|
|
||||||
if (state->ocio_shader && state->vert_shader) {
|
|
||||||
state->program = linkShaders(state->ocio_shader, state->vert_shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->program) {
|
|
||||||
if (state->shader_interface) {
|
|
||||||
GWN_shaderinterface_discard(state->shader_interface);
|
|
||||||
}
|
|
||||||
state->shader_interface = GWN_shaderinterface_create(state->program);
|
|
||||||
}
|
|
||||||
|
|
||||||
state->curve_mapping_used = use_curve_mapping;
|
|
||||||
state->dither_used = use_dither;
|
|
||||||
state->predivide_used = use_predivide;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state->program) {
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
|
|
||||||
|
|
||||||
if (use_curve_mapping) {
|
if (use_curve_mapping) {
|
||||||
glActiveTexture(GL_TEXTURE2);
|
glActiveTexture(GL_TEXTURE2);
|
||||||
glBindTexture(GL_TEXTURE_1D, state->curve_mapping_texture);
|
glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
@@ -409,7 +464,7 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc
|
|||||||
Gwn_VertFormat *format = immVertexFormat();
|
Gwn_VertFormat *format = immVertexFormat();
|
||||||
GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
||||||
GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
GWN_vertformat_attr_add(format, "texCoord", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
||||||
immBindProgram(state->program, state->shader_interface);
|
immBindProgram(shader->program, shader->shader_interface);
|
||||||
|
|
||||||
immUniform1i("image_texture", 0);
|
immUniform1i("image_texture", 0);
|
||||||
immUniform1i("lut3d_texture", 1);
|
immUniform1i("lut3d_texture", 1);
|
||||||
@@ -453,27 +508,13 @@ void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state)
|
|||||||
immUnbindProgram();
|
immUnbindProgram();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state)
|
void OCIOImpl::freeGLState(OCIO_GLSLDrawState *state)
|
||||||
{
|
{
|
||||||
using std::string;
|
for (int i = 0; i < SHADER_CACHE_SIZE; i++) {
|
||||||
|
if (state->shader_cache[i]) {
|
||||||
if (state->lut3d_texture_allocated)
|
freeGLSLShader(state->shader_cache[i]);
|
||||||
glDeleteTextures(1, &state->lut3d_texture);
|
}
|
||||||
|
}
|
||||||
if (state->lut3d)
|
|
||||||
MEM_freeN(state->lut3d);
|
|
||||||
|
|
||||||
if (state->program)
|
|
||||||
glDeleteProgram(state->program);
|
|
||||||
|
|
||||||
if (state->shader_interface)
|
|
||||||
GWN_shaderinterface_discard(state->shader_interface);
|
|
||||||
|
|
||||||
if (state->ocio_shader)
|
|
||||||
glDeleteShader(state->ocio_shader);
|
|
||||||
|
|
||||||
state->lut3dcacheid.~string();
|
|
||||||
state->shadercacheid.~string();
|
|
||||||
|
|
||||||
MEM_freeN(state);
|
MEM_freeN(state);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user