home contents changes options help


Render Architecture
by Stefan Klein

This gives you a very brief overview of the rendering code of CinePaint. It should be enough, however, to get you started, if you need to work with the code.


The strings of image rendering run together in the function gdisplay.c:gdisplay_flush. It flushes two queues of outstanding updates: update_areas and display_areas

So to expose or update a certain area you add it to the respective list using the provided functions (gdisplay_add_display_area/add_udpate_area) and then call gdisplay_flush. e.g. gdisplay_flush is called upon a GDK_EXPOSE event in disp_callbacks.c:gdisplay_canvas_events. The area of the expose event is added as a display_area and gdisplay_flush is invoked.

gdisplay_flush works in two steps, the first processing update_areas, the second processing display_areas.

step 1: gdisplay_paint_area()

In the first step, gdisplay_flush traverses the update_areas list and repaints each area in it using gdisplay_paint_area. This is mostly done by a call to gimage_construct. gimage_construct initializes the image's projection (gimage->projection) and composes layer by layer and channel by channel onto it. The projection is a display buffer. It is a canvas of the same type (channels/format/alpha) as the image itself. So composition onto this canvas is done without losing any precision. Conversion to 8bit RGB for display is done later. At the end of the process, the projection contains the image as it will be displayed on screen. With the introduction of CMS, however, not only each image, but each display, needs its own projection (gdisplay->projection). This is currently only implemented in a very rudimentary way by making copies of the image projection after constructing it. In the future, construction should be done directly onto the display's projection getting rid of the image's projection. After the projection has been constructed, its data is transformed through the selected ICC profile, if CMS is switched on. Finally, gdisplay_flush adds the updated area to the display_areas list, so that it gets later redrawn onto the screen.

step 2: gdisplay_display_area()

In the second step of gdisplay_flush, the display_areas list is traversed and each of the areas is redisplayed on the screen using gdisplay_display_area. This is mainly done by calling render_image. render_image composes the image with a checker background if it is transparent and scales the image to the zoom factor. It then converts it into 8bit RGB and writes it into a global 8bit buffer called gximage (defined in gximage.c/h). This buffer is then taken by gdisplay_display and drawn onto the gtk drawing widget of the display (in gximage.c:gximage_put).