From 24d8e5de2cef6bec092ce4f9e6dda7d55fbd0239 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Wed, 1 Feb 2023 01:23:24 +0100 Subject: [PATCH] NSGLView: implement partial exposure --- libs/gtkmm2ext/nsglview.mm | 68 +++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/libs/gtkmm2ext/nsglview.mm b/libs/gtkmm2ext/nsglview.mm index 1008f5e602..ad0e7027fd 100644 --- a/libs/gtkmm2ext/nsglview.mm +++ b/libs/gtkmm2ext/nsglview.mm @@ -25,6 +25,9 @@ #include +//#define NSVIEW_PROFILE +//#define DEBUG_NSVIEW_EXPOSURE + #include #import @@ -40,6 +43,7 @@ * Gdk events propagate. */ #ifndef ARDOUR_CANVAS_NSVIEW_TAG +#error NO TAG #define ARDOUR_CANVAS_NSVIEW_TAG 0x0 #endif @@ -53,6 +57,8 @@ __attribute__ ((visibility ("hidden"))) Cairo::RefPtr surf; Gtkmm2ext::CairoCanvas *cairo_canvas; NSInteger _tag; + + GdkRectangle _expose_area; } @property (readwrite) NSInteger tag; @@ -62,6 +68,7 @@ __attribute__ ((visibility ("hidden"))) - (void) setCairoCanvas:(Gtkmm2ext::CairoCanvas*)c; - (void) reshape; - (void) setNeedsDisplayInRect:(NSRect)rect; +- (void) setNeedsDisplay:(BOOL)yn; - (void) drawRect:(NSRect)rect; - (BOOL) canBecomeKeyWindow:(id)sender; - (BOOL) acceptsFirstResponder:(id)sender; @@ -98,6 +105,7 @@ __attribute__ ((visibility ("hidden"))) _texture_id = 0; _width = 0; _height = 0; + _expose_area.x = _expose_area.y = _expose_area.width = _expose_area.height = 0; if (self) { self.tag = ARDOUR_CANVAS_NSVIEW_TAG; @@ -109,6 +117,13 @@ __attribute__ ((visibility ("hidden"))) glEnable (GL_TEXTURE_RECTANGLE_ARB); [NSOpenGLContext clearCurrentContext]; +#if 1 + [self setWantsBestResolutionOpenGLSurface:YES]; + [self setWantsLayer:YES]; +#else + [self setWantsBestResolutionOpenGLSurface:NO]; +#endif + [self reshape]; } @@ -138,6 +153,7 @@ __attribute__ ((visibility ("hidden"))) - (void) reshape { + [super reshape]; [[self openGLContext] update]; NSRect bounds = [self bounds]; @@ -172,19 +188,54 @@ __attribute__ ((visibility ("hidden"))) _width = width; _height = height; + + _expose_area.x = _expose_area.y = 0; + _expose_area.width = width; + _expose_area.height = height; +} + +- (void) setNeedsDisplay:(BOOL)yn +{ + if (yn) { + _expose_area.x = _expose_area.y = 0; + _expose_area.width = _width; + _expose_area.height = _height; +#ifdef DEBUG_NSVIEW_EXPOSURE + printf ("needsDisplay: FULL %d x %d\n", _width, _height); +#endif + } + [super setNeedsDisplay:yn]; } - (void) setNeedsDisplayInRect:(NSRect)rect { - [super setNeedsDisplayInRect:rect]; #ifdef DEBUG_NSVIEW_EXPOSURE printf ("needsDisplay: %5.1f %5.1f %5.1f %5.1f\n", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); #endif + + //GdkRectangle r2 = {_expose_area.x, _expose_area.y, _expose_area.width, _expose_area.height }; + if (_expose_area.width == 0 && _expose_area.height == 0) { + _expose_area.x = rect.origin.x; + _expose_area.y = rect.origin.y; + _expose_area.width = rect.size.width; + _expose_area.height = rect.size.height; + } else { + GdkRectangle r1 = {(int)rect.origin.x, (int)rect.origin.y, (int)rect.size.width, (int)rect.size.height}; + gdk_rectangle_union (&r1, &_expose_area, &_expose_area); + } + + GdkRectangle rw = {0, 0, _width, _height}; + gdk_rectangle_intersect (&rw, &_expose_area, &_expose_area); + + [super setNeedsDisplayInRect:rect]; } - (void) drawRect:(NSRect)rect { +#ifdef NSVIEW_PROFILE + const int64_t start = g_get_monotonic_time (); +#endif [[self openGLContext] makeCurrentContext]; glMatrixMode(GL_MODELVIEW); @@ -194,10 +245,18 @@ __attribute__ ((visibility ("hidden"))) /* call back into CairoCanvas */ cairo_rectangle_t cairo_rect; +#if 0 cairo_rect.x = rect.origin.x; cairo_rect.y = rect.origin.y; cairo_rect.width = rect.size.width; cairo_rect.height = rect.size.height; +#else + cairo_rect.x = _expose_area.x; + cairo_rect.y = _expose_area.y; + cairo_rect.width = _expose_area.width; + cairo_rect.height = _expose_area.height; +#endif + _expose_area.x = _expose_area.y = _expose_area.width = _expose_area.height = 0; if (!surf || surf->get_width () != _width || surf->get_height() != _height) { surf = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, _width, _height); @@ -271,6 +330,13 @@ __attribute__ ((visibility ("hidden"))) glSwapAPPLE(); [NSOpenGLContext clearCurrentContext]; [super setNeedsDisplay:NO]; + +#ifdef NSVIEW_PROFILE + const int64_t end = g_get_monotonic_time (); + const int64_t elapsed = end - start; + printf ("NSGL::drawRect %f ms\n", elapsed / 1000.f); +#endif + } @end