Refactors preview drawing code with few functional modifications:
authorRichard Antalik <richardantalik@gmail.com>
Wed, 27 Feb 2019 21:48:27 +0000 (13:48 -0800)
committerRichard Antalik <richardantalik@gmail.com>
Wed, 27 Feb 2019 21:48:27 +0000 (13:48 -0800)
Fix T61241

 - Changing preview size does not affect drawn image size, only resolution.
 -- Consistent behavior, when changing full-size / proxy / scene render size
 -- Scopes are rendered in *same size* as source image
 -- Over all, user does not have to readjust preview zoom.

Reviewed by: Brecht

Differential revision: https://developer.blender.org/D4315

source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_sequencer/sequencer_intern.h
source/blender/editors/space_sequencer/space_sequencer.c

index 089a30b..fc33ec3 100644 (file)
@@ -985,30 +985,13 @@ static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scop
        return scope;
 }
 
-static void sequencer_display_size(Scene *scene, SpaceSeq *sseq, float r_viewrect[2])
+static void sequencer_display_size(Scene *scene, float r_viewrect[2])
 {
-       float render_size, proxy_size;
+       r_viewrect[0] = (float)scene->r.xsch;
+       r_viewrect[1] = (float)scene->r.ysch;
 
-       if (sseq->render_size == SEQ_PROXY_RENDER_SIZE_SCENE) {
-               render_size = (float)scene->r.size / 100.0f;
-               proxy_size = 1.0f;
-       }
-       else {
-               render_size = (float)sseq->render_size / 100.0f;
-               proxy_size = render_size;
-       }
-
-       r_viewrect[0] = (render_size * (float)scene->r.xsch);
-       r_viewrect[1] = (render_size * (float)scene->r.ysch);
-
-       /* rectx = viewrectx + 0.5f; */ /* UNUSED */
-       /* recty = viewrecty + 0.5f; */ /* UNUSED */
-
-       if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
-               r_viewrect[0] *= scene->r.xasp / scene->r.yasp;
-               r_viewrect[0] /= proxy_size;
-               r_viewrect[1] /= proxy_size;
-       }
+       /* Aspect ratio seems to have no effect on output image*/
+       /* r_viewrect[0] *= scene->r.xasp / scene->r.yasp; */
 }
 
 static void sequencer_draw_gpencil(const bContext *C)
@@ -1069,43 +1052,105 @@ static void sequencer_draw_borders(const SpaceSeq *sseq, const View2D *v2d, cons
        immUnbindProgram();
 }
 
-/* draws checkerboard background for transparent content */
-static void sequencer_draw_background(
-        const SpaceSeq *sseq, View2D *v2d, const float viewrect[2], const bool draw_overlay)
+#if 0
+void sequencer_draw_maskedit(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq)
 {
-       /* setting up the view */
-       UI_view2d_totRect_set(v2d, viewrect[0] + 0.5f, viewrect[1] + 0.5f);
-       UI_view2d_curRect_validate(v2d);
-       UI_view2d_view_ortho(v2d);
+       /* NOTE: sequencer mask editing isnt finished, the draw code is working but editing not,
+       * for now just disable drawing since the strip frame will likely be offset */
 
-       /* only draw alpha for main buffer */
-       if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
-               if ((sseq->flag & SEQ_USE_ALPHA) && !draw_overlay) {
-                       imm_draw_box_checker_2d(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
+       // if (sc->mode == SC_MODE_MASKEDIT)
+       if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
+               Mask *mask = BKE_sequencer_mask_get(scene);
+
+               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);
+                       width = (scene->r.size * scene->r.xsch) / 100;
+                       height = (scene->r.size * scene->r.ysch) / 100;
+
+                       ED_mask_draw_region(mask, ar,
+                               0, 0, 0,  /* TODO */
+                               width, height,
+                               aspx, aspy,
+                               false, true,
+                               NULL, C);
                }
        }
 }
+#endif
 
