
Am Donnerstag 04 März 2010 14:55:30 schrieb Peter Verswyvelen:
I just converted an old HOpenGL application of mine to the new Haskell OpenGL using GHC 6.12.1, using realToFrac to convert Double to GLdouble.
The performance dropped from over 800 frames per second to 10 frames per second... Using unsafeCoerce I got 800 FPS again.
Yes, without rules, realToFrac = fromRational . toRational.
So for all of you using new OpenGL package, be warned about this, it can really kill performance (it's a known issue to those how already knew it ;-)
I think one would have to add {-# RULES #-} pragmas to Graphics.Rendering.OpenGL.Raw.Core31.TypesInternal, along the lines of {-# RULES "realToFrac/CDouble->GLdouble" realToFrac x = GLdouble x "realToFrac/GLdouble -> CDouble" realToFrac (GLdouble x) = x #-} (There are corresponding rules for Double->CDouble and CDouble->Double in Foreign.C.Types, so I think no rules Double->GLdouble are needed).
On Wed, Sep 30, 2009 at 4:06 PM, Peter Verswyvelen
wrote: I don't want to use the GL types directly since the OpenGL renderer is not exposes in the rest of the API. I was hoping that realToFrac would be a nop in case it would be identical to an unsafeCoerce. I guess one could make rules for that, but this tickets makes me wander if that really works: http://hackage.haskell.org/trac/ghc/ticket/1434
Well, someone would have to add the rules.
On Wed, Sep 30, 2009 at 4:58 PM, Roel van Dijk
wrote:
If you are *really* sure that the runtime representation is the same
Yup, CDouble is a newtype wrapper for Double, GLdouble is the same newtype wrapper for CDouble.
you could use usafeCoerce. You could use a small test function for profiling, something like:
convertGLfloat :: GLfloat -> Float convertGLFloat = realToFrac -- convertGLFloat = unsafeCoerce
and toggle between the two (assuming you won't get a segmentation fault).
Another option is to not convert at all but use the GL types everywhere. Either explicitly or by exploiting polymorphism.