Stručný přehled grafických knihoven pro Raspberry Pi

18. 2. 2016
Doba čtení: 13 minut

Sdílet

Na čtyřdílný článek o přímém přístupu do framebufferu (obrazové paměti) mikropočítače Raspberry Pi dnes navážeme přehledem některých knihoven, které je možné použít pro tvorbu 2D a 3D grafiky.

Obsah

1. Stručný přehled grafických knihoven pro Raspberry Pi

2. Kterou knihovnu si mám vybrat pro svůj projekt?

3. SDL verze 1.2

4. Allegro 4 a Allegro 5

5. Použití GPU v knihovně SDL verze 2

6. EGL (Native Platform Interface)

7. OpenGL ES (GLES)

8. OpenVG

9. Vykreslovací pipeline realizovaná v OpenVG

10. Odkazy na Internetu

1. Stručný přehled grafických knihoven pro Raspberry Pi

V předchozí čtveřici článků o tvorbě počítačové grafiky na oblíbeném jednodeskovém mikropočítači Raspberry Pi [1] [2] [3] [4] jsme se s využitím několika demonstračních příkladů seznámili se způsobem vykreslování základních grafických entit (primitiv) přímo do framebufferu. Připomeňme si ve stručnosti, že se v tomto případě pracuje se speciálním zařízením /dev/fb0, které v uživatelském prostoru zpřístupňuje jak vlastní obsah framebufferu (takzvanou Video RAM), tak i konfiguraci framebufferu, kterou lze číst či měnit s využitím operace typu ioctl. Pro dosažení co největší rychlosti vykreslování (a samozřejmě taktéž čtení) pixelů jsme celý framebuffer zpřístupnili uživatelské aplikaci pomocí funkce mmap (memory map), takže nebylo zapotřebí používat sekvenční čtení a zápis pomocí funkcí read a write.

Ovšem jednodeskový mikropočítač Raspberry Pi ve skutečnosti není vybaven „hloupým“ framebufferem, u něhož se pouze nastaví požadované rozlišení, obnovovací frekvence a barevná hloubka. Ústředním čipem, na němž je vlastně celé Raspberry Pi postaveno, je integrovaný obvod BCM2835 popř. BCM2836. První z těchto čipů je použit ve většině modelů Raspberry Pi, včetně Modelu A, první verze modelu B a nejnověji i RPi Zero, zatímco druhý čip nalezneme v nejvýkonnějším modelu Raspberry Pi 2 Model B. Na těchto čipech nalezneme kromě procesorového jádra typu ARM 11 resp.  ARM Cortex-A7 i plně programovatelný grafický procesor neboli GPU. Není se ostatně čemu divit, protože čipy BCM2835 či BCM2836 byly navrženy pro použití v multimediálních zařízeních u nichž se programovatelné GPU mohou hodit k mnoha různým činnostem: akceleraci 2D grafiky, akceleraci 3D grafiky, implementaci audio i video kodeků apod. Především u prvního zmíněného čipu, tj. u BCM2836 je patrné, že procesorové jádro (dnes již vlastně zastaralé) mělo původně sloužit pouze pro podpůrnou činnost, zatímco nejvíce práce mělo ležet právě na programovatelném grafickém procesoru.

2. Kterou knihovnu si mám vybrat pro svůj projekt?

Ve chvíli, kdy si uvědomíme, že právě GPU může mít největší vliv na schopnosti Raspberry Pi, se nabízí logická otázka: jakým způsobem vlastně může vývojář možnosti programovatelného grafického procesoru využít ve svých aplikacích a jaká knihovna se popř. může použít jako náhrada za funkce, které přímo přistupují k framebufferu a s jejichž možnostmi jsme se již seznámili? Ve skutečnosti variant existuje hned několik. Konkrétní výběr přitom závisí jak na tom, do jaké míry má být či musí být aplikace přenositelná i na další zařízení (běžné PC, smartphone, tablety atd.) a zda programátor skutečně potřebuje vytvářet vlastní algoritmy pro GPU či zda se spokojí již s předpřipravenou sadou hotových a otestovaných funkcí (vykreslení úsečky, vykreslení rastrového obrázku, tvorba křivky, vyplněného tvaru, textu, otexturovaného trojúhelníku apod.). V navazujících částech tohoto seriálu se průběžně seznámíme hned s několika knihovnami a technologiemi, které jsou pro mikropočítače Raspberry Pi dostupné. Všechny příklady budou odzkoušeny na Raspberry Pi 1 Model B, který je vybaven 512 MB RAM a čipem BCM2835 (ostatně i tento text vzniká na stejném zařízení).

