gtk: periodic canvas flushing

This commit is contained in:
Matthew Flatt 2010-11-01 07:58:23 -06:00
parent 9fbb7d3a99
commit 72a19d2ab3
6 changed files with 66 additions and 15 deletions

View File

@ -279,12 +279,20 @@
(queue-window-refresh-event this thunk)) (queue-window-refresh-event this thunk))
(define/public (paint-or-queue-paint) (define/public (paint-or-queue-paint)
(or (do-backing-flush this dc (tell NSGraphicsContext currentContext) (or (do-canvas-backing-flush #f)
(if is-combo? 2 0) (if is-combo? 2 0))
(begin (begin
(queue-paint) (queue-paint)
#f))) #f)))
(define/public (do-canvas-backing-flush ctx)
(do-backing-flush this dc (tell NSGraphicsContext currentContext)
(if is-combo? 2 0) (if is-combo? 2 0)))
;; not used, because Cocoa canvas refreshes do not go through
;; the eventspace queue:
(define/public (schedule-periodic-backing-flush)
(void))
(define/public (begin-refresh-sequence) (define/public (begin-refresh-sequence)
(send dc suspend-flush)) (send dc suspend-flush))
(define/public (end-refresh-sequence) (define/public (end-refresh-sequence)

View File

@ -1,6 +1,7 @@
#lang racket/base #lang racket/base
(require racket/class (require racket/class
racket/draw racket/draw
"../common/queue.rkt"
"backing-dc.rkt") "backing-dc.rkt")
(provide (provide
@ -162,7 +163,28 @@
(define/override (paint-children) (define/override (paint-children)
(when (or paint-queued (when (or paint-queued
(not (send (get-dc) can-backing-flush?))) (not (send (get-dc) can-backing-flush?)))
(do-on-paint #f #f))))) (do-on-paint #f #f)))
(define flush-box #f)
;; Periodic flush is needed for Windows and Gtk, where
;; updates otherwise happen only via the eventspace's queue
(define/override (schedule-periodic-backing-flush)
(unless flush-box
(set! flush-box (box #t))
(add-event-boundary-sometimes-callback!
flush-box
(lambda (b)
(when (unbox b)
(do-canvas-backing-flush #f))))))
(define/override (do-canvas-backing-flush ctx)
;; cancel scheduled flush, if any:
(when flush-box
(set-box! flush-box #f)
(set! flush-box #f))
(super do-canvas-backing-flush ctx))))
;; useful for fixing the size of a collecting blit: ;; useful for fixing the size of a collecting blit:
(define (fix-bitmap-size on w h on-x on-y) (define (fix-bitmap-size on w h on-x on-y)

View File

@ -18,6 +18,7 @@
remove-event-boundary-callback! remove-event-boundary-callback!
pre-event-sync pre-event-sync
boundary-tasks-ready-evt boundary-tasks-ready-evt
sometimes-delay-msec
eventspace? eventspace?
current-eventspace current-eventspace
@ -127,11 +128,12 @@
(alert-tasks-ready))) (alert-tasks-ready)))
(define last-time -inf.0) (define last-time -inf.0)
(define sometimes-delay-msec 50)
;; Call this function only in atomic mode: ;; Call this function only in atomic mode:
(define (pre-event-sync force?) (define (pre-event-sync force?)
(let ([now (current-inexact-milliseconds)]) (let ([now (current-inexact-milliseconds)])
(when (or (now . > . (+ last-time 200)) (when (or (now . > . (+ last-time sometimes-delay-msec))
force?) force?)
(set! last-time now) (set! last-time now)
(hash-for-each sometimes-boundary-ht (hash-for-each sometimes-boundary-ht

View File

@ -352,15 +352,22 @@
(queue-window-refresh-event this thunk)) (queue-window-refresh-event this thunk))
(define/public (paint-or-queue-paint) (define/public (paint-or-queue-paint)
;; in atomic mode
(if for-gl? (if for-gl?
(queue-paint) (queue-paint)
(or (do-backing-flush this dc (if is-combo? (or (do-canvas-backing-flush #f)
(get-subwindow client-gtk)
(widget-window client-gtk)))
(begin (begin
(queue-paint) (queue-paint)
#f)))) #f))))
;; overridden to extend for scheduled periodic flushes:
(define/public (schedule-periodic-backing-flush)
(void))
(define/public (do-canvas-backing-flush ctx)
(do-backing-flush this dc (if is-combo?
(get-subwindow client-gtk)
(widget-window client-gtk))))
(define/public (on-paint) (void)) (define/public (on-paint) (void))
(define/public (get-flush-window) client-gtk) (define/public (get-flush-window) client-gtk)
@ -374,9 +381,11 @@
(queue-paint)) (queue-paint))
(define/public (queue-backing-flush) (define/public (queue-backing-flush)
;; called atomically (not expecting exceptions) ;; called atomically
(unless for-gl? (unless for-gl?
(gtk_widget_queue_draw client-gtk))) (gtk_widget_queue_draw client-gtk)
;; peridodically flush to the screen:
(schedule-periodic-backing-flush)))
(define/override (reset-child-dcs) (define/override (reset-child-dcs)
(when (dc . is-a? . dc%) (when (dc . is-a? . dc%)

View File

@ -194,10 +194,12 @@
(thread (lambda () (thread (lambda ()
(let loop () (let loop ()
(unless (let ([any-tasks? (sync/timeout 0 boundary-tasks-ready-evt)]) (unless (let ([any-tasks? (sync/timeout 0 boundary-tasks-ready-evt)])
(sync queue-evt (if any-tasks? (sync/timeout (and any-tasks? (* sometimes-delay-msec 0.001))
(wrap-evt (system-idle-evt) queue-evt
(lambda (v) #f)) (if any-tasks?
boundary-tasks-ready-evt))) (wrap-evt (system-idle-evt)
(lambda (v) #f))
boundary-tasks-ready-evt)))
(pre-event-sync #t)) (pre-event-sync #t))
(atomically (dispatch-all-ready)) (atomically (dispatch-all-ready))
(loop))))) (loop)))))

View File

@ -168,7 +168,7 @@
(FillRect hdc r hbrush)) (FillRect hdc r hbrush))
(unless transparent? (unless transparent?
(DeleteObject hbrush))) (DeleteObject hbrush)))
(unless (do-backing-flush this dc hdc) (unless (do-canvas-backing-flush hdc)
(queue-paint))))) (queue-paint)))))
(EndPaint hdc ps)) (EndPaint hdc ps))
0] 0]
@ -257,7 +257,15 @@
(define/public (queue-backing-flush) (define/public (queue-backing-flush)
(unless for-gl? (unless for-gl?
(InvalidateRect canvas-hwnd #f #f))) (InvalidateRect canvas-hwnd #f #f)
(schedule-periodic-backing-flush)))
;; overridden to extend for scheduled periodic flushes:
(define/public (schedule-periodic-backing-flush)
(void))
(define/public (do-canvas-backing-flush hdc)
(when hdc
(do-backing-flush this dc hdc)))
(define/public (make-compatible-bitmap w h) (define/public (make-compatible-bitmap w h)
(send dc make-backing-bitmap w h)) (send dc make-backing-bitmap w h))