-void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay, bool draw_backdrop)
+static void *sequencer_OCIO_transform_ibuf(const bContext *C, ImBuf *ibuf, bool *glsl_used, int *format, int *type)
 {
-       struct Main *bmain = CTX_data_main(C);
-       struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
-       struct ImBuf *ibuf = NULL;
-       struct ImBuf *scope = NULL;
-       struct View2D *v2d = &ar->v2d;
-       /* int rectx, recty; */ /* UNUSED */
-       float viewrect[2];
-       float col[3];
-       GLuint texid;
        void *display_buffer;
        void *cache_handle = NULL;
-       const bool is_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
-       int format, type;
-       bool glsl_used = false;
-       const bool draw_gpencil = ((sseq->flag & SEQ_SHOW_GPENCIL) && sseq->gpd);
-       const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
-       bool draw_metadata = false;
+       bool force_fallback = false;
+       *glsl_used = false;
+       force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);
+       force_fallback |= (ibuf->dither != 0.0f);
+
+       if (force_fallback) {
+               /* Fallback to CPU based color space conversion */
+               *glsl_used = false;
+               *format = GL_RGBA;
+               *type = GL_UNSIGNED_BYTE;
+               display_buffer = NULL;
+       }
+       else if (ibuf->rect_float) {
+               display_buffer = ibuf->rect_float;
+
+               if (ibuf->channels == 4) {
+                       *format = GL_RGBA;
+               }
+               else if (ibuf->channels == 3) {
+                       *format = GL_RGB;
+               }
+               else {
+                       BLI_assert(!"Incompatible number of channels for float buffer in sequencer");
+                       *format = GL_RGBA;
+                       display_buffer = NULL;
+               }
+
+               *type = GL_FLOAT;
+
+               if (ibuf->float_colorspace) {
+                       *glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, ibuf->float_colorspace, ibuf->dither, true);
+               }
+               else {
+                       *glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true);
+               }
+       }
+       else if (ibuf->rect) {
+               display_buffer = ibuf->rect;
+               *format = GL_RGBA;
+               *type = GL_UNSIGNED_BYTE;
+
+               *glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, ibuf->rect_colorspace, ibuf->dither, false);
+       }
+       else {
+               *format = GL_RGBA;
+               *type = GL_UNSIGNED_BYTE;
+               display_buffer = NULL;
+       }
+
+       /* there's a data to be displayed, but GLSL is not initialized
+        * properly, in this case we fallback to CPU-based display transform
+        */
+       if ((ibuf->rect || ibuf->rect_float) && !*glsl_used) {
+               display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
+               *format = GL_RGBA;
+               *type = GL_UNSIGNED_BYTE;
+       }
+       if (cache_handle)
+               IMB_display_buffer_release(cache_handle);
 
+       return display_buffer;
+}
+
+static void sequencer_stop_running_jobs(const bContext *C, Scene *scene)
+{
        if (G.is_rendering == false && (scene->r.seq_prev_type) == OB_RENDER) {
                /* stop all running jobs, except screen one. currently previews frustrate Render
                 * needed to make so sequencer's rendering doesn't conflict with compositor
@@ -1117,105 +1162,52 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
                 */
                WM_jobs_kill_type(CTX_wm_manager(C), NULL, WM_JOB_TYPE_RENDER_PREVIEW);
        }
+}
 
