13
0

NSGLView: implement partial exposure

This commit is contained in:
Robin Gareus 2023-02-01 01:23:24 +01:00
parent 91fc57b943
commit 24d8e5de2c

View File

@ -25,6 +25,9 @@
#include <gdk/gdkquartz.h> #include <gdk/gdkquartz.h>
//#define NSVIEW_PROFILE
//#define DEBUG_NSVIEW_EXPOSURE
#include <OpenGL/gl.h> #include <OpenGL/gl.h>
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
@ -40,6 +43,7 @@
* Gdk events propagate. * Gdk events propagate.
*/ */
#ifndef ARDOUR_CANVAS_NSVIEW_TAG #ifndef ARDOUR_CANVAS_NSVIEW_TAG
#error NO TAG
#define ARDOUR_CANVAS_NSVIEW_TAG 0x0 #define ARDOUR_CANVAS_NSVIEW_TAG 0x0
#endif #endif
@ -53,6 +57,8 @@ __attribute__ ((visibility ("hidden")))
Cairo::RefPtr<Cairo::ImageSurface> surf; Cairo::RefPtr<Cairo::ImageSurface> surf;
Gtkmm2ext::CairoCanvas *cairo_canvas; Gtkmm2ext::CairoCanvas *cairo_canvas;
NSInteger _tag; NSInteger _tag;
GdkRectangle _expose_area;
} }
@property (readwrite) NSInteger tag; @property (readwrite) NSInteger tag;
@ -62,6 +68,7 @@ __attribute__ ((visibility ("hidden")))
- (void) setCairoCanvas:(Gtkmm2ext::CairoCanvas*)c; - (void) setCairoCanvas:(Gtkmm2ext::CairoCanvas*)c;
- (void) reshape; - (void) reshape;
- (void) setNeedsDisplayInRect:(NSRect)rect; - (void) setNeedsDisplayInRect:(NSRect)rect;
- (void) setNeedsDisplay:(BOOL)yn;
- (void) drawRect:(NSRect)rect; - (void) drawRect:(NSRect)rect;
- (BOOL) canBecomeKeyWindow:(id)sender; - (BOOL) canBecomeKeyWindow:(id)sender;
- (BOOL) acceptsFirstResponder:(id)sender; - (BOOL) acceptsFirstResponder:(id)sender;
@ -98,6 +105,7 @@ __attribute__ ((visibility ("hidden")))
_texture_id = 0; _texture_id = 0;
_width = 0; _width = 0;
_height = 0; _height = 0;
_expose_area.x = _expose_area.y = _expose_area.width = _expose_area.height = 0;
if (self) { if (self) {
self.tag = ARDOUR_CANVAS_NSVIEW_TAG; self.tag = ARDOUR_CANVAS_NSVIEW_TAG;
@ -109,6 +117,13 @@ __attribute__ ((visibility ("hidden")))
glEnable (GL_TEXTURE_RECTANGLE_ARB); glEnable (GL_TEXTURE_RECTANGLE_ARB);
[NSOpenGLContext clearCurrentContext]; [NSOpenGLContext clearCurrentContext];
#if 1
[self setWantsBestResolutionOpenGLSurface:YES];
[self setWantsLayer:YES];
#else
[self setWantsBestResolutionOpenGLSurface:NO];
#endif
[self reshape]; [self reshape];
} }
@ -138,6 +153,7 @@ __attribute__ ((visibility ("hidden")))
- (void) reshape - (void) reshape
{ {
[super reshape];
[[self openGLContext] update]; [[self openGLContext] update];
NSRect bounds = [self bounds]; NSRect bounds = [self bounds];
@ -172,19 +188,54 @@ __attribute__ ((visibility ("hidden")))
_width = width; _width = width;
_height = height; _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 - (void) setNeedsDisplayInRect:(NSRect)rect
{ {
[super setNeedsDisplayInRect:rect];
#ifdef DEBUG_NSVIEW_EXPOSURE #ifdef DEBUG_NSVIEW_EXPOSURE
printf ("needsDisplay: %5.1f %5.1f %5.1f %5.1f\n", printf ("needsDisplay: %5.1f %5.1f %5.1f %5.1f\n",
rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
#endif #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 - (void) drawRect:(NSRect)rect
{ {
#ifdef NSVIEW_PROFILE
const int64_t start = g_get_monotonic_time ();
#endif
[[self openGLContext] makeCurrentContext]; [[self openGLContext] makeCurrentContext];
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
@ -194,10 +245,18 @@ __attribute__ ((visibility ("hidden")))
/* call back into CairoCanvas */ /* call back into CairoCanvas */
cairo_rectangle_t cairo_rect; cairo_rectangle_t cairo_rect;
#if 0
cairo_rect.x = rect.origin.x; cairo_rect.x = rect.origin.x;
cairo_rect.y = rect.origin.y; cairo_rect.y = rect.origin.y;
cairo_rect.width = rect.size.width; cairo_rect.width = rect.size.width;
cairo_rect.height = rect.size.height; 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) { if (!surf || surf->get_width () != _width || surf->get_height() != _height) {
surf = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, _width, _height); surf = Cairo::ImageSurface::create (Cairo::FORMAT_ARGB32, _width, _height);
@ -271,6 +330,13 @@ __attribute__ ((visibility ("hidden")))
glSwapAPPLE(); glSwapAPPLE();
[NSOpenGLContext clearCurrentContext]; [NSOpenGLContext clearCurrentContext];
[super setNeedsDisplay:NO]; [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 @end