| Start | Super Packer | Atari Graphics Studio / AGS | Graph2Font / G2F | Mads | MadPascal |   http://madteam.atari8.info  
SKŁAD GRUPY
PRODUKCJE
scena
gry
użytki
vbxe
SPRZĘT
Sio2SD / Pajero
Sio2SD / Rocky
Stereo / Pajero
GTIA / Psychol
ANTIC + VBXE test
ARTYKUŁY
DEMO EFFECTS
LINKI
   

Piotr Fusik (Fox/Taquart)
Jak uniknąć dwubuforowania ?
Atarynka #2/2002

Dwubuforowanie (ang. double-buffering) jest techniką pozwalającą uniknąć wyświetlania obrazu, którego tworzenie nie zostało jeszcze ukończone. Idea dwubuforowania jest prosta: w pamięci są dwa obrazy, z których jeden jest wyświetlany na ekranie, a drugi tworzony (rysowany). Po utworzeniu obrazu zaczynamy go wyświetlać, jednocześnie rozpoczynając rysowanie na obrazie, który dotychczas był wyświetlany. Podstawową wadą dwubuforowania jest pamięciochłonność: trzeba przeznaczyć pamięć co najmniej na dodatkowy drugi obraz. Zużycie pamięci na implementację dwubuforowania jest jeszcze większe w przypadku rozpętlonego programu, w którym każdy bajt obrazu jest zapisywany inną instrukcją. Chcielibyśmy oszczędzić tę pamięc, oczywiście nie wprowadzając migotania obrazu. Poniżej opiszę, jak można rysować na jednym obrazie, który jest ciągle wyświetlany, w ten sposób aby rysowanie nie było widoczne.

Podstawowe znaczenie mają dwie rzeczy:

  • w jakiej kolejności rysujemy (preferowane jest rysowanie całego obrazu linia po linii z góry na dół)
  • jak szybko rysujemy w porównaniu z prędkością wyświetlania

    Rysowanie w dowolnej kolejności

    Pierwszy przypadek jest najbardziej ogólny: obraz jest tworzony przez stawianie pikseli w dowolnej kolejności. Jeśli nie chcemy, aby wyświetlił się obraz nie dokończony, musimy zdążyć z narysowaniem go w czasie, gdy obraz nie jest wyświetlany.

                -------------------------                    Rys. 1a
                |       poprzedni       |
                -------------------------
    rysowanie > |XXXXXXXXXXXXXXXXXXXXXXX|
                -------------------------
                |                       |
        wolne > |       aktualny        |
                |                       |
                -------------------------
                |XXXXXXXXXXXXXXXXXXXXXXX|
    

    Rys. 1a pokazuje upływ czasu mierzony w liniach ekranowych. Termin "linia ekranowa" został tutaj użyty w znaczeniu jednostki czasu, równej 114 cyklom głównego zegara Atari. Oczywiście jest to czas potrzebny na wyświetlenie jednej linii ekranowej. Na rysunku został zaznaczony czas, w którym wyświetlany jest obraz (na biało) oraz czas, w którym obraz nie jest wuświetlany (wyświetlana jest ramka lub następuje powrót pionowy - kolor szary). Jak pokazuje rysunek, czasu dostępnego na rysowanie w przypadku jest niewiele. W czasie wyświetlania obrazu (na schemacie oznaczenie "wolne") nie możemy nic rysować, możemy natomiast wykonać obliczenia.

    Rysowanie z góry na dół szybsze od wyświetlania
                -------------------------                    Rys. 1b
                |       poprzedni       |
                -------------------------
        wolne > |XXXXXXXXXXXXXXXXXXXXXXX|
                -------------------------
                |                       |
    rysowanie > |       aktualny        |
                |                       |
                -------------------------
                |XXXXXXXXXXXXXXXXXXXXXXX|
    

    Jeśli w tym przypadku zaczniemy rysować chwilę przed tym, jak obraz zacznie być wyświetlany, zdążymy z jego ukończeniem przed zakończeniem wyświetlania (rys. 1b). Przypadek ten jest o tyle ciekawy, że możemy ograniczyć pamięć obrazu do jednej, stale aktualizowanej linii (ew. dwóch). Umieszczenie tej linii na stronie zerowej lub na stosie pozwala dodatkowo przyspieszyć rysowanie.

    Rysowanie z góry na dół wolniejsze od wyświetlania
                -------------------------                    Rys. 1c
                |       poprzedni       |
                -------------------------
        wolne > |XXXXXXXXXXXXXXXXXXXXXXX|
                -------------------------
                |                       |
                |       poprzedni       |
                |                       |
    rysowanie > |XXXXXXXXXXXXXXXXXXXXXXX|
                |                       |
                |        aktualny       |
                |                       |
                -------------------------
                |XXXXXXXXXXXXXXXXXXXXXXX|
    

    Nic nie stoi na przeszkodzie, aby zacząć rysować wcześniej. Możemy zacząć rysować pierwszą linię w czasie wyświetlania ostatniej. Tym samym możemy przeznaczyć na rysowanie całą ramkę.

    Czy można nie stosować dwubuforowania, gdy rysowanie trwa dłużej niż jedną ramkę? Oczywiście. Jest to wyjaśnione na rysunku 1c. Jeśli rozpoczniemy rysowanie po pobraniu przez ANTIC pierwszej linii (można użyć przerwania DLI), w pierwszej ramce zostanie wyświetlony stary obraz. Natomiast w drugiej ramce powinniśmy skończyć rysowanie, zanim ANTIC pobierze dane ostatniej linii. Wtedy zostanie wyświetlony cały aktualny obraz. Do pełnych dwóch ramek pozostaje jeszcze nieco czasu, oznaczonego jako "wolne".

    Piotr Fusik (Fox/Taquart)


  •  

    madteam.atari8.info © MadTeam, hosted: www.atari8.info