3. SDL verze 1.2

Největší (i když nikoli nesložitější) výběr mají ti vývojáři, kteří se spokojí se softwarově řízeným vykreslováním, tj. s funkcemi, které ve výsledku budou programově zapisovat barvy jednotlivých pixelů do framebufferu. Pravděpodobně nejjednodušší a nejpřímější cestou je v tomto případě použití knihovny SDL verze 1.2, která je dostupná přímo v základní instalaci Raspbianu. Tato knihovna programátorům nabízí jak vykreslování do okna v případě použití systému X Window, tak i vykreslování do framebufferu. Přitom se v případě SDL 1.2 jedná o poměrně úzkou vrstvu mezi framebufferem a aplikací, což mj. znamená, že z vykreslovacích (grafických) operací jsou k dispozici pouze operace určené pro vykreslení obdélníku konstantní barvou, přenosu obrázku operací bitblt a uzamčení obrazové paměti s vrácením ukazatele do framebufferu (v tento okamžik, tj. po uzamčení obrazové paměti, se vlastně programátor nachází v podobném stavu, jako my při otevření speciálního zařízení /dev/fb0 a jeho namapování do adresního prostoru aplikace). V případě potřeby jsou k dispozici i pluginy nabízející další funkce, například práci s TrueType fonty apod.

Poznámka: v některých případech je určitá forma akcelerace použita i v SDL 1.2, a to v závislosti na tom, která nižší vrstva je z této knihovny volána.

4. Allegro 4 a Allegro 5

Určitou alternativou (či možná lépe řečeno konkurencí) ke knihovně SDL verze 1.2 je knihovna nazvaná Allegro, která v současnosti existuje ve dvou variantách: „klasická“ varianta založená na softwarovém renderingu nese označení Allegro 4 a zcela přepracovaná varianta, která již dokáže využívat některé možnosti nabízené grafickými akcelerátory, se jmenuje Allegro 5 (zpětná kompatibilita zde není zachována, podobně jako u SDL 1.2 → SDL 2.0). V Raspbiannu je dostupná knihovna Allegro 4, která programátorům nabízí široké množství různých modulů. Z hlediska tvorby grafiky jsou nejdůležitější funkce pro vykreslování různých grafických primitiv (od pixelů přes úsečky až po křivky), práci s rastrovými obrázky a sprity (včetně použití tzv. kompilovaných spritů), ale i například podpora pro práci s animacemi uloženými ve formátu FLI/FLC. Pro některé účely může být zajímavý i modul nabízející velmi snadno použitelné GUI, které sice neobsahuje všechny dnes očekávané widgety (chybí například strom), ale pro konfigurační dialogy s tlačítky, scrollbary, vstupními textovými poli, přepínači atd. je to použitelná a přitom výkonostně a především paměťově nenáročná alternativa k „plnohodnotným“ GUI knihovnám.

Poznámka: i v tomto případě platí, že některé operace mohou být v knihovně Allegro prováděny grafickým procesorem.

5. Použití GPU v knihovně SDL verze 2

