Complete.Org: Mailing Lists: Archives: freeciv-dev: January 2003:
[Freeciv-Dev] Re: city text , sdl widgets and rock & roll ( was Re: (PR#
Home

[Freeciv-Dev] Re: city text , sdl widgets and rock & roll ( was Re: (PR#

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: bursig@xxxxxxxxx
Cc: freeciv-dev@xxxxxxxxxxx
Subject: [Freeciv-Dev] Re: city text , sdl widgets and rock & roll ( was Re: (PR#2858) )
From: "Jason Short via RT" <rt@xxxxxxxxxxxxxx>
Date: Thu, 23 Jan 2003 21:19:02 -0800
Reply-to: rt@xxxxxxxxxxxxxx

Rafa³ Bursig via RT wrote:
> Dnia 2003.01.23 18:00 Jason Short via RT napisa³(a):

> Jason wait a moment ...
> 
> Primo : How should I do it when all main draw functions are outside gui 
> depended code ?
> 
> Secundo :
> I don't know gtk API and only suspect about which "buffer" you speak 
> now.
> 
> I suspect that you want have :
> 1) main screen/display buffer - gtk use funct. gtk_flush() to flush 
> this buffer to framebuffer.
> 2) map buffer - terrain, cities , units are draw here.
> 3) city text/widgets buffer -  city descriptions or sdl widgets should 
> be draw here.

Hmm, not exactly.

My idea is simply that everything should be buffered, and only written 
to the display when flush_mapcanvas (and friends) are called.  The 
method of buffering is left up to the GUI.

The current method has city descriptions drawn directly to the display; 
that is flush_mapcanvas will (and has to) draw over them.  I suspect 
gui-sdl does buffering slightly differently (although I'm not quite sure 
how), so that everything goes into the buffer and you only flush to the 
display at certain points (which you have to guess at - and the guesses 
are sometimes wrong - leading to problems).  Anyway, my point is that 
flush_mapcanvas should flush everything to the display - including the 
map tiles, city text, and widgets.

If I were to design a buffer system, though, it would be:

1.  main buffer
2.  tile buffer
3.  city desc buffer (needs mask or alpha layer)
4.  widgets buffer (needs mask or alpha layer)

So that when you call refresh_tile_mapcanvas, it updates a single tile 
of the tile buffer then calls flush_mapcanvas.  This then in turn copies 
the three buffers (2-4) onto the main buffer, and flushes that to the 
display.  The end result is that the display is updated perfectly, 
nothing is overwritten, and there is no flicker.

Of course, this 4-buffer system (only 3 buffers for most clients since 
they don't have manually managed widgets) is a lot of work.  But since 
the client can do whatever they want (so long as everything is 
buffered), things will also work without the city desc buffer - just 
draw that stuff onto the tile buffer.

Note, the "main buffer" is a little confusing.  gui-gtk-2.0 provides 
this main buffer, but gui-gtk does not (or not reliably?  I'm not 
sure...).  Currently in the GTK clients, we have two buffers:

1. main buffer (provided by GUI)
2. map buffer

where terrain, units, and cities are drawn to the map buffer and flushed 
to the main buffer via flush_mapcanvas.  Then the city texts are drawn 
onto the main buffer on top.  The whole thing goes out to the display 
automatically when you call gdk_flush (or whenever gdk feels like it). 
Since the final flush step is done manually under SDL, the current 
system doesn't work for SDL.  Note that if city descriptions are drawn 
to buffer#2, there is no longer a need for buffer#1.

This may not work cleanly for animations, but that is something that can 
be handled separately (e.g., with an individual animation buffer).

>    update_map_canvas(..., FALSE) - will redraw 2)

update_map_canvas needs to redraw both the map and the city descriptions.

 >
>    show_city_descriptions() - will redraw 3)

This function is never called outside of the other update functions 
(update_mapcanvas_full and update_city_descriptions).

update_city_descriptions should redraw 3 and flush everything.  As long 
as no consistent buffering system is used this should probably be left 
on the GUI side.  So a client that has the 4-buffer system above will 
simply have

   show_city_descriptions();
   flush_mapcanvas_full();

whereas a client with the standard two-buffer system will need a full 
update, i.e.

   update_map_canvas(..., FALSE); /* draw the underlying terrain */
   show_city_descriptions(); /* draw texts over terrain */
   flush_mapcanvas_full();

>    flush_mapcanvas_full() - will draw 2) -> 1) and 3) -> 1) and call 
> gtk_flush() ( copy 1) to framebuffer )

Yes, although the exact number of buffers used may vary.

> but here is small problem :   show_city_descriptions() is "common" 
> function.

Yes, but it calls show_city_desc() to do the drawing.

To allow the 4-buffer system we will need an additional function, 
clear_city_descriptions() or similar, to be called at the beginning of 
show_city_descriptions().  With the two-buffer system, this is not 
necessary since this is implicit in drawing the map tiles.

> I propose :
> 1) main screen/display buffer. 2) map buffer - terrain, cities , units 
> are draw here.
> 
>    update_map_canvas(..., TRUE) - will redraw 2) and draw it to 1)
>    update_city_descriptions( FALSE ) - will draw city text /widgets to 
> 1)
>    flush_screen() - call gtk_flush() ( copy 1) to framebuffer )

Note that flush_mapcanvas does not call gtk_flush.  In fact, we rarely 
call gtk_flush - it happens automatically when we are "done".  Only in 
the case of animations do we need to flush in the middle of drawing.

So, any update_map_canvas(TRUE) is suppose to do the flushing itself. 
In gtk this just means copying to the main buffer.  In gui-sdl it means 
doing some manual work.  This process is slow, which is why we should 
try to limit these calls (using queue_mapview_update() or similar).

So...

   update_map_canvas(..., TRUE)
     draw the map buffer, and flush to the display
   update_map_canvas(..., FALSE)
     draw the map buffer, no flush
   update_map_canvas_visible()
     draw the map buffer and city descriptions, full flush
   update_city_descriptions()
     clear old city descriptions, draw new ones, full flush
   show_city_descriptions()
     draw new city descriptions, no flush. (Currently, there is a flush.
     But IMO there shouldn't be.)
   flush_mapcanvas() - copy the underlying buffers (2-4) to the main
     buffer (#1), and flush, for part of the mapcanvas
   flush_mapcanvas_full() - same as flush_mapcanvas but for the entire
     canvas

The challenge is to fit where in here the map widgets get redrawn.  If 
you provide a separate buffer for them you can do it any time 
flush_mapcanvas() is called.  Otherwise you can do it any time 
flush_mapcanvas_full() is called and there is no real workaround for 
partial-flush scenarios.

jason




[Prev in Thread] Current Thread [Next in Thread]