Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/opencolorio/CMakeLists.txt1
-rw-r--r--intern/opencolorio/SConscript1
-rw-r--r--intern/opencolorio/fallback_impl.cc12
-rw-r--r--intern/opencolorio/ocio_capi.cc15
-rw-r--r--intern/opencolorio/ocio_capi.h6
-rw-r--r--intern/opencolorio/ocio_impl.cc235
-rw-r--r--intern/opencolorio/ocio_impl.h12
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc274
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/editors/include/ED_clip.h7
-rw-r--r--source/blender/editors/screen/glutil.c9
-rw-r--r--source/blender/editors/space_clip/clip_draw.c113
-rw-r--r--source/blender/editors/space_clip/clip_editor.c161
-rw-r--r--source/blender/editors/space_clip/space_clip.c3
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h8
-rw-r--r--source/blender/imbuf/intern/colormanagement.c88
-rw-r--r--source/blender/makesdna/DNA_space_types.h2
17 files changed, 728 insertions, 220 deletions
diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt
index c281a6e7bbb..91bf6550f27 100644
--- a/intern/opencolorio/CMakeLists.txt
+++ b/intern/opencolorio/CMakeLists.txt
@@ -52,6 +52,7 @@ if(WITH_OPENCOLORIO)
list(APPEND SRC
ocio_impl.cc
+ ocio_impl_glsl.cc
)
if(WIN32 AND NOT MINGW)
diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript
index 6e7c467f64f..e4a0d3ebb7c 100644
--- a/intern/opencolorio/SConscript
+++ b/intern/opencolorio/SConscript
@@ -40,5 +40,6 @@ if env['WITH_BF_OCIO']:
incs += ' ' + env['BF_BOOST_INC']
else:
sources.remove('ocio_impl.cc')
+ sources.remove('ocio_impl_glsl.cc')
env.BlenderLib( 'bf_intern_opencolorio', sources, Split(incs), defs, libtype=['extern','player'], priority=[10, 185])
diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc
index d01d8d4c8f4..47c648e9cba 100644
--- a/intern/opencolorio/fallback_impl.cc
+++ b/intern/opencolorio/fallback_impl.cc
@@ -380,3 +380,15 @@ void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *)
void FallbackImpl::matrixTransformScale(float * , float * , const float *)
{
}
+
+void FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor)
+{
+}
+
+void FallbackImpl::finishGLSLDraw(OCIO_GLSLDrawState *state)
+{
+}
+
+void FallbackImpl::freeGLState(struct OCIO_GLSLDrawState *state_r)
+{
+}
diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc
index 4f839a61fad..73d8af295f2 100644
--- a/intern/opencolorio/ocio_capi.cc
+++ b/intern/opencolorio/ocio_capi.cc
@@ -282,3 +282,18 @@ void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4
{
impl->matrixTransformScale(m44, offset4, scale4f);
}
+
+void OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor)
+{
+ impl->setupGLSLDraw(state_r, processor);
+}
+
+void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state)
+{
+ impl->finishGLSLDraw(state);
+}
+
+void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state)
+{
+ impl->freeGLState(state);
+}
diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h
index 19fd8fe643b..3c42e0a1a1e 100644
--- a/intern/opencolorio/ocio_capi.h
+++ b/intern/opencolorio/ocio_capi.h
@@ -32,6 +32,8 @@
extern "C" {
#endif
+struct OCIO_GLSLDrawState;
+
#define OCIO_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
#define OCIO_ROLE_SCENE_LINEAR "scene_linear"
@@ -119,6 +121,10 @@ void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale4);
+void OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor);
+void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state);
+void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state);
+
#ifdef __cplusplus
}
#endif
diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc
index b073a038f0d..8803814ce3f 100644
--- a/intern/opencolorio/ocio_impl.cc
+++ b/intern/opencolorio/ocio_impl.cc
@@ -26,8 +26,16 @@
*/
#include <iostream>
+#include <sstream>
#include <string.h>
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/glew.h>
+#endif
+
#include <OpenColorIO/OpenColorIO.h>
using namespace OCIO_NAMESPACE;
@@ -50,6 +58,8 @@ using namespace OCIO_NAMESPACE;
#define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type()
#define MEM_DELETE(what, type) if(what) { ((type*)(what))->~type(); MEM_freeN(what); } (void)0
+static const int LUT3D_EDGE_SIZE = 32;
+
static void OCIO_reportError(const char *err)
{
std::cerr << "OpenColorIO Error: " << err << std::endl;
@@ -541,3 +551,228 @@ void OCIOImpl::matrixTransformScale(float * m44, float * offset4, const float *s
{
MatrixTransform::Scale(m44, offset4, scale4f);
}
+
+/* **** OpenGL drawing routines using GLSL for color space transform ***** */
+
+/* Some of the GLSL transform related functions below are adopted from
+ * ociodisplay utility of OpenColorIO project which are originally
+ *
+ * Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved.
+ */
+
+typedef struct OCIO_GLSLDrawState {
+ bool lut3d_texture_allocated; /* boolean flag indicating whether
+ * lut texture is allocated
+ */
+
+ GLuint lut3d_texture; /* OGL texture ID for 3D LUT */
+
+ float *lut3d; /* 3D LUT table */
+
+ /* Cache */
+ std::string lut3dcacheid;
+ std::string shadercacheid;
+
+ /* GLSL stuff */
+ GLuint fragShader;
+ GLuint program;
+
+ /* Previous OpenGL state. */
+ GLint last_texture, last_texture_unit;
+} OCIO_GLSLDrawState;
+
+static const char * g_fragShaderText = ""
+"\n"
+"uniform sampler2D tex1;\n"
+"uniform sampler3D tex2;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n"
+" gl_FragColor = OCIODisplay(col, tex2);\n"
+"}\n";
+
+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);
+ return 0;
+ }
+
+ return shader;
+}
+
+static GLuint linkShaders(GLuint fragShader)
+{
+ if (!fragShader)
+ return 0;
+
+ GLuint program = glCreateProgram();
+
+ if (fragShader)
+ glAttachShader(program, fragShader);
+
+ 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)
+{
+ OCIO_GLSLDrawState *state;
+
+ /* 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 */
+static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state)
+{
+ int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE;
+
+ if (state->lut3d_texture_allocated)
+ return;
+
+ glGenTextures(1, &state->lut3d_texture);
+
+ state->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT");
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_3D, state->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);
+ glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB,
+ LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
+ 0, GL_RGB,GL_FLOAT, &state->lut3d);
+
+ state->lut3d_texture_allocated = true;
+}
+
+/**
+ * Setup OpenGL contexts for a transform defined by processor using GLSL
+ * All LUT allocating baking and shader compilation happens here.
+ *
+ * Once this function is called, callee could start drawing images
+ * using regular 2D texture.
+ *
+ * When all drawing is finished, finishGLSLDraw shall be called to
+ * restore OpenGL context to it's pre-GLSL draw state.
+ */
+void OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor)
+{
+ ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor;
+
+ /* Create state if needed. */
+ OCIO_GLSLDrawState *state;
+ if (!*state_r)
+ *state_r = allocateOpenGLState();
+ state = *state_r;
+
+ glGetIntegerv(GL_TEXTURE_2D, &state->last_texture);
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit);
+
+ ensureLUT3DAllocated(state);
+
+ /* Step 1: Create a GPU Shader Description */
+ GpuShaderDesc shaderDesc;
+ shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_0);
+ shaderDesc.setFunctionName("OCIODisplay");
+ shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);
+
+ /* Step 2: Compute the 3D LUT */
+ std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc);
+ if (lut3dCacheID != state->lut3dcacheid) {
+ state->lut3dcacheid = lut3dCacheID;
+ ocio_processor->getGpuLut3D(state->lut3d, shaderDesc);
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_3D, state->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) {
+ state->shadercacheid = shaderCacheID;
+
+ std::ostringstream os;
+ os << ocio_processor->getGpuShaderText(shaderDesc) << "\n";
+ os << g_fragShaderText;
+
+ if (state->fragShader)
+ glDeleteShader(state->fragShader);
+ state->fragShader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
+
+ if (state->program)
+ glDeleteProgram(state->program);
+
+ state->program = linkShaders(state->fragShader);
+ }
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
+
+ glActiveTexture(GL_TEXTURE0);
+
+ glUseProgram(state->program);
+ glUniform1i(glGetUniformLocation(state->program, "tex1"), 0);
+ glUniform1i(glGetUniformLocation(state->program, "tex2"), 1);
+}
+
+void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state)
+{
+ glActiveTexture(state->last_texture_unit);
+ glBindTexture(GL_TEXTURE_2D, state->last_texture);
+ glUseProgram(0);
+}
+
+void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state)
+{
+ using std::string;
+
+ if (state->lut3d_texture_allocated)
+ glDeleteTextures(1, &state->lut3d_texture);
+
+ if (state->lut3d)
+ MEM_freeN(state->lut3d);
+
+ state->lut3dcacheid.~string();
+ state->shadercacheid.~string();
+
+ MEM_freeN(state);
+}
diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h
index b6bbc912e5b..2a1f88be5f4 100644
--- a/intern/opencolorio/ocio_impl.h
+++ b/intern/opencolorio/ocio_impl.h
@@ -95,6 +95,10 @@ public:
virtual void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) = 0;
virtual void matrixTransformScale(float * m44, float * offset4, const float * scale4) = 0;
+
+ virtual void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) = 0;
+ virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0;
+ virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0;
};
class FallbackImpl : public IOCIOImpl {
@@ -164,6 +168,10 @@ public:
void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
void matrixTransformScale(float * m44, float * offset4, const float * scale4);
+
+ void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor);
+ void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
+ void freeGLState(struct OCIO_GLSLDrawState *state_r);
};
#ifdef WITH_OCIO
@@ -234,6 +242,10 @@ public:
void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
void matrixTransformScale(float * m44, float * offset4, const float * scale4);
+
+ void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor);
+ void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
+ void freeGLState(struct OCIO_GLSLDrawState *state_r);
};
#endif
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
new file mode 100644
index 00000000000..c79593779cf
--- /dev/null
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -0,0 +1,274 @@
+/*
+ * Adapted from OpenColorIO with this license:
+ *
+ * Copyright (c) 2003-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.
+ *
+ * Modifications Copyright 2013, Blender Foundation.
+ *
+ * Contributor(s): Sergey Sharybin
+ *
+ */
+
+#include <sstream>
+#include <string.h>
+
+#ifdef __APPLE__
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#else
+#include <GL/glew.h>
+#endif
+
+#include <OpenColorIO/OpenColorIO.h>
+
+using namespace OCIO_NAMESPACE;
+
+#include "MEM_guardedalloc.h"
+
+#include "ocio_impl.h"
+
+static const int LUT3D_EDGE_SIZE = 32;
+
+
+/* **** OpenGL drawing routines using GLSL for color space transform ***** */
+
+typedef struct OCIO_GLSLDrawState {
+ bool lut3d_texture_allocated; /* boolean flag indicating whether
+ * lut texture is allocated
+ */
+
+ GLuint lut3d_texture; /* OGL texture ID for 3D LUT */
+
+ float *lut3d; /* 3D LUT table */
+
+ /* Cache */
+ std::string lut3dcacheid;
+ std::string shadercacheid;
+
+ /* GLSL stuff */
+ GLuint fragShader;
+ GLuint program;
+
+ /* Previous OpenGL state. */
+ GLint last_texture, last_texture_unit;
+} OCIO_GLSLDrawState;
+
+static const char * g_fragShaderText = ""
+"\n"
+"uniform sampler2D tex1;\n"
+"uniform sampler3D tex2;\n"
+"\n"
+"void main()\n"
+"{\n"
+" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n"
+" gl_FragColor = OCIODisplay(col, tex2);\n"
+"}\n";
+
+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);
+ return 0;
+ }
+
+ return shader;
+}
+
+static GLuint linkShaders(GLuint fragShader)
+{
+ if (!fragShader)
+ return 0;
+
+ GLuint program = glCreateProgram();
+
+ if (fragShader)
+ glAttachShader(program, fragShader);
+
+ 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)
+{
+ OCIO_GLSLDrawState *state;
+
+ /* 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 */
+static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state)
+{
+ int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE;
+
+ if (state->lut3d_texture_allocated)
+ return;
+
+ glGenTextures(1, &state->lut3d_texture);
+
+ state->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT");
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_3D, state->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);
+ glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB,
+ LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE,
+ 0, GL_RGB,GL_FLOAT, &state->lut3d);
+
+ state->lut3d_texture_allocated = true;
+}
+
+/**
+ * Setup OpenGL contexts for a transform defined by processor using GLSL
+ * All LUT allocating baking and shader compilation happens here.
+ *
+ * Once this function is called, callee could start drawing images
+ * using regular 2D texture.
+ *
+ * When all drawing is finished, finishGLSLDraw shall be called to
+ * restore OpenGL context to it's pre-GLSL draw state.
+ */
+void OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor)
+{
+ ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor;
+
+ /* Create state if needed. */
+ OCIO_GLSLDrawState *state;
+ if (!*state_r)
+ *state_r = allocateOpenGLState();
+ state = *state_r;
+
+ glGetIntegerv(GL_TEXTURE_2D, &state->last_texture);
+ glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit);
+
+ ensureLUT3DAllocated(state);
+
+ /* Step 1: Create a GPU Shader Description */
+ GpuShaderDesc shaderDesc;
+ shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_0);
+ shaderDesc.setFunctionName("OCIODisplay");
+ shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE);
+
+ /* Step 2: Compute the 3D LUT */
+ std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc);
+ if (lut3dCacheID != state->lut3dcacheid) {
+ state->lut3dcacheid = lut3dCacheID;
+ ocio_processor->getGpuLut3D(state->lut3d, shaderDesc);
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_3D, state->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) {
+ state->shadercacheid = shaderCacheID;
+
+ std::ostringstream os;
+ os << ocio_processor->getGpuShaderText(shaderDesc) << "\n";
+ os << g_fragShaderText;
+
+ if (state->fragShader)
+ glDeleteShader(state->fragShader);
+ state->fragShader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str());
+
+ if (state->program)
+ glDeleteProgram(state->program);
+
+ state->program = linkShaders(state->fragShader);
+ }
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_3D, state->lut3d_texture);
+
+ glActiveTexture(GL_TEXTURE0);
+
+ glUseProgram(state->program);
+ glUniform1i(glGetUniformLocation(state->program, "tex1"), 0);
+ glUniform1i(glGetUniformLocation(state->program, "tex2"), 1);
+}
+
+void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state)
+{
+ glActiveTexture(state->last_texture_unit);
+ glBindTexture(GL_TEXTURE_2D, state->last_texture);
+ glUseProgram(0);
+}
+
+void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state)
+{
+ using std::string;
+
+ if (state->lut3d_texture_allocated)
+ glDeleteTextures(1, &state->lut3d_texture);
+
+ if (state->lut3d)
+ MEM_freeN(state->lut3d);
+
+ state->lut3dcacheid.~string();
+ state->shadercacheid.~string();
+
+ MEM_freeN(state);
+}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 7399bfec2b5..682680e53c5 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6350,7 +6350,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
sclip->scopes.track_search = NULL;
sclip->scopes.track_preview = NULL;
- sclip->draw_context = NULL;
sclip->scopes.ok = 0;
}
}
diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h
index 28727c913cb..541956136bd 100644
--- a/source/blender/editors/include/ED_clip.h
+++ b/source/blender/editors/include/ED_clip.h
@@ -39,6 +39,7 @@ struct Main;
struct Mask;
struct MovieClip;
struct SpaceClip;
+struct Scene;
/* ** clip_editor.c ** */
@@ -81,12 +82,6 @@ void ED_space_clip_set_clip(struct bContext *C, struct bScreen *screen, struct S
struct Mask *ED_space_clip_get_mask(struct SpaceClip *sc);
void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask);
-/* textures buffer */
-int ED_space_clip_texture_buffer_supported(struct SpaceClip *sc);
-int ED_space_clip_load_movieclip_buffer(struct SpaceClip *sc, struct ImBuf *ibuf, const unsigned char *display_buffer);
-void ED_space_clip_unload_movieclip_buffer(struct SpaceClip *sc);
-void ED_space_clip_free_texture_buffer(struct SpaceClip *sc);
-
/* ** clip_ops.c ** */
void ED_operatormacros_clip(void);
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 8501b53afae..89315e041de 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -519,6 +519,15 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
nsubparts_x = (img_w + (offset_x - 1)) / (offset_x);
nsubparts_y = (img_h + (offset_y - 1)) / (offset_y);
+ if (format == GL_FLOAT) {
+ /* need to set internal format to higher range float */
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, tex_w, tex_h, 0, GL_RGBA, GL_FLOAT, NULL);
+ }
+ else {
+ /* switch to 8bit RGBA for byte buffer */
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ }
+
for (subpart_y = 0; subpart_y < nsubparts_y; subpart_y++) {
for (subpart_x = 0; subpart_x < nsubparts_x; subpart_x++) {
int remainder_x = img_w - subpart_x * offset_x;
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index 2d3dc9127c3..cbca2f0c46e 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -248,6 +248,53 @@ static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar)
ED_region_info_draw(ar, str, block, 0.6f);
}
+static void draw_movieclip_buffer_glsl(SpaceClip *sc, ImBuf *ibuf, int x, int y,
+ float zoomx, float zoomy)
+{
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ int filter = GL_LINEAR;
+
+ glPushMatrix();
+ glTranslatef(x, y, 0.0f);
+ glScalef(zoomx, zoomy, 1.0f);
+
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+
+ /* non-scaled proxy shouldn;t use diltering */
+ if ((clip->flag & MCLIP_USE_PROXY) == 0 ||
+ ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100))
+ {
+ filter = GL_NEAREST;
+ }
+
+ glaDrawPixelsTex(0, 0, ibuf->x, ibuf->y, GL_FLOAT, filter, ibuf->rect_float);
+
+ glPopMatrix();
+}
+
+static void draw_movieclip_buffer_fallback(const bContext *C, ImBuf *ibuf, int x, int y,
+ int width, int height, float zoomx, float zoomy)
+{
+ unsigned char *display_buffer;
+ void *cache_handle;
+
+ display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
+
+ if (display_buffer) {
+ /* set zoom */
+ glPixelZoom(zoomx * width / ibuf->x, zoomy * height / ibuf->y);
+
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer);
+
+ /* reset zoom */
+ glPixelZoom(1.0f, 1.0f);
+ }
+
+ IMB_display_buffer_release(cache_handle);
+}
+
static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar, ImBuf *ibuf,
int width, int height, float zoomx, float zoomy)
{
@@ -261,62 +308,32 @@ static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar,
glRectf(x, y, x + zoomx * width, y + zoomy * height);
}
else {
- unsigned char *display_buffer;
- void *cache_handle;
-
- display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
-
- if (display_buffer) {
- int need_fallback = 1;
-
- /* checkerboard for case alpha */
- if (ibuf->planes == 32) {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- fdrawcheckerboard(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y);
- }
+ bool need_fallback = true;
- if (ED_space_clip_texture_buffer_supported(sc)) {
- if (ED_space_clip_load_movieclip_buffer(sc, ibuf, display_buffer)) {
- glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ /* checkerboard for case alpha */
+ if (ibuf->planes == 32) {
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glPushMatrix();
- glTranslatef(x, y, 0.0f);
- glScalef(zoomx, zoomy, 1.0f);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
- glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f);
- glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height);
- glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height);
- glEnd();
-
- glPopMatrix();
-
- ED_space_clip_unload_movieclip_buffer(sc);
-
- need_fallback = 0;
- }
- }
+ fdrawcheckerboard(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y);
+ }
- /* if texture buffers aren't efficiently supported or texture is too large to
- * be binder fallback to simple draw pixels solution */
- if (need_fallback) {
- /* set zoom */
- glPixelZoom(zoomx * width / ibuf->x, zoomy * height / ibuf->y);
+ /* GLSL display transform for byte buffers is not supported yet */
+ if (ibuf->rect_float && IMB_coloemanagement_setup_glsl_draw_from_ctx(C)) {
+ draw_movieclip_buffer_glsl(sc, ibuf, x, y, zoomx, zoomy);
- glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer);
+ IMB_coloemanagement_finish_glsl_draw();
- /* reset zoom */
- glPixelZoom(1.0f, 1.0f);
- }
+ need_fallback = false;
+ }
- if (ibuf->planes == 32)
- glDisable(GL_BLEND);
+ /* if GLSL display failed, fallback to regular glaDrawPixelsAuto method */
+ if (need_fallback) {
+ draw_movieclip_buffer_fallback(C, ibuf, x, y, width, height, zoomx, zoomy);
}
- IMB_display_buffer_release(cache_handle);
+ if (ibuf->planes == 32)
+ glDisable(GL_BLEND);
}
}
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index b00cc564a99..d297d0485e3 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -62,15 +62,13 @@
#include "GPU_extensions.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "ED_screen.h"
#include "ED_clip.h"
-#include "BIF_gl.h"
-#include "BIF_glutil.h"
-
#include "WM_api.h"
#include "WM_types.h"
@@ -580,163 +578,6 @@ void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask)
}
}
-/* OpenGL draw context */
-
-typedef struct SpaceClipDrawContext {
- int support_checked, buffers_supported;
-
- GLuint texture; /* OGL texture ID */
- short texture_allocated; /* flag if texture was allocated by glGenTextures */
- struct ImBuf *texture_ibuf; /* image buffer for which texture was created */
- const unsigned char *display_buffer; /* display buffer for which texture was created */
- int image_width, image_height; /* image width and height for which texture was created */
- unsigned last_texture; /* ID of previously used texture, so it'll be restored after clip drawing */
-
- /* fields to check if cache is still valid */
- int framenr, start_frame, frame_offset;
- short render_size, render_flag;
-
- char colorspace[64];
-} SpaceClipDrawContext;
-
-int ED_space_clip_texture_buffer_supported(SpaceClip *sc)
-{
- SpaceClipDrawContext *context = sc->draw_context;
-
- if (!context) {
- context = MEM_callocN(sizeof(SpaceClipDrawContext), "SpaceClipDrawContext");
- sc->draw_context = context;
- }
-
- if (!context->support_checked) {
- context->support_checked = TRUE;
- if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- context->buffers_supported = FALSE;
- }
- else {
- context->buffers_supported = GPU_non_power_of_two_support();
- }
- }
-
- return context->buffers_supported;
-}
-
-int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf, const unsigned char *display_buffer)
-{
- SpaceClipDrawContext *context = sc->draw_context;
- MovieClip *clip = ED_space_clip_get_clip(sc);
- int need_rebind = 0;
-
- context->last_texture = glaGetOneInteger(GL_TEXTURE_2D);
-
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- /* image texture need to be rebinded if displaying another image buffer
- * assuming displaying happens of footage frames only on which painting doesn't happen.
- * so not changed image buffer pointer means unchanged image content */
- need_rebind |= context->texture_ibuf != ibuf;
- need_rebind |= context->display_buffer != display_buffer;
- need_rebind |= context->framenr != sc->user.framenr;
- need_rebind |= context->render_size != sc->user.render_size;
- need_rebind |= context->render_flag != sc->user.render_flag;
- need_rebind |= context->start_frame != clip->start_frame;
- need_rebind |= context->frame_offset != clip->frame_offset;
-
- if (!need_rebind) {
- /* OCIO_TODO: not entirely nice, but currently it seems to be easiest way
- * to deal with changing input color space settings
- * pointer-based check could fail due to new buffers could be
- * be allocated on on old memory
- */
- need_rebind = strcmp(context->colorspace, clip->colorspace_settings.name) != 0;
- }
-
- if (need_rebind) {
- int width = ibuf->x, height = ibuf->y;
- int need_recreate = 0;
-
- if (width > GL_MAX_TEXTURE_SIZE || height > GL_MAX_TEXTURE_SIZE)
- return 0;
-
- /* if image resolution changed (e.g. switched to proxy display) texture need to be recreated */
- need_recreate = context->image_width != ibuf->x || context->image_height != ibuf->y;
-
- if (context->texture_ibuf && need_recreate) {
- glDeleteTextures(1, &context->texture);
- context->texture_allocated = 0;
- }
-
- if (need_recreate || !context->texture_allocated) {
- /* texture doesn't exist yet or need to be re-allocated because of changed dimensions */
- int filter = GL_LINEAR;
-
- /* non-scaled proxy shouldn;t use diltering */
- if ((clip->flag & MCLIP_USE_PROXY) == 0 ||
- ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100))
- {
- filter = GL_NEAREST;
- }
-
- glGenTextures(1, &context->texture);
- glBindTexture(GL_TEXTURE_2D, context->texture);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- }
- else {
- /* if texture doesn't need to be reallocated itself, just bind it so
- * loading of image will happen to a proper texture */
- glBindTexture(GL_TEXTURE_2D, context->texture);
- }
-
- if (display_buffer)
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
-
- /* store settings */
- context->texture_allocated = 1;
- context->display_buffer = display_buffer;
- context->texture_ibuf = ibuf;
- context->image_width = ibuf->x;
- context->image_height = ibuf->y;
- context->framenr = sc->user.framenr;
- context->render_size = sc->user.render_size;
- context->render_flag = sc->user.render_flag;
- context->start_frame = clip->start_frame;
- context->frame_offset = clip->frame_offset;
-
- BLI_strncpy(context->colorspace, clip->colorspace_settings.name, sizeof(context->colorspace));
- }
- else {
- /* displaying exactly the same image which was loaded t oa texture,
- * just bint texture in this case */
- glBindTexture(GL_TEXTURE_2D, context->texture);
- }
-
- glEnable(GL_TEXTURE_2D);
-
- return TRUE;
-}
-
-void ED_space_clip_unload_movieclip_buffer(SpaceClip *sc)
-{
- SpaceClipDrawContext *context = sc->draw_context;
-
- glBindTexture(GL_TEXTURE_2D, context->last_texture);
- glDisable(GL_TEXTURE_2D);
-}
-
-void ED_space_clip_free_texture_buffer(SpaceClip *sc)
-{
- SpaceClipDrawContext *context = sc->draw_context;
-
- if (context) {
- glDeleteTextures(1, &context->texture);
-
- MEM_freeN(context);
- }
-}
-
/* ******** pre-fetching functions ******** */
typedef struct PrefetchJob {
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index ced19020034..64b643f8a58 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -327,8 +327,6 @@ static void clip_free(SpaceLink *sl)
if (sc->scopes.track_search)
IMB_freeImBuf(sc->scopes.track_search);
-
- ED_space_clip_free_texture_buffer(sc);
}
/* spacetype; init callback */
@@ -348,7 +346,6 @@ static SpaceLink *clip_duplicate(SpaceLink *sl)
scn->scopes.track_search = NULL;
scn->scopes.track_preview = NULL;
scn->scopes.ok = FALSE;
- scn->draw_context = NULL;
return (SpaceLink *)scn;
}
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index b981390582e..473bd7d0c7a 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -148,6 +148,14 @@ void IMB_colormanagement_processor_apply(struct ColormanageProcessor *cm_process
int channels, int predivide);
void IMB_colormanagement_processor_free(struct ColormanageProcessor *cm_processor);
+/* ** OpenGL drawing routines using GLSL for color space transform ** */
+
+int IMB_coloemanagement_setup_glsl_draw(const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings);
+
+int IMB_coloemanagement_setup_glsl_draw_from_ctx(const struct bContext *C);
+void IMB_coloemanagement_finish_glsl_draw(void);
+
/* Roles */
enum {
COLOR_ROLE_SCENE_LINEAR = 0,
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 65a3db839a9..6c33f6e3e33 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -102,6 +102,19 @@ typedef struct ColormanageProcessor {
int is_data_result;
} ColormanageProcessor;
+static struct global_glsl_state {
+ /* Actual processor used for GLSL baked LUTs. */
+ OCIO_ConstProcessorRcPtr *processor;
+
+ /* Settings of processor for comparison. */
+ char view[MAX_COLORSPACE_NAME];
+ char display[MAX_COLORSPACE_NAME];
+ float exposure, gamma;
+
+ /* Container for GLSL state needed for OCIO module. */
+ struct OCIO_GLSLDrawState *ocio_glsl_state;
+} global_glsl_state;
+
/*********************** Color managed cache *************************/
/* Cache Implementation Notes
@@ -607,6 +620,12 @@ void colormanagement_init(void)
void colormanagement_exit(void)
{
+ if (global_glsl_state.processor)
+ OCIO_processorRelease(global_glsl_state.processor);
+
+ if (global_glsl_state.ocio_glsl_state)
+ OCIO_freeOGLState(global_glsl_state.ocio_glsl_state);
+
colormanage_free_config();
}
@@ -2691,3 +2710,72 @@ void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor)
MEM_freeN(cm_processor);
}
+
+/* **** OpenGL drawing routines using GLSL for color space transform ***** */
+
+static bool check_glsl_display_processor_changed(const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
+{
+ return !(global_glsl_state.exposure == view_settings->exposure &&
+ global_glsl_state.gamma == view_settings->gamma &&
+ STREQ(global_glsl_state.view, view_settings->view_transform) &&
+ STREQ(global_glsl_state.display, display_settings->display_device));
+}
+
+static void update_glsl_display_processor(const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
+{
+ /* Update state if there's no processor yet or
+ * processor settings has been changed.
+ */
+ if (global_glsl_state.processor == NULL ||
+ check_glsl_display_processor_changed(view_settings, display_settings))
+ {
+ /* Store settings of processor for further comparison. */
+ strcpy(global_glsl_state.view, view_settings->view_transform);
+ strcpy(global_glsl_state.display, display_settings->display_device);
+ global_glsl_state.exposure = view_settings->exposure;
+ global_glsl_state.gamma = view_settings->gamma;
+
+ /* Free old processor, if any. */
+ if (global_glsl_state.processor)
+ OCIO_processorRelease(global_glsl_state.processor);
+
+ /* We're using display OCIO processor, no RGB curves yet. */
+ global_glsl_state.processor =
+ create_display_buffer_processor(global_glsl_state.view,
+ global_glsl_state.display,
+ global_glsl_state.exposure,
+ global_glsl_state.gamma);
+ }
+}
+
+int IMB_coloemanagement_setup_glsl_draw(const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
+{
+ /* RGB curves mapping is not supported on GPU yet. */
+ if (view_settings->flag & COLORMANAGE_VIEW_USE_CURVES)
+ return FALSE;
+
+ /* Make sure OCIO processor is up-to-date. */
+ update_glsl_display_processor(view_settings, display_settings);
+
+ OCIO_setupGLSLDraw(&global_glsl_state.ocio_glsl_state, global_glsl_state.processor);
+
+ return TRUE;
+}
+
+int IMB_coloemanagement_setup_glsl_draw_from_ctx(const bContext *C)
+{
+ ColorManagedViewSettings *view_settings;
+ ColorManagedDisplaySettings *display_settings;
+
+ display_transform_get_from_ctx(C, &view_settings, &display_settings);
+
+ return IMB_coloemanagement_setup_glsl_draw(view_settings, display_settings);
+}
+
+void IMB_coloemanagement_finish_glsl_draw(void)
+{
+ OCIO_finishGLSLDraw(global_glsl_state.ocio_glsl_state);
+}
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index e5e38d66de5..8253bb570f6 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -1072,8 +1072,6 @@ typedef struct SpaceClip {
/* grease pencil */
short gpencil_src, pad2;
- void *draw_context;
-
int around, pad4; /* pivot point for transforms */
MaskSpaceInfo mask_info;