Pokud programátor potřebuje či chce využít některé základní možnosti nabízené GPU nainstalovaném na mikropočítači Raspberry Pi, může být velmi dobrou alternativou knihovna SDL 2. Ta vznikla z již zmíněné knihovny SDL 1.2, přičemž prakticky celý modul týkající se grafického výstupu byl přepracován a není zpětně kompatibilní. Proč se vlastně tvůrci rozšířené a současně i velmi oblíbené knihovny SDL 1.2 (ta je použita v mnoha open source i komerčních hrách) vlastně rozhodli pro změnu API, které není zpětně kompatibilní a která tedy nutí vývojáře k přepisu části svých zdrojových kódů? Odpovědí je vývoj grafických čipů a především pak programovatelných GPU. Knihovna SDL 1.2 vlastně (i z historických důvodů) tvoří jen velmi úzkou vrstvu mezi framebufferem a aplikací, což například znamená, většina vykreslovacích operací je prováděna softwarově přenosem barev jednotlivých pixelů do obrazové paměti (což je přesně ten způsob, s nímž jsme se již seznámili). V knihovně SDL 2 je vykreslování prováděno odlišně: nejprve se rastrové obrázky a sprity převedou do video paměti či do texturovací paměti a teprve odsud jsou velmi rychle vykresleny.

Knihovna SDL 2 přitom může při práci s texturami interně volat funkce knihoven OpenGL, OpenGL ES, Direct X atd. Pro nás je v tuto chvíli zajímavá především podpora pro volání funkcí OpenGL ES, a to z toho důvodu, že OpenGL ES 2.0 je na mikropočítači Raspberry Pi přímo podporována (viz též navazující kapitoly). Návod pro překlad knihovny SDL 2 pro Raspberry Pi a Raspbian je popsán na stránce https://solarianprogrammer­.com/2015/01/22/raspberry-pi-raspbian-getting-started-sdl-2/.

6. EGL (Native Platform Interface)

Konečně se dostáváme k technologii, která je přímo navržena pro práci s grafickým procesorem. Jedná se o EGL neboli též Native Platform Interface používané jako mezivrstva mezi grafickým procesorem (přičemž každý grafický procesor může mít zcela odlišný způsob ovládání) na jedné straně a knihovnou OpenVG či OpenGL ES na straně druhé (alternativně je samozřejmě možné volat funkce poskytované EGL přímo, hlavičkové soubory naleznete v adresáři /opt/vc/include/EGL). Za vývojem EGL stojí sdružení Khronos, které kromě toho „pečuje“ i o specifikace a implementace OpenGL, OpenGL ES, OpenVG atd. Jedním ze základních úkolů EGL je vytvoření a správa grafického kontextu, ploch (surface), do kterých je možné přes knihovny OpenGL ES a OpenVG provádět vykreslování atd. Mimochodem – plochy (surface) mohou být vytvořeny tak, aby aplikace běžela v systému X Window (i v okně), přes framebuffer nebo lze vykreslování provádět do zadního bufferu. Další důležitou funkcí nabízenou EGL je kopie obsahu bitmap mezi jednotlivými plochami, tj. operace typu bitblt.

7. OpenGL ES (GLES)

V článku o knihovnách určených pro tvorbu grafiky na jednodeskových mikropočítačích Raspberry Pi samozřejmě nesmí chybět zmínka o knihovně OpenGL ES, která se též někdy označuje zkratkou GLES. Jedná se o variantu známé knihovny OpenGL, ovšem upravené takovým způsobem, aby se tato knihovna dala efektivně použít na smartphonech a tabletech vybavených GPU (právě pro je v názvu použito „ES“, což znamená „for Embedded Systems“). Dnes existuje již několik specifikací OpenGL ES; nás bude nejvíce zajímat OpenGL ES 2.0, protože právě tato verze je dostupná pro Raspberry Pi (několik vývojářů se dokonce vyjádřilo v tom smyslu, že na RPi je specifikace dodržována velmi dobře a proto je RPi ideální pro ladění aplikací, které OpenGL ES 2.0 používají). Proto také všechny demonstrační příklady, s nimiž se později seznámíme, budou překládány a linkovány právě proti OpenGL ES 2.0.

