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/fallback_impl.cc2
-rw-r--r--intern/opencolorio/ocio_capi.cc4
-rw-r--r--intern/opencolorio/ocio_capi.h2
-rw-r--r--intern/opencolorio/ocio_impl.h6
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc25
-rw-r--r--source/blender/editors/include/BIF_glutil.h6
-rw-r--r--source/blender/editors/interface/interface_draw.c2
-rw-r--r--source/blender/editors/render/render_internal.c30
-rw-r--r--source/blender/editors/screen/glutil.c140
-rw-r--r--source/blender/editors/space_file/file_draw.c2
-rw-r--r--source/blender/editors/space_node/drawnode.c4
-rw-r--r--source/blender/editors/space_node/node_draw.c2
-rw-r--r--source/blender/editors/space_view3d/drawobject.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c2
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h16
-rw-r--r--source/blender/imbuf/intern/colormanagement.c67
-rw-r--r--source/blender/windowmanager/intern/wm_dragdrop.c2
17 files changed, 235 insertions, 79 deletions
diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc
index 4c19c454aee..37f624e1f8b 100644
--- a/intern/opencolorio/fallback_impl.cc
+++ b/intern/opencolorio/fallback_impl.cc
@@ -381,7 +381,7 @@ void FallbackImpl::matrixTransformScale(float * , float * , const float *)
{
}
-bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor)
+bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide)
{
return false;
}
diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc
index 8e831bb0736..c8db2c2b531 100644
--- a/intern/opencolorio/ocio_capi.cc
+++ b/intern/opencolorio/ocio_capi.cc
@@ -283,9 +283,9 @@ void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4
impl->matrixTransformScale(m44, offset4, scale4f);
}
-int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor)
+int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, int predivide)
{
- return (int) impl->setupGLSLDraw(state_r, processor);
+ return (int) impl->setupGLSLDraw(state_r, processor, (bool) predivide);
}
void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state)
diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h
index 8d8db161077..3632a0da1c6 100644
--- a/intern/opencolorio/ocio_capi.h
+++ b/intern/opencolorio/ocio_capi.h
@@ -121,7 +121,7 @@ void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt);
void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale4);
-int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor);
+int OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, int predivide);
void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state);
void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state);
diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h
index 3a1207d0870..a328470ccb5 100644
--- a/intern/opencolorio/ocio_impl.h
+++ b/intern/opencolorio/ocio_impl.h
@@ -96,7 +96,7 @@ public:
virtual void matrixTransformScale(float * m44, float * offset4, const float * scale4) = 0;
- virtual bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) = 0;
+ virtual bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide) = 0;
virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0;
virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0;
};
@@ -169,7 +169,7 @@ public:
void matrixTransformScale(float * m44, float * offset4, const float * scale4);
- bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor);
+ bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide);
void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
void freeGLState(struct OCIO_GLSLDrawState *state_r);
};
@@ -243,7 +243,7 @@ public:
void matrixTransformScale(float * m44, float * offset4, const float * scale4);
- bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor);
+ bool setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor, bool predivide);
void finishGLSLDraw(struct OCIO_GLSLDrawState *state);
void freeGLState(struct OCIO_GLSLDrawState *state_r);
};
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
index 59845abca33..9343a13e888 100644
--- a/intern/opencolorio/ocio_impl_glsl.cc
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -77,15 +77,33 @@ typedef struct OCIO_GLSLDrawState {
GLint last_texture, last_texture_unit;
} OCIO_GLSLDrawState;
-static const char * g_fragShaderText = ""
+/* Hardcoded to do alpha predivide before color space conversion */
+static const char *g_fragShaderText = ""
"\n"
"uniform sampler2D tex1;\n"
"uniform sampler3D tex2;\n"
+"uniform bool predivide;\n"
"\n"
"void main()\n"
"{\n"
" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n"
-" gl_FragColor = OCIODisplay(col, tex2);\n"
+" if (predivide == false || col[3] == 1.0f || col[3] == 0.0f) {\n"
+" gl_FragColor = OCIODisplay(col, tex2);\n"
+" } else {\n"
+" float alpha = col[3];\n"
+" float inv_alpha = 1.0f / alpha;\n"
+"\n"
+" col[0] *= inv_alpha;\n"
+" col[1] *= inv_alpha;\n"
+" col[2] *= inv_alpha;\n"
+"\n"
+" gl_FragColor = OCIODisplay(col, tex2);\n"
+"\n"
+" col[0] *= alpha;\n"
+" col[1] *= alpha;\n"
+" col[2] *= alpha;\n"
+" }\n"
+"\n"
"}\n";
static GLuint compileShaderText(GLenum shaderType, const char *text)
@@ -187,7 +205,7 @@ static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state)
* 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, bool predivide)
{
ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor;
@@ -252,6 +270,7 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc
glUseProgram(state->program);
glUniform1i(glGetUniformLocation(state->program, "tex1"), 0);
glUniform1i(glGetUniformLocation(state->program, "tex2"), 1);
+ glUniform1i(glGetUniformLocation(state->program, "predivide"), predivide);
return true;
}
diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h
index a356821fb53..af2dc884508 100644
--- a/source/blender/editors/include/BIF_glutil.h
+++ b/source/blender/editors/include/BIF_glutil.h
@@ -144,17 +144,17 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int fo
* 1-to-1 mapping to screen space.
*/
-void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect);
+void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect);
/**
* glaDrawPixelsAuto - Switches between texture or pixel drawing using UserDef.
* only RGBA
* needs glaDefine2DArea to be set.
*/
-void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect);
+void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect);
-void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect, float scaleX, float scaleY);
+void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect, float scaleX, float scaleY);
/* 2D Drawing Assistance */
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 6edbb90febe..c0f1ed28b3f 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -454,7 +454,7 @@ void ui_draw_but_IMAGE(ARegion *UNUSED(ar), uiBut *but, uiWidgetColors *UNUSED(w
float facy = (float)h / (float)ibuf->y;
glPixelZoom(facx, facy);
}
- glaDrawPixelsAuto((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect);
+ glaDrawPixelsAuto((float)rect->xmin, (float)rect->ymin, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect);
glPixelZoom(1.0f, 1.0f);
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 90c80cae1ad..6832cd5baa0 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -429,10 +429,38 @@ static void render_endjob(void *rjv)
nodeUpdateID(rj->scene->nodetree, &rj->scene->id);
WM_main_add_notifier(NC_NODE | NA_EDITED, rj->scene);
}
-
+
/* XXX render stability hack */
G.is_rendering = FALSE;
WM_main_add_notifier(NC_WINDOW, NULL);
+
+ /* Partial render result will always update display buffer
+ * for first render layer only. This is nice because you'll
+ * see render progress during rendering, but it ends up in
+ * wrong display buffer shown after rendering.
+ *
+ * The code below will mark display buffer as invalid after
+ * rendering in case multiple layers were rendered, which
+ * ensures display buffer matches render layer after
+ * rendering.
+ *
+ * Perhaps proper way would be to toggle active render
+ * layer in image editor and job, so we always display
+ * layer being currently rendered. But this is not so much
+ * trivial at this moment, especially because of external
+ * engine API, so lets use simple and robust way for now
+ * - sergey -
+ */
+ if (rj->scene->r.layers.first != rj->scene->r.layers.last) {
+ void *lock;
+ Image *ima = rj->image;
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, &rj->iuser, &lock);
+
+ if (ibuf)
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+ }
}
/* called by render, check job 'stop' value or the global */
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index b5c2b106a15..ec1a085f9da 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -42,6 +42,7 @@
#include "BLI_threads.h"
#include "BKE_blender.h"
+#include "BKE_global.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
@@ -488,7 +489,7 @@ static int get_cached_work_texture(int *w_r, int *h_r)
return texid;
}
-void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect, float scaleX, float scaleY)
+void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect, float scaleX, float scaleY)
{
unsigned char *uc_rect = (unsigned char *) rect;
float *f_rect = (float *)rect;
@@ -498,7 +499,8 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
int subpart_x, subpart_y, tex_w, tex_h;
int seamless, offset_x, offset_y, nsubparts_x, nsubparts_y;
int texid = get_cached_work_texture(&tex_w, &tex_h);
-
+ int components;
+
/* Specify the color outside this function, and tex will modulate it.
* This is useful for changing alpha without using glPixelTransferf()
*/
@@ -525,13 +527,22 @@ 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) {
+ if (format == GL_RGBA)
+ components = 4;
+ else if (format == GL_RGB)
+ components = 3;
+ else if (format == GL_LUMINANCE)
+ components = 1;
+ else
+ BLI_assert(!"Incompatible format passed to glaDrawPixelsTexScaled");
+
+ if (type == 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);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, tex_w, tex_h, 0, format, 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);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, format, GL_UNSIGNED_BYTE, NULL);
}
for (subpart_y = 0; subpart_y < nsubparts_y; subpart_y++) {
@@ -551,26 +562,26 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
if (subpart_w <= seamless || subpart_h <= seamless)
continue;
- if (format == GL_FLOAT) {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, GL_RGBA, GL_FLOAT, &f_rect[subpart_y * offset_y * img_w * 4 + subpart_x * offset_x * 4]);
+ if (type == GL_FLOAT) {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_FLOAT, &f_rect[subpart_y * offset_y * img_w * components + subpart_x * offset_x * components]);
/* add an extra border of pixels so linear looks ok at edges of full image. */
if (subpart_w < tex_w)
- glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, GL_RGBA, GL_FLOAT, &f_rect[subpart_y * offset_y * img_w * 4 + (subpart_x * offset_x + subpart_w - 1) * 4]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_FLOAT, &f_rect[subpart_y * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
if (subpart_h < tex_h)
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, GL_RGBA, GL_FLOAT, &f_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * 4 + subpart_x * offset_x * 4]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, GL_FLOAT, &f_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]);
if (subpart_w < tex_w && subpart_h < tex_h)
- glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, GL_RGBA, GL_FLOAT, &f_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * 4 + (subpart_x * offset_x + subpart_w - 1) * 4]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_FLOAT, &f_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
}
else {
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, GL_RGBA, GL_UNSIGNED_BYTE, &uc_rect[subpart_y * offset_y * img_w * 4 + subpart_x * offset_x * 4]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subpart_w, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[subpart_y * offset_y * img_w * components + subpart_x * offset_x * components]);
if (subpart_w < tex_w)
- glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, GL_RGBA, GL_UNSIGNED_BYTE, &uc_rect[subpart_y * offset_y * img_w * 4 + (subpart_x * offset_x + subpart_w - 1) * 4]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, 0, 1, subpart_h, format, GL_UNSIGNED_BYTE, &uc_rect[subpart_y * offset_y * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
if (subpart_h < tex_h)
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, GL_RGBA, GL_UNSIGNED_BYTE, &uc_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * 4 + subpart_x * offset_x * 4]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, subpart_h, subpart_w, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * components + subpart_x * offset_x * components]);
if (subpart_w < tex_w && subpart_h < tex_h)
- glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &uc_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * 4 + (subpart_x * offset_x + subpart_w - 1) * 4]);
+ glTexSubImage2D(GL_TEXTURE_2D, 0, subpart_w, subpart_h, 1, 1, format, GL_UNSIGNED_BYTE, &uc_rect[(subpart_y * offset_y + subpart_h - 1) * img_w * components + (subpart_x * offset_x + subpart_w - 1) * components]);
}
glEnable(GL_TEXTURE_2D);
@@ -601,9 +612,9 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format,
#endif
}
-void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect)
+void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect)
{
- glaDrawPixelsTexScaled(x, y, img_w, img_h, format, zoomfilter, rect, 1.0f, 1.0f);
+ glaDrawPixelsTexScaled(x, y, img_w, img_h, format, type, zoomfilter, rect, 1.0f, 1.0f);
}
void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int format, int type, void *rect)
@@ -686,7 +697,7 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int fo
}
/* uses either DrawPixelsSafe or DrawPixelsTex, based on user defined maximum */
-void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int zoomfilter, void *rect)
+void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int type, int zoomfilter, void *rect)
{
if (U.image_gpubuffer_limit) {
/* Megapixels, use float math to prevent overflow */
@@ -694,11 +705,11 @@ void glaDrawPixelsAuto(float x, float y, int img_w, int img_h, int format, int z
if (U.image_gpubuffer_limit > (int)img_size) {
glColor4f(1.0, 1.0, 1.0, 1.0);
- glaDrawPixelsTex(x, y, img_w, img_h, format, zoomfilter, rect);
+ glaDrawPixelsTex(x, y, img_w, img_h, format, type, zoomfilter, rect);
return;
}
}
- glaDrawPixelsSafe(x, y, img_w, img_h, img_w, GL_RGBA, format, rect);
+ glaDrawPixelsSafe(x, y, img_w, img_h, img_w, format, type, rect);
}
/* 2D Drawing Assistance */
@@ -1017,22 +1028,83 @@ void bglFlush(void)
/* 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 force_fallback = false;
bool need_fallback = true;
- /* Bytes and dithering are not supported on GLSL yet */
+ /* Early out */
+ if (ibuf->rect == NULL && ibuf->rect_float == NULL)
+ return;
+
+ /* Dithering is not supported on GLSL yet */
+ force_fallback = ibuf->dither != 0.0f;
+
+ /* Single channel images could not be transformed using GLSL yet */
+ force_fallback = ibuf->channels == 1;
- /* WORKAROUND: only use GLSL if there's no byte buffer at all,
- * this is because of how render results are handled,
- * they're not updating image buffer's float buffer,
- * but writes data directly to it's byte buffer and
- * modifies display buffer.
+ /* This is actually lots of crap, but currently not sure about
+ * more clear way to bypass partial buffer update crappyness
+ * while rendering.
+ *
+ * The thing is -- render engines are only updating byte and
+ * display buffers for active render result opened in image
+ * editor. This works fine to show render progress without
+ * switching render layers in image editor user, but this is
+ * completely useless for GLSL display, where we need to have
+ * original buffer which we could color manage.
+ *
+ * For the time of rendering, we'll stick back to slower CPU
+ * display buffer update. GLSL could be used as soon as some
+ * fixes (?) are done in render itself, so we'll always have
+ * image buffer with relevant float buffer opened while
+ * rendering.
+ *
+ * On the other hand, when using Cycles, stressing GPU with
+ * GLSL could backfire on a performance.
+ * - sergey -
*/
- if (ibuf->rect == NULL && ibuf->rect_float && ibuf->dither == 0.0f) {
- if (IMB_colormanagement_setup_glsl_draw_from_ctx(C)) {
+ if (G.is_rendering) {
+ /* Try to detect whether we're drawing render result,
+ * other images could have both rect and rect_float
+ * but they'll be synchronized
+ */
+ if (ibuf->rect_float && ibuf->rect &&
+ ((ibuf->mall & IB_rectfloat) == 0))
+ {
+ force_fallback = true;
+ }
+ }
+
+ /* Try to draw buffer using GLSL display transform */
+ if (force_fallback == false) {
+ int ok;
+
+ if (ibuf->rect_float)
+ ok = IMB_colormanagement_setup_glsl_draw_ctx(C, TRUE);
+ else
+ ok = IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, ibuf->rect_colorspace, FALSE);
+
+ if (ok) {
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);
+ if (ibuf->rect_float) {
+ int format;
+
+ if (ibuf->channels == 3)
+ format = GL_RGB;
+ else if (ibuf->channels == 4)
+ format = GL_RGBA;
+ else
+ BLI_assert(!"Incompatible number of channels for GLSL display");
+
+ glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, format, GL_FLOAT,
+ zoomfilter, ibuf->rect_float);
+ }
+ else if (ibuf->rect) {
+ /* ibuf->rect is always RGBA */
+ glaDrawPixelsTex(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
+ zoomfilter, ibuf->rect);
+ }
IMB_colormanagement_finish_glsl_draw();
@@ -1040,6 +1112,7 @@ void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int
}
}
+ /* In case GLSL failed or not usable, fallback to glaDrawPixelsAuto */
if (need_fallback) {
unsigned char *display_buffer;
void *cache_handle;
@@ -1047,7 +1120,8 @@ void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int
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);
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE,
+ zoomfilter, display_buffer);
IMB_display_buffer_release(cache_handle);
}
@@ -1057,6 +1131,8 @@ void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int
*
* See IMB_colormanagement_setup_transform_from_role_glsl description for
* some more details
+ *
+ * NOTE: this only works for RGBA buffers!
*/
int glaBufferTransformFromRole_glsl(float *buffer, int width, int height, int role)
{
@@ -1071,7 +1147,7 @@ int glaBufferTransformFromRole_glsl(float *buffer, int width, int height, int ro
GPU_offscreen_bind(ofs);
- if (!IMB_colormanagement_setup_transform_from_role_glsl(role)) {
+ if (!IMB_colormanagement_setup_transform_from_role_glsl(role, TRUE)) {
GPU_offscreen_unbind(ofs);
GPU_offscreen_free(ofs);
return FALSE;
@@ -1085,9 +1161,9 @@ int glaBufferTransformFromRole_glsl(float *buffer, int width, int height, int ro
glPushMatrix();
glaDefine2DArea(&display_rect);
- glLoadIdentity();
- glaDrawPixelsTex(0, 0, width, height, GL_FLOAT, GL_NEAREST, buffer);
+ glaDrawPixelsTex(0, 0, width, height, GL_RGBA, GL_FLOAT,
+ GL_NEAREST, buffer);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 1c677d7c006..601c86b3029 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -376,7 +376,7 @@ static void file_draw_preview(uiBlock *block, struct direntry *file, int sx, int
/* the image */
glColor4f(1.0, 1.0, 1.0, 1.0);
- glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_UNSIGNED_BYTE, GL_NEAREST, imb->rect, scale, scale);
+ glaDrawPixelsTexScaled((float)xco, (float)yco, imb->x, imb->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, imb->rect, scale, scale);
/* border */
if (dropshadow) {
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index 5e5b2ece8c9..d7206c9b111 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -3011,7 +3011,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPixelZoom(snode->zoom, snode->zoom);
- glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer);
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer);
glPixelZoom(1.0f, 1.0f);
glDisable(GL_BLEND);
@@ -3019,7 +3019,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode)
else {
glPixelZoom(snode->zoom, snode->zoom);
- glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer);
+ glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer);
glPixelZoom(1.0f, 1.0f);
}
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index f1915a82f69..39b12b321dd 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -710,7 +710,7 @@ static void node_draw_preview(bNodePreview *preview, rctf *prv)
glColor4f(1.0, 1.0, 1.0, 1.0);
glPixelZoom(scale, scale);
- glaDrawPixelsTex(draw_rect.xmin, draw_rect.ymin, preview->xsize, preview->ysize, GL_UNSIGNED_BYTE, GL_LINEAR, preview->rect);
+ glaDrawPixelsTex(draw_rect.xmin, draw_rect.ymin, preview->xsize, preview->ysize, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, preview->rect);
glPixelZoom(1.0f, 1.0f);
glDisable(GL_BLEND);
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 2f0a2b7cb7a..6a450f6415e 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -618,7 +618,7 @@ static void draw_empty_image(Object *ob, const short dflag, const unsigned char
glColor4fv(ob->col);
/* Draw the Image on the screen */
- glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
+ glaDrawPixelsTex(ofs_x, ofs_y, ima_x, ima_y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
glDisable(GL_BLEND);
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index b6d46f82e6a..d0437c77af7 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1831,7 +1831,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
* glaDrawPixelsSafe in some cases, which will end up in misssing
* alpha transparency for the background image (sergey)
*/
- glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
+ glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect);
glPixelZoom(1.0, 1.0);
glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index a758cfa04f0..203d01cab67 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -152,14 +152,22 @@ void IMB_colormanagement_processor_free(struct ColormanageProcessor *cm_processo
/* 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);
-/* 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);
+ const struct ColorManagedDisplaySettings *display_settings,
+ int predivide);
+/* Same as above, but display space conversion happens from a specified space */
+int IMB_colormanagement_setup_glsl_draw_from_space(const struct ColorManagedViewSettings *view_settings,
+ const struct ColorManagedDisplaySettings *display_settings,
+ struct ColorSpace *colorspace,
+ int predivide);
+/* Same as setup_glsl_draw, but color management settings are guessing from a given context */
+int IMB_colormanagement_setup_glsl_draw_ctx(const struct bContext *C, int predivide);
+/* Same as setup_glsl_draw_from_space, but color management settings are guessing from a given context */
+int IMB_colormanagement_setup_glsl_draw_from_space_ctx(const struct bContext *C, struct ColorSpace *colorspace, int predivide);
/* 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);
+int IMB_colormanagement_setup_transform_from_role_glsl(int role, int predivide);
/* Finish GLSL-based color space conversion */
void IMB_colormanagement_finish_glsl_transform(void);
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 3ed69550873..1e6fac4f4f0 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -109,6 +109,7 @@ static struct global_glsl_state {
/* Settings of processor for comparison. */
char view[MAX_COLORSPACE_NAME];
char display[MAX_COLORSPACE_NAME];
+ char input[MAX_COLORSPACE_NAME];
float exposure, gamma;
/* Container for GLSL state needed for OCIO module. */
@@ -703,8 +704,10 @@ static ColorSpace *display_transform_get_colorspace(const ColorManagedViewSettin
return NULL;
}
-static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform, const char *display,
- float exposure, float gamma)
+static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *view_transform,
+ const char *display,
+ float exposure, float gamma,
+ const char *from_colorspace)
{
OCIO_ConstConfigRcPtr *config = OCIO_getCurrentConfig();
OCIO_DisplayTransformRcPtr *dt;
@@ -712,8 +715,7 @@ static OCIO_ConstProcessorRcPtr *create_display_buffer_processor(const char *vie
dt = OCIO_createDisplayTransform();
- /* assuming handling buffer was already converted to scene linear space */
- OCIO_displayTransformSetInputColorSpaceName(dt, global_role_scene_linear);
+ OCIO_displayTransformSetInputColorSpaceName(dt, from_colorspace);
OCIO_displayTransformSetView(dt, view_transform);
OCIO_displayTransformSetDisplay(dt, display);
@@ -2621,7 +2623,8 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManag
cm_processor->is_data_result = display_space->is_data;
cm_processor->processor = create_display_buffer_processor(applied_view_settings->view_transform, display_settings->display_device,
- applied_view_settings->exposure, applied_view_settings->gamma);
+ applied_view_settings->exposure, applied_view_settings->gamma,
+ global_role_scene_linear);
if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) {
cm_processor->curve_mapping = curvemapping_copy(applied_view_settings->curve_mapping);
@@ -2718,26 +2721,30 @@ void IMB_colormanagement_processor_free(ColormanageProcessor *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)
+ const ColorManagedDisplaySettings *display_settings,
+ const char *from_colorspace)
{
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));
+ STREQ(global_glsl_state.display, display_settings->display_device) &&
+ STREQ(global_glsl_state.input, from_colorspace));
}
static void update_glsl_display_processor(const ColorManagedViewSettings *view_settings,
- const ColorManagedDisplaySettings *display_settings)
+ const ColorManagedDisplaySettings *display_settings,
+ const char *from_colorspace)
{
/* 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))
+ check_glsl_display_processor_changed(view_settings, display_settings, from_colorspace))
{
/* 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);
+ strcpy(global_glsl_state.input, from_colorspace);
global_glsl_state.exposure = view_settings->exposure;
global_glsl_state.gamma = view_settings->gamma;
@@ -2750,13 +2757,14 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
create_display_buffer_processor(global_glsl_state.view,
global_glsl_state.display,
global_glsl_state.exposure,
- global_glsl_state.gamma);
+ global_glsl_state.gamma,
+ global_glsl_state.input);
}
}
/**
- * Configures GLSL shader for conversion from scene linear
- * to display space
+ * Configures GLSL shader for conversion from specified to
+ * display color space
*
* Will create appropriate OCIO processor and setup GLSL shader,
* so further 2D texture usage will use this conversion.
@@ -2767,8 +2775,9 @@ static void update_glsl_display_processor(const ColorManagedViewSettings *view_s
* 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)
+int IMB_colormanagement_setup_glsl_draw_from_space(const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings,
+ struct ColorSpace *from_colorspace, int predivide)
{
ColorManagedViewSettings default_view_settings;
const ColorManagedViewSettings *applied_view_settings;
@@ -2790,20 +2799,36 @@ int IMB_colormanagement_setup_glsl_draw(const ColorManagedViewSettings *view_set
return FALSE;
/* Make sure OCIO processor is up-to-date. */
- update_glsl_display_processor(applied_view_settings, display_settings);
+ update_glsl_display_processor(applied_view_settings, display_settings,
+ from_colorspace ? from_colorspace->name : global_role_scene_linear);
+
+ return OCIO_setupGLSLDraw(&global_glsl_state.ocio_glsl_state, global_glsl_state.processor, predivide);
+}
- return OCIO_setupGLSLDraw(&global_glsl_state.ocio_glsl_state, global_glsl_state.processor);
+/* Configures GLSL shader for conversion from scene linear to display space */
+int IMB_colormanagement_setup_glsl_draw(const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings,
+ int predivide)
+{
+ return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings,
+ NULL, predivide);
}
-/* Same as above, but color management settings are guessing from a given context */
-int IMB_colormanagement_setup_glsl_draw_from_ctx(const bContext *C)
+/* Same as setup_glsl_draw_from_space, but color management settings are guessing from a given context */
+int IMB_colormanagement_setup_glsl_draw_from_space_ctx(const struct bContext *C, struct ColorSpace *from_colorspace, int predivide)
{
ColorManagedViewSettings *view_settings;
ColorManagedDisplaySettings *display_settings;
display_transform_get_from_ctx(C, &view_settings, &display_settings);
- return IMB_colormanagement_setup_glsl_draw(view_settings, display_settings);
+ return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, from_colorspace, predivide);
+}
+
+/* Same as setup_glsl_draw, but color management settings are guessing from a given context */
+int IMB_colormanagement_setup_glsl_draw_ctx(const bContext *C, int predivide)
+{
+ return IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, NULL, predivide);
}
/* Finish GLSL-based display space conversion */
@@ -2827,7 +2852,7 @@ void IMB_colormanagement_finish_glsl_draw(void)
* 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)
+int IMB_colormanagement_setup_transform_from_role_glsl(int role, int predivide)
{
OCIO_ConstProcessorRcPtr *processor;
ColorSpace *colorspace;
@@ -2836,7 +2861,7 @@ int IMB_colormanagement_setup_transform_from_role_glsl(int role)
processor = colorspace_to_scene_linear_processor(colorspace);
- return OCIO_setupGLSLDraw(&global_glsl_state.transform_ocio_glsl_state, processor);
+ return OCIO_setupGLSLDraw(&global_glsl_state.transform_ocio_glsl_state, processor, predivide);
}
/* Finish GLSL-based color space conversion */
diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c
index ed066117b28..0c78338c18a 100644
--- a/source/blender/windowmanager/intern/wm_dragdrop.c
+++ b/source/blender/windowmanager/intern/wm_dragdrop.c
@@ -323,7 +323,7 @@ void wm_drags_draw(bContext *C, wmWindow *win, rcti *rect)
drag_rect_minmax(rect, x, y, x + drag->sx, y + drag->sy);
else {
glColor4f(1.0, 1.0, 1.0, 0.65); /* this blends texture */
- glaDrawPixelsTexScaled(x, y, drag->imb->x, drag->imb->y, GL_UNSIGNED_BYTE, GL_NEAREST, drag->imb->rect, drag->scale, drag->scale);
+ glaDrawPixelsTexScaled(x, y, drag->imb->x, drag->imb->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, drag->imb->rect, drag->scale, drag->scale);
}
}
else {