Re: please keep those gdk draw- functions
Espen S Johnsen <[email protected]> 02 Nov 2007 14:13:35 +0100
| Newsgroups | gmane.lisp.clg.devel |
|---|---|
| Message-ID | <[email protected]> |
Chisheng Huang <[email protected]> writes: > The following comment is from gdk/gdk.lisp: > > ;;; Drawable -- all the draw- functions are deprecated and will be > ;;; removed, use cairo for drawing instead. > > I'd like to plea to keep the support of these draw- functions in > GDK as long as they are officially supported. The index of deprecated > symbols of GDK Reference Manual only listed 4 drawing functions: > gdk_draw_pixmap, gdk_draw_string, gdk_draw_text, and gdk_draw_text_wc. Keeping those function would be no problem. > Cairo is nice but is just too slow for statistical graphics. > To draw 25,000 circles, GDK:DRAW-ARC takes 0.07 seconds and Cairo > takes 6.01 seconds. Timing code is attached at the end. Cairo could definitely have been faster, but it isn't to bad either. I am using it to render vector maps, which is a quite demanding task. Among the techniques I use to achieve sufficient performance is doing as much clipping and polygon simplification as possible in the Lisp code and reducing the number of calls to stroke and fill. When rendering curves one may also speed up things by setting the tolerance to a higher value than default. I am also rendering to offscreen buffers which are reused on subsequent expose events and scaled/moved around to give the user the impression of better performance. Although I haven't done any real benchmarking, my impression is that the performance is comparable to similar commercial available systems. To see if it was possible to speed up the circle drawing code, I've did a few test. The code and timings is included below. As you can see the final version used Even if this still is more than 10 times longer time than the Gdk version and without knowing how representative this test is for the final application and what what would be acceptable rendering time, I would have reconsidered using Cario. It has a much nicer API than the Gdk drawing functions, the same code can be used to draw on screen and to create Postscript/PDF output and the antialiased output is superior. > this version of CAIRO-CIRCLES will kill CMUCL immediately when the length > of CENTERS is 3000 or bigger. I have also experienced this on some machines while on others it works as expected, which has lead me to believe that it is a X server problem. For this reason I am calling stroke for every 500th circle in the code below. (defparameter *centers* (loop repeat 50000 collect (+ 10.0d0 (random 280)))) (defun cairo-circles-1 (da centers) (declare (optimize (speed 3) (safety 1))) (write-line "Cairo, original") (gdk:with-cairo-context (cr (gtk:widget-window da)) (setf (cairo:line-width cr) 1.0) (loop with 2pi = (* 2.0d0 pi) for (x y) on centers by #'cddr do (cairo:fast-arc cr x y 5.0d0 00d0 2pi) (cairo:close-path cr) (cairo:stroke cr)))) (defun cairo-circles-2 (da centers) (declare (optimize (speed 3) (safety 1))) (write-line "Cairo, stroke every 500") (gdk:with-cairo-context (cr (gtk:widget-window da)) (setf (cairo:line-width cr) 1.0) (loop with 2pi = (* 2.0d0 pi) for n from 0 for (x y) on centers by #'cddr do (cairo:new-sub-path cr) (cairo:fast-arc cr x y 5.0d0 00d0 2pi) (cairo:close-path cr) (when (zerop (mod n 500)) (cairo:stroke cr))) (cairo:stroke cr))) (defun cairo-circles-3 (da centers) (declare (optimize (speed 3) (safety 1))) (write-line "Cairo, stroke every 500, tolerance 1.0") (gdk:with-cairo-context (cr (gtk:widget-window da)) (setf (cairo:tolerance cr) 1.0) (setf (cairo:line-width cr) 1.0) (loop with 2pi = (* 2.0d0 pi) for n from 0 for (x y) on centers by #'cddr do (cairo:fast-arc cr x y 5.0d0 00d0 2pi) (cairo:close-path cr) (cairo:new-sub-path cr) (when (zerop (mod n 500)) (cairo:stroke cr))) (cairo:stroke cr))) (defun circle-approximation (cr x0 y0 radius edges) (declare (double-float x0 y0 radius) (fixnum edges)) (declare (optimize (speed 3) (safety 1))) (cairo:new-sub-path cr) (let ((delta (/ (* 2 pi) edges))) (declare (double-float delta)) (loop for i from 0 below edges do (let ((x (+ x0 (* radius (sin (* (+ 0.5 i) delta))))) (y (- y0 (* radius (cos (* (+ 0.5 i) delta)))))) (cairo:fast-line-to cr x y)))) (cairo:close-path cr)) (defun cairo-circles-4 (da centers) (declare (optimize (speed 3) (safety 1))) (write-line "Cairo, circle approximation with 8 edges") (gdk:with-cairo-context (cr (gtk:widget-window da)) (setf (cairo:line-width cr) 1.0) (loop for (x y) on centers by #'cddr do (circle-approximation cr x y 5.0d0 8) (cairo:stroke cr)))) (defun cairo-circles-5 (da centers) (declare (optimize (speed 3) (safety 1))) (write-line "Cairo, circle approximation with 8 edges, stroke every 500") (gdk:with-cairo-context (cr (gtk:widget-window da)) (setf (cairo:line-width cr) 1.0) (loop for n from 0 for (x y) on centers by #'cddr do (circle-approximation cr x y 5.0d0 8) (when (zerop (mod n 500)) (cairo:stroke cr))) (cairo:stroke cr))) (defun test-all () (test-circles 'gdk-circles) (test-circles 'cairo-circles-1) (test-circles 'cairo-circles-2) (test-circles 'cairo-circles-3) (test-circles 'cairo-circles-4) (test-circles 'cairo-circles-5) * (test-all) Cairo, original Evaluation took: 5.421 seconds of real time 5.28833 seconds of user run time 0.092006 seconds of system run time 0 calls to %EVAL 0 page faults and 36,816 bytes consed. Cairo, stroke every 500 Evaluation took: 4.479 seconds of real time 4.344272 seconds of user run time 0.072004 seconds of system run time 0 calls to %EVAL 0 page faults and 39,840 bytes consed. Cairo, stroke every 500, tolerance 1.0 Evaluation took: 2.323 seconds of real time 2.200137 seconds of user run time 0.044003 seconds of system run time 0 calls to %EVAL 0 page faults and 35,968 bytes consed. Cairo, circle approximation with 8 edges Evaluation took: 2.007 seconds of real time 0.860053 seconds of user run time 0.024002 seconds of system run time 0 calls to %EVAL 0 page faults and 39,808 bytes consed. Cairo, circle approximation with 8 edges, stroke every 500 Evaluation took: 1.084 seconds of real time 0.352022 seconds of user run time 0.028001 seconds of system run time 0 calls to %EVAL 0 page faults and 36,720 bytes consed. -- Espen ------------------------------------------------------------------------- This SF.net email is sponsored by: Splunk Inc. Still grepping through log files to find problems? Stop. Now Search log events and configuration files using AJAX and a browser. Download your FREE copy of Splunk now >> http://get.splunk.com/