Již na začátku je nutné zdůraznit, že OpenGL ES 2.0 je v mnoha ohledech odlišná od „klasické desktopové“ knihovny OpenGL (ta vznikla pro grafické pracovní stanice společnosti SGI, ostatně některé funkce OpenGL nalezneme i ve starší knihovně IRIS GL). To znamená, že není možné například převzít zdrojové kódy aplikace postavené na OpenGL a GLUTu a přeložit je beze změny pro Raspberry Pi. Provedené úpravy v API GLESu však mají svůj smysl, protože konstrukce GPU se velmi změnila – namísto pevně nastavené vykreslovací pipeline dnes máme k dispozici programovatelná GPU, takže například všechny funkce, které se v původní OpenGL zabývaly výpočtem osvětlení, již není nutné mít zafixovány, protože je možné implementovat si vlastní shadery. Navíc je možné vhodným naprogramováním GPU použít tento čip i pro jiné výpočty (FFT, kodeky apod.)

8. OpenVG

Pro mnoho aplikací může být zajímavé a užitečné použít relativně novou knihovnu nazvanou OpenVG. Zatímco výše zmíněná knihovna OpenGL ES je určena především pro tvorbu 3D grafiky, na niž se v posledních dvou desetiletích soustředili i výrobci grafických akcelerátorů pro počítače řady PC, uvědomili si tvůrci OpenVG jednu „maličkost“: při práci s desktopem popř. i při práci na tabletu či smartphonu je velmi důležitá i 2D grafika. Typickou 2D aplikací dneška je webový prohlížeč, od něhož se mj. vyžaduje i co nejrychlejší vykreslení mnohdy velmi složitého layoutu stránek, plynulý scrolling, kvalitně zobrazené písmo, dynamické změny ve stránkách, podpora HTML 5 canvasu apod. Dalšími 2D aplikacemi mohou být některé oblíbené hry, ať již se jedná o typicky dvourozměrné Angry Birds či o hry s isometrickou grafikou. Na tabletech, smartphonech a některých „moderních“ desktopech se taktéž velmi často požaduje zmenšení aplikace do živé ikony či použití vektorových ikon a widgetů (škálovatelné grafické uživatelské rozhraní).

Právě pro tyto účely vznikla knihovna nazvaná OpenVG, která například obsahuje funkce pro deklaraci a vykreslení takzvaných cest (paths), aplikaci různých filtrů na 2D scénu, práci s fonty apod. Funkce byly mj. vybrány i s ohledem na předpokládané větší použití formátu SVG (Scalable Vector Graphics). Předpokládá se, že OpenVG může být použita ve funkci backendu například pro Cairo a Pango apod. Zajímavé je, že existuje i čistě softwarová implementace funkcí OpenVG naprogramovaná v ANSI C a tedy přenositelná na prakticky jakoukoli platformu. Z pohledu programátora je sympatické, že způsob pojmenování funkcí OpenVG je podobný se způsobem použitým v knihovně OpenGL; samozřejmě až na odlišný prefix (vgDrawImage() versus glDrawArrays() – toto jsou mimochodem funkce s odlišnou sémantikou).

bitcoin_skoleni

Některé možnosti OpenVG si ukážeme příště.

9. Vykreslovací pipeline realizovaná v OpenVG

