[Scummvm-devel] New GUI thoughts in the Wiki

Max Horn max at quendi.de
Sat Nov 19 06:05:06 CET 2005


Am 19.11.2005 um 14:19 schrieb Marcus Comstedt:

[...]
Thanks for the explanation. What you said makes more sense to me now :-)

>
>
>> Keeping in mind, of course, that this should work for 320x200 8bpp
>> targets just as well as for 640x480 16bpp or bigger targets; and that
>> partial redraws are a must on slow targets (e.g. a full redraw of the
>> display list each time a click happen is no option)
>
> Yes, we'd need to design it so that the backend can choose whether to
> do a partial or a full redraw.  I think this can be accomplished by
> submitting a delta to the displaylist rather than a whole new
> displaylist.

OK, a very rough sketch of how the API for this could look:

Use something like this to display display list elements:
   struct DisplayListElement {
     DLEType type; = // = line, bitmap, ...
          // maybe also: (filled) rect, rect with color gradient, text
     Rect rect;
     Color color;  // Used by line, rect, text, ignored for bitmaps
     void *extraData; // Additional data, like a second color for
          // gradients, a text, a Graphics::Surface...
     uint32 flags; // Optional flags? Like 'render drop shadow' ?
         // Or a flag that indicates whether to dispose the
         // "extraData" when the DLE is removed
    };

For briefness I'll just talk about DLE's in the following :-).

in OSystem:
    DLE_ID appendElementToDisplayList(DLE e);
    void removeElementFromDisplayList(DLE_ID id);
    void clearDisplayList();

    // Could be used to switch between pressed/normal button bitmaps.
    // Probably should ENFORCE that the new and old DLE have
    // identical type & rect (so that you can only change the color
    // of a line, a label, the content of a bitmap etc.)
    // Not sure if we need this...
    void updateElementInDisplayList(DLE_ID id, DLE e);

    // Insert an element into the list before another element.
    // Not sure if we need this...
    void insertElementIntoDisplayListBefore(DLE's e, DLE_ID id);



However, I am not yet sure how efficient redrawing would be  
implemented... Maybe like this:
1) The z-order of elements in the DL is equal to their order in the DL
2) Each DLE has a "dirty" flag marking it as in need of a redraw
3) Appending a new element to the end of the DL marks just that  
element as dirty
4) Removing an element marks all elements which very previously  
(partially) covered by it as dirty. This in turn has to mark all  
objects that are covering those object as dirty
5) Inserting an element makes it dirty, and also everything which  
covers it (partially).
6) If the GUI is designed carefully as to reduce overlap, this means  
we get a relatively low redraw count
7) Making it possible to modify a DLE in-place could be used to speed  
up in-place modifications. Typical example: A button which switches  
between active, clicked, and disabled. By using  
updateElementInDisplayList, ideally only the button has to be redrawn  
(assuming nothing else covers it); if we handle text via DLEs, too,  
then the button and the text have to be redraw, which is still quite  
moderate.
To make this efficient, updateElementInDisplayList restricts changes  
(see above).

Of course we must provide a good default implementation for this, and  
one which is easy to make use of in the existing backends (i.e. it  
must be easy  for all porters to upgrade to the new system, while  
still making it possible for e.g. the DC port to provide a custom  
implementation...).



Cheers,
Max






More information about the Scummvm-devel mailing list