From 307d7f624510fcca7a7f6c1e683796cb73637106 Mon Sep 17 00:00:00 2001 From: Good Guy Date: Wed, 8 May 2019 19:18:44 -0600 Subject: [PATCH] tags tweak, rework canvas lock/refresh, vgui/cgui segv if closed while playing --- cinelerra-5.1/Makefile.devel | 2 +- cinelerra-5.1/cinelerra/Makefile | 2 +- cinelerra-5.1/cinelerra/canvas.C | 124 +++++++++--------- cinelerra-5.1/cinelerra/canvas.h | 12 +- cinelerra-5.1/cinelerra/cpanel.C | 3 +- cinelerra-5.1/cinelerra/cwindow.C | 2 +- cinelerra-5.1/cinelerra/cwindowgui.C | 28 ++--- cinelerra-5.1/cinelerra/cwindowtool.C | 4 +- cinelerra-5.1/cinelerra/playback3d.C | 175 ++++++++++---------------- cinelerra-5.1/cinelerra/vdevicex11.C | 130 +++++++++---------- cinelerra-5.1/cinelerra/vwindowgui.C | 8 +- 11 files changed, 210 insertions(+), 280 deletions(-) diff --git a/cinelerra-5.1/Makefile.devel b/cinelerra-5.1/Makefile.devel index a12d8f2b..aac14d67 100644 --- a/cinelerra-5.1/Makefile.devel +++ b/cinelerra-5.1/Makefile.devel @@ -18,7 +18,7 @@ all: clean: for dir in $(SUBDIRS); do $(MAKE) -C $$dir clean; done rm -rf thirdparty/opencv* - rm -rf bin + rm -rf bin cinelerra/tags ./autogen.sh clean install: diff --git a/cinelerra-5.1/cinelerra/Makefile b/cinelerra-5.1/cinelerra/Makefile index 1bd04ab6..4652f02f 100644 --- a/cinelerra-5.1/cinelerra/Makefile +++ b/cinelerra-5.1/cinelerra/Makefile @@ -592,7 +592,7 @@ shudmp: shudmp.C @g++ $(CFLAGS) shudmp.C -o $@ -lusb-1.0 clean: - rm -rf $(OBJDIR) tags + rm -rf $(OBJDIR) rm -f shuttle_keys.h tags: diff --git a/cinelerra-5.1/cinelerra/canvas.C b/cinelerra-5.1/cinelerra/canvas.C index 707c95c0..f0ea0a12 100644 --- a/cinelerra-5.1/cinelerra/canvas.C +++ b/cinelerra-5.1/cinelerra/canvas.C @@ -63,7 +63,7 @@ Canvas::Canvas(MWindow *mwindow, this->scr_w0 = subwindow->get_screen_w(0, 0); this->root_w = subwindow->get_root_w(0); this->root_h = subwindow->get_root_h(0); - canvas_lock = new Mutex("Canvas::canvas_lock", 1); + canvas_lock = new Condition(1, "Canvas::canvas_lock", 1); } Canvas::~Canvas() @@ -92,22 +92,21 @@ void Canvas::reset() cursor_inside = 0; } -void Canvas::lock_canvas(const char *location) +BC_WindowBase *Canvas::lock_canvas(const char *loc) { - canvas_lock->lock(location); + canvas_lock->lock(loc); + BC_WindowBase *wdw = get_canvas(); + if( wdw ) wdw->lock_window(loc); + return wdw; } void Canvas::unlock_canvas() { + BC_WindowBase *wdw = get_canvas(); + if( wdw ) wdw->unlock_window(); canvas_lock->unlock(); } -int Canvas::is_locked() -{ - return canvas_lock->is_locked(); -} - - BC_WindowBase* Canvas::get_canvas() { if(get_fullscreen() && canvas_fullscreen) @@ -623,7 +622,28 @@ void Canvas::reposition_window(EDL *edl, int x, int y, int w, int h) canvas_subwindow->flash(0); } } - draw_refresh(0); + refresh(0); +} + +// must hold window lock +int Canvas::refresh(int flush) +{ + BC_WindowBase *window = get_canvas(); + if( !window ) return 0; +// relock in lock order to prevent deadlock + window->unlock_window(); + lock_canvas("Canvas::refresh"); + draw_refresh(flush); + canvas_lock->unlock(); + return 1; +} +// must not hold locks +int Canvas::redraw(int flush) +{ + lock_canvas("Canvas::redraw"); + draw_refresh(flush); + unlock_canvas(); + return 1; } void Canvas::set_cursor(int cursor) @@ -728,44 +748,34 @@ void Canvas::stop_fullscreen() void Canvas::create_canvas() { + canvas_lock->lock("Canvas::create_canvas"); int video_on = 0; - lock_canvas("Canvas::create_canvas"); - - if(!get_fullscreen()) + BC_WindowBase *wdw = 0; + if( !get_fullscreen() ) { // Enter windowed - { - if(canvas_fullscreen) - { + if( canvas_fullscreen ) { + canvas_fullscreen->lock_window("Canvas::create_canvas 1"); video_on = canvas_fullscreen->get_video_on(); - canvas_fullscreen->stop_video(); - canvas_fullscreen->lock_window("Canvas::create_canvas 2"); + if( video_on ) canvas_fullscreen->stop_video(); canvas_fullscreen->hide_window(); canvas_fullscreen->unlock_window(); } - - if(!canvas_auxwindow && !canvas_subwindow) - { + if( !canvas_auxwindow && !canvas_subwindow ) { subwindow->add_subwindow(canvas_subwindow = new CanvasOutput(this, - view_x, - view_y, - view_w, - view_h)); + view_x, view_y, view_w, view_h)); } + wdw = get_canvas(); + wdw->lock_window("Canvas::create_canvas 2"); } - else + else { // Enter fullscreen - { - BC_WindowBase *wdw = canvas_auxwindow ? - canvas_auxwindow : canvas_subwindow; - if(wdw) - { - video_on = wdw->get_video_on(); - wdw->stop_video(); - } - + wdw = canvas_auxwindow ? canvas_auxwindow : canvas_subwindow; + wdw->lock_window("Canvas::create_canvas 3"); + video_on = wdw->get_video_on(); + if( video_on ) wdw->stop_video(); int x, y, w, h; wdw->get_fullscreen_geometry(x, y, w, h); - + wdw->unlock_window(); if( canvas_fullscreen ) { if( x != canvas_fullscreen->get_x() || y != canvas_fullscreen->get_y() || @@ -777,25 +787,20 @@ void Canvas::create_canvas() } if( !canvas_fullscreen ) canvas_fullscreen = new CanvasFullScreen(this, w, h); - canvas_fullscreen->show_window(); - canvas_fullscreen->sync_display(); - canvas_fullscreen->reposition_window(x, y); - } - - if( !video_on ) { - get_canvas()->lock_window("Canvas::create_canvas 1"); - draw_refresh(); - get_canvas()->unlock_window(); + wdw = canvas_fullscreen; + wdw->lock_window("Canvas::create_canvas 4"); + wdw->show_window(); + wdw->sync_display(); + wdw->reposition_window(x, y); } - if( video_on ) - get_canvas()->start_video(); - - get_canvas()->lock_window("Canvas::create_canvas 2"); - get_canvas()->focus(); - get_canvas()->unlock_window(); - - unlock_canvas(); + if( !video_on ) + draw_refresh(1); + else + wdw->start_video(); + wdw->focus(); + wdw->unlock_window(); + canvas_lock->unlock(); } @@ -888,11 +893,9 @@ void Canvas::update_refresh(VideoDevice *device, VFrame *output_frame) } if( use_opengl ) { - get_canvas()->unlock_window(); unlock_canvas(); mwindow->playback_3d->copy_from(this, refresh_frame, output_frame, 0); - lock_canvas(" Canvas::output_refresh"); - get_canvas()->lock_window(" Canvas::output_refresh"); + lock_canvas("Canvas::update_refresh"); } else refresh_frame->transfer_from(output_frame, -1); @@ -978,10 +981,8 @@ CanvasXScroll::~CanvasXScroll() int CanvasXScroll::handle_event() { -//printf("CanvasXScroll::handle_event %d %d %d\n", get_length(), get_value(), get_handlelength()); canvas->update_zoom(get_value(), canvas->get_yscroll(), canvas->get_zoom()); - canvas->draw_refresh(); - return 1; + return canvas->refresh(1); } @@ -998,10 +999,8 @@ CanvasYScroll::~CanvasYScroll() int CanvasYScroll::handle_event() { -//printf("CanvasYScroll::handle_event %d %d\n", get_value(), get_length()); canvas->update_zoom(canvas->get_xscroll(), get_value(), canvas->get_zoom()); - canvas->draw_refresh(); - return 1; + return canvas->refresh(1); } @@ -1131,7 +1130,6 @@ int CanvasPopupSize::handle_event() } - CanvasPopupResetCamera::CanvasPopupResetCamera(Canvas *canvas) : BC_MenuItem(_("Reset camera"), _("F11"), KEY_F11) { diff --git a/cinelerra-5.1/cinelerra/canvas.h b/cinelerra-5.1/cinelerra/canvas.h index 2fd2a23e..775df7d0 100644 --- a/cinelerra-5.1/cinelerra/canvas.h +++ b/cinelerra-5.1/cinelerra/canvas.h @@ -44,11 +44,9 @@ public: void calculate_sizes(float aspect_ratio, int output_w, int output_h, float zoom, int &w, int &h); -// Lock access to the canvas pointer. -// Must be called before get_canvas or locking the canvas. - void lock_canvas(const char *location); +// Lock canvas pointer and window + BC_WindowBase *lock_canvas(const char *loc); void unlock_canvas(); - int is_locked(); void create_objects(EDL *edl); void set_cursor(int cursor); @@ -173,6 +171,9 @@ public: int get_buttonpress(); // Gets whatever video surface is enabled BC_WindowBase* get_canvas(); +// draw_refresh, with/without locks + int refresh(int flush); + int redraw(int flush); // The owner of the canvas BC_WindowBase *subwindow; @@ -215,7 +216,8 @@ public: private: void get_scrollbars(EDL *edl, int &canvas_x, int &canvas_y, int &canvas_w, int &canvas_h); - Mutex *canvas_lock; +// Lock access to the canvas pointer. + Condition *canvas_lock; }; diff --git a/cinelerra-5.1/cinelerra/cpanel.C b/cinelerra-5.1/cinelerra/cpanel.C index da3fd827..e73879e4 100644 --- a/cinelerra-5.1/cinelerra/cpanel.C +++ b/cinelerra-5.1/cinelerra/cpanel.C @@ -364,8 +364,7 @@ CPanelTitleSafe::~CPanelTitleSafe() int CPanelTitleSafe::handle_event() { mwindow->edl->session->safe_regions = get_value(); - gui->subwindow->canvas->draw_refresh(); - return 1; + return gui->subwindow->canvas->refresh(1); } CPanelZoom::CPanelZoom(MWindow *mwindow, CPanel *gui, int x, int y, int h) diff --git a/cinelerra-5.1/cinelerra/cwindow.C b/cinelerra-5.1/cinelerra/cwindow.C index 5285fd4e..9fed7292 100644 --- a/cinelerra-5.1/cinelerra/cwindow.C +++ b/cinelerra-5.1/cinelerra/cwindow.C @@ -224,7 +224,7 @@ void CWindow::update(int dir, int overlays, int tool_window, int operation, int // Updated by video device. if( overlays && !dir ) - gui->canvas->draw_refresh(); + gui->canvas->refresh(1); // Update tool parameters // Never updated by someone else diff --git a/cinelerra-5.1/cinelerra/cwindowgui.C b/cinelerra-5.1/cinelerra/cwindowgui.C index 7b3e9198..d29e0575 100644 --- a/cinelerra-5.1/cinelerra/cwindowgui.C +++ b/cinelerra-5.1/cinelerra/cwindowgui.C @@ -119,6 +119,7 @@ CWindowGUI::CWindowGUI(MWindow *mwindow, CWindow *cwindow) CWindowGUI::~CWindowGUI() { + cwindow->stop_playback(1); if(tool_panel) delete tool_panel; delete meters; delete composite_panel; @@ -419,7 +420,7 @@ void CWindowGUI::zoom_canvas(double value, int update_menu) canvas->reposition_window(mwindow->edl, mwindow->theme->ccanvas_x, mwindow->theme->ccanvas_y, mwindow->theme->ccanvas_w, mwindow->theme->ccanvas_h); - canvas->draw_refresh(); + canvas->refresh(0); } void CWindowGUI::set_operation(int value) @@ -443,7 +444,7 @@ void CWindowGUI::set_operation(int value) edit_panel->update(); tool_panel->start_tool(value); - canvas->draw_refresh(); + canvas->refresh(0); } void CWindowGUI::update_tool() @@ -672,7 +673,7 @@ void CWindowGUI::sync_parameters(int change_type, int redraw, int overlay) { if( redraw ) { update_tool(); - canvas->draw_refresh(); + canvas->refresh(1); } if( change_type < 0 && !overlay ) return; unlock_window(); @@ -698,7 +699,7 @@ void CWindowGUI::drag_motion() int need_highlight = cursor_above() && get_cursor_over_window(); if( highlighted == need_highlight ) return; highlighted = need_highlight; - canvas->draw_refresh(); + canvas->refresh(1); } int CWindowGUI::drag_stop() @@ -710,7 +711,7 @@ int CWindowGUI::drag_stop() mwindow->session->current_operation != DRAG_VTRANSITION && mwindow->session->current_operation != DRAG_VEFFECT) return 0; highlighted = 0; - canvas->draw_refresh(); + canvas->refresh(1); result = 1; if(mwindow->session->current_operation == DRAG_ASSET) @@ -1125,15 +1126,16 @@ float CWindowCanvas::get_zoom() void CWindowCanvas::draw_refresh(int flush) { - if( get_canvas() && !get_canvas()->get_video_on() ) { + BC_WindowBase *window = get_canvas(); + if( window && !window->get_video_on() ) { clear(0); if( mwindow->uses_opengl() ) { // this code is to idle rendering before drawing overlays on refresh frame // if this is not done, occationally opengl finishs late, and overwrites // the x11 refresh frame and the overlay is not visible. Rarely happens. - get_canvas()->unlock_window(); + unlock_canvas(); mwindow->playback_3d->finish_output(this); - get_canvas()->lock_window("CWindowCanvas::draw_refresh"); + lock_canvas("CWindowCanvas::draw_refresh"); } if( refresh_frame && refresh_frame->get_w()>0 && refresh_frame->get_h()>0 ) { float in_x1, in_y1, in_x2, in_y2; @@ -1160,7 +1162,7 @@ void CWindowCanvas::draw_refresh(int flush) in_y1 *= ys; in_y2 *= ys; // Can't use OpenGL here because it is called asynchronously of the // playback operation. - get_canvas()->draw_vframe(refresh_frame, + window->draw_vframe(refresh_frame, (int)out_x1, (int)out_y1, (int)(out_x2 - out_x1), (int)(out_y2 - out_y1), @@ -1172,7 +1174,7 @@ void CWindowCanvas::draw_refresh(int flush) } //usleep(10000); draw_overlays(); - get_canvas()->flash(flush); + window->flash(flush); } //printf("CWindowCanvas::draw_refresh 10\n"); } @@ -1186,10 +1188,6 @@ void CWindowCanvas::draw_crophandle(int x, int y) } - - - - #define CONTROL_W 10 #define CONTROL_H 10 #define FIRST_CONTROL_W 20 @@ -1200,8 +1198,6 @@ void CWindowCanvas::draw_crophandle(int x, int y) #define RULERHANDLE_W 16 #define RULERHANDLE_H 16 - - int CWindowCanvas::do_ruler(int draw, int motion, int button_press, diff --git a/cinelerra-5.1/cinelerra/cwindowtool.C b/cinelerra-5.1/cinelerra/cwindowtool.C index efa4cdb1..99577fd8 100644 --- a/cinelerra-5.1/cinelerra/cwindowtool.C +++ b/cinelerra-5.1/cinelerra/cwindowtool.C @@ -466,9 +466,7 @@ void CWindowCropGUI::handle_event() mwindow->edl->session->crop_y2 = atol(height->get_text()) + mwindow->edl->session->crop_y1; update(); - mwindow->cwindow->gui->lock_window("CWindowCropGUI::handle_event"); - mwindow->cwindow->gui->canvas->draw_refresh(); - mwindow->cwindow->gui->unlock_window(); + mwindow->cwindow->gui->canvas->redraw(1); } void CWindowCropGUI::update() diff --git a/cinelerra-5.1/cinelerra/playback3d.C b/cinelerra-5.1/cinelerra/playback3d.C index 0f5e84fe..8d58deb3 100644 --- a/cinelerra-5.1/cinelerra/playback3d.C +++ b/cinelerra-5.1/cinelerra/playback3d.C @@ -469,11 +469,9 @@ void Playback3D::copy_from(Canvas *canvas, void Playback3D::copy_from_sync(Playback3DCommand *command) { #ifdef HAVE_GL - command->canvas->lock_canvas("Playback3D::draw_refresh_sync"); - BC_WindowBase *window = command->canvas->get_canvas(); - if(window) - { - window->lock_window("Playback3D:draw_refresh_sync"); + BC_WindowBase *window = + command->canvas->lock_canvas("Playback3D::copy_from_sync"); + if( window ) { window->enable_opengl(); int w = command->input->get_w(); int h = command->input->get_h(); @@ -530,8 +528,6 @@ void Playback3D::copy_from_sync(Playback3DCommand *command) command->input->get_opengl_state(), w, h, command->frame->get_w(), command->frame->get_h()); } - - window->unlock_window(); } command->canvas->unlock_canvas(); #endif @@ -568,11 +564,10 @@ void Playback3D::copy_from_sync(Playback3DCommand *command) // // void Playback3D::draw_refresh_sync(Playback3DCommand *command) // { -// command->canvas->lock_canvas("Playback3D::draw_refresh_sync"); -// BC_WindowBase *window = command->canvas->get_canvas(); -// if(window) -// { -// window->lock_window("Playback3D:draw_refresh_sync"); +// #ifdef HAVE_GL +// BC_WindowBase *window = +// command->canvas->lock_canvas("Playback3D::draw_refresh_sync"); +// if( window ) { // window->enable_opengl(); // // // Read output pbuffer back to RAM in project colormodel @@ -602,9 +597,9 @@ void Playback3D::copy_from_sync(Playback3DCommand *command) // (int)(command->in_y2 - command->in_y1), // 0); // -// window->unlock_window(); // } // command->canvas->unlock_canvas(); +// #endif // } @@ -642,11 +637,10 @@ void Playback3D::write_buffer(Canvas *canvas, void Playback3D::write_buffer_sync(Playback3DCommand *command) { - command->canvas->lock_canvas("Playback3D::write_buffer_sync"); - if(command->canvas->get_canvas()) - { - BC_WindowBase *window = command->canvas->get_canvas(); - window->lock_window("Playback3D::write_buffer_sync"); +#ifdef HAVE_GL + BC_WindowBase *window = + command->canvas->lock_canvas("Playback3D::write_buffer_sync"); + if( window ) { // Update hidden cursor window->update_video_cursor(); // Make sure OpenGL is enabled first. @@ -677,10 +671,9 @@ void Playback3D::write_buffer_sync(Playback3DCommand *command) break; } command->frame->set_opengl_state(frame_state); - window->unlock_window(); } - command->canvas->unlock_canvas(); +#endif } @@ -780,8 +773,9 @@ void Playback3D::finish_output(Canvas *canvas) void Playback3D::finish_output_sync(Playback3DCommand *command) { #ifdef HAVE_GL - command->canvas->lock_canvas("Playback3D::clear_output_sync"); - if( command->canvas->get_canvas() ) { + BC_WindowBase *window = + command->canvas->lock_canvas("Playback3D::finish_output_sync"); + if( window ) { command->canvas->get_canvas()->enable_opengl(); glFinish(); } @@ -801,26 +795,24 @@ void Playback3D::clear_output(Canvas *canvas, VFrame *output) void Playback3D::clear_output_sync(Playback3DCommand *command) { - command->canvas->lock_canvas("Playback3D::clear_output_sync"); - if(command->canvas->get_canvas()) - { - command->canvas->get_canvas()->lock_window("Playback3D::clear_output_sync"); +#ifdef HAVE_GL + BC_WindowBase *window = + command->canvas->lock_canvas("Playback3D::clear_output_sync"); + if( window ) { // If we get here, the virtual console is being used. command->canvas->get_canvas()->enable_opengl(); int is_yuv = 0; - // Using pbuffer for refresh frame. - if(command->frame) - { + if( command->frame ) { command->frame->enable_opengl(); int color_model = command->canvas->mwindow->edl->session->color_model; is_yuv = BC_CModels::is_yuv(color_model); } init_frame(command, is_yuv); - command->canvas->get_canvas()->unlock_window(); } command->canvas->unlock_canvas(); +#endif } @@ -835,17 +827,17 @@ void Playback3D::clear_input(Canvas *canvas, VFrame *frame) void Playback3D::clear_input_sync(Playback3DCommand *command) { - command->canvas->lock_canvas("Playback3D::clear_output_sync"); - if(command->canvas->get_canvas()) - { - command->canvas->get_canvas()->lock_window("Playback3D::clear_output_sync"); +#ifdef HAVE_GL + BC_WindowBase *window = + command->canvas->lock_canvas("Playback3D::clear_input_sync"); + if( window ) { command->canvas->get_canvas()->enable_opengl(); command->frame->enable_opengl(); command->frame->clear_pbuffer(); command->frame->set_opengl_state(VFrame::SCREEN); - command->canvas->get_canvas()->unlock_window(); } command->canvas->unlock_canvas(); +#endif } void Playback3D::do_camera(Canvas *canvas, @@ -878,10 +870,10 @@ void Playback3D::do_camera(Canvas *canvas, void Playback3D::do_camera_sync(Playback3DCommand *command) { - command->canvas->lock_canvas("Playback3D::do_camera_sync"); - if(command->canvas->get_canvas()) - { - command->canvas->get_canvas()->lock_window("Playback3D::clear_output_sync"); +#ifdef HAVE_GL + BC_WindowBase *window = + command->canvas->lock_canvas("Playback3D::do_camera_sync"); + if( window ) { command->canvas->get_canvas()->enable_opengl(); command->input->to_texture(); @@ -912,9 +904,9 @@ void Playback3D::do_camera_sync(Playback3DCommand *command) command->frame->set_opengl_state(VFrame::SCREEN); command->frame->screen_to_ram(); - command->canvas->get_canvas()->unlock_window(); } command->canvas->unlock_canvas(); +#endif } void Playback3D::overlay(Canvas *canvas, VFrame *input, @@ -981,10 +973,9 @@ void Playback3D::overlay_sync(Playback3DCommand *command) blend_DIFFERENCE_frag, // TRANSFER_DIFFERENCE }; - command->canvas->lock_canvas("Playback3D::overlay_sync"); - if(command->canvas->get_canvas()) { - BC_WindowBase *window = command->canvas->get_canvas(); - window->lock_window("Playback3D::overlay_sync"); + BC_WindowBase *window = + command->canvas->lock_canvas("Playback3D::overlay_sync"); + if( window ) { // Make sure OpenGL is enabled first. window->enable_opengl(); window->update_video_cursor(); @@ -1116,8 +1107,6 @@ void Playback3D::overlay_sync(Playback3DCommand *command) } glActiveTexture(GL_TEXTURE0); glDisable(GL_TEXTURE_2D); - - window->unlock_window(); } command->canvas->unlock_canvas(); #endif @@ -1191,30 +1180,24 @@ static void combine_callback(GLdouble coords[3], void Playback3D::do_mask_sync(Playback3DCommand *command) { #ifdef HAVE_GL - command->canvas->lock_canvas("Playback3D::do_mask_sync"); - if(command->canvas->get_canvas()) - { - BC_WindowBase *window = command->canvas->get_canvas(); - window->lock_window("Playback3D::do_mask_sync"); + BC_WindowBase *window = + command->canvas->lock_canvas("Playback3D::do_mask_sync"); + if( window ) { window->enable_opengl(); - switch(command->frame->get_opengl_state()) - { - case VFrame::RAM: + switch( command->frame->get_opengl_state() ) { + case VFrame::RAM: // Time to upload to the texture - command->frame->to_texture(); - break; + command->frame->to_texture(); + break; - case VFrame::SCREEN: + case VFrame::SCREEN: // Read back from PBuffer // Bind context to pbuffer - command->frame->enable_opengl(); - command->frame->screen_to_texture(); - break; + command->frame->enable_opengl(); + command->frame->screen_to_texture(); + break; } - - - // Create PBuffer and draw the mask on it command->frame->enable_opengl(); @@ -1225,16 +1208,14 @@ void Playback3D::do_mask_sync(Playback3DCommand *command) // Clear screen glDisable(GL_TEXTURE_2D); - if(command->default_auto->mode == MASK_MULTIPLY_ALPHA) - { + if( command->default_auto->mode == MASK_MULTIPLY_ALPHA ) { glClearColor(0.0, 0.0, 0.0, 0.0); glColor4f((float)command->keyframe->value / 100, (float)command->keyframe->value / 100, (float)command->keyframe->value / 100, 1.0); } - else - { + else { glClearColor(1.0, 1.0, 1.0, 1.0); glColor4f((float)1.0 - (float)command->keyframe->value / 100, (float)1.0 - (float)command->keyframe->value / 100, @@ -1460,7 +1441,6 @@ void Playback3D::do_mask_sync(Playback3DCommand *command) // Default drawable window->enable_opengl(); - window->unlock_window(); } command->canvas->unlock_canvas(); #endif @@ -1508,11 +1488,9 @@ void Playback3D::convert_cmodel(Canvas *canvas, void Playback3D::convert_cmodel_sync(Playback3DCommand *command) { #ifdef HAVE_GL - command->canvas->lock_canvas("Playback3D::convert_cmodel_sync"); - - if( command->canvas->get_canvas() ) { - BC_WindowBase *window = command->canvas->get_canvas(); - window->lock_window("Playback3D::convert_cmodel_sync"); + BC_WindowBase *window = + command->canvas->lock_canvas("Playback3D::convert_cmodel_sync"); + if( window ) { window->enable_opengl(); // Import into hardware @@ -1597,8 +1575,6 @@ void Playback3D::convert_cmodel_sync(Playback3DCommand *command) if(shader) glUseProgram(0); command->frame->set_opengl_state(VFrame::SCREEN); } - - window->unlock_window(); } command->canvas->unlock_canvas(); @@ -1618,28 +1594,23 @@ void Playback3D::do_fade(Canvas *canvas, VFrame *frame, float fade) void Playback3D::do_fade_sync(Playback3DCommand *command) { #ifdef HAVE_GL - command->canvas->lock_canvas("Playback3D::do_mask_sync"); - if(command->canvas->get_canvas()) - { - BC_WindowBase *window = command->canvas->get_canvas(); - window->lock_window("Playback3D::do_fade_sync"); + BC_WindowBase *window = + command->canvas->lock_canvas("Playback3D::do_fade_sync"); + if( window ) { window->enable_opengl(); + switch( command->frame->get_opengl_state() ) { + case VFrame::RAM: + command->frame->to_texture(); + break; - switch(command->frame->get_opengl_state()) - { - case VFrame::RAM: - command->frame->to_texture(); - break; - - case VFrame::SCREEN: + case VFrame::SCREEN: // Read back from PBuffer // Bind context to pbuffer - command->frame->enable_opengl(); - command->frame->screen_to_texture(); - break; + command->frame->enable_opengl(); + command->frame->screen_to_texture(); + break; } - command->frame->enable_opengl(); command->frame->init_screen(); command->frame->bind_texture(0); @@ -1690,23 +1661,12 @@ void Playback3D::do_fade_sync(Playback3DCommand *command) glColor4f(1, 1, 1, 1); glDisable(GL_BLEND); - - window->unlock_window(); } command->canvas->unlock_canvas(); #endif } - - - - - - - - - int Playback3D::run_plugin(Canvas *canvas, PluginClient *client) { Playback3DCommand command; @@ -1718,16 +1678,11 @@ int Playback3D::run_plugin(Canvas *canvas, PluginClient *client) void Playback3D::run_plugin_sync(Playback3DCommand *command) { - command->canvas->lock_canvas("Playback3D::run_plugin_sync"); - if(command->canvas->get_canvas()) - { - BC_WindowBase *window = command->canvas->get_canvas(); - window->lock_window("Playback3D::run_plugin_sync"); + BC_WindowBase *window = + command->canvas->lock_canvas("Playback3D::run_plugin_sync"); + if( window ) { window->enable_opengl(); - command->result = ((PluginVClient*)command->plugin_client)->handle_opengl(); - - window->unlock_window(); } command->canvas->unlock_canvas(); } diff --git a/cinelerra-5.1/cinelerra/vdevicex11.C b/cinelerra-5.1/cinelerra/vdevicex11.C index 8cd64fe6..ebdb520c 100644 --- a/cinelerra-5.1/cinelerra/vdevicex11.C +++ b/cinelerra-5.1/cinelerra/vdevicex11.C @@ -96,70 +96,58 @@ int VDeviceX11::open_input() int VDeviceX11::open_output() { - if( output ) { + if( !output ) return 0; + BC_WindowBase *window = output->lock_canvas("VDeviceX11::open_output"); - output->get_canvas()->lock_window("VDeviceX11::open_output"); + if( window ) { if( !device->single_frame ) output->start_video(); else output->start_single(); - output->get_canvas()->unlock_window(); - -// Enable opengl in the first routine that needs it, to reduce the complexity. - output->unlock_canvas(); } + output->unlock_canvas(); return 0; } int VDeviceX11::output_visible() { - if( !output ) return 0; - - output->lock_canvas("VDeviceX11::output_visible"); - if( output->get_canvas()->get_hidden() ) { - output->unlock_canvas(); - return 0; - } - else { + int ret = 0; + if( output ) { + BC_WindowBase *window = + output->lock_canvas("VDeviceX11::output_visible"); + ret = !window || window->get_hidden() ? 0 : 1; output->unlock_canvas(); - return 1; } + return ret; } int VDeviceX11::close_all() { if( output ) { - output->lock_canvas("VDeviceX11::close_all 1"); - output->get_canvas()->lock_window("VDeviceX11::close_all 1"); - int video_on = output->get_canvas()->get_video_on(); + BC_WindowBase *window = + output->lock_canvas("VDeviceX11::close_all"); + int video_on = window ? window->get_video_on() : 0; // Update the status bug - if( !device->single_frame ) { + if( !device->single_frame ) output->stop_video(); - } - else { + else output->stop_single(); - } - if( output_frame ) { + + if( output_frame ) output->update_refresh(device, output_frame); // if the last frame is good, don't draw over it - if( !video_on || output->need_overlays() ) { - output->unlock_canvas(); - output->draw_refresh(1); - output->lock_canvas("VDeviceX11::close_all 2"); - } - } + if( !video_on || output->need_overlays() ) + output->draw_refresh(1); } delete bitmap; bitmap = 0; delete output_frame; output_frame = 0; delete capture_bitmap; capture_bitmap = 0; - if( output ) { - output->get_canvas()->unlock_window(); + if( output ) output->unlock_canvas(); - } reset_parameters(); @@ -223,11 +211,10 @@ int VDeviceX11::get_display_colormodel(int file_colormodel) result = file_colormodel; break; - default: - output->lock_canvas("VDeviceX11::get_display_colormodel"); - result = output->get_canvas()->get_color_model(); - output->unlock_canvas(); - break; + default: { + BC_WindowBase *window = output->get_canvas(); + result = window ? window->get_color_model() : BC_RGB888; + break; } } } @@ -239,9 +226,8 @@ void VDeviceX11::new_output_buffer(VFrame **result, int file_colormodel, EDL *ed { // printf("VDeviceX11::new_output_buffer %d hardware_scaling=%d\n", // __LINE__, bitmap ? bitmap->hardware_scaling() : 0); - output->lock_canvas("VDeviceX11::new_output_buffer"); - output->get_canvas()->lock_window("VDeviceX11::new_output_buffer 1"); - + BC_WindowBase *window = + output->lock_canvas("VDeviceX11::new_output_buffer"); // Get the best colormodel the display can handle. int display_colormodel = get_display_colormodel(file_colormodel); @@ -255,7 +241,7 @@ void VDeviceX11::new_output_buffer(VFrame **result, int file_colormodel, EDL *ed output_frame = new VFrame(device->out_w, device->out_h, file_colormodel); } - window_id = output->get_canvas()->get_id(); + window_id = window->get_id(); output_frame->set_opengl_state(VFrame::RAM); } else { @@ -301,27 +287,27 @@ void VDeviceX11::new_output_buffer(VFrame **result, int file_colormodel, EDL *ed // "canvas_x1=%d canvas_y1=%d canvas_x2=%d canvas_y2=%d\n", // __LINE__, // (int)output->w, (int)output->h, // (int)canvas_x1, (int)canvas_y1, (int)canvas_x2, (int)canvas_y2); - output->get_canvas()->set_color(BLACK); + window->set_color(BLACK); if( canvas_y1 > 0 ) { - output->get_canvas()->draw_box(0, 0, output->w, canvas_y1); - output->get_canvas()->flash(0, 0, output->w, canvas_y1); + window->draw_box(0, 0, output->w, canvas_y1); + window->flash(0, 0, output->w, canvas_y1); } if( canvas_y2 < output->h ) { - output->get_canvas()->draw_box(0, canvas_y2, output->w, output->h - canvas_y2); - output->get_canvas()->flash(0, canvas_y2, output->w, output->h - canvas_y2); + window->draw_box(0, canvas_y2, output->w, output->h - canvas_y2); + window->flash(0, canvas_y2, output->w, output->h - canvas_y2); } if( canvas_x1 > 0 ) { - output->get_canvas()->draw_box(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1); - output->get_canvas()->flash(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1); + window->draw_box(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1); + window->flash(0, canvas_y1, canvas_x1, canvas_y2 - canvas_y1); } if( canvas_x2 < output->w ) { - output->get_canvas()->draw_box(canvas_x2, canvas_y1, + window->draw_box(canvas_x2, canvas_y1, output->w - canvas_x2, canvas_y2 - canvas_y1); - output->get_canvas()->flash(canvas_x2, canvas_y1, + window->flash(canvas_x2, canvas_y1, output->w - canvas_x2, canvas_y2 - canvas_y1); } } @@ -348,32 +334,32 @@ void VDeviceX11::new_output_buffer(VFrame **result, int file_colormodel, EDL *ed case BC_YUV420P: if( device->out_config->driver == PLAYBACK_X11_XV && - output->get_canvas()->accel_available(display_colormodel, 0) && + window->accel_available(display_colormodel, 0) && !output->use_scrollbars ) bitmap_type = BITMAP_PRIMARY; break; case BC_YUV422P: if( device->out_config->driver == PLAYBACK_X11_XV && - output->get_canvas()->accel_available(display_colormodel, 0) && + window->accel_available(display_colormodel, 0) && !output->use_scrollbars ) bitmap_type = BITMAP_PRIMARY; else if( device->out_config->driver == PLAYBACK_X11_XV && - output->get_canvas()->accel_available(BC_YUV422, 0) ) { - bitmap = new BC_Bitmap(output->get_canvas(), + window->accel_available(BC_YUV422, 0) ) { + bitmap = new BC_Bitmap(window, device->out_w, device->out_h, BC_YUV422, 1); } break; case BC_YUV422: if( device->out_config->driver == PLAYBACK_X11_XV && - output->get_canvas()->accel_available(display_colormodel, 0) && + window->accel_available(display_colormodel, 0) && !output->use_scrollbars ) { bitmap_type = BITMAP_PRIMARY; } else if( device->out_config->driver == PLAYBACK_X11_XV && - output->get_canvas()->accel_available(BC_YUV422P, 0) ) { - bitmap = new BC_Bitmap(output->get_canvas(), + window->accel_available(BC_YUV422P, 0) ) { + bitmap = new BC_Bitmap(window, device->out_w, device->out_h, BC_YUV422P, 1); } break; @@ -381,19 +367,19 @@ void VDeviceX11::new_output_buffer(VFrame **result, int file_colormodel, EDL *ed if( bitmap_type == BITMAP_PRIMARY ) { int bitmap_w = use_direct ? canvas_w : device->out_w; int bitmap_h = use_direct ? canvas_h : device->out_h; - bitmap = new BC_Bitmap(output->get_canvas(), + bitmap = new BC_Bitmap(window, bitmap_w, bitmap_h, display_colormodel, -1); output_frame = new VFrame(bitmap, bitmap_w, bitmap_h, display_colormodel, -1); } // Make an intermediate frame if( !bitmap ) { - display_colormodel = output->get_canvas()->get_color_model(); + display_colormodel = window->get_color_model(); // printf("VDeviceX11::new_output_buffer %d creating temp display_colormodel=%d " // "file_colormodel=%d %dx%d %dx%d %dx%d\n", __LINE__, // display_colormodel, file_colormodel, device->out_w, device->out_h, -// output->get_canvas()->get_w(), output->get_canvas()->get_h(), canvas_w, canvas_h); - bitmap = new BC_Bitmap(output->get_canvas(), +// window->get_w(), window->get_h(), canvas_w, canvas_h); + bitmap = new BC_Bitmap(window, canvas_w, canvas_h, display_colormodel, 1); bitmap_type = BITMAP_TEMP; } @@ -411,9 +397,8 @@ void VDeviceX11::new_output_buffer(VFrame **result, int file_colormodel, EDL *ed } *result = output_frame; -//printf("VDeviceX11::new_output_buffer 10 %d\n", output->get_canvas()->get_window_lock()); +//printf("VDeviceX11::new_output_buffer 10 %d\n", window->get_window_lock()); - output->get_canvas()->unlock_window(); output->unlock_canvas(); } @@ -437,8 +422,8 @@ int VDeviceX11::stop_playback() int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl) { - output->lock_canvas("VDeviceX11::write_buffer"); - output->get_canvas()->lock_window("VDeviceX11::write_buffer 1"); + BC_WindowBase *window = + output->lock_canvas("VDeviceX11::write_buffer"); // if( device->out_config->driver == PLAYBACK_X11_GL && // output_frame->get_color_model() != BC_RGB888 ) { // this is handled by overlay call in virtualvnode, using flatten alpha @@ -447,7 +432,7 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl) // printf("VDeviceX11::write_buffer %d %d bitmap_type=%d\n", // __LINE__, -// output->get_canvas()->get_video_on(), +// window->get_video_on(), // bitmap_type); // int use_bitmap_extents = 0; @@ -504,7 +489,7 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl) // Cause X server to display it if( device->out_config->driver == PLAYBACK_X11_GL ) { // Output is drawn in close_all if no video. - if( output->get_canvas()->get_video_on() ) { + if( window->get_video_on() ) { canvas_w = -1; canvas_h = -1; // Canvas may be a different size than the temporary bitmap for pure software if( bitmap_type == BITMAP_TEMP && @@ -520,20 +505,18 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl) //printf("VDeviceX11::write_buffer %d\n", __LINE__); // Draw output frame directly. Not used for compositing. - output->get_canvas()->unlock_window(); output->unlock_canvas(); output->mwindow->playback_3d->write_buffer(output, output_frame, output_x1, output_y1, output_x2, output_y2, canvas_x1, canvas_y1, canvas_x2, canvas_y2, is_cleared); is_cleared = 0; - output->lock_canvas("VDeviceX11::write_buffer 2"); - output->get_canvas()->lock_window("VDeviceX11::write_buffer 2"); + return 0; } } else { if( bitmap->hardware_scaling() ) { - output->get_canvas()->draw_bitmap(bitmap, !device->single_frame, + window->draw_bitmap(bitmap, !device->single_frame, (int)canvas_x1, (int)canvas_y1, (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), (int)output_x1, (int)output_y1, @@ -543,8 +526,8 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl) else { //printf("VDeviceX11::write_buffer %d x=%d y=%d w=%d h=%d\n", // __LINE__, (int)canvas_x1, (int)canvas_y1, -// output->get_canvas()->get_w(), output->get_canvas()->get_h()); - output->get_canvas()->draw_bitmap(bitmap, !device->single_frame, +// window->get_w(), window->get_h()); + window->draw_bitmap(bitmap, !device->single_frame, (int)canvas_x1, (int)canvas_y1, (int)(canvas_x2 - canvas_x1), (int)(canvas_y2 - canvas_y1), 0, 0, @@ -554,7 +537,6 @@ int VDeviceX11::write_buffer(VFrame *output_channels, EDL *edl) } } - output->get_canvas()->unlock_window(); output->unlock_canvas(); return 0; } diff --git a/cinelerra-5.1/cinelerra/vwindowgui.C b/cinelerra-5.1/cinelerra/vwindowgui.C index 44a9948c..e1524d6d 100644 --- a/cinelerra-5.1/cinelerra/vwindowgui.C +++ b/cinelerra-5.1/cinelerra/vwindowgui.C @@ -86,7 +86,7 @@ VWindowGUI::VWindowGUI(MWindow *mwindow, VWindow *vwindow) VWindowGUI::~VWindowGUI() { - vwindow->playback_engine->interrupt_playback(1); + vwindow->stop_playback(1); sources.remove_all_objects(); labels.remove_all_objects(); delete canvas; @@ -135,7 +135,7 @@ void VWindowGUI::draw_wave() delete cache; delete canvas->refresh_frame; canvas->refresh_frame = vframe; - canvas->draw_refresh(1); + canvas->refresh(1); } void VWindowGUI::change_source(EDL *edl, const char *title) @@ -457,7 +457,7 @@ void VWindowGUI::drag_motion() int need_highlight = cursor_above() && get_cursor_over_window() ? 1 : 0; if( highlighted == need_highlight ) return; highlighted = need_highlight; - canvas->draw_refresh(); + canvas->refresh(1); } int VWindowGUI::drag_stop() @@ -467,7 +467,7 @@ int VWindowGUI::drag_stop() if( highlighted && mwindow->session->current_operation == DRAG_ASSET ) { highlighted = 0; - canvas->draw_refresh(); + canvas->refresh(1); unlock_window(); Indexable *indexable = -- 2.26.2