Podívejme se nyní poněkud podrobněji na způsob realizace vykreslovací pipeline v knihovně OpenVG, protože způsob postupné aplikace jednotlivých operací v pipeline vlastně přímo určuje, jak se budou jednotlivé grafické prvky vykreslovat. Vykreslování probíhá v těchto krocích (které mohou být skutečně prováděny v pipeline za účelem urychlení vykreslování, při softwarové implementaci však pravděpodobně budou prováděny sekvenčně):

  1. Na vstupu do pipeline se nachází informace o grafických objektech, které se mají vykreslit. Jedná se o cesty (path), informace o lineárních transformacích, které se mají provést (transformation), informace o štětcích použitých při vykreslování (stroke) a konečně informace o způsobu vykreslení výplně uzavřených křivek (paint).
  2. Prvním krokem je aplikace štětců (stroke) na cesty (path). Výsledkem je datová struktura popisující vrcholy, které budou následně při vlastní rasterizaci pospojovány. Pokud se má například vykreslit široká úsečka, vznikne aplikací štětce úzký obdélník. V případě čárkované úsečky pak sekvence obdélníků.
  3. Následuje transformace souřadnic vrcholů na základě vstupních informací (transformačních matic). Transformovány jsou samozřejmě vrcholy vypočtené v předchozím kroku. Pod pojmem transformace si můžeme představit především posun, změnu měřítka či otočení (popř. kombinaci těchto transformací).
  4. V dalším kroku je prováděna takzvaná rasterizace, tj. převod geometrického tvaru na pixely. My jsme se již s rasterizací setkali, a to při implementaci algoritmů pro vykreslování úseček. Ovšem vzhledem k podpoře složitějších tvarů v OpenVG jsou zde implementované rasterizační algoritmy složitější, navíc se rasterizace nemusí provádět přímo do framebufferu, ale například do bitmapy uložené v paměti GPU (to z toho důvodu, aby bylo možné aplikovat další tři kroky).
  5. Již během rasterizace popř. v navazujícím kroku se provádí ořezání (clipping) a popř. maskování (masking), opět na základě údajů získaných z uživatelské aplikace (ořezové obdélníky, bitová maska apod.).
  6. Následuje případná výplň uzavřených tvarů (paint). Nejjednodušší výplní je konstantní barva, lze však použít i složitější styl výplně, včetně textur.
  7. Při některých operacích s rastrovými obrázky je nutné aplikovat (bilineární) interpolaci. Jedná se zejména o zvětšení, zmenšení či otočení obrázku před jeho vykreslením do framebufferu.
  8. Poslední operací je blending, tj. aplikace nějaké funkce (například lineární interpolace) na barvy pixelů ve zdrojovém obrázku (získaném rasterizací a vyplněním uzavřených ploch) a v obrázku cílovém (což může být například framebuffer).

