Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел...
-
Upload
unigine-corp -
Category
Documents
-
view
1.179 -
download
5
description
Transcript of Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел...
Портирование C++ Портирование C++ приложений на FLASCC:приложений на FLASCC:
Опыт Unreal Engine 3Опыт Unreal Engine 3
Павел Наказненко, 2013Павел Наказненко, [email protected]@gmail.com
Это вообще о чем?
О технологии Adobe Flash О том, что такое Alchemy\FLASCC О том, как происходит портирование
на Flash с помощью FLASCC О моей коллекции граблей
Все это на основе опыта портирования Unreal Engine 3
А Вы, собственно, кто?
Павел Наказненко, Красноярск сМагистр в области микропроцессорных
систем Почти Настоящий Сварщик В геймдеве 7 лет Зашипил всякого на мобилы, браузер,
PC, mac, Xbox360, PS3 Работал в США 2 года Руки по локоть в Flash'е
Adobe Flash
Кросс-платформенная технология Большая база пользователей Flash Player – работает как standalone
или как plugin Action Script 3 – ECMAscript 4 AVM2 исполняет файлы SWF (abc-
bytecode)
Adobe Flash 11.4
3D Аппартное ускорение Поддержка шейдеров (AGAL) Многопоточность
С++ → Flash – Зачем?
Есть готовая игра\демо Хочется расширить userbase\привести
траффик Хочется на все платформы И при этом чтоб одна codebase И при этом чтоб с минимальными
затратами
С++ → Flash – Как?
Вручную = долго и дорого Codegen + Flash Wrapper = дорого и
забагованно Как то иначе?
С помощью LLVM!
LLVM – low level virtual machine
Платформонезависимая виртуальная машина с RISC-подобными инструкциями
Link time optimization, Compile time optimization
Куча back-end'ов: x86, x86_64, AMD64, PowerPC, MIPS, целочисленные ARM
Куча front-end'ов: C++, ObjC, Fortran, Ada, Haskell, Java, Python, Ruby, AS3, GLSL, D, Rust и продолжают появляться
Как поможет LLVM?
Компилируем С++ код в промежуточные LLVM инструкции
LLVM тулсет собирает промежуточные файлы под конкретную платформу в родной для платформы машинный код
GCC, Clang
Adobe FLASCC (Alchemy)
Это GCC тулсет с поддержкой LLVM Компилирует C++ в байткод LLVM Производит LLVM compile- and link-time
оптимизацию Собирает LLVM байткод в AVM2 байткод
(ABC) Отдает результат обычному Flash build-
pipeline
Подробнее о FLASCC
GCC based toolset + Cygwin in redist
Кое-что спортировали за вас: SDL, zlib, vorbis ogg, box2d, libqren, Bullet, Lua, итд. (подробнее на сайте Adobe)
Аппаратное ускорение и рендер 3D с помощью вызовов к Stage3D
GLS3D – OpenGL-подобный враппер для Stage3D API
AGAL - HLSL\GLSL-подобный язык шейдеров
Поддерживаются P-threads, OpenMP
Для отладки - GDB
Для профайлинга кода, памяти и Stage3d – Adobe Scout
Портирование на Flash за 7 шагов
1) Скачать FLASCC sdk
2) Прочесть ReadMe
3) С помощью туториалов по I/O, многопоточности и рендеру соорудить каркас
4) Написать makefile
5) Профайлить Scout'ом
6) Использовать GDB для отладки
7) Профит!
Не все так просто
Сырой стек технологий Тулсет часто падает с OutOfMemoryException
при попытке сбилдить debug версию большого проекта (размером с UE3)
Изменил строчку в .cpp = 15 минут жди билд Чуть меньше при -O0
При разных -Ox – разные build pipeline Компилируй в голове! Профайлер очень долго не работал
Не все так просто – часть 2
Портирование происходило на дорелизных версиях FLASCC. Поломки с каждым новым дропом
В AVM2 нет такого понятия как многопоточность
Очень большой оверхед на потоки и memory sharing
Asset Pipeline придется писать свой Надо написать кучу врапперов (RHI, I/O, Net
итд)
VFS или кстати о врапперах
VFS – Virtual File System, унифицированный, POSIX-подобный интерфейс доступа к файлам
Часть стандарта FLASCC sdk Для справки: Flash не может совершать
произвольные I/O операции с локальной файловой системой
Два способа заполнения VFS: embed data и загрузка run-time
VFS или кстати о врапперах, ч. 2
Для общих случаев FLASCC SDK предоставляет свои имлементации (InMemoryBackingStore для Embed, LSOBackingStore для хранения в кеше, HTTPBackingSTore для динамической подгрузки c WWW, итп)
Загрузка происходит в основном потоке, а к файлам обращаются второстепенные потоки
Надо шарить память или перепоручать I\O главному потоку
ES2APIили кстати о врапперах, ч. 3
Оборачивает Stage3D API аля GLES1.0 API
Часть Adobe in-house codebase (публике не доступен)
Все еще в разработке
Сетьили кстати о врапперах, ч. 4
Flash не поддерживает UDP Придется написать UDP over TCP
прослойку, либо менять приложение под TCP
Нет возможности прямого Peer-to-Peer соединения
Cross-domain policy hell
Особенности многопоточности в Adobe
Flash Back-end: Байткод компонуется в отдельный блок,
который запускается на новом фоновом инстансе AVM2.
Front-end C++ : POSIX совместимый интерфейс (pthreads)
Атомики: семейство __sync_***
Front-end AS3: Worker, Mutex, Condition (пакет flash.concurrent)
Flash Player работает в потоке UI (Primordial)
Точка входа в приложение может быть достигнута через: startBackground и startAsync
Моя коллекция граблей Worker не имеет доступа к Stage3d
Worker не может совершать I\O операции с локальной или удаленной файловой системой из-за security sandbox restrictions
Через startBackground точка входа не работает из-за бага с конструкторами статическихобъектов
Доступ к общей памяти через сообщения = сериализовать и десериализовать данные на каждый чих
Костыль: Перепоручение доступа к памяти главному потоку
Моя коллекция граблей – ч. 2 Точка входа через startAsync, а затем создаем поток с
логикой (обход проблемы с startBackground)
Каждое перепоручение команды главному потоку занимает frame interval, т.е. 16ms в среднем
while (true); на главном потоке вешает Flash Player
Чтобы перепоручить главному потоку исполнение команды, ее нужно обернуть:void* function(void *args);
Из за all-purpose встроенного аллокатора сильная фрагментация памяти. Обходится трюком с утечкой памяти
Маленький лимит памяти – около 600 Mb на приложение, 1.4Gb на весь Flash Player (Windows)
Моя коллекция граблей – ч. 3
Нет memory page protection. Т.е. вполне работает: *((int*)0) = 100;
Оверхед на каждый созданный поток в среднем 120 Мб
AlcZIP не освобождает память после декомпрессии
Чтобы профайлить приложение нужно добавлять специальный тег телеметрии сторонним питон скриптом
Отладка (общее) GDB, но только для небольшой codebase Для большой codebase отладочную
версию не собрать. Так что никаких breakpoint, step-by-step и проч.
Множество inline_as3(“trace((new Error()).getStackTrace());\n”);
Включаем мозг. Компилируем в уме (т.к. билд в среднем 15 мин)
Мониторим лог Flash Player с помощью “tail” или подобного, например, “Baretail”
Отладка (render)
Flash Stage3D использует DirectX renderer на Windows
Stage3D API вызовы ≈ DirectX API вызовы
AGAL ≈ HLSL Windows Standalone Flash Player -
обычное DirectX приложение Используйте PIX для отладки рендера!
Профайлинг
Adobe Scout Потребуется -advanced-telemetry флаг.
Раньше нужен был специальный скрипт, сейчас поддерживается компилятором
Позволяет профайлить rendering, memory, calls, display lists и потоки
Часто придется использовать вместо дебаггера
Все так плохо? Таки портировали же:
http://www.unrealengine.com/flash Обещают интеграцию Clang вместо
GCC (читай: будет отладка и нормальный build time)
Выпустили open-source версию FLASCC – CrossBridge. Теперь можно не ныть и править самому. Либо надеяться на community
Есть конкурирующая технология: emscripten
Бонусные ссылки
http://blogs.adobe.com/digitalmedia/2013/06/open-source-flash-c-compiler-crossbridge/
http://www.adobe.com/devnet/games/articles/compiling-opengl-games.html
http://gaming.adobe.com/technologies/flascc/
http://blogs.adobe.com/flascc/
https://github.com/alexmac/alcexamples
https://github.com/alexmac/alcextra
https://github.com/adamcath/telemetry-utils
https://github.com/alexmac/
http://www.baremetalsoft.com/baretail/
Бонусный котейка (за терпение)