From 3a7f190f52e534135f81fa84ec7be5a5beac257b Mon Sep 17 00:00:00 2001 From: Good Guy Date: Tue, 7 Apr 2020 18:37:17 -0600 Subject: [PATCH] boxblur tweak for w=1:h=0, speedup canvas bline draw for floatautos+audio waveform, tweak display scale limits --- cinelerra-5.1/cinelerra/boxblur.C | 1 + cinelerra-5.1/cinelerra/indexfile.C | 4 +- cinelerra-5.1/cinelerra/resourcepixmap.C | 4 +- cinelerra-5.1/cinelerra/trackcanvas.C | 93 +++++++++++++++++++----- cinelerra-5.1/cinelerra/trackcanvas.h | 1 + cinelerra-5.1/guicast/bcwindowbase.C | 4 + 6 files changed, 84 insertions(+), 23 deletions(-) diff --git a/cinelerra-5.1/cinelerra/boxblur.C b/cinelerra-5.1/cinelerra/boxblur.C index d0c00c09..31f017d8 100644 --- a/cinelerra-5.1/cinelerra/boxblur.C +++ b/cinelerra-5.1/cinelerra/boxblur.C @@ -6,6 +6,7 @@ void blurt(dst_t *dst, int dst_step, src_t *src, int src_step, int len, int radius, float s) { int n = len/2-1; + if( n <= 0 ) return; if( radius > n ) radius = n; const int length = radius*2 + 1; const int inv = s * ((1<<16) + length/2)/length; diff --git a/cinelerra-5.1/cinelerra/indexfile.C b/cinelerra-5.1/cinelerra/indexfile.C index 87b8853a..e73a8710 100644 --- a/cinelerra-5.1/cinelerra/indexfile.C +++ b/cinelerra-5.1/cinelerra/indexfile.C @@ -790,7 +790,7 @@ SET_TRACE // A different algorithm has to be used if it's 1 sample per pixel and the // index is used. Now the min and max values are equal so we join the max samples. if(mwindow->edl->local_session->zoom_sample == 1) { - canvas->draw_line(x2 - 1, !rect_audio ? prev_y1 : center_pixel, x2, y1, pixmap); + canvas->draw_bline(x2 - 1, !rect_audio ? prev_y1 : center_pixel, x2, y1, pixmap); } else { // Extend line height if it doesn't connect to previous line @@ -801,7 +801,7 @@ SET_TRACE else { first_frame = 0; } - canvas->draw_line(x2, y1, x2, !rect_audio ? y2 : center_pixel, pixmap); + canvas->draw_bline(x2, y1, x2, !rect_audio ? y2 : center_pixel, pixmap); } prev_y1 = next_y1; prev_y2 = next_y2; diff --git a/cinelerra-5.1/cinelerra/resourcepixmap.C b/cinelerra-5.1/cinelerra/resourcepixmap.C index b0bc49b7..1201f044 100644 --- a/cinelerra-5.1/cinelerra/resourcepixmap.C +++ b/cinelerra-5.1/cinelerra/resourcepixmap.C @@ -523,9 +523,9 @@ void ResourcePixmap::draw_audio_source(TrackCanvas *canvas, Edit *edit, int x, i y2 = CLIP(y1, 0, y_max); //printf("ResourcePixmap::draw_audio_source %d %d %d\n", __LINE__, y1, y2); if( !rect_audio ) - canvas->draw_line(x1, y0, x2, y2, this); + canvas->draw_bline(x1, y0, x2, y2, this); else - canvas->draw_line(x2, center_pixel, x2, y2, this); + canvas->draw_bline(x2, center_pixel, x2, y2, this); } } diff --git a/cinelerra-5.1/cinelerra/trackcanvas.C b/cinelerra-5.1/cinelerra/trackcanvas.C index a4faec2b..96726f68 100644 --- a/cinelerra-5.1/cinelerra/trackcanvas.C +++ b/cinelerra-5.1/cinelerra/trackcanvas.C @@ -2781,6 +2781,24 @@ int TrackCanvas::test_floatauto(FloatAuto *current, int x, int y, int in_x, return result; } +static int is_linear(FloatAuto *prev, FloatAuto *next) +{ + if( !prev || !next ) return 1; + if( prev->curve_mode == FloatAuto::LINEAR ) return 1; + int64_t ipos, opos; + if( !(ipos = prev->get_control_in_position()) && + !(opos = prev->get_control_out_position()) ) return 1; + if( !ipos || !opos ) return 0; + float ival = prev->get_control_in_value(); + float oval = prev->get_control_out_value(); + float cval = prev->get_value(), nval = next->get_value(); + if( !ival && !oval && EQUIV(cval, nval) ) return 1; + float ig = ival / ipos, og = oval / opos; + int64_t cpos = prev->position, npos = next->position; + float g = (nval - cval) / (npos - cpos); + if( EQUIV(ig, g) && EQUIV(og, g) ) return 1; + return 0; +} // Get the float value & y for position x on the canvas #define X_TO_FLOATLINE(x) \ @@ -2813,45 +2831,45 @@ void TrackCanvas::draw_floatline(int center_pixel, int x1, int y1, int x2, int y2, int color, int autogrouptype) { + int ytop = center_pixel - yscale / 2; + int ybot = center_pixel + yscale / 2 - 1; + y1 += center_pixel; y2 += center_pixel; + if( (y1 < ytop && y1 >= ybot) && (y2 < ytop || y2 >= ybot) ) return; +// check for line draw + if( is_linear(previous, next) ) { + draw_line(x1, y1, x2, y2); + return; + } + // Solve bezier equation for either every pixel or a certain large number of // points. // Not using slope intercept x1 = MAX(0, x1); - int prev_y = y1 + center_pixel; - + draw_pixel(x1, y1); + int prev_y = y1; // Call by reference fails for some reason here FloatAuto *previous1 = previous, *next1 = next; float automation_min = mwindow->edl->local_session->automation_mins[autogrouptype]; float automation_max = mwindow->edl->local_session->automation_maxs[autogrouptype]; float automation_range = automation_max - automation_min; - - for(int x = x1; x < x2; x++) - { + for( int x=x1; x x1 && */ - y >= center_pixel - yscale / 2 && - y < center_pixel + yscale / 2 - 1) - { -// printf("TrackCanvas::draw_floatline y=%d min=%d max=%d\n", -// y, -// (int)(center_pixel - yscale / 2), -// (int)(center_pixel + yscale / 2 - 1)); - -//printf("draw_line(%d,%d, %d,%d)\n", x - 1, prev_y , x, y); - draw_line(x - 1, prev_y , x, y ); + if( /* x > x1 && */ y >= ytop && y < ybot ) { + int x1 = x-1, y1 = prev_y, x2 = x, y2 = y; + if( abs(y2-y1) < 2 ) + draw_pixel(x2, y2); + else + draw_bline(x1, y1, x2, y2); } prev_y = y; } } - - - int TrackCanvas::test_floatline(int center_pixel, FloatAutos *autos, double unit_start, @@ -3698,6 +3716,43 @@ int TrackCanvas::draw_hairline(Auto *auto_keyframe, int color, int show) return 0; } +void TrackCanvas::draw_bline(int x1, int y1, int x2, int y2, BC_Pixmap *pixmap) +{ +// Short lines are all overhead to hw or sw setup, use bresenhams + if( y1 > y2 ) { + int tx = x1; x1 = x2; x2 = tx; + int ty = y1; y1 = y2; y2 = ty; + } + + int x = x1, y = y1; + int dx = x2-x1, dy = y2-y1; + int dx2 = 2*dx, dy2 = 2*dy; + if( dx < 0 ) dx = -dx; + int r = dx > dy ? dx : dy, n = r; + int dir = 0; + if( dx2 < 0 ) dir += 1; + if( dy >= dx ) { + if( dx2 >= 0 ) do { /* +Y, +X */ + draw_pixel(x, y++, pixmap); + if( (r -= dx2) < 0 ) { r += dy2; ++x; } + } while( --n >= 0 ); + else do { /* +Y, -X */ + draw_pixel(x, y++, pixmap); + if( (r += dx2) < 0 ) { r += dy2; --x; } + } while( --n >= 0 ); + } + else { + if( dx2 >= 0 ) do { /* +X, +Y */ + draw_pixel(x++, y, pixmap); + if( (r -= dy2) < 0 ) { r += dx2; ++y; } + } while( --n >= 0 ); + else do { /* -X, +Y */ + draw_pixel(x--, y, pixmap); + if( (r -= dy2) < 0 ) { r -= dx2; ++y; } + } while( --n >= 0 ); + } +} + void TrackCanvas::draw_overlays() { int new_cursor, update_cursor, rerender; diff --git a/cinelerra-5.1/cinelerra/trackcanvas.h b/cinelerra-5.1/cinelerra/trackcanvas.h index 4b9c4eba..490b67b1 100644 --- a/cinelerra-5.1/cinelerra/trackcanvas.h +++ b/cinelerra-5.1/cinelerra/trackcanvas.h @@ -71,6 +71,7 @@ public: void draw_highlighting(); void draw_keyframe_reticle(); int draw_hairline(Auto *auto_keyframe, int color, int show); + void draw_bline(int x1, int y1, int x2, int y2, BC_Pixmap *pixmap=0); // User can either call draw or draw_overlays to copy a fresh // canvas and just draw the overlays over it diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index e64b2eb0..a2cccd2c 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -4357,6 +4357,10 @@ void BC_WindowBase::init_resources(float scale) int wx, wy, ww, wh; int cins = info.xinerama_big_screen(); if( !info.xinerama_geometry(cins, wx, wy, ww, wh) ) { + int sh = ww * 9 / 16; + int sw = wh * 16 / 9; + if( sw < ww ) ww = sw; + if( sh < wh ) wh = sh; if( (x_scale = ww/1920.) < 1 ) x_scale = 1; if( (y_scale = wh/1080.) < 1 ) y_scale = 1; } -- 2.26.2