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--source/blender/editors/include/BIF_glutil.h11
-rw-r--r--source/blender/editors/render/render_internal.c20
-rw-r--r--source/blender/editors/render/render_opengl.c15
-rw-r--r--source/blender/editors/screen/CMakeLists.txt1
-rw-r--r--source/blender/editors/screen/glutil.c92
-rw-r--r--source/blender/editors/space_clip/clip_draw.c69
-rw-r--r--source/blender/editors/space_image/image_draw.c10
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h15
-rw-r--r--source/blender/imbuf/intern/colormanagement.c60
9 files changed, 205 insertions, 88 deletions
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index 5774a057eb5..650e4527196 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -33,6 +33,9 @@
struct rcti;
struct rctf;
+struct ImBuf;
+struct bContext;
+
void fdrawbezier(float vec[4][3]);
void fdrawline(float x1, float y1, float x2, float y2);
void fdrawbox(float x1, float y1, float x2, float y2);
@@ -223,5 +226,13 @@ typedef struct bglMats {
} bglMats;
void bgl_get_mats(bglMats *mats);
+/* **** Color management helper functions for GLSL display/transform ***** */
+
+/* Draw imbuf on a screen, preferably using GLSL display transform */
+void glaDrawImBuf_glsl_ctx(const struct bContext *C, struct ImBuf *ibuf, float x, float y, int zoomfilter);
+
+/* Transform buffer from role to scene linear space using GLSL OCIO conversion */
+int glaBufferTransformFromRole_glsl(float *buffer, int width, int height, int role);
+
#endif /* __BIF_GLUTIL_H__ */
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 365ac02d15b..de8accf0180 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -140,15 +140,23 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat
}
}
if (rectf == NULL) return;
-
- if (ibuf->rect == NULL)
- imb_addrectImBuf(ibuf);
rectf += 4 * (rr->rectx * ymin + xmin);
- IMB_partial_display_buffer_update(ibuf, rectf, NULL, rr->rectx, rxmin, rymin,
- &scene->view_settings, &scene->display_settings,
- rxmin, rymin, rxmin + xmax, rymin + ymax, TRUE);
+ if (ibuf->rect) {
+ IMB_partial_display_buffer_update(ibuf, rectf, NULL, rr->rectx, rxmin, rymin,
+ &scene->view_settings, &scene->display_settings,
+ rxmin, rymin, rxmin + xmax, rymin + ymax, TRUE);
+ }
+
+ /* update float buffer as well, so fast GLSL display could use it
+ *
+ * TODO(sergey): not actually sure it is nice thing to modify something here
+ * but ibuf->rect used to be modified here
+ */
+ IMB_buffer_float_from_float(ibuf->rect_float + 4 * (ibuf->x * rymin + rxmin), rectf,
+ 4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_LINEAR_RGB, FALSE,
+ xmax, ymax, ibuf->x, rr->rectx);
}
/* ****************************** render invoking ***************** */
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index f47d737beca..9d443fab552 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -69,6 +69,8 @@
#include "RNA_access.h"
#include "RNA_define.h"
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
#include "GPU_extensions.h"
@@ -261,11 +263,14 @@ static void screen_opengl_render_apply(OGLRender *oglrender)
*/
if (!oglrender->is_sequencer) {
- /* sequencer has got tricker ocnversion happened above */
-
- IMB_buffer_float_from_float(rr->rectf, rr->rectf,
- 4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, TRUE,
- oglrender->sizex, oglrender->sizey, oglrender->sizex, oglrender->sizex);
+ /* sequencer has got trickier conversion happened above
+ * also assume opengl's space matches byte buffer color space
+ */
+ if (!glaBufferTransformFromRole_glsl(rr->rectf, oglrender->sizex, oglrender->sizey, COLOR_ROLE_DEFAULT_BYTE)) {
+ IMB_buffer_float_from_float(rr->rectf, rr->rectf,
+ 4, IB_PROFILE_LINEAR_RGB, IB_PROFILE_SRGB, TRUE,
+ oglrender->sizex, oglrender->sizey, oglrender->sizex, oglrender->sizex);
+ }
}
/* rr->rectf is now filled with image data */
diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt
index 33373354aa4..c9c4c253e28 100644
--- a/source/blender/editors/screen/CMakeLists.txt
+++ b/source/blender/editors/screen/CMakeLists.txt
@@ -25,6 +25,7 @@ set(INC
../../blenlib
../../blenloader
../../bmesh
+ ../../gpu
../../imbuf
../../makesdna
../../makesrna
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 89315e041de..fecb3c58a2d 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -43,10 +43,16 @@
#include "BKE_blender.h"
#include "BKE_colortools.h"
+#include "BKE_context.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
+#include "GPU_extensions.h"
+
+#include "IMB_colormanagement.h"
+#include "IMB_imbuf_types.h"
+
#ifndef GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE 0x812F
#endif
@@ -983,3 +989,89 @@ void bglFlush(void)
#endif
}
#endif
+
+/* **** Color management helper functions for GLSL display/transform ***** */
+
+/* Draw given image buffer on a screen using GLSL for display transform */
+void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter)
+{
+ bool need_fallback = true;
+
+ /* Bytes and dithering are not supported on GLSL yet */
+ if (ibuf->rect_float && ibuf->dither == 0.0f) {
+ if (IMB_colormanagement_setup_glsl_draw_from_ctx(C)) {
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glColor4f(1.0, 1.0, 1.0, 1.0);
+
+ glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_FLOAT, zoomfilter, ibuf->rect_float);
+
+ IMB_colormanagement_finish_glsl_draw();
+
+ need_fallback = false;
+ }
+ }
+
+ if (need_fallback) {
+ unsigned char *display_buffer;
+ void *cache_handle;
+
+ display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
+
+ if (display_buffer)
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, zoomfilter, display_buffer);
+
+ IMB_display_buffer_release(cache_handle);
+ }
+}
+
+/* Transform buffer from role to scene linear space using GLSL OCIO conversion
+ *
+ * See IMB_colormanagement_setup_transform_from_role_glsl description for
+ * some more details
+ */
+int glaBufferTransformFromRole_glsl(float *buffer, int width, int height, int role)
+{
+ GPUOffScreen *ofs;
+ char err_out[256];
+ rcti display_rect;
+
+ ofs = GPU_offscreen_create(width, height, err_out);
+
+ if (!ofs)
+ return FALSE;
+
+ GPU_offscreen_bind(ofs);
+
+ if (!IMB_colormanagement_setup_transform_from_role_glsl(role)) {
+ GPU_offscreen_unbind(ofs);
+ GPU_offscreen_free(ofs);
+ return FALSE;
+ }
+
+ BLI_rcti_init(&display_rect, 0, width, 0, height);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+
+ glaDefine2DArea(&display_rect);
+ glLoadIdentity();
+
+ glaDrawPixelsTex(0, 0, width, height, GL_FLOAT, GL_NEAREST, buffer);
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ GPU_offscreen_read_pixels(ofs, GL_FLOAT, buffer);
+
+ IMB_colormanagement_finish_glsl_transform();
+
+ /* unbind */
+ GPU_offscreen_unbind(ofs);
+ GPU_offscreen_free(ofs);
+
+ return TRUE;
+}
diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c
index cbca2f0c46e..774220764e7 100644
--- a/source/blender/editors/space_clip/clip_draw.c
+++ b/source/blender/editors/space_clip/clip_draw.c
@@ -248,53 +248,6 @@ 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)
{
@@ -308,7 +261,8 @@ static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar,
glRectf(x, y, x + zoomx * width, y + zoomy * height);
}
else {
- bool need_fallback = true;
+ MovieClip *clip = ED_space_clip_get_clip(sc);
+ int filter = GL_LINEAR;
/* checkerboard for case alpha */
if (ibuf->planes == 32) {
@@ -318,19 +272,14 @@ static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar,
fdrawcheckerboard(x, y, x + zoomx * ibuf->x, y + zoomy * 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);
-
- IMB_coloemanagement_finish_glsl_draw();
-
- need_fallback = false;
- }
+ /* non-scaled proxy shouldn't use filtering */
+ 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;
+ }
- /* if GLSL display failed, fallback to regular glaDrawPixelsAuto method */
- if (need_fallback) {
- draw_movieclip_buffer_fallback(C, ibuf, x, y, width, height, zoomx, zoomy);
- }
+ glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
if (ibuf->planes == 32)
glDisable(GL_BLEND);
diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c
index f27a99ac44b..7fc83809b60 100644
--- a/source/blender/editors/space_image/image_draw.c
+++ b/source/blender/editors/space_image/image_draw.c
@@ -505,9 +505,6 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
sima_draw_zbuffloat_pixels(scene, x, y, ibuf->x, ibuf->y, ibuf->rect_float);
}
else {
- unsigned char *display_buffer;
- void *cache_handle;
-
if (sima->flag & SI_USE_ALPHA) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@@ -515,12 +512,7 @@ static void draw_image_buffer(const bContext *C, SpaceImage *sima, ARegion *ar,
fdrawcheckerboard(x, y, x + ibuf->x * zoomx, y + ibuf->y * zoomy);
}
- display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
-
- if (display_buffer)
- glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer);
-
- IMB_display_buffer_release(cache_handle);
+ glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST);
if (sima->flag & SI_USE_ALPHA)
glDisable(GL_BLEND);
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 473bd7d0c7a..a758cfa04f0 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -150,11 +150,18 @@ void IMB_colormanagement_processor_free(struct ColormanageProcessor *cm_processo
/* ** OpenGL drawing routines using GLSL for color space transform ** */
-int IMB_coloemanagement_setup_glsl_draw(const struct ColorManagedViewSettings *view_settings,
+/* Configures GLSL shader for conversion from scene linear to display space */
+int IMB_colormanagement_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);
+/* Same as above, but color management settings are guessing from a given context */
+int IMB_colormanagement_setup_glsl_draw_from_ctx(const struct bContext *C);
+/* Finish GLSL-based display space conversion */
+void IMB_colormanagement_finish_glsl_draw(void);
+
+/* Configures GLSL shader for conversion from space defined by role to scene linear space */
+int IMB_colormanagement_setup_transform_from_role_glsl(int role);
+/* Finish GLSL-based color space conversion */
+void IMB_colormanagement_finish_glsl_transform(void);
/* Roles */
enum {
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index e9447d255cb..1aa8c5af342 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -113,6 +113,7 @@ static struct global_glsl_state {
/* Container for GLSL state needed for OCIO module. */
struct OCIO_GLSLDrawState *ocio_glsl_state;
+ struct OCIO_GLSLDrawState *transform_ocio_glsl_state;
} global_glsl_state;
/*********************** Color managed cache *************************/
@@ -626,6 +627,9 @@ void colormanagement_exit(void)
if (global_glsl_state.ocio_glsl_state)
OCIO_freeOGLState(global_glsl_state.ocio_glsl_state);
+ if (global_glsl_state.transform_ocio_glsl_state)
+ OCIO_freeOGLState(global_glsl_state.transform_ocio_glsl_state);
+
colormanage_free_config();
}
@@ -2750,7 +2754,20 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
}
}
-int IMB_coloemanagement_setup_glsl_draw(const ColorManagedViewSettings *view_settings,
+/**
+ * Configures GLSL shader for conversion from scene linear
+ * to display space
+ *
+ * Will create appropriate OCIO processor and setup GLSL shader,
+ * so further 2D texture usage will use this conversion.
+ *
+ * When there's no need to apply transform on 2D textures, use
+ * IMB_colormanagement_finish_glsl_draw().
+ *
+ * This is low-level function, use glaDrawImBuf_glsl_ctx if you
+ * only need to display given image buffer
+ */
+int IMB_colormanagement_setup_glsl_draw(const ColorManagedViewSettings *view_settings,
const ColorManagedDisplaySettings *display_settings)
{
ColorManagedViewSettings default_view_settings;
@@ -2778,17 +2795,52 @@ int IMB_coloemanagement_setup_glsl_draw(const ColorManagedViewSettings *view_set
return OCIO_setupGLSLDraw(&global_glsl_state.ocio_glsl_state, global_glsl_state.processor);
}
-int IMB_coloemanagement_setup_glsl_draw_from_ctx(const bContext *C)
+/* Same as above, but color management settings are guessing from a given context */
+int IMB_colormanagement_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);
+ return IMB_colormanagement_setup_glsl_draw(view_settings, display_settings);
}
-void IMB_coloemanagement_finish_glsl_draw(void)
+/* Finish GLSL-based display space conversion */
+void IMB_colormanagement_finish_glsl_draw(void)
{
OCIO_finishGLSLDraw(global_glsl_state.ocio_glsl_state);
}
+
+/* ** Color space conversion using GLSL shader ** */
+
+/**
+ * Configures GLSL shader for conversion from space defined by role
+ * to scene linear space
+ *
+ * Will create appropriate OCIO processor and setup GLSL shader,
+ * so further 2D texture usage will use this conversion.
+ *
+ * Role is an pseudonym for a color space, see bottom of file
+ * IMB_colormanagement.h for list of available roles.
+ *
+ * When there's no need to apply transform on 2D textures, use
+ * IMB_colormanagement_finish_glsl_transform().
+ */
+int IMB_colormanagement_setup_transform_from_role_glsl(int role)
+{
+ OCIO_ConstProcessorRcPtr *processor;
+ ColorSpace *colorspace;
+
+ colorspace = colormanage_colorspace_get_roled(role);
+
+ processor = colorspace_to_scene_linear_processor(colorspace);
+
+ return OCIO_setupGLSLDraw(&global_glsl_state.transform_ocio_glsl_state, processor);
+}
+
+/* Finish GLSL-based color space conversion */
+void IMB_colormanagement_finish_glsl_transform(void)
+{
+ OCIO_finishGLSLDraw(global_glsl_state.transform_ocio_glsl_state);
+}