-       if ((!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) && !draw_backdrop) {
-               UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col);
-               GPU_clear_color(col[0], col[1], col[2], 0.0);
-               GPU_clear(GPU_COLOR_BIT);
-       }
-
-       /* only initialize the preview if a render is in progress */
-       if (G.is_rendering)
-               return;
-
-       if (sseq->render_size == SEQ_PROXY_RENDER_SIZE_NONE) {
-               return;
-       }
-
-       /* for now we only support Left/Right */
-       ibuf = sequencer_ibuf_get(bmain, depsgraph, scene, sseq, cfra, frame_ofs, names[sseq->multiview_eye]);
+static void sequencer_preview_clear()
+{
+       float col[3];
 
-       if ((ibuf == NULL) ||
-           (ibuf->rect == NULL && ibuf->rect_float == NULL))
-       {
-               sequencer_display_size(scene, sseq, viewrect);
+       UI_GetThemeColor3fv(TH_SEQ_PREVIEW, col);
+       GPU_clear_color(col[0], col[1], col[2], 0.0);
+       GPU_clear(GPU_COLOR_BIT);
+}
 
-               sequencer_draw_background(sseq, v2d, viewrect, false);
-               sequencer_draw_borders(sseq, v2d, scene);
+static void sequencer_preview_get_rect(rctf *preview, Scene *scene, ARegion *ar, SpaceSeq *sseq, bool draw_overlay, bool draw_backdrop)
+{
+       struct View2D *v2d = &ar->v2d;
+       float viewrect[2];
 
-               /* gpencil can also be drawn without a valid imbuf */
-               if ((draw_gpencil && is_imbuf) && !draw_overlay) {
-                       sequencer_draw_gpencil(C);
-               }
+       sequencer_display_size(scene, viewrect);
+       BLI_rctf_init(preview, -1.0f, 1.0f, -1.0f, 1.0f);
 
-               UI_view2d_view_restore(C);
-               return;
+       if (draw_overlay && sseq->overlay_type == SEQ_DRAW_OVERLAY_RECT) {
+               preview->xmax = v2d->tot.xmin + (fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->over_border.xmax);
+               preview->xmin = v2d->tot.xmin + (fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->over_border.xmin);
+               preview->ymax = v2d->tot.ymin + (fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->over_border.ymax);
+               preview->ymin = v2d->tot.ymin + (fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->over_border.ymin);
        }
+       else if (draw_backdrop) {
+               float aspect = BLI_rcti_size_x(&ar->winrct) / (float)BLI_rcti_size_y(&ar->winrct);
+               float image_aspect = viewrect[0] / viewrect[1];
 
-       sequencer_display_size(scene, sseq, viewrect);
-
-       if (!draw_backdrop && (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);
-
-                                       if (display_ibuf->rect_float) {
-                                               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;
-               }
-
-               /* future files may have new scopes we don't catch above */
-               if (scope) {
-                       scopes->reference_ibuf = ibuf;
-                       if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
-                               /* scopes drawn in image preview use viewrect from orig ibuf - currently that's only zebra */
-                       }
-                       else {
-                               viewrect[0] = scope->x;
-                               viewrect[1] = scope->y;
-                       }
+               if (aspect >= image_aspect) {
+                       preview->xmax = image_aspect / aspect;
+                       preview->xmin = -preview->xmax;
                }
                else {
-                       scopes->reference_ibuf = NULL;
+                       preview->ymax = aspect / image_aspect;
+                       preview->ymin = -preview->ymax;
                }
        }
-
-       if (!draw_backdrop) {
-               sequencer_draw_background(sseq, v2d, viewrect, draw_overlay);
+       else {
+               *preview = v2d->tot;
        }
+}
+
+static void sequencer_draw_display_buffer(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, ImBuf *ibuf, ImBuf *scope, bool draw_overlay, bool draw_backdrop)
+{
+       void *display_buffer;
 
        if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
                GPU_blend(true);
@@ -1225,12 +1217,14 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
        /* Format needs to be created prior to any immBindProgram call.
         * Do it here because OCIO binds it's own shader.
         */
+       int format, type;
+       bool glsl_used = false;
+       GLuint texid;
        GPUVertFormat *imm_format = immVertexFormat();
        uint pos = GPU_vertformat_attr_add(imm_format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
        uint texCoord = GPU_vertformat_attr_add(imm_format, "texCoord", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
 
        if (scope) {
-               IMB_freeImBuf(ibuf);
                ibuf = scope;
 
                if (ibuf->rect_float && ibuf->rect == NULL) {
@@ -1242,63 +1236,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
                type = GL_UNSIGNED_BYTE;
        }
        else {
-               bool force_fallback = false;
-
-               force_fallback |= (U.image_draw_method != IMAGE_DRAW_METHOD_GLSL);
-               force_fallback |= (ibuf->dither != 0.0f);
-
-               if (force_fallback) {
-                       /* Fallback to CPU based color space conversion */
-                       glsl_used = false;
-                       format = GL_RGBA;
-                       type = GL_UNSIGNED_BYTE;
-                       display_buffer = NULL;
-               }
-               else if (ibuf->rect_float) {
-                       display_buffer = ibuf->rect_float;
-
-                       if (ibuf->channels == 4) {
-                               format = GL_RGBA;
-                       }
-                       else if (ibuf->channels == 3) {
-                               format = GL_RGB;
-                       }
-                       else {
-                               BLI_assert(!"Incompatible number of channels for float buffer in sequencer");
-                               format = GL_RGBA;
-                               display_buffer = NULL;
-                       }
-
-                       type = GL_FLOAT;
-
-                       if (ibuf->float_colorspace) {
-                               glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, ibuf->float_colorspace, ibuf->dither, true);
-                       }
-                       else {
-                               glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true);
-                       }
-               }
-               else if (ibuf->rect) {
-                       display_buffer = ibuf->rect;
-                       format = GL_RGBA;
-                       type = GL_UNSIGNED_BYTE;
-
-                       glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, ibuf->rect_colorspace, ibuf->dither, false);
-               }
-               else {
-                       format = GL_RGBA;
-                       type = GL_UNSIGNED_BYTE;
-                       display_buffer = NULL;
-               }
-
-               /* there's a data to be displayed, but GLSL is not initialized
-                * properly, in this case we fallback to CPU-based display transform
-                */
-               if ((ibuf->rect || ibuf->rect_float) && !glsl_used) {
-                       display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle);
-                       format = GL_RGBA;
-                       type = GL_UNSIGNED_BYTE;
-               }
+               display_buffer = sequencer_OCIO_transform_ibuf(C, ibuf, &glsl_used, &format, &type);
        }
 
        if (draw_backdrop) {
@@ -1309,17 +1247,17 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
        }
 
        glGenTextures(1, (GLuint *)&texid);
-
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texid);
-
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 
-       if (type == GL_FLOAT)
+       if (type == GL_FLOAT) {
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, ibuf->x, ibuf->y, 0, format, type, display_buffer);
-       else
+       }
+       else {
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, format, type, display_buffer);
+       }
 
        if (!glsl_used) {
                immBindBuiltinProgram(GPU_SHADER_2D_IMAGE_COLOR);
@@ -1329,154 +1267,174 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
 
        immBegin(GPU_PRIM_TRI_FAN, 4);
 
-       if (draw_overlay) {
-               if (sseq->overlay_type == SEQ_DRAW_OVERLAY_RECT) {
-                       rctf tot_clip;
-                       tot_clip.xmin = v2d->tot.xmin + (fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->over_border.xmin);
-                       tot_clip.ymin = v2d->tot.ymin + (fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->over_border.ymin);
-                       tot_clip.xmax = v2d->tot.xmin + (fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->over_border.xmax);
-                       tot_clip.ymax = v2d->tot.ymin + (fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->over_border.ymax);
+       rctf preview;
+       rctf canvas;
+       sequencer_preview_get_rect(&preview, scene, ar, sseq, draw_overlay, draw_backdrop);
 
-                       immAttr2f(texCoord, scene->ed->over_border.xmin, scene->ed->over_border.ymin);
-                       immVertex2f(pos, tot_clip.xmin, tot_clip.ymin);
-
-                       immAttr2f(texCoord, scene->ed->over_border.xmin, scene->ed->over_border.ymax);
-                       immVertex2f(pos, tot_clip.xmin, tot_clip.ymax);
-
-                       immAttr2f(texCoord, scene->ed->over_border.xmax, scene->ed->over_border.ymax);
-                       immVertex2f(pos, tot_clip.xmax, tot_clip.ymax);
-
-                       immAttr2f(texCoord, scene->ed->over_border.xmax, scene->ed->over_border.ymin);
-                       immVertex2f(pos, tot_clip.xmax, tot_clip.ymin);
-               }
-               else if (sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) {
-                       immAttr2f(texCoord, 0.0f, 0.0f);
-                       immVertex2f(pos, v2d->tot.xmin, v2d->tot.ymin);
-
-                       immAttr2f(texCoord, 0.0f, 1.0f);
-                       immVertex2f(pos, v2d->tot.xmin, v2d->tot.ymax);
-
-                       immAttr2f(texCoord, 1.0f, 1.0f);
-                       immVertex2f(pos, v2d->tot.xmax, v2d->tot.ymax);
-
-                       immAttr2f(texCoord, 1.0f, 0.0f);
-                       immVertex2f(pos, v2d->tot.xmax, v2d->tot.ymin);
-               }
-       }
-       else if (draw_backdrop) {
-               float aspect;
-               float image_aspect = viewrect[0] / viewrect[1];
-               float imagex, imagey;
-
-               aspect = BLI_rcti_size_x(&ar->winrct) / (float)BLI_rcti_size_y(&ar->winrct);
-
-               if (aspect >= image_aspect) {
-                       imagex = image_aspect / aspect;
-                       imagey = 1.0f;
-               }
-               else {
-                       imagex = 1.0f;
-                       imagey = aspect / image_aspect;
-               }
-
-               immAttr2f(texCoord, 0.0f, 0.0f);
-               immVertex2f(pos, -imagex, -imagey);
-
-               immAttr2f(texCoord, 0.0f, 1.0f);
-               immVertex2f(pos, -imagex, imagey);
-
-               immAttr2f(texCoord, 1.0f, 1.0f);
-               immVertex2f(pos, imagex, imagey);
-
-               immAttr2f(texCoord, 1.0f, 0.0f);
-               immVertex2f(pos, imagex, -imagey);
+       if (draw_overlay && sseq->overlay_type == SEQ_DRAW_OVERLAY_RECT) {
+               canvas = scene->ed->over_border;
        }
        else {
-               draw_metadata = ((sseq->flag & SEQ_SHOW_METADATA) != 0);
+               BLI_rctf_init(&canvas, 0.0f, 1.0f, 0.0f, 1.0f);
+       }
 
-               immAttr2f(texCoord, 0.0f, 0.0f);
-               immVertex2f(pos, v2d->tot.xmin, v2d->tot.ymin);
+       immAttr2f(texCoord, canvas.xmin, canvas.ymin);
+       immVertex2f(pos, preview.xmin, preview.ymin);
 
-               immAttr2f(texCoord, 0.0f, 1.0f);
-               immVertex2f(pos, v2d->tot.xmin, v2d->tot.ymax);
+       immAttr2f(texCoord, canvas.xmin, canvas.ymax);
+       immVertex2f(pos, preview.xmin, preview.ymax);
 
-               immAttr2f(texCoord, 1.0f, 1.0f);
-               immVertex2f(pos, v2d->tot.xmax, v2d->tot.ymax);
+       immAttr2f(texCoord, canvas.xmax, canvas.ymax);
+       immVertex2f(pos, preview.xmax, preview.ymax);
 
-               immAttr2f(texCoord, 1.0f, 0.0f);
-               immVertex2f(pos, v2d->tot.xmax, v2d->tot.ymin);
-       }
+       immAttr2f(texCoord, canvas.xmax, canvas.ymin);
+       immVertex2f(pos, preview.xmax, preview.ymin);
 
        immEnd();
-
        glBindTexture(GL_TEXTURE_2D, 0);
+       glDeleteTextures(1, &texid);
 
        if (!glsl_used) {
                immUnbindProgram();
        }
+       else {
+               IMB_colormanagement_finish_glsl_draw();
+       }
 
        if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
                GPU_blend(false);
        }
 
