Cleanup: Split VSE timeline and preview drawing code
This commit is contained in:
@@ -29,18 +29,19 @@ set(SRC
|
||||
sequencer_channels_draw.cc
|
||||
sequencer_channels_edit.cc
|
||||
sequencer_drag_drop.cc
|
||||
sequencer_draw.cc
|
||||
sequencer_edit.cc
|
||||
sequencer_gizmo_retime.cc
|
||||
sequencer_gizmo_retime_type.cc
|
||||
sequencer_modifier.cc
|
||||
sequencer_ops.cc
|
||||
sequencer_preview.cc
|
||||
sequencer_preview_draw.cc
|
||||
sequencer_proxy.cc
|
||||
sequencer_retiming.cc
|
||||
sequencer_scopes.cc
|
||||
sequencer_select.cc
|
||||
sequencer_thumbnails.cc
|
||||
sequencer_timeline_draw.cc
|
||||
sequencer_view.cc
|
||||
space_sequencer.cc
|
||||
|
||||
|
||||
@@ -58,10 +58,17 @@ typedef struct SeqChannelDrawContext {
|
||||
float scale;
|
||||
} SeqChannelDrawContext;
|
||||
|
||||
/* `sequencer_draw.cc` */
|
||||
/* `sequencer_timeline_draw.cc` */
|
||||
|
||||
void draw_timeline_seq(const struct bContext *C, struct ARegion *region);
|
||||
void draw_timeline_seq_display(const struct bContext *C, struct ARegion *region);
|
||||
void color3ubv_from_seq(const struct Scene *curscene,
|
||||
const struct Sequence *seq,
|
||||
bool show_strip_color_tag,
|
||||
uchar r_col[3]);
|
||||
|
||||
/* `sequencer_preview_draw.cc` */
|
||||
|
||||
void sequencer_draw_preview(const struct bContext *C,
|
||||
struct Scene *scene,
|
||||
struct ARegion *region,
|
||||
@@ -70,10 +77,8 @@ void sequencer_draw_preview(const struct bContext *C,
|
||||
int offset,
|
||||
bool draw_overlay,
|
||||
bool draw_backdrop);
|
||||
void color3ubv_from_seq(const struct Scene *curscene,
|
||||
const struct Sequence *seq,
|
||||
bool show_strip_color_tag,
|
||||
uchar r_col[3]);
|
||||
bool sequencer_draw_get_transform_preview(SpaceSeq *sseq, Scene *scene);
|
||||
int sequencer_draw_get_transform_preview_frame(Scene *scene);
|
||||
|
||||
void sequencer_special_update_set(Sequence *seq);
|
||||
/* Get handle width in 2d-View space. */
|
||||
|
||||
829
source/blender/editors/space_sequencer/sequencer_preview_draw.cc
Normal file
829
source/blender/editors/space_sequencer/sequencer_preview_draw.cc
Normal file
@@ -0,0 +1,829 @@
|
||||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup spseq
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_scene.h"
|
||||
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_immediate_util.h"
|
||||
#include "GPU_matrix.h"
|
||||
#include "GPU_viewport.h"
|
||||
|
||||
#include "ED_gpencil_legacy.hh"
|
||||
#include "ED_screen.hh"
|
||||
#include "ED_sequencer.hh"
|
||||
#include "ED_space_api.hh"
|
||||
#include "ED_util.hh"
|
||||
|
||||
#include "BIF_glutil.hh"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_prefetch.h"
|
||||
#include "SEQ_proxy.h"
|
||||
#include "SEQ_render.h"
|
||||
#include "SEQ_select.h"
|
||||
#include "SEQ_sequencer.h"
|
||||
#include "SEQ_time.h"
|
||||
#include "SEQ_transform.h"
|
||||
|
||||
#include "UI_interface.hh"
|
||||
#include "UI_resources.hh"
|
||||
#include "UI_view2d.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
/* Own include. */
|
||||
#include "sequencer_intern.h"
|
||||
|
||||
static Sequence *special_seq_update = nullptr;
|
||||
|
||||
void sequencer_special_update_set(Sequence *seq)
|
||||
{
|
||||
special_seq_update = seq;
|
||||
}
|
||||
|
||||
Sequence *ED_sequencer_special_preview_get()
|
||||
{
|
||||
return special_seq_update;
|
||||
}
|
||||
|
||||
void ED_sequencer_special_preview_set(bContext *C, const int mval[2])
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
int hand;
|
||||
Sequence *seq;
|
||||
seq = find_nearest_seq(scene, ®ion->v2d, &hand, mval);
|
||||
sequencer_special_update_set(seq);
|
||||
}
|
||||
|
||||
void ED_sequencer_special_preview_clear()
|
||||
{
|
||||
sequencer_special_update_set(nullptr);
|
||||
}
|
||||
|
||||
ImBuf *sequencer_ibuf_get(Main *bmain,
|
||||
ARegion *region,
|
||||
Depsgraph *depsgraph,
|
||||
Scene *scene,
|
||||
SpaceSeq *sseq,
|
||||
int timeline_frame,
|
||||
int frame_ofs,
|
||||
const char *viewname)
|
||||
{
|
||||
SeqRenderData context = {nullptr};
|
||||
ImBuf *ibuf;
|
||||
int rectx, recty;
|
||||
double render_size;
|
||||
short is_break = G.is_break;
|
||||
|
||||
if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (sseq->render_size == SEQ_RENDER_SIZE_SCENE) {
|
||||
render_size = scene->r.size / 100.0;
|
||||
}
|
||||
else {
|
||||
render_size = SEQ_rendersize_to_scale_factor(sseq->render_size);
|
||||
}
|
||||
|
||||
rectx = roundf(render_size * scene->r.xsch);
|
||||
recty = roundf(render_size * scene->r.ysch);
|
||||
|
||||
SEQ_render_new_render_data(
|
||||
bmain, depsgraph, scene, rectx, recty, sseq->render_size, false, &context);
|
||||
context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
|
||||
context.use_proxies = (sseq->flag & SEQ_USE_PROXIES) != 0;
|
||||
|
||||
/* Sequencer could start rendering, in this case we need to be sure it wouldn't be canceled
|
||||
* by Escape pressed somewhere in the past. */
|
||||
G.is_break = false;
|
||||
|
||||
GPUViewport *viewport = WM_draw_region_get_bound_viewport(region);
|
||||
GPUFrameBuffer *fb = GPU_framebuffer_active_get();
|
||||
if (viewport) {
|
||||
/* Unbind viewport to release the DRW context. */
|
||||
GPU_viewport_unbind(viewport);
|
||||
}
|
||||
else {
|
||||
/* Rendering can change OGL context. Save & Restore frame-buffer. */
|
||||
GPU_framebuffer_restore();
|
||||
}
|
||||
|
||||
if (special_seq_update) {
|
||||
ibuf = SEQ_render_give_ibuf_direct(&context, timeline_frame + frame_ofs, special_seq_update);
|
||||
}
|
||||
else {
|
||||
ibuf = SEQ_render_give_ibuf(&context, timeline_frame + frame_ofs, sseq->chanshown);
|
||||
}
|
||||
|
||||
if (viewport) {
|
||||
/* Follows same logic as wm_draw_window_offscreen to make sure to restore the same
|
||||
* viewport. */
|
||||
int view = (sseq->multiview_eye == STEREO_RIGHT_ID) ? 1 : 0;
|
||||
GPU_viewport_bind(viewport, view, ®ion->winrct);
|
||||
}
|
||||
else if (fb) {
|
||||
GPU_framebuffer_bind(fb);
|
||||
}
|
||||
|
||||
/* Restore state so real rendering would be canceled if needed. */
|
||||
G.is_break = is_break;
|
||||
|
||||
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 = nullptr;
|
||||
}
|
||||
|
||||
if (scopes->waveform_ibuf) {
|
||||
IMB_freeImBuf(scopes->waveform_ibuf);
|
||||
scopes->waveform_ibuf = nullptr;
|
||||
}
|
||||
|
||||
if (scopes->sep_waveform_ibuf) {
|
||||
IMB_freeImBuf(scopes->sep_waveform_ibuf);
|
||||
scopes->sep_waveform_ibuf = nullptr;
|
||||
}
|
||||
|
||||
if (scopes->vector_ibuf) {
|
||||
IMB_freeImBuf(scopes->vector_ibuf);
|
||||
scopes->vector_ibuf = nullptr;
|
||||
}
|
||||
|
||||
if (scopes->histogram_ibuf) {
|
||||
IMB_freeImBuf(scopes->histogram_ibuf);
|
||||
scopes->histogram_ibuf = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scope_fn)(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_fn(display_ibuf);
|
||||
|
||||
IMB_freeImBuf(display_ibuf);
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
static void sequencer_display_size(Scene *scene, float r_viewrect[2])
|
||||
{
|
||||
r_viewrect[0] = float(scene->r.xsch);
|
||||
r_viewrect[1] = float(scene->r.ysch);
|
||||
|
||||
r_viewrect[0] *= scene->r.xasp / scene->r.yasp;
|
||||
}
|
||||
|
||||
static void sequencer_draw_gpencil_overlay(const bContext *C)
|
||||
{
|
||||
/* Draw grease-pencil (image aligned). */
|
||||
ED_annotation_draw_2dimage(C);
|
||||
|
||||
/* Orthographic at pixel level. */
|
||||
UI_view2d_view_restore(C);
|
||||
|
||||
/* Draw grease-pencil (screen aligned). */
|
||||
ED_annotation_draw_view2d(C, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw content and safety borders.
|
||||
*/
|
||||
static void sequencer_draw_borders_overlay(const SpaceSeq *sseq,
|
||||
const View2D *v2d,
|
||||
const Scene *scene)
|
||||
{
|
||||
float x1 = v2d->tot.xmin;
|
||||
float y1 = v2d->tot.ymin;
|
||||
float x2 = v2d->tot.xmax;
|
||||
float y2 = v2d->tot.ymax;
|
||||
|
||||
GPU_line_width(1.0f);
|
||||
|
||||
/* Draw border. */
|
||||
const uint shdr_pos = GPU_vertformat_attr_add(
|
||||
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
|
||||
|
||||
float viewport_size[4];
|
||||
GPU_viewport_size_get_f(viewport_size);
|
||||
immUniform2f("viewport_size", viewport_size[2] / UI_SCALE_FAC, viewport_size[3] / UI_SCALE_FAC);
|
||||
|
||||
immUniformThemeColor(TH_BACK);
|
||||
immUniform1i("colors_len", 0); /* Simple dashes. */
|
||||
immUniform1f("dash_width", 6.0f);
|
||||
immUniform1f("udash_factor", 0.5f);
|
||||
|
||||
imm_draw_box_wire_2d(shdr_pos, x1 - 0.5f, y1 - 0.5f, x2 + 0.5f, y2 + 0.5f);
|
||||
|
||||
/* Draw safety border. */
|
||||
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_SAFE_MARGINS) {
|
||||
immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
|
||||
rctf rect;
|
||||
rect.xmin = x1;
|
||||
rect.xmax = x2;
|
||||
rect.ymin = y1;
|
||||
rect.ymax = y2;
|
||||
UI_draw_safe_areas(shdr_pos, &rect, scene->safe_areas.title, scene->safe_areas.action);
|
||||
|
||||
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_SAFE_CENTER) {
|
||||
|
||||
UI_draw_safe_areas(
|
||||
shdr_pos, &rect, scene->safe_areas.title_center, scene->safe_areas.action_center);
|
||||
}
|
||||
}
|
||||
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
#if 0
|
||||
void sequencer_draw_maskedit(const bContext *C, Scene *scene, ARegion *region, SpaceSeq *sseq)
|
||||
{
|
||||
/* NOTE: sequencer mask editing isn't finished, the draw code is working but editing not.
|
||||
* For now just disable drawing since the strip frame will likely be offset. */
|
||||
|
||||
// if (sc->mode == SC_MODE_MASKEDIT)
|
||||
if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
|
||||
Mask *mask = SEQ_active_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);
|
||||
BKE_render_resolution(&scene->r, false, &width, &height);
|
||||
|
||||
ED_mask_draw_region(mask,
|
||||
region,
|
||||
0,
|
||||
0,
|
||||
0, /* TODO */
|
||||
width,
|
||||
height,
|
||||
aspx,
|
||||
aspy,
|
||||
false,
|
||||
true,
|
||||
nullptr,
|
||||
C);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Force redraw, when prefetching and using cache view. */
|
||||
static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
|
||||
{
|
||||
if (SEQ_prefetch_need_redraw(CTX_data_main(C), scene)) {
|
||||
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
static void *sequencer_OCIO_transform_ibuf(const bContext *C,
|
||||
ImBuf *ibuf,
|
||||
bool *r_glsl_used,
|
||||
eGPUTextureFormat *r_format,
|
||||
eGPUDataFormat *r_data,
|
||||
void **r_buffer_cache_handle)
|
||||
{
|
||||
void *display_buffer;
|
||||
bool force_fallback = false;
|
||||
*r_glsl_used = false;
|
||||
force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
|
||||
force_fallback |= (ibuf->dither != 0.0f);
|
||||
|
||||
/* Default */
|
||||
*r_format = GPU_RGBA8;
|
||||
*r_data = GPU_DATA_UBYTE;
|
||||
|
||||
/* Fallback to CPU based color space conversion. */
|
||||
if (force_fallback) {
|
||||
*r_glsl_used = false;
|
||||
display_buffer = nullptr;
|
||||
}
|
||||
else if (ibuf->float_buffer.data) {
|
||||
display_buffer = ibuf->float_buffer.data;
|
||||
|
||||
*r_data = GPU_DATA_FLOAT;
|
||||
if (ibuf->channels == 4) {
|
||||
*r_format = GPU_RGBA16F;
|
||||
}
|
||||
else if (ibuf->channels == 3) {
|
||||
/* Alpha is implicitly 1. */
|
||||
*r_format = GPU_RGB16F;
|
||||
}
|
||||
else {
|
||||
BLI_assert_msg(0, "Incompatible number of channels for float buffer in sequencer");
|
||||
*r_format = GPU_RGBA16F;
|
||||
display_buffer = nullptr;
|
||||
}
|
||||
|
||||
if (ibuf->float_buffer.colorspace) {
|
||||
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
|
||||
C, ibuf->float_buffer.colorspace, ibuf->dither, true);
|
||||
}
|
||||
else {
|
||||
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true);
|
||||
}
|
||||
}
|
||||
else if (ibuf->byte_buffer.data) {
|
||||
display_buffer = ibuf->byte_buffer.data;
|
||||
|
||||
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
|
||||
C, ibuf->byte_buffer.colorspace, ibuf->dither, false);
|
||||
}
|
||||
else {
|
||||
display_buffer = nullptr;
|
||||
}
|
||||
|
||||
/* There is data to be displayed, but GLSL is not initialized
|
||||
* properly, in this case we fallback to CPU-based display transform. */
|
||||
if ((ibuf->byte_buffer.data || ibuf->float_buffer.data) && !*r_glsl_used) {
|
||||
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, r_buffer_cache_handle);
|
||||
*r_format = GPU_RGBA8;
|
||||
*r_data = GPU_DATA_UBYTE;
|
||||
}
|
||||
|
||||
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.
|
||||
* Need to make so sequencers rendering doesn't conflict with compositor. */
|
||||
WM_jobs_kill_type(CTX_wm_manager(C), nullptr, WM_JOB_TYPE_COMPOSITE);
|
||||
|
||||
/* In case of final rendering used for preview, kill all previews,
|
||||
* otherwise threading conflict will happen in rendering module. */
|
||||
WM_jobs_kill_type(CTX_wm_manager(C), nullptr, WM_JOB_TYPE_RENDER_PREVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
static void sequencer_preview_clear()
|
||||
{
|
||||
UI_ThemeClearColor(TH_SEQ_PREVIEW);
|
||||
}
|
||||
|
||||
static void sequencer_preview_get_rect(rctf *preview,
|
||||
Scene *scene,
|
||||
ARegion *region,
|
||||
SpaceSeq *sseq,
|
||||
bool draw_overlay,
|
||||
bool draw_backdrop)
|
||||
{
|
||||
View2D *v2d = ®ion->v2d;
|
||||
float viewrect[2];
|
||||
|
||||
sequencer_display_size(scene, viewrect);
|
||||
BLI_rctf_init(preview, -1.0f, 1.0f, -1.0f, 1.0f);
|
||||
|
||||
if (draw_overlay && (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT)) {
|
||||
preview->xmax = v2d->tot.xmin +
|
||||
(fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->overlay_frame_rect.xmax);
|
||||
preview->xmin = v2d->tot.xmin +
|
||||
(fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->overlay_frame_rect.xmin);
|
||||
preview->ymax = v2d->tot.ymin +
|
||||
(fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->overlay_frame_rect.ymax);
|
||||
preview->ymin = v2d->tot.ymin +
|
||||
(fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->overlay_frame_rect.ymin);
|
||||
}
|
||||
else if (draw_backdrop) {
|
||||
float aspect = BLI_rcti_size_x(®ion->winrct) / float(BLI_rcti_size_y(®ion->winrct));
|
||||
float image_aspect = viewrect[0] / viewrect[1];
|
||||
|
||||
if (aspect >= image_aspect) {
|
||||
preview->xmax = image_aspect / aspect;
|
||||
preview->xmin = -preview->xmax;
|
||||
}
|
||||
else {
|
||||
preview->ymax = aspect / image_aspect;
|
||||
preview->ymin = -preview->ymax;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*preview = v2d->tot;
|
||||
}
|
||||
}
|
||||
|
||||
static void sequencer_draw_display_buffer(const bContext *C,
|
||||
Scene *scene,
|
||||
ARegion *region,
|
||||
SpaceSeq *sseq,
|
||||
ImBuf *ibuf,
|
||||
ImBuf *scope,
|
||||
bool draw_overlay,
|
||||
bool draw_backdrop)
|
||||
{
|
||||
void *display_buffer;
|
||||
void *buffer_cache_handle = nullptr;
|
||||
|
||||
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
}
|
||||
|
||||
/* Format needs to be created prior to any #immBindShader call.
|
||||
* Do it here because OCIO binds its own shader. */
|
||||
eGPUTextureFormat format;
|
||||
eGPUDataFormat data;
|
||||
bool glsl_used = false;
|
||||
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) {
|
||||
ibuf = scope;
|
||||
|
||||
if (ibuf->float_buffer.data && ibuf->byte_buffer.data == nullptr) {
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
|
||||
display_buffer = ibuf->byte_buffer.data;
|
||||
format = GPU_RGBA8;
|
||||
data = GPU_DATA_UBYTE;
|
||||
}
|
||||
else {
|
||||
display_buffer = sequencer_OCIO_transform_ibuf(
|
||||
C, ibuf, &glsl_used, &format, &data, &buffer_cache_handle);
|
||||
}
|
||||
|
||||
if (draw_backdrop) {
|
||||
GPU_matrix_push();
|
||||
GPU_matrix_identity_set();
|
||||
GPU_matrix_push_projection();
|
||||
GPU_matrix_identity_projection_set();
|
||||
}
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
|
||||
GPUTexture *texture = GPU_texture_create_2d(
|
||||
"seq_display_buf", ibuf->x, ibuf->y, 1, format, usage, nullptr);
|
||||
GPU_texture_update(texture, data, display_buffer);
|
||||
GPU_texture_filter_mode(texture, false);
|
||||
|
||||
GPU_texture_bind(texture, 0);
|
||||
|
||||
if (!glsl_used) {
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_COLOR);
|
||||
immUniformColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
immBegin(GPU_PRIM_TRI_FAN, 4);
|
||||
|
||||
rctf preview;
|
||||
rctf canvas;
|
||||
sequencer_preview_get_rect(&preview, scene, region, sseq, draw_overlay, draw_backdrop);
|
||||
|
||||
if (draw_overlay && (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT)) {
|
||||
canvas = scene->ed->overlay_frame_rect;
|
||||
}
|
||||
else {
|
||||
BLI_rctf_init(&canvas, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
immAttr2f(texCoord, canvas.xmin, canvas.ymin);
|
||||
immVertex2f(pos, preview.xmin, preview.ymin);
|
||||
|
||||
immAttr2f(texCoord, canvas.xmin, canvas.ymax);
|
||||
immVertex2f(pos, preview.xmin, preview.ymax);
|
||||
|
||||
immAttr2f(texCoord, canvas.xmax, canvas.ymax);
|
||||
immVertex2f(pos, preview.xmax, preview.ymax);
|
||||
|
||||
immAttr2f(texCoord, canvas.xmax, canvas.ymin);
|
||||
immVertex2f(pos, preview.xmax, preview.ymin);
|
||||
|
||||
immEnd();
|
||||
|
||||
GPU_texture_unbind(texture);
|
||||
GPU_texture_free(texture);
|
||||
|
||||
if (!glsl_used) {
|
||||
immUnbindProgram();
|
||||
}
|
||||
else {
|
||||
IMB_colormanagement_finish_glsl_draw();
|
||||
}
|
||||
|
||||
if (buffer_cache_handle) {
|
||||
IMB_display_buffer_release(buffer_cache_handle);
|
||||
}
|
||||
|
||||
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
if (draw_backdrop) {
|
||||
GPU_matrix_pop();
|
||||
GPU_matrix_pop_projection();
|
||||
}
|
||||
}
|
||||
|
||||
static ImBuf *sequencer_get_scope(Scene *scene, SpaceSeq *sseq, ImBuf *ibuf, bool draw_backdrop)
|
||||
{
|
||||
ImBuf *scope = nullptr;
|
||||
SequencerScopes *scopes = &sseq->scopes;
|
||||
|
||||
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->float_buffer.data) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
bool sequencer_draw_get_transform_preview(SpaceSeq *sseq, Scene *scene)
|
||||
{
|
||||
Sequence *last_seq = SEQ_select_active_get(scene);
|
||||
if (last_seq == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (G.moving & G_TRANSFORM_SEQ) && (last_seq->flag & SELECT) &&
|
||||
((last_seq->flag & SEQ_LEFTSEL) || (last_seq->flag & SEQ_RIGHTSEL)) &&
|
||||
(sseq->draw_flag & SEQ_DRAW_TRANSFORM_PREVIEW);
|
||||
}
|
||||
|
||||
int sequencer_draw_get_transform_preview_frame(Scene *scene)
|
||||
{
|
||||
Sequence *last_seq = SEQ_select_active_get(scene);
|
||||
/* #sequencer_draw_get_transform_preview must already have been called. */
|
||||
BLI_assert(last_seq != nullptr);
|
||||
int preview_frame;
|
||||
|
||||
if (last_seq->flag & SEQ_RIGHTSEL) {
|
||||
preview_frame = SEQ_time_right_handle_frame_get(scene, last_seq) - 1;
|
||||
}
|
||||
else {
|
||||
preview_frame = SEQ_time_left_handle_frame_get(scene, last_seq);
|
||||
}
|
||||
|
||||
return preview_frame;
|
||||
}
|
||||
|
||||
static void seq_draw_image_origin_and_outline(const bContext *C, Sequence *seq, bool is_active_seq)
|
||||
{
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
if (region->regiontype == RGN_TYPE_PREVIEW && !sequencer_view_preview_only_poll(C)) {
|
||||
return;
|
||||
}
|
||||
if ((seq->flag & SELECT) == 0) {
|
||||
return;
|
||||
}
|
||||
if (ED_screen_animation_no_scrub(CTX_wm_manager(C))) {
|
||||
return;
|
||||
}
|
||||
if ((sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
|
||||
(sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_OUTLINE_SELECTED) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (ELEM(sseq->mainb, SEQ_DRAW_IMG_WAVEFORM, SEQ_DRAW_IMG_VECTORSCOPE, SEQ_DRAW_IMG_HISTOGRAM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
float origin[2];
|
||||
SEQ_image_transform_origin_offset_pixelspace_get(CTX_data_scene(C), seq, origin);
|
||||
|
||||
/* Origin. */
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
|
||||
immUniform1f("outlineWidth", 1.5f);
|
||||
immUniformColor3f(1.0f, 1.0f, 1.0f);
|
||||
immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
immUniform1f("size", 15.0f * U.pixelsize);
|
||||
immBegin(GPU_PRIM_POINTS, 1);
|
||||
immVertex2f(pos, origin[0], origin[1]);
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
|
||||
/* Outline. */
|
||||
float seq_image_quad[4][2];
|
||||
SEQ_image_transform_final_quad_get(CTX_data_scene(C), seq, seq_image_quad);
|
||||
|
||||
GPU_line_smooth(true);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
GPU_line_width(2);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
|
||||
float col[3];
|
||||
if (is_active_seq) {
|
||||
UI_GetThemeColor3fv(TH_SEQ_ACTIVE, col);
|
||||
}
|
||||
else {
|
||||
UI_GetThemeColor3fv(TH_SEQ_SELECTED, col);
|
||||
}
|
||||
immUniformColor3fv(col);
|
||||
immUniform1f("lineWidth", U.pixelsize);
|
||||
immBegin(GPU_PRIM_LINE_LOOP, 4);
|
||||
immVertex2f(pos, seq_image_quad[0][0], seq_image_quad[0][1]);
|
||||
immVertex2f(pos, seq_image_quad[1][0], seq_image_quad[1][1]);
|
||||
immVertex2f(pos, seq_image_quad[2][0], seq_image_quad[2][1]);
|
||||
immVertex2f(pos, seq_image_quad[3][0], seq_image_quad[3][1]);
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
GPU_line_width(1);
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
GPU_line_smooth(false);
|
||||
}
|
||||
|
||||
void sequencer_draw_preview(const bContext *C,
|
||||
Scene *scene,
|
||||
ARegion *region,
|
||||
SpaceSeq *sseq,
|
||||
int timeline_frame,
|
||||
int offset,
|
||||
bool draw_overlay,
|
||||
bool draw_backdrop)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
|
||||
View2D *v2d = ®ion->v2d;
|
||||
ImBuf *ibuf = nullptr;
|
||||
ImBuf *scope = nullptr;
|
||||
float viewrect[2];
|
||||
const bool show_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
|
||||
const bool draw_gpencil = ((sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_GPENCIL) && sseq->gpd);
|
||||
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
|
||||
|
||||
sequencer_stop_running_jobs(C, scene);
|
||||
if (G.is_rendering) {
|
||||
return;
|
||||
}
|
||||
|
||||
int preview_frame = timeline_frame;
|
||||
if (sequencer_draw_get_transform_preview(sseq, scene)) {
|
||||
preview_frame = sequencer_draw_get_transform_preview_frame(scene);
|
||||
}
|
||||
|
||||
/* Get image. */
|
||||
ibuf = sequencer_ibuf_get(
|
||||
bmain, region, depsgraph, scene, sseq, preview_frame, offset, names[sseq->multiview_eye]);
|
||||
|
||||
/* Setup off-screen buffers. */
|
||||
GPUViewport *viewport = WM_draw_region_get_viewport(region);
|
||||
GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
|
||||
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
|
||||
GPU_depth_test(GPU_DEPTH_NONE);
|
||||
|
||||
if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
|
||||
sequencer_preview_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup view. */
|
||||
sequencer_display_size(scene, viewrect);
|
||||
UI_view2d_totRect_set(v2d, roundf(viewrect[0] + 0.5f), roundf(viewrect[1] + 0.5f));
|
||||
UI_view2d_curRect_validate(v2d);
|
||||
UI_view2d_view_ortho(v2d);
|
||||
|
||||
/* Draw background. */
|
||||
if (!draw_backdrop &&
|
||||
(!draw_overlay || (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_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);
|
||||
}
|
||||
}
|
||||
|
||||
if (ibuf) {
|
||||
scope = sequencer_get_scope(scene, sseq, ibuf, draw_backdrop);
|
||||
|
||||
/* Draw image. */
|
||||
sequencer_draw_display_buffer(
|
||||
C, scene, region, sseq, ibuf, scope, draw_overlay, draw_backdrop);
|
||||
|
||||
/* Draw over image. */
|
||||
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_METADATA && sseq->flag & SEQ_SHOW_OVERLAY) {
|
||||
ED_region_image_metadata_draw(0.0, 0.0, ibuf, &v2d->tot, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (show_imbuf && (sseq->flag & SEQ_SHOW_OVERLAY)) {
|
||||
sequencer_draw_borders_overlay(sseq, v2d, scene);
|
||||
}
|
||||
|
||||
if (!draw_backdrop && scene->ed != nullptr) {
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_displayed_get(ed);
|
||||
SeqCollection *collection = SEQ_query_rendered_strips(
|
||||
scene, channels, ed->seqbasep, timeline_frame, 0);
|
||||
Sequence *seq;
|
||||
Sequence *active_seq = SEQ_select_active_get(scene);
|
||||
SEQ_ITERATOR_FOREACH (seq, collection) {
|
||||
seq_draw_image_origin_and_outline(C, seq, seq == active_seq);
|
||||
}
|
||||
SEQ_collection_free(collection);
|
||||
}
|
||||
|
||||
if (draw_gpencil && show_imbuf && (sseq->flag & SEQ_SHOW_OVERLAY)) {
|
||||
sequencer_draw_gpencil_overlay(C);
|
||||
}
|
||||
|
||||
#if 0
|
||||
sequencer_draw_maskedit(C, scene, region, sseq);
|
||||
#endif
|
||||
|
||||
/* Draw registered callbacks. */
|
||||
GPU_framebuffer_bind(framebuffer_overlay);
|
||||
ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
|
||||
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
|
||||
|
||||
/* Scope is freed in sequencer_check_scopes when `ibuf` changes and redraw is needed. */
|
||||
if (ibuf) {
|
||||
IMB_freeImBuf(ibuf);
|
||||
}
|
||||
|
||||
UI_view2d_view_restore(C);
|
||||
seq_prefetch_wm_notify(C, scene);
|
||||
}
|
||||
@@ -14,11 +14,6 @@
|
||||
#include "BLI_threads.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_mask_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_sound_types.h"
|
||||
@@ -34,16 +29,12 @@
|
||||
#include "IMB_colormanagement.h"
|
||||
#include "IMB_imbuf.h"
|
||||
|
||||
#include "GPU_framebuffer.h"
|
||||
#include "GPU_immediate.h"
|
||||
#include "GPU_immediate_util.h"
|
||||
#include "GPU_matrix.h"
|
||||
#include "GPU_state.h"
|
||||
#include "GPU_vertex_buffer.h"
|
||||
#include "GPU_viewport.h"
|
||||
|
||||
#include "ED_anim_api.hh"
|
||||
#include "ED_gpencil_legacy.hh"
|
||||
#include "ED_markers.hh"
|
||||
#include "ED_mask.hh"
|
||||
#include "ED_screen.hh"
|
||||
@@ -52,15 +43,12 @@
|
||||
#include "ED_time_scrub_ui.hh"
|
||||
#include "ED_util.hh"
|
||||
|
||||
#include "BIF_glutil.hh"
|
||||
|
||||
#include "RNA_prototypes.h"
|
||||
|
||||
#include "SEQ_channels.h"
|
||||
#include "SEQ_effects.h"
|
||||
#include "SEQ_iterator.h"
|
||||
#include "SEQ_prefetch.h"
|
||||
#include "SEQ_proxy.h"
|
||||
#include "SEQ_relations.h"
|
||||
#include "SEQ_render.h"
|
||||
#include "SEQ_select.h"
|
||||
@@ -1540,255 +1528,6 @@ static void draw_effect_inputs_highlight(const Scene *scene, Sequence *seq)
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
void sequencer_special_update_set(Sequence *seq)
|
||||
{
|
||||
special_seq_update = seq;
|
||||
}
|
||||
|
||||
Sequence *ED_sequencer_special_preview_get()
|
||||
{
|
||||
return special_seq_update;
|
||||
}
|
||||
|
||||
void ED_sequencer_special_preview_set(bContext *C, const int mval[2])
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
int hand;
|
||||
Sequence *seq;
|
||||
seq = find_nearest_seq(scene, ®ion->v2d, &hand, mval);
|
||||
sequencer_special_update_set(seq);
|
||||
}
|
||||
|
||||
void ED_sequencer_special_preview_clear()
|
||||
{
|
||||
sequencer_special_update_set(nullptr);
|
||||
}
|
||||
|
||||
ImBuf *sequencer_ibuf_get(Main *bmain,
|
||||
ARegion *region,
|
||||
Depsgraph *depsgraph,
|
||||
Scene *scene,
|
||||
SpaceSeq *sseq,
|
||||
int timeline_frame,
|
||||
int frame_ofs,
|
||||
const char *viewname)
|
||||
{
|
||||
SeqRenderData context = {nullptr};
|
||||
ImBuf *ibuf;
|
||||
int rectx, recty;
|
||||
double render_size;
|
||||
short is_break = G.is_break;
|
||||
|
||||
if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (sseq->render_size == SEQ_RENDER_SIZE_SCENE) {
|
||||
render_size = scene->r.size / 100.0;
|
||||
}
|
||||
else {
|
||||
render_size = SEQ_rendersize_to_scale_factor(sseq->render_size);
|
||||
}
|
||||
|
||||
rectx = roundf(render_size * scene->r.xsch);
|
||||
recty = roundf(render_size * scene->r.ysch);
|
||||
|
||||
SEQ_render_new_render_data(
|
||||
bmain, depsgraph, scene, rectx, recty, sseq->render_size, false, &context);
|
||||
context.view_id = BKE_scene_multiview_view_id_get(&scene->r, viewname);
|
||||
context.use_proxies = (sseq->flag & SEQ_USE_PROXIES) != 0;
|
||||
|
||||
/* Sequencer could start rendering, in this case we need to be sure it wouldn't be canceled
|
||||
* by Escape pressed somewhere in the past. */
|
||||
G.is_break = false;
|
||||
|
||||
GPUViewport *viewport = WM_draw_region_get_bound_viewport(region);
|
||||
GPUFrameBuffer *fb = GPU_framebuffer_active_get();
|
||||
if (viewport) {
|
||||
/* Unbind viewport to release the DRW context. */
|
||||
GPU_viewport_unbind(viewport);
|
||||
}
|
||||
else {
|
||||
/* Rendering can change OGL context. Save & Restore frame-buffer. */
|
||||
GPU_framebuffer_restore();
|
||||
}
|
||||
|
||||
if (special_seq_update) {
|
||||
ibuf = SEQ_render_give_ibuf_direct(&context, timeline_frame + frame_ofs, special_seq_update);
|
||||
}
|
||||
else {
|
||||
ibuf = SEQ_render_give_ibuf(&context, timeline_frame + frame_ofs, sseq->chanshown);
|
||||
}
|
||||
|
||||
if (viewport) {
|
||||
/* Follows same logic as wm_draw_window_offscreen to make sure to restore the same
|
||||
* viewport. */
|
||||
int view = (sseq->multiview_eye == STEREO_RIGHT_ID) ? 1 : 0;
|
||||
GPU_viewport_bind(viewport, view, ®ion->winrct);
|
||||
}
|
||||
else if (fb) {
|
||||
GPU_framebuffer_bind(fb);
|
||||
}
|
||||
|
||||
/* Restore state so real rendering would be canceled if needed. */
|
||||
G.is_break = is_break;
|
||||
|
||||
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 = nullptr;
|
||||
}
|
||||
|
||||
if (scopes->waveform_ibuf) {
|
||||
IMB_freeImBuf(scopes->waveform_ibuf);
|
||||
scopes->waveform_ibuf = nullptr;
|
||||
}
|
||||
|
||||
if (scopes->sep_waveform_ibuf) {
|
||||
IMB_freeImBuf(scopes->sep_waveform_ibuf);
|
||||
scopes->sep_waveform_ibuf = nullptr;
|
||||
}
|
||||
|
||||
if (scopes->vector_ibuf) {
|
||||
IMB_freeImBuf(scopes->vector_ibuf);
|
||||
scopes->vector_ibuf = nullptr;
|
||||
}
|
||||
|
||||
if (scopes->histogram_ibuf) {
|
||||
IMB_freeImBuf(scopes->histogram_ibuf);
|
||||
scopes->histogram_ibuf = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ImBuf *sequencer_make_scope(Scene *scene, ImBuf *ibuf, ImBuf *(*make_scope_fn)(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_fn(display_ibuf);
|
||||
|
||||
IMB_freeImBuf(display_ibuf);
|
||||
|
||||
return scope;
|
||||
}
|
||||
|
||||
static void sequencer_display_size(Scene *scene, float r_viewrect[2])
|
||||
{
|
||||
r_viewrect[0] = float(scene->r.xsch);
|
||||
r_viewrect[1] = float(scene->r.ysch);
|
||||
|
||||
r_viewrect[0] *= scene->r.xasp / scene->r.yasp;
|
||||
}
|
||||
|
||||
static void sequencer_draw_gpencil_overlay(const bContext *C)
|
||||
{
|
||||
/* Draw grease-pencil (image aligned). */
|
||||
ED_annotation_draw_2dimage(C);
|
||||
|
||||
/* Orthographic at pixel level. */
|
||||
UI_view2d_view_restore(C);
|
||||
|
||||
/* Draw grease-pencil (screen aligned). */
|
||||
ED_annotation_draw_view2d(C, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw content and safety borders.
|
||||
*/
|
||||
static void sequencer_draw_borders_overlay(const SpaceSeq *sseq,
|
||||
const View2D *v2d,
|
||||
const Scene *scene)
|
||||
{
|
||||
float x1 = v2d->tot.xmin;
|
||||
float y1 = v2d->tot.ymin;
|
||||
float x2 = v2d->tot.xmax;
|
||||
float y2 = v2d->tot.ymax;
|
||||
|
||||
GPU_line_width(1.0f);
|
||||
|
||||
/* Draw border. */
|
||||
const uint shdr_pos = GPU_vertformat_attr_add(
|
||||
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_LINE_DASHED_UNIFORM_COLOR);
|
||||
|
||||
float viewport_size[4];
|
||||
GPU_viewport_size_get_f(viewport_size);
|
||||
immUniform2f("viewport_size", viewport_size[2] / UI_SCALE_FAC, viewport_size[3] / UI_SCALE_FAC);
|
||||
|
||||
immUniformThemeColor(TH_BACK);
|
||||
immUniform1i("colors_len", 0); /* Simple dashes. */
|
||||
immUniform1f("dash_width", 6.0f);
|
||||
immUniform1f("udash_factor", 0.5f);
|
||||
|
||||
imm_draw_box_wire_2d(shdr_pos, x1 - 0.5f, y1 - 0.5f, x2 + 0.5f, y2 + 0.5f);
|
||||
|
||||
/* Draw safety border. */
|
||||
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_SAFE_MARGINS) {
|
||||
immUniformThemeColorBlend(TH_VIEW_OVERLAY, TH_BACK, 0.25f);
|
||||
rctf rect;
|
||||
rect.xmin = x1;
|
||||
rect.xmax = x2;
|
||||
rect.ymin = y1;
|
||||
rect.ymax = y2;
|
||||
UI_draw_safe_areas(shdr_pos, &rect, scene->safe_areas.title, scene->safe_areas.action);
|
||||
|
||||
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_SAFE_CENTER) {
|
||||
|
||||
UI_draw_safe_areas(
|
||||
shdr_pos, &rect, scene->safe_areas.title_center, scene->safe_areas.action_center);
|
||||
}
|
||||
}
|
||||
|
||||
immUnbindProgram();
|
||||
}
|
||||
|
||||
#if 0
|
||||
void sequencer_draw_maskedit(const bContext *C, Scene *scene, ARegion *region, SpaceSeq *sseq)
|
||||
{
|
||||
/* NOTE: sequencer mask editing isn't finished, the draw code is working but editing not.
|
||||
* For now just disable drawing since the strip frame will likely be offset. */
|
||||
|
||||
// if (sc->mode == SC_MODE_MASKEDIT)
|
||||
if (0 && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
|
||||
Mask *mask = SEQ_active_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);
|
||||
BKE_render_resolution(&scene->r, false, &width, &height);
|
||||
|
||||
ED_mask_draw_region(mask,
|
||||
region,
|
||||
0,
|
||||
0,
|
||||
0, /* TODO */
|
||||
width,
|
||||
height,
|
||||
aspx,
|
||||
aspy,
|
||||
false,
|
||||
true,
|
||||
nullptr,
|
||||
C);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Force redraw, when prefetching and using cache view. */
|
||||
static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
|
||||
{
|
||||
@@ -1797,516 +1536,6 @@ static void seq_prefetch_wm_notify(const bContext *C, Scene *scene)
|
||||
}
|
||||
}
|
||||
|
||||
static void *sequencer_OCIO_transform_ibuf(const bContext *C,
|
||||
ImBuf *ibuf,
|
||||
bool *r_glsl_used,
|
||||
eGPUTextureFormat *r_format,
|
||||
eGPUDataFormat *r_data,
|
||||
void **r_buffer_cache_handle)
|
||||
{
|
||||
void *display_buffer;
|
||||
bool force_fallback = false;
|
||||
*r_glsl_used = false;
|
||||
force_fallback |= (ED_draw_imbuf_method(ibuf) != IMAGE_DRAW_METHOD_GLSL);
|
||||
force_fallback |= (ibuf->dither != 0.0f);
|
||||
|
||||
/* Default */
|
||||
*r_format = GPU_RGBA8;
|
||||
*r_data = GPU_DATA_UBYTE;
|
||||
|
||||
/* Fallback to CPU based color space conversion. */
|
||||
if (force_fallback) {
|
||||
*r_glsl_used = false;
|
||||
display_buffer = nullptr;
|
||||
}
|
||||
else if (ibuf->float_buffer.data) {
|
||||
display_buffer = ibuf->float_buffer.data;
|
||||
|
||||
*r_data = GPU_DATA_FLOAT;
|
||||
if (ibuf->channels == 4) {
|
||||
*r_format = GPU_RGBA16F;
|
||||
}
|
||||
else if (ibuf->channels == 3) {
|
||||
/* Alpha is implicitly 1. */
|
||||
*r_format = GPU_RGB16F;
|
||||
}
|
||||
else {
|
||||
BLI_assert_msg(0, "Incompatible number of channels for float buffer in sequencer");
|
||||
*r_format = GPU_RGBA16F;
|
||||
display_buffer = nullptr;
|
||||
}
|
||||
|
||||
if (ibuf->float_buffer.colorspace) {
|
||||
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
|
||||
C, ibuf->float_buffer.colorspace, ibuf->dither, true);
|
||||
}
|
||||
else {
|
||||
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, ibuf->dither, true);
|
||||
}
|
||||
}
|
||||
else if (ibuf->byte_buffer.data) {
|
||||
display_buffer = ibuf->byte_buffer.data;
|
||||
|
||||
*r_glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(
|
||||
C, ibuf->byte_buffer.colorspace, ibuf->dither, false);
|
||||
}
|
||||
else {
|
||||
display_buffer = nullptr;
|
||||
}
|
||||
|
||||
/* There is data to be displayed, but GLSL is not initialized
|
||||
* properly, in this case we fallback to CPU-based display transform. */
|
||||
if ((ibuf->byte_buffer.data || ibuf->float_buffer.data) && !*r_glsl_used) {
|
||||
display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, r_buffer_cache_handle);
|
||||
*r_format = GPU_RGBA8;
|
||||
*r_data = GPU_DATA_UBYTE;
|
||||
}
|
||||
|
||||
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.
|
||||
* Need to make so sequencers rendering doesn't conflict with compositor. */
|
||||
WM_jobs_kill_type(CTX_wm_manager(C), nullptr, WM_JOB_TYPE_COMPOSITE);
|
||||
|
||||
/* In case of final rendering used for preview, kill all previews,
|
||||
* otherwise threading conflict will happen in rendering module. */
|
||||
WM_jobs_kill_type(CTX_wm_manager(C), nullptr, WM_JOB_TYPE_RENDER_PREVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
static void sequencer_preview_clear()
|
||||
{
|
||||
UI_ThemeClearColor(TH_SEQ_PREVIEW);
|
||||
}
|
||||
|
||||
static void sequencer_preview_get_rect(rctf *preview,
|
||||
Scene *scene,
|
||||
ARegion *region,
|
||||
SpaceSeq *sseq,
|
||||
bool draw_overlay,
|
||||
bool draw_backdrop)
|
||||
{
|
||||
View2D *v2d = ®ion->v2d;
|
||||
float viewrect[2];
|
||||
|
||||
sequencer_display_size(scene, viewrect);
|
||||
BLI_rctf_init(preview, -1.0f, 1.0f, -1.0f, 1.0f);
|
||||
|
||||
if (draw_overlay && (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT)) {
|
||||
preview->xmax = v2d->tot.xmin +
|
||||
(fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->overlay_frame_rect.xmax);
|
||||
preview->xmin = v2d->tot.xmin +
|
||||
(fabsf(BLI_rctf_size_x(&v2d->tot)) * scene->ed->overlay_frame_rect.xmin);
|
||||
preview->ymax = v2d->tot.ymin +
|
||||
(fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->overlay_frame_rect.ymax);
|
||||
preview->ymin = v2d->tot.ymin +
|
||||
(fabsf(BLI_rctf_size_y(&v2d->tot)) * scene->ed->overlay_frame_rect.ymin);
|
||||
}
|
||||
else if (draw_backdrop) {
|
||||
float aspect = BLI_rcti_size_x(®ion->winrct) / float(BLI_rcti_size_y(®ion->winrct));
|
||||
float image_aspect = viewrect[0] / viewrect[1];
|
||||
|
||||
if (aspect >= image_aspect) {
|
||||
preview->xmax = image_aspect / aspect;
|
||||
preview->xmin = -preview->xmax;
|
||||
}
|
||||
else {
|
||||
preview->ymax = aspect / image_aspect;
|
||||
preview->ymin = -preview->ymax;
|
||||
}
|
||||
}
|
||||
else {
|
||||
*preview = v2d->tot;
|
||||
}
|
||||
}
|
||||
|
||||
static void sequencer_draw_display_buffer(const bContext *C,
|
||||
Scene *scene,
|
||||
ARegion *region,
|
||||
SpaceSeq *sseq,
|
||||
ImBuf *ibuf,
|
||||
ImBuf *scope,
|
||||
bool draw_overlay,
|
||||
bool draw_backdrop)
|
||||
{
|
||||
void *display_buffer;
|
||||
void *buffer_cache_handle = nullptr;
|
||||
|
||||
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
}
|
||||
|
||||
/* Format needs to be created prior to any #immBindShader call.
|
||||
* Do it here because OCIO binds its own shader. */
|
||||
eGPUTextureFormat format;
|
||||
eGPUDataFormat data;
|
||||
bool glsl_used = false;
|
||||
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) {
|
||||
ibuf = scope;
|
||||
|
||||
if (ibuf->float_buffer.data && ibuf->byte_buffer.data == nullptr) {
|
||||
IMB_rect_from_float(ibuf);
|
||||
}
|
||||
|
||||
display_buffer = ibuf->byte_buffer.data;
|
||||
format = GPU_RGBA8;
|
||||
data = GPU_DATA_UBYTE;
|
||||
}
|
||||
else {
|
||||
display_buffer = sequencer_OCIO_transform_ibuf(
|
||||
C, ibuf, &glsl_used, &format, &data, &buffer_cache_handle);
|
||||
}
|
||||
|
||||
if (draw_backdrop) {
|
||||
GPU_matrix_push();
|
||||
GPU_matrix_identity_set();
|
||||
GPU_matrix_push_projection();
|
||||
GPU_matrix_identity_projection_set();
|
||||
}
|
||||
eGPUTextureUsage usage = GPU_TEXTURE_USAGE_SHADER_READ | GPU_TEXTURE_USAGE_ATTACHMENT;
|
||||
GPUTexture *texture = GPU_texture_create_2d(
|
||||
"seq_display_buf", ibuf->x, ibuf->y, 1, format, usage, nullptr);
|
||||
GPU_texture_update(texture, data, display_buffer);
|
||||
GPU_texture_filter_mode(texture, false);
|
||||
|
||||
GPU_texture_bind(texture, 0);
|
||||
|
||||
if (!glsl_used) {
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_IMAGE_COLOR);
|
||||
immUniformColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
immBegin(GPU_PRIM_TRI_FAN, 4);
|
||||
|
||||
rctf preview;
|
||||
rctf canvas;
|
||||
sequencer_preview_get_rect(&preview, scene, region, sseq, draw_overlay, draw_backdrop);
|
||||
|
||||
if (draw_overlay && (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_RECT)) {
|
||||
canvas = scene->ed->overlay_frame_rect;
|
||||
}
|
||||
else {
|
||||
BLI_rctf_init(&canvas, 0.0f, 1.0f, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
immAttr2f(texCoord, canvas.xmin, canvas.ymin);
|
||||
immVertex2f(pos, preview.xmin, preview.ymin);
|
||||
|
||||
immAttr2f(texCoord, canvas.xmin, canvas.ymax);
|
||||
immVertex2f(pos, preview.xmin, preview.ymax);
|
||||
|
||||
immAttr2f(texCoord, canvas.xmax, canvas.ymax);
|
||||
immVertex2f(pos, preview.xmax, preview.ymax);
|
||||
|
||||
immAttr2f(texCoord, canvas.xmax, canvas.ymin);
|
||||
immVertex2f(pos, preview.xmax, preview.ymin);
|
||||
|
||||
immEnd();
|
||||
|
||||
GPU_texture_unbind(texture);
|
||||
GPU_texture_free(texture);
|
||||
|
||||
if (!glsl_used) {
|
||||
immUnbindProgram();
|
||||
}
|
||||
else {
|
||||
IMB_colormanagement_finish_glsl_draw();
|
||||
}
|
||||
|
||||
if (buffer_cache_handle) {
|
||||
IMB_display_buffer_release(buffer_cache_handle);
|
||||
}
|
||||
|
||||
if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) {
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
}
|
||||
|
||||
if (draw_backdrop) {
|
||||
GPU_matrix_pop();
|
||||
GPU_matrix_pop_projection();
|
||||
}
|
||||
}
|
||||
|
||||
static ImBuf *sequencer_get_scope(Scene *scene, SpaceSeq *sseq, ImBuf *ibuf, bool draw_backdrop)
|
||||
{
|
||||
ImBuf *scope = nullptr;
|
||||
SequencerScopes *scopes = &sseq->scopes;
|
||||
|
||||
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->float_buffer.data) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
return scope;
|
||||
}
|
||||
|
||||
static bool sequencer_draw_get_transform_preview(SpaceSeq *sseq, Scene *scene)
|
||||
{
|
||||
Sequence *last_seq = SEQ_select_active_get(scene);
|
||||
if (last_seq == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (G.moving & G_TRANSFORM_SEQ) && (last_seq->flag & SELECT) &&
|
||||
((last_seq->flag & SEQ_LEFTSEL) || (last_seq->flag & SEQ_RIGHTSEL)) &&
|
||||
(sseq->draw_flag & SEQ_DRAW_TRANSFORM_PREVIEW);
|
||||
}
|
||||
|
||||
static int sequencer_draw_get_transform_preview_frame(Scene *scene)
|
||||
{
|
||||
Sequence *last_seq = SEQ_select_active_get(scene);
|
||||
/* #sequencer_draw_get_transform_preview must already have been called. */
|
||||
BLI_assert(last_seq != nullptr);
|
||||
int preview_frame;
|
||||
|
||||
if (last_seq->flag & SEQ_RIGHTSEL) {
|
||||
preview_frame = SEQ_time_right_handle_frame_get(scene, last_seq) - 1;
|
||||
}
|
||||
else {
|
||||
preview_frame = SEQ_time_left_handle_frame_get(scene, last_seq);
|
||||
}
|
||||
|
||||
return preview_frame;
|
||||
}
|
||||
|
||||
static void seq_draw_image_origin_and_outline(const bContext *C, Sequence *seq, bool is_active_seq)
|
||||
{
|
||||
SpaceSeq *sseq = CTX_wm_space_seq(C);
|
||||
const ARegion *region = CTX_wm_region(C);
|
||||
if (region->regiontype == RGN_TYPE_PREVIEW && !sequencer_view_preview_only_poll(C)) {
|
||||
return;
|
||||
}
|
||||
if ((seq->flag & SELECT) == 0) {
|
||||
return;
|
||||
}
|
||||
if (ED_screen_animation_no_scrub(CTX_wm_manager(C))) {
|
||||
return;
|
||||
}
|
||||
if ((sseq->flag & SEQ_SHOW_OVERLAY) == 0 ||
|
||||
(sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_OUTLINE_SELECTED) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (ELEM(sseq->mainb, SEQ_DRAW_IMG_WAVEFORM, SEQ_DRAW_IMG_VECTORSCOPE, SEQ_DRAW_IMG_HISTOGRAM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
float origin[2];
|
||||
SEQ_image_transform_origin_offset_pixelspace_get(CTX_data_scene(C), seq, origin);
|
||||
|
||||
/* Origin. */
|
||||
GPUVertFormat *format = immVertexFormat();
|
||||
uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_OUTLINE_AA);
|
||||
immUniform1f("outlineWidth", 1.5f);
|
||||
immUniformColor3f(1.0f, 1.0f, 1.0f);
|
||||
immUniform4f("outlineColor", 0.0f, 0.0f, 0.0f, 1.0f);
|
||||
immUniform1f("size", 15.0f * U.pixelsize);
|
||||
immBegin(GPU_PRIM_POINTS, 1);
|
||||
immVertex2f(pos, origin[0], origin[1]);
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
|
||||
/* Outline. */
|
||||
float seq_image_quad[4][2];
|
||||
SEQ_image_transform_final_quad_get(CTX_data_scene(C), seq, seq_image_quad);
|
||||
|
||||
GPU_line_smooth(true);
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
GPU_line_width(2);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
|
||||
float col[3];
|
||||
if (is_active_seq) {
|
||||
UI_GetThemeColor3fv(TH_SEQ_ACTIVE, col);
|
||||
}
|
||||
else {
|
||||
UI_GetThemeColor3fv(TH_SEQ_SELECTED, col);
|
||||
}
|
||||
immUniformColor3fv(col);
|
||||
immUniform1f("lineWidth", U.pixelsize);
|
||||
immBegin(GPU_PRIM_LINE_LOOP, 4);
|
||||
immVertex2f(pos, seq_image_quad[0][0], seq_image_quad[0][1]);
|
||||
immVertex2f(pos, seq_image_quad[1][0], seq_image_quad[1][1]);
|
||||
immVertex2f(pos, seq_image_quad[2][0], seq_image_quad[2][1]);
|
||||
immVertex2f(pos, seq_image_quad[3][0], seq_image_quad[3][1]);
|
||||
immEnd();
|
||||
immUnbindProgram();
|
||||
GPU_line_width(1);
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
GPU_line_smooth(false);
|
||||
}
|
||||
|
||||
void sequencer_draw_preview(const bContext *C,
|
||||
Scene *scene,
|
||||
ARegion *region,
|
||||
SpaceSeq *sseq,
|
||||
int timeline_frame,
|
||||
int offset,
|
||||
bool draw_overlay,
|
||||
bool draw_backdrop)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Depsgraph *depsgraph = CTX_data_expect_evaluated_depsgraph(C);
|
||||
View2D *v2d = ®ion->v2d;
|
||||
ImBuf *ibuf = nullptr;
|
||||
ImBuf *scope = nullptr;
|
||||
float viewrect[2];
|
||||
const bool show_imbuf = ED_space_sequencer_check_show_imbuf(sseq);
|
||||
const bool draw_gpencil = ((sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_GPENCIL) && sseq->gpd);
|
||||
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
|
||||
|
||||
sequencer_stop_running_jobs(C, scene);
|
||||
if (G.is_rendering) {
|
||||
return;
|
||||
}
|
||||
|
||||
int preview_frame = timeline_frame;
|
||||
if (sequencer_draw_get_transform_preview(sseq, scene)) {
|
||||
preview_frame = sequencer_draw_get_transform_preview_frame(scene);
|
||||
}
|
||||
|
||||
/* Get image. */
|
||||
ibuf = sequencer_ibuf_get(
|
||||
bmain, region, depsgraph, scene, sseq, preview_frame, offset, names[sseq->multiview_eye]);
|
||||
|
||||
/* Setup off-screen buffers. */
|
||||
GPUViewport *viewport = WM_draw_region_get_viewport(region);
|
||||
GPUFrameBuffer *framebuffer_overlay = GPU_viewport_framebuffer_overlay_get(viewport);
|
||||
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
|
||||
GPU_depth_test(GPU_DEPTH_NONE);
|
||||
|
||||
if (sseq->render_size == SEQ_RENDER_SIZE_NONE) {
|
||||
sequencer_preview_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Setup view. */
|
||||
sequencer_display_size(scene, viewrect);
|
||||
UI_view2d_totRect_set(v2d, roundf(viewrect[0] + 0.5f), roundf(viewrect[1] + 0.5f));
|
||||
UI_view2d_curRect_validate(v2d);
|
||||
UI_view2d_view_ortho(v2d);
|
||||
|
||||
/* Draw background. */
|
||||
if (!draw_backdrop &&
|
||||
(!draw_overlay || (sseq->overlay_frame_type == SEQ_OVERLAY_FRAME_TYPE_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);
|
||||
}
|
||||
}
|
||||
|
||||
if (ibuf) {
|
||||
scope = sequencer_get_scope(scene, sseq, ibuf, draw_backdrop);
|
||||
|
||||
/* Draw image. */
|
||||
sequencer_draw_display_buffer(
|
||||
C, scene, region, sseq, ibuf, scope, draw_overlay, draw_backdrop);
|
||||
|
||||
/* Draw over image. */
|
||||
if (sseq->preview_overlay.flag & SEQ_PREVIEW_SHOW_METADATA && sseq->flag & SEQ_SHOW_OVERLAY) {
|
||||
ED_region_image_metadata_draw(0.0, 0.0, ibuf, &v2d->tot, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
if (show_imbuf && (sseq->flag & SEQ_SHOW_OVERLAY)) {
|
||||
sequencer_draw_borders_overlay(sseq, v2d, scene);
|
||||
}
|
||||
|
||||
if (!draw_backdrop && scene->ed != nullptr) {
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
ListBase *channels = SEQ_channels_displayed_get(ed);
|
||||
SeqCollection *collection = SEQ_query_rendered_strips(
|
||||
scene, channels, ed->seqbasep, timeline_frame, 0);
|
||||
Sequence *seq;
|
||||
Sequence *active_seq = SEQ_select_active_get(scene);
|
||||
SEQ_ITERATOR_FOREACH (seq, collection) {
|
||||
seq_draw_image_origin_and_outline(C, seq, seq == active_seq);
|
||||
}
|
||||
SEQ_collection_free(collection);
|
||||
}
|
||||
|
||||
if (draw_gpencil && show_imbuf && (sseq->flag & SEQ_SHOW_OVERLAY)) {
|
||||
sequencer_draw_gpencil_overlay(C);
|
||||
}
|
||||
|
||||
#if 0
|
||||
sequencer_draw_maskedit(C, scene, region, sseq);
|
||||
#endif
|
||||
|
||||
/* Draw registered callbacks. */
|
||||
GPU_framebuffer_bind(framebuffer_overlay);
|
||||
ED_region_draw_cb_draw(C, region, REGION_DRAW_POST_VIEW);
|
||||
GPU_framebuffer_bind_no_srgb(framebuffer_overlay);
|
||||
|
||||
/* Scope is freed in sequencer_check_scopes when `ibuf` changes and redraw is needed. */
|
||||
if (ibuf) {
|
||||
IMB_freeImBuf(ibuf);
|
||||
}
|
||||
|
||||
UI_view2d_view_restore(C);
|
||||
seq_prefetch_wm_notify(C, scene);
|
||||
}
|
||||
|
||||
static void draw_seq_timeline_channels(View2D *v2d)
|
||||
{
|
||||
uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||
Reference in New Issue
Block a user