From e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Apr 2019 06:17:24 +0200 Subject: ClangFormat: apply to source, most of intern Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat --- intern/opencolorio/ocio_impl_glsl.cc | 801 ++++++++++++++++++----------------- 1 file changed, 414 insertions(+), 387 deletions(-) (limited to 'intern/opencolorio/ocio_impl_glsl.cc') diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc index cf41d0a4983..4d0908eafd5 100644 --- a/intern/opencolorio/ocio_impl_glsl.cc +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -64,211 +64,224 @@ extern "C" char datatoc_gpu_shader_display_transform_vertex_glsl[]; /* **** OpenGL drawing routines using GLSL for color space transform ***** */ typedef struct OCIO_GLSLShader { - /* Cache ID */ - std::string lut3dCacheID; - std::string shaderCacheID; - - /* LUT */ - bool lut3d_texture_allocated; /* boolean flag indicating whether - * lut texture is allocated - */ - bool lut3d_texture_valid; - - GLuint lut3d_texture; /* OGL texture ID for 3D LUT */ - - float *lut3d; /* 3D LUT table */ - - /* Dither */ - bool use_dither; - - /* Curve Mapping */ - bool use_curve_mapping; - bool curve_mapping_texture_allocated; - bool curve_mapping_texture_valid; - GLuint curve_mapping_texture; - size_t curve_mapping_cache_id; - - /* Alpha Predivide */ - bool use_predivide; - - /* GLSL stuff */ - GLuint ocio_shader; - GLuint vert_shader; - GLuint program; - GPUShaderInterface *shader_interface; + /* Cache ID */ + std::string lut3dCacheID; + std::string shaderCacheID; + + /* LUT */ + bool lut3d_texture_allocated; /* boolean flag indicating whether + * lut texture is allocated + */ + bool lut3d_texture_valid; + + GLuint lut3d_texture; /* OGL texture ID for 3D LUT */ + + float *lut3d; /* 3D LUT table */ + + /* Dither */ + bool use_dither; + + /* Curve Mapping */ + bool use_curve_mapping; + bool curve_mapping_texture_allocated; + bool curve_mapping_texture_valid; + GLuint curve_mapping_texture; + size_t curve_mapping_cache_id; + + /* Alpha Predivide */ + bool use_predivide; + + /* GLSL stuff */ + GLuint ocio_shader; + GLuint vert_shader; + GLuint program; + GPUShaderInterface *shader_interface; } GLSLDrawState; typedef struct OCIO_GLSLDrawState { - /* Shader Cache */ - OCIO_GLSLShader *shader_cache[SHADER_CACHE_SIZE]; + /* Shader Cache */ + OCIO_GLSLShader *shader_cache[SHADER_CACHE_SIZE]; - /* Previous OpenGL state. */ - GLint last_texture, last_texture_unit; + /* Previous OpenGL state. */ + GLint last_texture, last_texture_unit; } OCIO_GLSLDrawState; static GLuint compileShaderText(GLenum shaderType, const char *text) { - GLuint shader; - GLint stat; - - shader = glCreateShader(shaderType); - glShaderSource(shader, 1, (const GLchar **) &text, NULL); - glCompileShader(shader); - glGetShaderiv(shader, GL_COMPILE_STATUS, &stat); - - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetShaderInfoLog(shader, 1000, &len, log); - fprintf(stderr, "Shader compile error:\n%s\n", log); - return 0; - } - - return shader; + GLuint shader; + GLint stat; + + shader = glCreateShader(shaderType); + glShaderSource(shader, 1, (const GLchar **)&text, NULL); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &stat); + + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog(shader, 1000, &len, log); + fprintf(stderr, "Shader compile error:\n%s\n", log); + return 0; + } + + return shader; } static GLuint linkShaders(GLuint ocio_shader, GLuint vert_shader) { - if (!ocio_shader || !vert_shader) - return 0; - - GLuint program = glCreateProgram(); - - glAttachShader(program, ocio_shader); - glAttachShader(program, vert_shader); - - glLinkProgram(program); - - /* check link */ - { - GLint stat; - glGetProgramiv(program, GL_LINK_STATUS, &stat); - if (!stat) { - GLchar log[1000]; - GLsizei len; - glGetProgramInfoLog(program, 1000, &len, log); - fprintf(stderr, "Shader link error:\n%s\n", log); - return 0; - } - } - - return program; + if (!ocio_shader || !vert_shader) + return 0; + + GLuint program = glCreateProgram(); + + glAttachShader(program, ocio_shader); + glAttachShader(program, vert_shader); + + glLinkProgram(program); + + /* check link */ + { + GLint stat; + glGetProgramiv(program, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog(program, 1000, &len, log); + fprintf(stderr, "Shader link error:\n%s\n", log); + return 0; + } + } + + return program; } static OCIO_GLSLDrawState *allocateOpenGLState(void) { - return (OCIO_GLSLDrawState *) MEM_callocN(sizeof(OCIO_GLSLDrawState), - "OCIO OpenGL State struct"); + return (OCIO_GLSLDrawState *)MEM_callocN(sizeof(OCIO_GLSLDrawState), "OCIO OpenGL State struct"); } /* Ensure LUT texture and array are allocated */ static bool ensureLUT3DAllocated(OCIO_GLSLShader *shader) { - int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE; - - if (shader->lut3d_texture_allocated) - return shader->lut3d_texture_valid; - - glGenTextures(1, &shader->lut3d_texture); - - shader->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT"); - - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture); - 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_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - /* clean glError buffer */ - while (glGetError() != GL_NO_ERROR) {} - - glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB, - LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, - 0, GL_RGB, GL_FLOAT, shader->lut3d); - - shader->lut3d_texture_allocated = true; - - /* GL_RGB16F_ARB could be not supported at some drivers - * in this case we could not use GLSL display - */ - shader->lut3d_texture_valid = glGetError() == GL_NO_ERROR; - - return shader->lut3d_texture_valid; + int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE; + + if (shader->lut3d_texture_allocated) + return shader->lut3d_texture_valid; + + glGenTextures(1, &shader->lut3d_texture); + + shader->lut3d = (float *)MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT"); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture); + 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_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + /* clean glError buffer */ + while (glGetError() != GL_NO_ERROR) { + } + + glTexImage3D(GL_TEXTURE_3D, + 0, + GL_RGB16F_ARB, + LUT3D_EDGE_SIZE, + LUT3D_EDGE_SIZE, + LUT3D_EDGE_SIZE, + 0, + GL_RGB, + GL_FLOAT, + shader->lut3d); + + shader->lut3d_texture_allocated = true; + + /* GL_RGB16F_ARB could be not supported at some drivers + * in this case we could not use GLSL display + */ + shader->lut3d_texture_valid = glGetError() == GL_NO_ERROR; + + return shader->lut3d_texture_valid; } -static bool ensureCurveMappingAllocated(OCIO_GLSLShader *shader, OCIO_CurveMappingSettings *curve_mapping_settings) +static bool ensureCurveMappingAllocated(OCIO_GLSLShader *shader, + OCIO_CurveMappingSettings *curve_mapping_settings) { - if (shader->curve_mapping_texture_allocated) - return shader->curve_mapping_texture_valid; - - glGenTextures(1, &shader->curve_mapping_texture); - - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture); - 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_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - /* clean glError buffer */ - while (glGetError() != GL_NO_ERROR) {} - - glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA16F, curve_mapping_settings->lut_size, - 0, GL_RGBA, GL_FLOAT, curve_mapping_settings->lut); - - shader->curve_mapping_texture_allocated = true; - - /* GL_RGB16F_ARB could be not supported at some drivers - * in this case we could not use GLSL display - */ - shader->curve_mapping_texture_valid = glGetError() == GL_NO_ERROR; - - return shader->curve_mapping_texture_valid; + if (shader->curve_mapping_texture_allocated) + return shader->curve_mapping_texture_valid; + + glGenTextures(1, &shader->curve_mapping_texture); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture); + 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_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + /* clean glError buffer */ + while (glGetError() != GL_NO_ERROR) { + } + + glTexImage1D(GL_TEXTURE_1D, + 0, + GL_RGBA16F, + curve_mapping_settings->lut_size, + 0, + GL_RGBA, + GL_FLOAT, + curve_mapping_settings->lut); + + shader->curve_mapping_texture_allocated = true; + + /* GL_RGB16F_ARB could be not supported at some drivers + * in this case we could not use GLSL display + */ + shader->curve_mapping_texture_valid = glGetError() == GL_NO_ERROR; + + 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->curve_mapping_texture_allocated) { + glDeleteTextures(1, &shader->curve_mapping_texture); + } - if (shader->lut3d_texture_allocated) { - glDeleteTextures(1, &shader->lut3d_texture); - } + if (shader->lut3d_texture_allocated) { + glDeleteTextures(1, &shader->lut3d_texture); + } - if (shader->lut3d) { - MEM_freeN(shader->lut3d); - } + if (shader->lut3d) { + MEM_freeN(shader->lut3d); + } - if (shader->program) { - glDeleteProgram(shader->program); - } + if (shader->program) { + glDeleteProgram(shader->program); + } - if (shader->shader_interface) { - GPU_shaderinterface_discard(shader->shader_interface); - } + if (shader->shader_interface) { + GPU_shaderinterface_discard(shader->shader_interface); + } - if (shader->ocio_shader) { - glDeleteShader(shader->ocio_shader); - } + if (shader->ocio_shader) { + glDeleteShader(shader->ocio_shader); + } - using std::string; - shader->lut3dCacheID.~string(); - shader->shaderCacheID.~string(); + using std::string; + shader->lut3dCacheID.~string(); + shader->shaderCacheID.~string(); - MEM_freeN(shader); + MEM_freeN(shader); } - - /* Detect if we can support GLSL drawing */ bool OCIOImpl::supportGLSLDraw() { - /* uses GL_RGB16F_ARB */ - return GLEW_VERSION_3_0 || GLEW_ARB_texture_float; + /* uses GL_RGB16F_ARB */ + return GLEW_VERSION_3_0 || GLEW_ARB_texture_float; } /** @@ -281,237 +294,251 @@ bool OCIOImpl::supportGLSLDraw() * When all drawing is finished, finishGLSLDraw shall be called to * restore OpenGL context to it's pre-GLSL draw state. */ -bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, +bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, + OCIO_ConstProcessorRcPtr *processor, OCIO_CurveMappingSettings *curve_mapping_settings, - float dither, bool use_predivide) + float dither, + bool use_predivide) { - ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor; - bool use_curve_mapping = curve_mapping_settings != NULL; - bool use_dither = dither > std::numeric_limits::epsilon(); - - /* Create state if needed. */ - OCIO_GLSLDrawState *state; - if (!*state_r) - *state_r = allocateOpenGLState(); - state = *state_r; - - glGetIntegerv(GL_TEXTURE_BINDING_2D, &state->last_texture); - glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit); - - /* Compute cache IDs. */ - GpuShaderDesc shaderDesc; - shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_3); - shaderDesc.setFunctionName("OCIODisplay"); - shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE); - - std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc); - 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) { - GPU_shaderinterface_discard(shader->shader_interface); - } - shader->shader_interface = GPU_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); - glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture); - glTexSubImage1D(GL_TEXTURE_1D, 0, 0, curve_mapping_settings->lut_size, - GL_RGBA, GL_FLOAT, curve_mapping_settings->lut); - } - } - - /* Bind Shader. */ - if (shader->program) { - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture); - - if (use_curve_mapping) { - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture); - } - - glActiveTexture(GL_TEXTURE0); - - /* IMM needs vertex format even if we don't draw with it. - * - * NOTE: The only reason why it's here is because of Cycles viewport. - * All other areas are managing their own vertex formats. - * Doing it here is probably harmless, but kind of stupid. - * - * TODO(sergey): Look into some nicer solution. - */ - GPUVertFormat *format = immVertexFormat(); - GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); - immBindProgram(shader->program, shader->shader_interface); - - immUniform1i("image_texture", 0); - immUniform1i("lut3d_texture", 1); - - if (use_dither) { - immUniform1f("dither", dither); - } - - if (use_curve_mapping) { - immUniform1i("curve_mapping_texture", 2); - immUniform1i("curve_mapping_lut_size", curve_mapping_settings->lut_size); - immUniform4iv("use_curve_mapping_extend_extrapolate", curve_mapping_settings->use_extend_extrapolate); - immUniform4fv("curve_mapping_mintable", curve_mapping_settings->mintable); - immUniform4fv("curve_mapping_range", curve_mapping_settings->range); - immUniform4fv("curve_mapping_ext_in_x", curve_mapping_settings->ext_in_x); - immUniform4fv("curve_mapping_ext_in_y", curve_mapping_settings->ext_in_y); - immUniform4fv("curve_mapping_ext_out_x", curve_mapping_settings->ext_out_x); - immUniform4fv("curve_mapping_ext_out_y", curve_mapping_settings->ext_out_y); - immUniform4fv("curve_mapping_first_x", curve_mapping_settings->first_x); - immUniform4fv("curve_mapping_first_y", curve_mapping_settings->first_y); - immUniform4fv("curve_mapping_last_x", curve_mapping_settings->last_x); - immUniform4fv("curve_mapping_last_y", curve_mapping_settings->last_y); - immUniform3fv("curve_mapping_black", curve_mapping_settings->black); - immUniform3fv("curve_mapping_bwmul", curve_mapping_settings->bwmul); - } - - return true; - } - else { - glActiveTexture(state->last_texture_unit); - glBindTexture(GL_TEXTURE_2D, state->last_texture); - - return false; - } + ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *)processor; + bool use_curve_mapping = curve_mapping_settings != NULL; + bool use_dither = dither > std::numeric_limits::epsilon(); + + /* Create state if needed. */ + OCIO_GLSLDrawState *state; + if (!*state_r) + *state_r = allocateOpenGLState(); + state = *state_r; + + glGetIntegerv(GL_TEXTURE_BINDING_2D, &state->last_texture); + glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit); + + /* Compute cache IDs. */ + GpuShaderDesc shaderDesc; + shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_3); + shaderDesc.setFunctionName("OCIODisplay"); + shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE); + + std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc); + 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) { + GPU_shaderinterface_discard(shader->shader_interface); + } + shader->shader_interface = GPU_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); + glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture); + glTexSubImage1D(GL_TEXTURE_1D, + 0, + 0, + curve_mapping_settings->lut_size, + GL_RGBA, + GL_FLOAT, + curve_mapping_settings->lut); + } + } + + /* Bind Shader. */ + if (shader->program) { + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, shader->lut3d_texture); + + if (use_curve_mapping) { + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_1D, shader->curve_mapping_texture); + } + + glActiveTexture(GL_TEXTURE0); + + /* IMM needs vertex format even if we don't draw with it. + * + * NOTE: The only reason why it's here is because of Cycles viewport. + * All other areas are managing their own vertex formats. + * Doing it here is probably harmless, but kind of stupid. + * + * TODO(sergey): Look into some nicer solution. + */ + GPUVertFormat *format = immVertexFormat(); + GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + GPU_vertformat_attr_add(format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT); + immBindProgram(shader->program, shader->shader_interface); + + immUniform1i("image_texture", 0); + immUniform1i("lut3d_texture", 1); + + if (use_dither) { + immUniform1f("dither", dither); + } + + if (use_curve_mapping) { + immUniform1i("curve_mapping_texture", 2); + immUniform1i("curve_mapping_lut_size", curve_mapping_settings->lut_size); + immUniform4iv("use_curve_mapping_extend_extrapolate", + curve_mapping_settings->use_extend_extrapolate); + immUniform4fv("curve_mapping_mintable", curve_mapping_settings->mintable); + immUniform4fv("curve_mapping_range", curve_mapping_settings->range); + immUniform4fv("curve_mapping_ext_in_x", curve_mapping_settings->ext_in_x); + immUniform4fv("curve_mapping_ext_in_y", curve_mapping_settings->ext_in_y); + immUniform4fv("curve_mapping_ext_out_x", curve_mapping_settings->ext_out_x); + immUniform4fv("curve_mapping_ext_out_y", curve_mapping_settings->ext_out_y); + immUniform4fv("curve_mapping_first_x", curve_mapping_settings->first_x); + immUniform4fv("curve_mapping_first_y", curve_mapping_settings->first_y); + immUniform4fv("curve_mapping_last_x", curve_mapping_settings->last_x); + immUniform4fv("curve_mapping_last_y", curve_mapping_settings->last_y); + immUniform3fv("curve_mapping_black", curve_mapping_settings->black); + immUniform3fv("curve_mapping_bwmul", curve_mapping_settings->bwmul); + } + + return true; + } + else { + glActiveTexture(state->last_texture_unit); + glBindTexture(GL_TEXTURE_2D, state->last_texture); + + return false; + } } void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state) { - glActiveTexture(state->last_texture_unit); - glBindTexture(GL_TEXTURE_2D, state->last_texture); - immUnbindProgram(); + glActiveTexture(state->last_texture_unit); + glBindTexture(GL_TEXTURE_2D, state->last_texture); + immUnbindProgram(); } void OCIOImpl::freeGLState(OCIO_GLSLDrawState *state) { - for (int i = 0; i < SHADER_CACHE_SIZE; i++) { - if (state->shader_cache[i]) { - freeGLSLShader(state->shader_cache[i]); - } - } + for (int i = 0; i < SHADER_CACHE_SIZE; i++) { + if (state->shader_cache[i]) { + freeGLSLShader(state->shader_cache[i]); + } + } - MEM_freeN(state); + MEM_freeN(state); } -- cgit v1.2.3