Color Management, Stage 2: Switch color pipeline to use OpenColorIO
[blender.git] / source / blender / editors / space_sequencer / sequencer_draw.c
index d6a2b0a001e206ed14771626a723ff4104454bbb..7363bf2fbd8a60d51443a56ebccfa918eb19f446 100644 (file)
@@ -52,6 +52,7 @@
 
 #include "BKE_sound.h"
 
+#include "IMB_colormanagement.h"
 #include "IMB_imbuf.h"
 
 #include "BIF_gl.h"
@@ -68,6 +69,9 @@
 #include "UI_resources.h"
 #include "UI_view2d.h"
 
+#include "WM_api.h"
+#include "WM_types.h"
+
 /* own include */
 #include "sequencer_intern.h"
 
@@ -846,19 +850,65 @@ ImBuf *sequencer_ibuf_get(struct Main *bmain, Scene *scene, SpaceSeq *sseq, int
        return ibuf;
 }
 
+static void sequencer_check_scopes(SequencerScopes *scopes, ImBuf *ibuf)
+{
+       if (scopes->reference_ibuf != ibuf) {
+               if (scopes->zebra_ibuf) {
+                       IMB_freeImBuf(scopes->zebra_ibuf);
+                       scopes->zebra_ibuf = NULL;
+               }
+
+               if (scopes->waveform_ibuf) {
+                       IMB_freeImBuf(scopes->waveform_ibuf);
+                       scopes->waveform_ibuf = NULL;
+               }
+
+               if (scopes->sep_waveform_ibuf) {
+                       IMB_freeImBuf(scopes->sep_waveform_ibuf);
+                       scopes->sep_waveform_ibuf = NULL;
+               }
+
+               if (scopes->vector_ibuf) {
+                       IMB_freeImBuf(scopes->vector_ibuf);
+                       scopes->vector_ibuf = NULL;
+               }
+
+               if (scopes->histogram_ibuf) {
+                       IMB_freeImBuf(scopes->histogram_ibuf);
+                       scopes->histogram_ibuf = NULL;
+               }
+       }
+}
+
+static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scope_cb) (ImBuf *ibuf))
+{
+       ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
+       ImBuf *scope;
+
+       IMB_colormanagement_imbuf_make_display_space(display_ibuf, &scene->view_settings, &scene->display_settings);
+
+       scope = make_scope_cb(display_ibuf);
+
+       IMB_freeImBuf(display_ibuf);
+
+       return scope;
+}
+
 void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, int draw_overlay)
 {
        struct Main *bmain = CTX_data_main(C);
        struct ImBuf *ibuf = NULL;
        struct ImBuf *scope = NULL;
        struct View2D *v2d = &ar->v2d;
-       int rectx, recty;
+       /* int rectx, recty; */ /* UNUSED */
        float viewrectx, viewrecty;
        float render_size = 0.0;
        float proxy_size = 100.0;
        float col[3];
        GLuint texid;
        GLuint last_texid;
+       unsigned char *display_buffer;
+       void *cache_handle = NULL;
 
        render_size = sseq->render_size;
        if (render_size == 0) {
@@ -874,8 +924,8 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
        viewrectx = (render_size * (float)scene->r.xsch) / 100.0f;
        viewrecty = (render_size * (float)scene->r.ysch) / 100.0f;
 
-       rectx = viewrectx + 0.5f;
-       recty = viewrecty + 0.5f;
+       /* rectx = viewrectx + 0.5f; */ /* UNUSED */
+       /* recty = viewrecty + 0.5f; */ /* UNUSED */
 
        if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
                viewrectx *= scene->r.xasp / scene->r.yasp;
@@ -906,38 +956,64 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
 
        if (ibuf->rect == NULL && ibuf->rect_float == NULL)
                return;
-       
-       switch (sseq->mainb) {
-               case SEQ_DRAW_IMG_IMBUF:
-                       if (sseq->zebra != 0) {
-                               scope = make_zebra_view_from_ibuf(ibuf, sseq->zebra);
-                       }
-                       break;
-               case SEQ_DRAW_IMG_WAVEFORM:
-                       if ((sseq->flag & SEQ_DRAW_COLOR_SEPARATED) != 0) {
-                               scope = make_sep_waveform_view_from_ibuf(ibuf);
-                       }
-                       else {
-                               scope = make_waveform_view_from_ibuf(ibuf);
-                       }
-                       break;
-               case SEQ_DRAW_IMG_VECTORSCOPE:
-                       scope = make_vectorscope_view_from_ibuf(ibuf);
-                       break;
-               case SEQ_DRAW_IMG_HISTOGRAM:
-                       scope = make_histogram_view_from_ibuf(ibuf);
-                       break;
+
+       if (sseq->mainb != SEQ_DRAW_IMG_IMBUF || sseq->zebra != 0) {
+               SequencerScopes *scopes = &sseq->scopes;
+
+               sequencer_check_scopes(scopes, ibuf);
+
+               switch (sseq->mainb) {
+                       case SEQ_DRAW_IMG_IMBUF:
+                               if (!scopes->zebra_ibuf) {
+                                       ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
+
+                                       IMB_colormanagement_imbuf_make_display_space(display_ibuf, &scene->view_settings, &scene->display_settings);
+                                       scopes->zebra_ibuf = make_zebra_view_from_ibuf(display_ibuf, sseq->zebra);
+                                       IMB_freeImBuf(display_ibuf);
+                               }
+                               scope = scopes->zebra_ibuf;
+                               break;
+                       case SEQ_DRAW_IMG_WAVEFORM:
+                               if ((sseq->flag & SEQ_DRAW_COLOR_SEPARATED) != 0) {
+                                       if (!scopes->sep_waveform_ibuf)
+                                               scopes->sep_waveform_ibuf = sequencer_make_scope(scene, ibuf, make_sep_waveform_view_from_ibuf);
+                                       scope = scopes->sep_waveform_ibuf;
+                               }
+                               else {
+                                       if (!scopes->waveform_ibuf)
+                                               scopes->waveform_ibuf = sequencer_make_scope(scene, ibuf, make_waveform_view_from_ibuf);
+                                       scope = scopes->waveform_ibuf;
+                               }
+                               break;
+                       case SEQ_DRAW_IMG_VECTORSCOPE:
+                               if (!scopes->vector_ibuf)
+                                       scopes->vector_ibuf = sequencer_make_scope(scene, ibuf, make_vectorscope_view_from_ibuf);
+                               scope = scopes->vector_ibuf;
+                               break;
+                       case SEQ_DRAW_IMG_HISTOGRAM:
+                               if (!scopes->histogram_ibuf)
+                                       scopes->histogram_ibuf = sequencer_make_scope(scene, ibuf, make_histogram_view_from_ibuf);
+                               scope = scopes->histogram_ibuf;
+                               break;
+               }
+
+               scopes->reference_ibuf = ibuf;
        }
 
        if (scope) {
                IMB_freeImBuf(ibuf);
                ibuf = scope;
-       }
 
-       if (ibuf->rect_float && ibuf->rect == NULL) {
-               IMB_rect_from_float(ibuf);      
+               if (ibuf->rect_float && ibuf->rect == NULL) {
+                       IMB_rect_from_float(ibuf);
+               }
+
+               display_buffer = (unsigned char *)ibuf->rect;
        }
-       
+       else {
+               display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
+       }
+
        /* setting up the view - actual drawing starts here */
        UI_view2d_view_ortho(v2d);
 
@@ -950,7 +1026,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
-       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
+       glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer);
        glBegin(GL_QUADS);
 
        if (draw_overlay) {
@@ -1030,7 +1106,8 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
        /* draw grease-pencil (image aligned) */
        draw_gpencil_2dimage(C);
 
-       IMB_freeImBuf(ibuf);
+       if (!scope)
+               IMB_freeImBuf(ibuf);
        
        /* ortho at pixel level */
        UI_view2d_view_restore(C);
@@ -1049,6 +1126,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
 
                if (mask) {
                        int width, height;
+                       float aspx = 1.0f, aspy = 1.0f;
                        // ED_mask_get_size(C, &width, &height);
 
                        //Scene *scene = CTX_data_scene(C);
@@ -1058,11 +1136,14 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
                        ED_mask_draw_region(mask, ar,
                                            0, 0,  /* TODO */
                                            width, height,
+                                           aspx, aspy,
                                            FALSE, TRUE,
                                            NULL, C);
                }
        }
 
+       if (cache_handle)
+               IMB_display_buffer_release(cache_handle);
 }
 
 #if 0