From b9f3957a767f3530f8a1e27a7be8ca4852e581f9 Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Mon, 1 Nov 2010 16:02:03 -0600 Subject: [PATCH] gtk and cocoa: add flush method to canvas% and fix periodic flush --- collects/mred/private/mrcanvas.rkt | 1 + collects/mred/private/wx/cocoa/dc.rkt | 3 ++ collects/mred/private/wx/cocoa/queue.rkt | 1 + collects/mred/private/wx/gtk/canvas.rkt | 14 ++++++--- collects/mred/private/wx/gtk/dc.rkt | 3 ++ collects/mred/private/wx/win32/canvas.rkt | 5 ++++ collects/mred/private/wx/win32/dc.rkt | 3 ++ collects/racket/draw/private/dc.rkt | 1 + collects/scribblings/gui/canvas-class.scrbl | 22 +------------- collects/scribblings/gui/canvas-intf.scrbl | 29 +++++++++++++++++++ collects/scribblings/gui/dc-intf.scrbl | 25 ++++++++++++++++ .../scribblings/gui/global-draw-funcs.scrbl | 10 ++++--- doc/release-notes/racket/Draw_and_GUI_X_Y.txt | 8 ++--- 13 files changed, 92 insertions(+), 33 deletions(-) diff --git a/collects/mred/private/mrcanvas.rkt b/collects/mred/private/mrcanvas.rkt index 2cb7b02774..1a3282ab63 100644 --- a/collects/mred/private/mrcanvas.rkt +++ b/collects/mred/private/mrcanvas.rkt @@ -66,6 +66,7 @@ (send wx begin-refresh-sequence))] [resume-flush (lambda () (send wx end-refresh-sequence))] + [flush (lambda () (send wx flush))] [set-canvas-background (entry-point diff --git a/collects/mred/private/wx/cocoa/dc.rkt b/collects/mred/private/wx/cocoa/dc.rkt index ed31168851..b6c04bf087 100644 --- a/collects/mred/private/wx/cocoa/dc.rkt +++ b/collects/mred/private/wx/cocoa/dc.rkt @@ -67,6 +67,9 @@ ;; is at then end of `do-backing-flush'. (send canvas queue-backing-flush)) + (define/override (flush) + (send canvas flush)) + (define/override (request-delay) (request-flush-delay (send canvas get-flush-window))) (define/override (cancel-delay req) diff --git a/collects/mred/private/wx/cocoa/queue.rkt b/collects/mred/private/wx/cocoa/queue.rkt index 31eb3b6004..5be58666ae 100644 --- a/collects/mred/private/wx/cocoa/queue.rkt +++ b/collects/mred/private/wx/cocoa/queue.rkt @@ -348,6 +348,7 @@ (lambda () (check-one-event #f #f))) (define (try-to-sync-refresh) + ;; atomically => outside of the event loop (atomically (pre-event-sync #t))) diff --git a/collects/mred/private/wx/gtk/canvas.rkt b/collects/mred/private/wx/gtk/canvas.rkt index 94265bb94e..d372d8fd94 100644 --- a/collects/mred/private/wx/gtk/canvas.rkt +++ b/collects/mred/private/wx/gtk/canvas.rkt @@ -328,7 +328,10 @@ scroll-width 0))) - (define/override (direct-update?) #f) + ;; Direct update is ok for a canvas, and it + ;; allows pushing updates to the screen even + ;; if the eventspace thread is busy indefinitely + (define/override (direct-update?) #t) (define/public (get-dc) dc) @@ -377,15 +380,18 @@ (define/public (end-refresh-sequence) (send dc resume-flush)) + ;; The `flush' method should be improved to flush local + ;; to the enclosing frame, instead of flushing globally. + (define/public (flush) + (flush-display)) + (define/override (refresh) (queue-paint)) (define/public (queue-backing-flush) ;; called atomically (unless for-gl? - (gtk_widget_queue_draw client-gtk) - ;; peridodically flush to the screen: - (schedule-periodic-backing-flush))) + (gtk_widget_queue_draw client-gtk))) (define/override (reset-child-dcs) (when (dc . is-a? . dc%) diff --git a/collects/mred/private/wx/gtk/dc.rkt b/collects/mred/private/wx/gtk/dc.rkt index bc770391a5..518ca143c2 100644 --- a/collects/mred/private/wx/gtk/dc.rkt +++ b/collects/mred/private/wx/gtk/dc.rkt @@ -125,6 +125,9 @@ (end-delay) (send canvas queue-backing-flush)) + (define/override (flush) + (send canvas flush)) + (define/override (request-delay) (request-flush-delay (send canvas get-flush-window))) (define/override (cancel-delay req) diff --git a/collects/mred/private/wx/win32/canvas.rkt b/collects/mred/private/wx/win32/canvas.rkt index 3b9316a4e0..2fc6525df5 100644 --- a/collects/mred/private/wx/win32/canvas.rkt +++ b/collects/mred/private/wx/win32/canvas.rkt @@ -251,6 +251,11 @@ (send dc suspend-flush)) (define/public (end-refresh-sequence) (send dc resume-flush)) + + ;; The `flush' method should be improved to flush local + ;; to the enclosing frame, instead of flushing globally. + (define/public (flush) + (flush-display)) ;; Improve this method to flush locally ;; instead of globally: diff --git a/collects/mred/private/wx/win32/dc.rkt b/collects/mred/private/wx/win32/dc.rkt index d3b6ead054..db260240a8 100644 --- a/collects/mred/private/wx/win32/dc.rkt +++ b/collects/mred/private/wx/win32/dc.rkt @@ -99,6 +99,9 @@ (end-delay) (send canvas queue-backing-flush)) + (define/override (flush) + (send canvas flush)) + (define/override (request-delay) (request-flush-delay canvas)) (define/override (cancel-delay req) diff --git a/collects/racket/draw/private/dc.rkt b/collects/racket/draw/private/dc.rkt index 708f20e2ac..b4fa39b0da 100644 --- a/collects/racket/draw/private/dc.rkt +++ b/collects/racket/draw/private/dc.rkt @@ -569,6 +569,7 @@ (def/public (suspend-flush) (void)) (def/public (resume-flush) (void)) + (def/public (flush) (void)) (def/public (set-text-mode [(symbol-in solid transparent) mode]) (set! text-mode mode)) diff --git a/collects/scribblings/gui/canvas-class.scrbl b/collects/scribblings/gui/canvas-class.scrbl index 161333d8d6..be13bbe9ad 100644 --- a/collects/scribblings/gui/canvas-class.scrbl +++ b/collects/scribblings/gui/canvas-class.scrbl @@ -94,6 +94,7 @@ The @scheme[gl-config] argument determines properties of an OpenGL } + @defmethod[(get-scroll-page [which (one-of/c 'horizontal 'vertical)]) (integer-in 1 1000000)]{ @@ -284,11 +285,6 @@ This method is called only when manual } -@defmethod[(resume-flush) void?]{ - -See @method[canvas% suspend-flush].} - - @defmethod[(scroll [h-value (or/c (real-in 0.0 1.0) false/c)] [v-value (or/c (real-in 0.0 1.0) false/c)]) void?]{ @@ -389,22 +385,6 @@ init-manual-scrollbars]. } -@defmethod[(suspend-flush) void?]{ - -Drawing to a canvas's drawing context actually renders into an -offscreen buffer. The buffer is automatically flushed to the screen by -a background thread, unless flushing has been disabled for the canvas. -The @method[canvas% suspend-flush] method suspends flushing for a -canvas until a matching @method[canvas% resume-flush] calls; calls to -@method[canvas% suspend-flush] and @method[canvas% resume-flush] can -be nested, in which case flushing is suspended until the outermost -@method[canvas% suspend-flush] is balanced by a @method[canvas% -resume-flush]. - -On some platforms, beware that suspending flushing for a canvas can -discourage refreshes for other windows in the same frame.} - - @defmethod[(swap-gl-buffers) void?]{ Calls diff --git a/collects/scribblings/gui/canvas-intf.scrbl b/collects/scribblings/gui/canvas-intf.scrbl index d7544a9427..e802de7772 100644 --- a/collects/scribblings/gui/canvas-intf.scrbl +++ b/collects/scribblings/gui/canvas-intf.scrbl @@ -48,6 +48,11 @@ For an @scheme[editor-canvas%] object, handling of Tab, arrow, Enter, } +@defmethod[(flush) void?]{ + +Like @racket[flush-display], but constrained if possible to the canvas.} + + @defmethod[(get-canvas-background) (or/c (is-a?/c color%) false/c)]{ Returns the color currently used to ``erase'' the canvas content before @@ -184,6 +189,12 @@ Does nothing. }} +@defmethod[(resume-flush) void?]{ + +See @method[canvas<%> suspend-flush].} + + + @defmethod[(set-canvas-background [color (is-a?/c color%)]) void?]{ @@ -209,6 +220,24 @@ Under Mac OS X, enables or disables space for a resize tab at the } + +@defmethod[(suspend-flush) void?]{ + +Drawing to a canvas's drawing context actually renders into an +offscreen buffer. The buffer is automatically flushed to the screen by +a background thread, explicitly via the @method[canvas<%> flush] method, +or explicitly via @racket[flush-display] --- unless flushing has been disabled for the canvas. +The @method[canvas<%> suspend-flush] method suspends flushing for a +canvas until a matching @method[canvas<%> resume-flush] calls; calls to +@method[canvas<%> suspend-flush] and @method[canvas<%> resume-flush] can +be nested, in which case flushing is suspended until the outermost +@method[canvas<%> suspend-flush] is balanced by a @method[canvas<%> +resume-flush]. + +On some platforms, beware that suspending flushing for a canvas can +discourage refreshes for other windows in the same frame.} + + @defmethod[(warp-pointer [x (integer-in 0 10000)] [y (integer-in 0 10000)]) void?]{ diff --git a/collects/scribblings/gui/dc-intf.scrbl b/collects/scribblings/gui/dc-intf.scrbl index 2b3367864c..e87508466e 100644 --- a/collects/scribblings/gui/dc-intf.scrbl +++ b/collects/scribblings/gui/dc-intf.scrbl @@ -446,6 +446,15 @@ For printer or PostScript output, an exception is raised if } + +@defmethod[(flush) void?]{ + +Calls the @xmethod[canvas<%> flush] method for +@racket[canvas<%>] output, and has no effect for other kinds of +drawing contexts.} + + + @defmethod[(get-alpha) (real-in 0 1)]{ @@ -733,6 +742,14 @@ Returns @scheme[#t] if the drawing context is usable. } + +@defmethod[(resume-flush) void?]{ + +Calls the @xmethod[canvas<%> resume-flush] method for +@racket[canvas<%>] output, and has no effect for other kinds of +drawing contexts.} + + @defmethod[(rotate [angle real?]) void?]{ Adds a rotation of @racket[angle] radians to the drawing context's @@ -1059,6 +1076,14 @@ For printer or PostScript output, an exception is raised if } + +@defmethod[(suspend-flush) void?]{ + +Calls the @xmethod[canvas<%> suspend-flush] method for +@racket[canvas<%>] output, and has no effect for other kinds of +drawing contexts.} + + @defmethod[(transform [m (vector/c real? real? real? real? real? real?)]) void?]{ diff --git a/collects/scribblings/gui/global-draw-funcs.scrbl b/collects/scribblings/gui/global-draw-funcs.scrbl index 2790d63d8c..d8f77670eb 100644 --- a/collects/scribblings/gui/global-draw-funcs.scrbl +++ b/collects/scribblings/gui/global-draw-funcs.scrbl @@ -6,11 +6,13 @@ @defproc[(flush-display) void?]{ -Under X and Mac OS X, flushes pending display messages such that the - user's display reflects the actual state of the windows. Under - Windows, the procedure has no effect. +Flushes canvas offscreen drawing and other updates onto the + screen. + +Normally, drawing is automatically flushed to the screen. Use +@racket[flush-display] sparingly to force updates to the screen when +other actions depend on updating the display.} -} @defproc[(get-display-depth) exact-nonnegative-integer?]{ diff --git a/doc/release-notes/racket/Draw_and_GUI_X_Y.txt b/doc/release-notes/racket/Draw_and_GUI_X_Y.txt index b881f0f420..f179447c3a 100644 --- a/doc/release-notes/racket/Draw_and_GUI_X_Y.txt +++ b/doc/release-notes/racket/Draw_and_GUI_X_Y.txt @@ -59,10 +59,10 @@ Canvases -------- Drawing to a canvas always draws into a bitmap that is kept offscreen -and periodically flushed onto the screen. The new `suspend-flush' and -`resume-flush' methods of `canvas%' provide some control over the -timing of the flushes, which in many cases avoids the need for -(additional) double buffering of canvas content. +and periodically flushed onto the screen. The new `suspend-flush', +`resume-flush', and `flush' methods of `canvas%' provide some control +over the timing of the flushes, which in many cases avoids the need +for (additional) double buffering of canvas content. OpenGL drawing in a canvas requires supplying 'gl as a style when creating the `canvas%' instance. OpenGL and normal dc<%> drawing no