-       glDeleteTextures(1, &texid);
+       if (draw_backdrop) {
+               GPU_matrix_pop();
+               GPU_matrix_pop_projection();
+       }
+}
 
-       if (glsl_used)
-               IMB_colormanagement_finish_glsl_draw();
+static ImBuf *sequencer_get_scope(Scene *scene, SpaceSeq *sseq, ImBuf *ibuf, bool draw_backdrop)
+{
+       struct ImBuf *scope = NULL;
+       SequencerScopes *scopes = &sseq->scopes;
 
-       if (cache_handle)
-               IMB_display_buffer_release(cache_handle);
+       if (!draw_backdrop && (sseq->mainb != SEQ_DRAW_IMG_IMBUF || sseq->zebra != 0)) {
+               sequencer_check_scopes(scopes, ibuf);
+
+
+               switch (sseq->mainb) {
+               case SEQ_DRAW_IMG_IMBUF:
+                       if (!scopes->zebra_ibuf) {
+                               ImBuf *display_ibuf = IMB_dupImBuf(ibuf);
+
+                               if (display_ibuf->rect_float) {
+                                       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;
+               }
 
-       if (draw_metadata) {
-               ED_region_image_metadata_draw(0.0, 0.0, ibuf, &v2d->tot, 1.0, 1.0);
+               /* future files may have new scopes we don't catch above */
+               if (scope) {
+                       scopes->reference_ibuf = ibuf;
+               }
        }
+       return scope;
+}
 
-       if (!scope)
-               IMB_freeImBuf(ibuf);
+void sequencer_draw_preview(
+       const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq, int cfra, int frame_ofs, bool draw_overlay, bool draw_backdrop)
+{
+       struct Main *bmain = CTX_data_main(C);
+       struct Depsgraph *depsgraph = CTX_data_depsgraph(C);
+       struct View2D *v2d = &ar->v2d;
+       struct ImBuf *ibuf = NULL;
+       struct ImBuf *scope = NULL;
+       float viewrect[2];
+       const bool show_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
+       const bool draw_gpencil = ((sseq->flag & SEQ_SHOW_GPENCIL) && sseq->gpd);
+       const char *names[2] = { STEREO_LEFT_NAME, STEREO_RIGHT_NAME };
 
-       if (draw_backdrop) {
-               GPU_matrix_pop();
-               GPU_matrix_pop_projection();
+       sequencer_stop_running_jobs(C, scene);
+       if (G.is_rendering) {
                return;
        }
 
-       if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
-               sequencer_draw_borders(sseq, v2d, scene);
+       if (sseq->render_size == SEQ_PROXY_RENDER_SIZE_NONE) {
+               sequencer_preview_clear();
+               return;
        }
 
-       if (draw_gpencil && is_imbuf) {
-               sequencer_draw_gpencil(C);
-       }
-       else {
-               /* ortho at pixel level */
-               UI_view2d_view_restore(C);
+       /* Setup view */
+       sequencer_display_size(scene, viewrect);
+       UI_view2d_totRect_set(v2d, viewrect[0] + 0.5f, viewrect[1] + 0.5f);
+       UI_view2d_curRect_validate(v2d);
+       UI_view2d_view_ortho(v2d);
+
+       /* Draw background */
+       if (!draw_backdrop && (!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE)) {
+               sequencer_preview_clear();
+
+               if (sseq->flag & SEQ_USE_ALPHA) {
+                       imm_draw_box_checker_2d(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax);
+               }
        }
+       /* Get image */
+       ibuf = sequencer_ibuf_get(bmain, depsgraph, scene, sseq, cfra, frame_ofs, names[sseq->multiview_eye]);
 
+       if (ibuf) {
+               scope = sequencer_get_scope(scene, sseq, ibuf, draw_backdrop);
 
-       /* NOTE: sequencer mask editing isnt finished, the draw code is working but editing not,
-        * for now just disable drawing since the strip frame will likely be offset */
+               /* Draw image */
+               sequencer_draw_display_buffer(C, scene, ar, sseq, ibuf, scope, draw_overlay, draw_backdrop);
 
-       // if (sc->mode == SC_MODE_MASKEDIT)
-       if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
-               Mask *mask = BKE_sequencer_mask_get(scene);
+               /* Draw over image */
+               if (sseq->flag & SEQ_SHOW_METADATA) {
+                       ED_region_image_metadata_draw(0.0, 0.0, ibuf, &v2d->tot, 1.0, 1.0);
+               }
+       }
 
-               if (mask) {
-                       int width, height;
-                       float aspx = 1.0f, aspy = 1.0f;
-                       // ED_mask_get_size(C, &width, &height);
+       if (draw_gpencil && show_imbuf) {
+               sequencer_draw_gpencil(C);
+       }
 
-                       //Scene *scene = CTX_data_scene(C);
-                       width = (scene->r.size * scene->r.xsch) / 100;
-                       height = (scene->r.size * scene->r.ysch) / 100;
+       if (show_imbuf) {
+               sequencer_draw_borders(sseq, v2d, scene);
+       }
 
-                       ED_mask_draw_region(mask, ar,
-                                           0, 0, 0,  /* TODO */
-                                           width, height,
-                                           aspx, aspy,
-                                           false, true,
-                                           NULL, C);
-               }
+       /* TODO */
+       /* sequencer_draw_maskedit(C, scene, ar, sseq); */
+
+       /* Scope is freed in sequencer_check_scopes when ibuf changes and scope image is to be replaced. */
+       if (ibuf) {
+               IMB_freeImBuf(ibuf);
        }
+
+       UI_view2d_view_restore(C);
 }
 
 #if 0
@@ -1700,7 +1658,7 @@ void draw_timeline_seq(const bContext *C, ARegion *ar)
 
        /* Only draw backdrop in pure sequence view. */
        if (sseq->view == SEQ_VIEW_SEQUENCE && sseq->draw_flag & SEQ_DRAW_BACKDROP) {
-               draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false, true);
+               sequencer_draw_preview(C, scene, ar, sseq, scene->r.cfra, 0, false, true);
                UI_view2d_view_ortho(v2d);
        }
 
index 6113ef6..ad3ac79 100644 (file)
@@ -48,7 +48,7 @@ struct ARegion *sequencer_has_buttons_region(struct ScrArea *sa);
 
 /* sequencer_draw.c */
 void draw_timeline_seq(const struct bContext *C, struct ARegion *ar);
-void draw_image_seq(const struct bContext *C, struct Scene *scene, struct  ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay, bool draw_backdrop);
+void sequencer_draw_preview(const struct bContext *C, struct Scene *scene, struct  ARegion *ar, struct SpaceSeq *sseq, int cfra, int offset, bool draw_overlay, bool draw_backdrop);
 void color3ubv_from_seq(struct Scene *curscene, struct Sequence *seq, unsigned char col[3]);
 
 void sequencer_special_update_set(Sequence *seq);
index 4f17406..dec70c4 100644 (file)
@@ -630,7 +630,7 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *ar)
        if (sseq->mainb == SEQ_DRAW_SEQUENCE) sseq->mainb = SEQ_DRAW_IMG_IMBUF;
 
        if (!show_split || sseq->overlay_type != SEQ_DRAW_OVERLAY_REFERENCE)
-               draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0, false, false);
+               sequencer_draw_preview(C, scene, ar, sseq, scene->r.cfra, 0, false, false);
 
        if (show_split && sseq->overlay_type != SEQ_DRAW_OVERLAY_CURRENT) {
                int over_cfra;
@@ -641,7 +641,7 @@ static void sequencer_preview_region_draw(const bContext *C, ARegion *ar)
                        over_cfra = scene->r.cfra + scene->ed->over_ofs;
 
                if (over_cfra != scene->r.cfra || sseq->overlay_type != SEQ_DRAW_OVERLAY_RECT)
-                       draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, true, false);
+                       sequencer_draw_preview(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra, true, false);
        }
 
        if ((U.uiflag & USER_SHOW_FPS) && ED_screen_animation_no_scrub(wm)) {