[HOpenGL] Pure, garbage-collected graphics resources

Sam Martin sam.martin at geomerics.com
Tue Jul 21 13:05:22 EDT 2009


I've been thinking about something similar for a while, and am toying
with the idea of building the rendering pipeline as a typed expression.
It's all very hand-wavey thoughts at the moment, but I reckon it's
possible to define a function that describes the pipeline you want to
establish and then 'compile' that expression into an executable object.

 

It's equivalent to defining the graph of the pipeline and compiling that
into an executable sequence.

 

They key thing is it separates the definition of what you want to do
(the expression) from the stateful execution. A major bonus is all
resource allocation/deallocations can be extracted late on in the
process, which offers the potential for clever resource usage
strategies. Increased efficiency is actually why I'm interested in
pursuing it. 

 

Not a small amount of work though. Any thoughts?

 

Ta,

Sam

 

From: hopengl-bounces at haskell.org [mailto:hopengl-bounces at haskell.org]
On Behalf Of Conal Elliott
Sent: 21 July 2009 17:15
To: hopengl at haskell.org; minh thu
Subject: Re: [HOpenGL] Pure, garbage-collected graphics resources

 

Thanks for these comments
 

	Anyway, I've not a clear picture of what you have in mind
(especially,
	at which point in time a, say, VBO should be considered to be
part of
	things to be rendered). Often, a data structure (say Blah) is
created
	in a pure way then given to some kind of run :: Blah -> IO ()
function
	for "interpretation". Why not mirror the OpenGL API in a purely
	data-centric way then give the data to the run function ?


This "data-centric" style (I like that term) is exactly what I like to
do in all of my libraries, and it's what I'm doing again now.  OpenGL
types are hidden in the library implementation, and the exposed
semantics is unaffected by the imperativeness of OpenGL (just as the
semantics of Integer is unaffected by the imperativeness of 'print').

And then I find myself in an implementation puzzle.  My 'run' function
(for the purely functional type) involves creating VBOs and textures,
which greatly accelerate rendering.  I want to *reuse* these resources
without mutation (i.e. reuse the content, not the memory), which is easy
if they're wrapped up as functional values that go into my higher-level
functional values, but tricky if they get created only during 'run'.
Another example is shader programs, which I synthesize and then never
mutate.

Since I'm using this graphics data in a purely functional way, I want
both creation and destruction to be handled in a functional way, i.e.,
lazy evaluation and garbage collection, with no visible IO.  I think we
can finally get there, now that we have dependable prompt execution of
C-based finalizers.

However, I do not think robust finalization can be added on top of the
Ptr type, which is used in HOpenGL, because GHC optimizations often drop
constructors (like Ptr) keeping only the contents, which allows
finalizers to get called much too soon.  Some examples of this general
problem are mentioned in the addFinalizer documentation [1].  I think a
solution would be to replace Ptr with ForeignPtr in HOpenGL.

   - Conal

[1]
http://www.haskell.org/ghc/docs/latest/html/libraries/base/System-Mem-We
ak.html#v%3AaddFinalizer



On Tue, Jul 21, 2009 at 4:30 AM, minh thu <noteed at gmail.com> wrote:

2009/7/21 Conal Elliott <conal at conal.net>:

> I'd like to use some OpenGL resources (VBOs, textures, shaders, and
shader
> programs) in a functional way, with immutability, garbage collection,
and
> IO-free creation interfaces.  Has anyone played with doing such a
thing?  I
> guess the GC part would involve foreign pointers with foreign
finalizers
> (which now run promptly in GHC iiuc).  I don't know of any reliable
way to
> add finalizers to Ptr values, because of the unboxing problem [1].
>
> One tricky issue is that graphics context initialization must take
place
> before any of these "pure" resources get evaluated.  If the APIs
allowed
> access to to multiple graphics contexts, things would get stickier.
>
> Comments?

Hi,

I wanted to point you to a paper (Stretching the storage manager: weak
pointers and stable names in Haskell) but see you're one of the
authors.

As you say, there is the notion of context. I guess you can create the
context with something explicitely in IO, like

createContext :: IO Context

then implementing the "pure" resources as data structure referencing
the context.

Anyway, I've not a clear picture of what you have in mind (especially,
at which point in time a, say, VBO should be considered to be part of
things to be rendered). Often, a data structure (say Blah) is created
in a pure way then given to some kind of run :: Blah -> IO () function
for "interpretation". Why not mirror the OpenGL API in a purely
data-centric way then give the data to the run function ?

Although the OpenGL C API is imperative, it maps fairly well to a
data-centric approach.

 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/hopengl/attachments/20090721/7d9ccd65/attachment.html


More information about the HOpenGL mailing list