Zásuvný modul prohlížeče pro Unity

Vývojové nástroje a engine Unity jsou dnes zdaleka nejrozšířenějším způsobem vytváření aplikací pro VR a AR. Již dříve jsme umožnili exportovat webové zážitky z Unity. Dnes bychom rádi ukázali několik prvních prací, které se zabývají dalším způsobem, jakým chtějí vývojáři Unity používat web: jako komponentu ve svých virtuálních prostředích založených na Unity.

V návaznosti na naši práci na portování enginu prohlížeče na mnoho platforem a scénářů vkládání, včetně jako Firefox Reality AR pro HoloLens 2, jsme vytvořili novou komponentu Unity založenou na Servo, moderním webovém enginu napsaném v jazyce Rust.

Engin Unity má velmi přizpůsobivý multiplatformní systém zásuvných modulů se zdravým ekosystémem zásuvných modulů třetích stran, a to jak open-source, tak proprietárních. Systém zásuvných modulů nám umožňuje spouštět moduly nativní pro operační systém a připojovat je přímo ke komponentám spouštěným ve skriptovacím prostředí Unity.

Cílem experimentů bylo vytvořit nativní zásuvný modul Unity a sadu skriptovacích komponent Unity C#, které by třetím stranám umožnily začlenit okna prohlížeče Servo do scén Unity a případně poskytnout podporu pro používání povrchu prohlížeče v aplikacích VR a AR vytvořených v Unity.

Dnes vydáváme plně funkční prototyp webového prohlížeče Servo běžícího uvnitř zásuvného modulu Unity. Jedná se o rané stádium naší práce, ale víme, že nadšení pro tento druh řešení je velké, takže doufáme, že tento prototyp vyzkoušíte, poskytnete nám zpětnou vazbu a připojíte se k nám při vytváření věcí s jeho pomocí. Dnes vydaná verze se zaměřuje na platformu macOS, ale brzy přidáme některé z dalších platforem podporovaných systémem Servo.

Začínáme

Zásuvný modul jsme otevřeli jako zdrojový kód, na adrese https://github.com/MozillaReality/servo-unity. Přejděte tam, klikněte na hvězdičku a forkněte kód, vyzkoušejte jej na svém lokálním počítači a poté otevřete projekt uvnitř Unity.

Pokyny pro vývojáře najdete v souboru README v úložišti.

Co to dělá

Můžete pracovat přímo s oknem prohlížeče a ovládacími prvky uvnitř editoru Unity. Konfigurace nejvyšší úrovně je na objektu ServoUnityController. Mezi další důležité objekty ve scéně patří ServoUnityWindow, ServoUnityNavbarController a ServoUnityMousePointer.

Objekt ServoUnityWindow lze umístit kamkoli ve scéně Unity. Zde jsme ji umístili do houbové jeskyně Mozilla (kterou znají uživatelé Firefoxu Reality od úžasné umělkyně Jasmin Habezai-Fekri) a opatřili ji manipulátorem kamery, který nám umožňuje pohybovat se po scéně a vidět, že se jedná o 3D zobrazení obsahu prohlížeče.

Servo má kvalitní přehrávání médií prostřednictvím frameworku GStreamer, včetně podpory zvuku. Zde si prohlížíme ukázkové video ve formátu MPEG4, které běží uvnitř nasazeného sestavení přehrávače Unity.

Součástí zásuvného modulu je přizpůsobitelné vyhledávání. V současné verzi Serva lze zobrazit širokou škálu webového obsahu, přičemž na větší kompatibilitě s webem se aktivně pracuje (více o tom níže). Funguje i webový obsah ve formátu WebGL.

Jak to funguje

Architektura

Vývoj v Unity využívá architekturu založenou na komponentách, kdy Unity spouští uživatelský kód připojený k GameObjectsubjektům uspořádaným do scén. Uživatelé přizpůsobují GameObjects připojením skriptů, které se spouštějí v prostředí C#, a to buď pomocí běhového prostředí Mono, nebo kompilátoru IL2CPP ahead-of-time. Životní cyklus událostí Unity je přístupný uživatelským skriptům, které dědí ze třídy Unity C# MonoBehaviour. Uživatelské skripty mohou vyvolávat nativní kód v zásuvných modulech (což jsou pouze dynamické sdílené objekty v operačním systému) prostřednictvím mechanismu P/Invoke běhového prostředí C#. Ve skutečnosti je samotné jádro Unity implementováno v jazyce C++ a poskytuje nativnímu kódu v zásuvných modulech druhou sadu rozhraní přístupných v jazyce C/C++, která pomáhají při některých nízkoúrovňových úlohách zásuvných modulů.

Servo je samo o sobě složitý kus softwaru. Podle návrhu je většina jeho funkcí, které nesměřují k uživateli, zkompilována do knihovny Rust, libservo. Pro tuto první fázi projektu využíváme zjednodušené rozhraní kompatibilní s jazykem C v jiné knihovně Rust s názvem libsimpleservo2. Tato knihovna vystavuje funkce volatelné v jazyce C a háčky zpětného volání pro ovládání prohlížeče a zobrazování jeho výstupu. Kolem libsimpleservo2 zavádíme nativní abstrakce C++, které zapouzdřují model vláken a vykreslování Unity a vystavují sadu rozhraní volatelných Unity, které jsou zase obsluhovány našimi komponentami skriptů C#.

