[Haskell-cafe] New OpenGL package: efficient way to convert datatypes?

Daniel Fischer daniel.is.fischer at web.de
Thu Mar 4 10:20:12 EST 2010


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 <bugfact at gmail.com> 
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
> > <vandijk.roel at gmail.com>
> >
> > 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.



More information about the Haskell-Cafe mailing list