Improved Fl_Window::make_current() that now creates a new NSGraphicsContext only when drawing

is not done through the standard event loop.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@10784 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Manolo Gouy
2015-07-11 15:35:20 +00:00
parent c9d8e0feaa
commit 9e320937fc
+13 -10
View File
@@ -98,6 +98,8 @@ static int main_screen_height; // height of menubar-containing screen used to co
// through_drawRect = YES means the drawRect: message was sent to the view, // through_drawRect = YES means the drawRect: message was sent to the view,
// thus the graphics context was prepared by the system // thus the graphics context was prepared by the system
static BOOL through_drawRect = NO; static BOOL through_drawRect = NO;
// through_Fl_X_flush = YES means Fl_X::flush() was called
static BOOL through_Fl_X_flush = NO;
static int im_enabled = -1; static int im_enabled = -1;
#if CONSOLIDATE_MOTION #if CONSOLIDATE_MOTION
@@ -2796,7 +2798,9 @@ void Fl_X::flush()
} else { } else {
make_current_counts = 1; make_current_counts = 1;
if (!through_drawRect) [[xid contentView] lockFocus]; if (!through_drawRect) [[xid contentView] lockFocus];
through_Fl_X_flush = YES;
w->flush(); w->flush();
through_Fl_X_flush = NO;
if (!through_drawRect) [[xid contentView] unlockFocus]; if (!through_drawRect) [[xid contentView] unlockFocus];
make_current_counts = 0; make_current_counts = 0;
Fl_X::q_release_context(); Fl_X::q_release_context();
@@ -3228,22 +3232,21 @@ void Fl_Window::resize(int X,int Y,int W,int H) {
1) When a window is created or resized. 1) When a window is created or resized.
The system sends the drawRect: message to the window's view after having prepared the current The system sends the drawRect: message to the window's view after having prepared the current
graphics context to draw to this view. Processing of drawRect: sets variable through_drawRect graphics context to draw to this view. Processing of drawRect: sets variable through_drawRect
to YES and calls handleUpdateEvent() that calls Fl_X::flush(). Fl_X::flush() calls to YES and calls handleUpdateEvent() that calls Fl_X::flush(). Fl_X::flush() sets through_Fl_X_flush
Fl_Window::flush() that calls Fl_Window::make_current() that only needs to identify the graphics to YES and calls Fl_Window::flush() that calls Fl_Window::make_current() that only needs to
port of the current graphics context. The window's draw() function is then executed. identify the graphics port of the current graphics context. The window's draw() function is then executed.
2) At each round of the FLTK event loop. 2) At each round of the FLTK event loop.
Fl::flush() is called, that calls Fl_X::flush() on each window that needs drawing. Variable Fl::flush() is called, that calls Fl_X::flush() on each window that needs drawing. Variable
through_drawRect is NO. Fl_X::flush() locks the focus to the view and calls Fl_Window::flush() through_Fl_X_flush is set to YES. Fl_X::flush() locks the focus to the view and calls Fl_Window::flush()
that calls Fl_Window::make_current() which creates a new graphics context for the window. that calls Fl_Window::make_current() which uses the current graphics context.
Fl_Window::flush() then runs the window's draw() function. Fl_Window::flush() then runs the window's draw() function.
3) An FLTK application can call Fl_Window::make_current() at any time before it draws to a window. 3) An FLTK application can call Fl_Window::make_current() at any time before it draws to a window.
This occurs for instance in the idle callback function of the mandelbrot test program. Variable This occurs for instance in the idle callback function of the mandelbrot test program. Variable
through_drawRect is NO, so Fl_Window::make_current() creates a new graphics context adequate for through_Fl_X_flush is NO, so Fl_Window::make_current() creates a new graphics context adequate for
the window. Subsequent drawing requests go to this window. CAUTION: it's not possible to call Fl::wait(), the window. Subsequent drawing requests go to this window. CAUTION: it's not possible to call Fl::wait(),
Fl::check() nor Fl::ready() while in the draw() function of a widget. Use an idle callback instead. Fl::check() nor Fl::ready() while in the draw() function of a widget. Use an idle callback instead.
*/ */
void Fl_Window::make_current() void Fl_Window::make_current()
{ {
@@ -3256,7 +3259,7 @@ void Fl_Window::make_current()
#endif #endif
current_ = this; current_ = this;
NSGraphicsContext *nsgc = through_drawRect ? [NSGraphicsContext currentContext] : NSGraphicsContext *nsgc = through_Fl_X_flush ? [NSGraphicsContext currentContext] :
[NSGraphicsContext graphicsContextWithWindow:fl_window]; [NSGraphicsContext graphicsContextWithWindow:fl_window];
i->gc = (CGContextRef)[nsgc graphicsPort]; i->gc = (CGContextRef)[nsgc graphicsPort];
fl_gc = i->gc; fl_gc = i->gc;
@@ -4185,7 +4188,7 @@ static NSBitmapImageRep* rect_to_NSBitmapImageRep(Fl_Window *win, int x, int y,
bitmap = GL_rect_to_nsbitmap(win, x, y, w, h); bitmap = GL_rect_to_nsbitmap(win, x, y, w, h);
} else { } else {
NSView *winview = nil; NSView *winview = nil;
if ( through_drawRect && Fl_Window::current() == win ) { if ( through_Fl_X_flush && Fl_Window::current() == win ) {
rect = NSMakeRect(x - 0.5, y - 0.5, w, h); rect = NSMakeRect(x - 0.5, y - 0.5, w, h);
} }
else { else {
@@ -4196,7 +4199,7 @@ static NSBitmapImageRep* rect_to_NSBitmapImageRep(Fl_Window *win, int x, int y,
} }
// The image depth is 3 until 10.5 and 4 with 10.6 and above // The image depth is 3 until 10.5 and 4 with 10.6 and above
bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:rect]; bitmap = [[NSBitmapImageRep alloc] initWithFocusedViewRect:rect];
if ( !( through_drawRect && Fl_Window::current() == win) ) [winview unlockFocus]; if ( !( through_Fl_X_flush && Fl_Window::current() == win) ) {[winview unlockFocus];}
if (!bitmap) return nil; if (!bitmap) return nil;
} }