Získání obsahu prohlížeče do Unity

Vytvoříme objekt v Unity, instanci ServoUnityWindow, která obalí instanci třídy Unity Texture2D a bude s ní zacházet jako s panelem obsahu prohlížeče. Při použití vykreslovače Unity OpenGL je třída Texture2D podpořena nativní texturou OpenGL a my předáme „jméno“ textury OpenGL (tj. ID) zásuvnému modulu, který texturu naváže na objekt framebufferu, který obdrží finální složenou texturu ze Serva.

Jelikož nemáme kontrolu nad vazbou textury a kontextu Unity, současný návrh aktualizace této textury používá blit (kopírování) prostřednictvím rozhraní API Servo surfman-chains. V podstatě WebRender Servo zapisuje do vyrovnávací paměti povrchu specifické pro operační systém v jednom vlákně a poté je tato vyrovnávací paměť povrchu vázána pouze pro čtení na vykreslovací vlákno Unity a pomocí rozhraní API OpenGL je vytvořena kopie textury. Například v původní implementaci pro macOS je vyrovnávací paměť povrchu IOSurface, kterou lze s nulovými náklady přesouvat mezi vlákny, což umožňuje efektivní implementaci, kdy kompozitor prohlížeče může zapisovat v jiném vlákně než vlákno zobrazující texturu v Unity.

Metadata ovládání a stránky se komunikují odděleně, prostřednictvím sady rozhraní API, která umožňují vyhledávání a navigaci na adresy URL, aktualizaci nadpisů stránek a obvyklou sadu tlačítek zpět/vpřed/zastavit/domů.

Protože obsah prohlížeče a ovládací prvky jsou v konečném důsledku objekty Unity, může je vytvářená aplikace Unity libovolným způsobem umisťovat, stylizovat nebo programově ovládat.

Výzvy

Dostat projekt do této fáze se neobešlo bez problémů, z nichž některé stále řešíme. Skriptovací prostředí Unity běží z velké části jednovláknově, s výjimkou vykreslovacích operací, které probíhají v samostatném vlákně na jiné kadenci. Servo však vytváří potenciálně desítky odlehčených vláken pro nejrůznější úlohy. Postarali jsme se o to, aby se vracení pracovních položek ze Serva vrátilo zpět do správných vláken v Unity. Zbývá ještě provést několik optimalizací při rozhodování o tom, kdy obnovit texturu Unity. V současné době se prostě obnovuje každý snímek, ale do rozhraní pro vkládání přidáváme rozhraní API, které umožní jemnější kontrolu.

Jako inkubátor pro technologie prohlížeče se Servo zaměřuje na vývoj nových technologií. Mezi významné technologie, které přešly ze Serva do jádra Gecko pohánějícího Firefox, patří vykreslovací jádro WebRender založené na GPU a jádro CSS Stylo. Nehledě na tyto úspěchy je plná kompatibilita s webem stále oblastí, kde má Servo značnou mezeru, protože jsme se zaměřili především na velká vylepšení pro uživatele a specifické zážitky na dlouhém chvostu webu. Nedávné úsilí komunity Serva přineslo velký pokrok ve webové kompatibilitě Serva, takže očekáváme, že podmnožina webu prohlížená Servem bude i nadále rychle růst.

Plány vývoje

Podpora celé řady platforem, které Servo v současné době podporuje, je naší první následnou prioritou vývoje, přičemž podpora Windows Win32 a Windows UWP je na prvním místě seznamu. Mnozí z vás viděli naši aplikaci Firefox Reality AR pro HoloLens 2 a podpora UWP vám umožní zabudovat Servo do vlastních AR aplikací pro platformu HoloLens s využitím stejného základního enginu prohlížeče.

Rádi bychom také podporovali větší podmnožinu plných možností prohlížeče. Vysoko na seznamu je podpora více oken. V současné době pracujeme na odstupňování zásuvného modulu z rozhraní libsimpleservo2 na nové rozhraní, které umožní aplikacím instancovat více oken, záložek a implementovat funkce, jako je historie, záložky a další.

Tato první verze je zaměřena na prohlížení webu prostřednictvím 2D webových stránek. Servo také podporuje imerzivní web prostřednictvím rozhraní WebXR API a zkoumáme možnost propojení WebXR s podporou hardwaru XR v Unity prostřednictvím rozhraní zásuvného modulu. Začneme s podporou prohlížení 360° videa, o kterém víme od našich uživatelů Firefoxu Reality, že je pro prohlížeč hlavním případem použití.

Konečně…

Ať už se jedná o přehrávač médií, herní rozhraní k otevřenému webu, prohlížeč jako uživatelské rozhraní, přinášení specifických webových zážitků nebo nespočet dalších možností, nemůžeme se dočkat, až uvidíme některé z nápaditých způsobů, jak vývojáři využijí sílu a výkon Serva uvnitř aplikací vytvořených v Unity.