10. Odkazy na Internetu

  1. Khronos Group
    https://www.khronos.org/
  2. Khronos Group (Wikipedia)
    https://en.wikipedia.org/wi­ki/Khronos_Group
  3. Raspberry Pi VideoCore APIs
    http://elinux.org/Raspberry_Pi_Vi­deoCore_APIs
  4. Programming AudioVideo on the Raspberry Pi GPU
    https://jan.newmarch.name/RPi/in­dex.html
  5. The Standard for Vector Graphics Acceleration
    https://www.khronos.org/openvg/
  6. OpenVG (Wikipedia)
    https://en.wikipedia.org/wiki/OpenVG
  7. OpenVG Quick Reference Card
    https://www.khronos.org/files/openvg-quick-reference-card.pdf
  8. OpenVG on the Raspberry Pi
    http://mindchunk.blogspot­.cz/2012/09/openvg-on-raspberry-pi.html
  9. ShivaVG: open-source ANSI C OpenVG
    http://ivanleben.blogspot­.cz/2007/07/shivavg-open-source-ansi-c-openvg.html
  10. Testbed for exploring OpenVG on the Raspberry Pi
    https://github.com/ajstarks/openvg
  11. Programovací jazyky a knihovny určené pro výuku základů počítačové grafiky: knihovna Pygame
    http://mojefedora.cz/programovaci-jazyky-a-knihovny-urcene-pro-vyuku-zakladu-pocitacove-grafiky-knihovna-pygame/
  12. Programovací jazyky a knihovny určené pro výuku základů počítačové grafiky: knihovna Pygame prakticky
    http://mojefedora.cz/programovaci-jazyky-a-knihovny-urcene-pro-vyuku-zakladu-pocitacove-grafiky-knihovna-pygame-prakticky/
  13. Programovací jazyky a knihovny určené pro výuku základů počítačové grafiky: práce s bitmapami a TrueType fonty
    http://mojefedora.cz/programovaci-jazyky-a-knihovny-urcene-pro-vyuku-zakladu-pocitacove-grafiky-prace-s-bitmapami-a-truetype-fonty/
  14. Programovací jazyky a knihovny určené pro výuku základů počítačové grafiky: sprity v knihovně Pygame
    http://mojefedora.cz/programovaci-jazyky-a-knihovny-urcene-pro-vyuku-zakladu-pocitacove-grafiky-sprity-v-knihovne-pygame/
  15. Programovací jazyky a knihovny určené pro výuku základů počítačové grafiky: detekce kolize spritů
    http://mojefedora.cz/programovaci-jazyky-a-knihovny-urcene-pro-vyuku-zakladu-pocitacove-grafiky-detekce-kolize-spritu/
  16. Seriál Grafické karty a grafické akcelerátory
    http://www.root.cz/serialy/graficke-karty-a-graficke-akceleratory/
  17. Grafika na osmibitových počítačích firmy Sinclair II
    http://www.root.cz/clanky/grafika-na-osmibitovych-pocitacich-firmy-sinclair-ii/
  18. Xiaolin_Wu's Line Algorithm
    https://en.wikipedia.org/wi­ki/Xiaolin_Wu's_line_algo­rithm
  19. Grafické čipy v osmibitových počítačích Atari
    http://www.root.cz/clanky/graficke-cipy-v-osmibitovych-pocitacich-atari/
  20. Osmibitové počítače Commodore a čip VIC-II
    http://www.root.cz/clanky/osmibitove-pocitace-commodore-a-cip-vic-ii/
  21. Grafika na osmibitových počítačích firmy Apple
    http://www.root.cz/clanky/grafika-na-osmibitovych-pocitacich-firmy-apple/
  22. Počátky grafiky na PC: grafické karty CGA a Hercules
    http://www.root.cz/clanky/pocatky-grafiky-na-pc-graficke-karty-cga-a-hercules/
  23. Karta EGA: první použitelná barevná grafika na PC
    http://www.root.cz/clanky/karta-ega-prvni-pouzitelna-barevna-grafika-na-pc/
  24. Grafické karty MCGA a VGA
    http://www.root.cz/clanky/graficke-karty-mcga-a-vga/
  25. Grafický subsystém počítačů Amiga
    http://www.root.cz/clanky/graficky-subsystem-pocitacu-amiga/
  26. Grafický subsystém počítačů Amiga II
    http://www.root.cz/clanky/graficky-subsystem-pocitacu-amiga-ii/
  27. Raspberry Pi pages
    https://www.raspberrypi.org/
  28. BCM2835 registers
    http://elinux.org/BCM2835_registers
  29. VideoCore (archiv stránek společnosti Alphamosaic)
    http://web.archive.org/web/20030209213838/www­.alphamosaic.com/videocore/
  30. VideoCore (Wikipedia)
    https://en.wikipedia.org/wi­ki/Videocore
  31. RPi lessons: Lesson 6 Screen01
    http://www.cl.cam.ac.uk/pro­jects/raspberrypi/tutorial­s/os/screen01.html
  32. Raspberry Pi forum: Bare metal
    https://www.raspberrypi.or­g/forums/viewforum.php?f=72
  33. C library for Broadcom BCM 2835 as used in Raspberry Pi
    http://www.airspayce.com/mi­kem/bcm2835/
  34. Raspberry Pi Hardware Components
    http://elinux.org/RPi_Har­dware#Components
  35. (Linux) Framebuffer
    http://wiki.linuxquestion­s.org/wiki/Framebuffer
  36. (Linux) Framebuffer HOWTO
    http://tldp.org/HOWTO/Framebuffer-HOWTO/
  37. Linux framebuffer (Wikipedia)
    https://en.wikipedia.org/wi­ki/Linux_framebuffer
  38. RPi Framebuffer
    http://elinux.org/RPi_Framebuffer
  39. HOWTO: Boot your Raspberry Pi into a fullscreen browser kiosk
    http://blogs.wcode.org/2013/09/howto-boot-your-raspberry-pi-into-a-fullscreen-browser-kiosk/
  40. Zdrojový kód fb.c pro RPI
    https://github.com/jncronin/rpi-boot/blob/master/fb.c
  41. RPiconfig
    http://elinux.org/RPi_config.txt
  42. Mailbox framebuffer interface
    https://github.com/raspbe­rrypi/firmware/wiki/Mailbox-framebuffer-interface
  43. Seriál Grafické formáty
    http://www.root.cz/serialy/graficke-formaty/

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.