Павел Наказненко, разработчик, freelance (Красноярск)
На основе нашего опыта портирования Unreal Engine 3 и Free Heroes 2 на Flash, расскажу немного о технологии FLASCC, а также тонкостях портирования С++ игр с помощью нее.
Разработка мультиплатформенных 3D игр (Unigine, CodeFest2012)
Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013.
1. Портирование C++Портирование C++
приложений на FLASCC:приложений на FLASCC:
Опыт Unreal Engine 3Опыт Unreal Engine 3
Павел Наказненко, 2013Павел Наказненко, 2013
p.nakaznenko@gmail.comp.nakaznenko@gmail.com
2. Это вообще о чем?
О технологии Adobe Flash
О том, что такое AlchemyFLASCC
О том, как происходит портирование
на Flash с помощью FLASCC
О моей коллекции граблей
Все это на основе опыта
портирования Unreal Engine 3
3. А Вы, собственно, кто?
Павел Наказненко, Красноярск
сМагистр в области микропроцессорных
систем
Почти Настоящий Сварщик
В геймдеве 7 лет
Зашипил всякого на мобилы, браузер,
PC, mac, Xbox360, PS3
Работал в США 2 года
Руки по локоть в Flash'е
5. Adobe Flash 11.4
3D Аппартное ускорение
Поддержка шейдеров (AGAL)
Многопоточность
6. С++ → Flash – Зачем?
Есть готовая иградемо
Хочется расширить userbaseпривести
траффик
Хочется на все платформы
И при этом чтоб одна codebase
И при этом чтоб с минимальными
затратами
7. С++ → Flash – Как?
Вручную = долго и дорого
Codegen + Flash Wrapper = дорого и
забагованно
Как то иначе?
9. 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 и продолжают появляться
10. Как поможет LLVM?
Компилируем С++ код в промежуточные
LLVM инструкции
LLVM тулсет собирает промежуточные
файлы под конкретную платформу в
родной для платформы машинный код
GCC, Clang
11. Adobe FLASCC (Alchemy)
Это GCC тулсет с поддержкой LLVM
Компилирует C++ в байткод LLVM
Производит LLVM compile- and link-time
оптимизацию
Собирает LLVM байткод в AVM2 байткод
(ABC)
Отдает результат обычному Flash build-
pipeline
12. Подробнее о FLASCC
GCC based toolset + Cygwin in redist
Кое-что спортировали за вас: SDL, zlib, vorbis ogg, box2d,
libqren, Bullet, Lua, итд.
(подробнее на сайте Adobe)
Аппаратное ускорение и рендер 3D с помощью вызовов к
Stage3D
GLS3D – OpenGL-подобный враппер для Stage3D API
AGAL - HLSLGLSL-подобный язык шейдеров
Поддерживаются P-threads, OpenMP
Для отладки - GDB
Для профайлинга кода, памяти и Stage3d – Adobe Scout
13. Портирование на Flash
за 7 шагов
1) Скачать FLASCC sdk
2) Прочесть ReadMe
3) С помощью туториалов по
I/O, многопоточности и
рендеру соорудить каркас
4) Написать makefile
5) Профайлить Scout'ом
6) Использовать GDB для
отладки
7) Профит!
14.
15. Не все так просто
Сырой стек технологий
Тулсет часто падает с OutOfMemoryException
при попытке сбилдить debug версию большого
проекта (размером с UE3)
Изменил строчку в .cpp = 15 минут жди билд
Чуть меньше при -O0
При разных -Ox – разные build pipeline
Компилируй в голове!
Профайлер очень долго не работал
16. Не все так просто – часть 2
Портирование происходило на дорелизных
версиях FLASCC. Поломки с каждым новым
дропом
В AVM2 нет такого понятия как
многопоточность
Очень большой оверхед на потоки и memory
sharing
Asset Pipeline придется писать свой
Надо написать кучу врапперов (RHI, I/O, Net
итд)
17. VFS
или кстати о врапперах
VFS – Virtual File System,
унифицированный, POSIX-подобный
интерфейс доступа к файлам
Часть стандарта FLASCC sdk
Для справки: Flash не может совершать
произвольные I/O операции с локальной
файловой системой
Два способа заполнения VFS: embed
data и загрузка run-time
18. VFS
или кстати о врапперах, ч. 2
Для общих случаев FLASCC SDK
предоставляет свои имлементации
(InMemoryBackingStore для Embed,
LSOBackingStore для хранения в кеше,
HTTPBackingSTore для динамической
подгрузки c WWW, итп)
Загрузка происходит в основном потоке, а к
файлам обращаются второстепенные потоки
Надо шарить память или перепоручать IO
главному потоку
19. ES2API
или кстати о врапперах, ч. 3
Оборачивает Stage3D API аля GLES1.0
API
Часть Adobe in-house codebase (публике
не доступен)
Все еще в разработке
20. Сеть
или кстати о врапперах, ч. 4
Flash не поддерживает UDP
Придется написать UDP over TCP
прослойку, либо менять приложение
под TCP
Нет возможности прямого Peer-to-Peer
соединения
Cross-domain policy hell
21. Особенности
многопоточности в 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
22. Моя коллекция граблей
Worker не имеет доступа к Stage3d
Worker не может совершать IO операции с
локальной или удаленной файловой системой
из-за security sandbox restrictions
Через startBackground точка входа не работает
из-за бага с конструкторами статических
объектов
Доступ к общей памяти через сообщения =
сериализовать и десериализовать данные на
каждый чих
Костыль: Перепоручение доступа к памяти
главному потоку
23. Моя коллекция граблей – ч. 2
Точка входа через startAsync, а затем создаем поток с
логикой (обход проблемы с startBackground)
Каждое перепоручение команды главному потоку занимает
frame interval, т.е. 16ms в среднем
while (true); на главном потоке вешает Flash Player
Чтобы перепоручить главному потоку исполнение команды,
ее нужно обернуть:
void* function(void *args);
Из за all-purpose встроенного аллокатора сильная
фрагментация памяти. Обходится трюком с утечкой памяти
Маленький лимит памяти – около 600 Mb на приложение,
1.4Gb на весь Flash Player (Windows)
24. Моя коллекция граблей – ч. 3
Нет memory page protection. Т.е. вполне работает:
*((int*)0) = 100;
Оверхед на каждый созданный поток в среднем 120
Мб
AlcZIP не освобождает память после декомпрессии
Чтобы профайлить приложение нужно добавлять
специальный тег телеметрии сторонним питон
скриптом
25. Отладка (общее)
GDB, но только для небольшой
codebase
Для большой codebase отладочную
версию не собрать. Так что никаких
breakpoint, step-by-step и проч.
Множество inline_as3(“trace((new
Error()).getStackTrace());n”);
Включаем мозг. Компилируем в уме (т.к.
билд в среднем 15 мин)
Мониторим лог Flash Player с помощью
“tail” или подобного, например, “Baretail”
26. Отладка (render)
Flash Stage3D использует DirectX
renderer на Windows
Stage3D API вызовы ≈ DirectX API
вызовы
AGAL ≈ HLSL
Windows Standalone Flash Player -
обычное DirectX приложение
Используйте PIX для отладки рендера!
27. Профайлинг
Adobe Scout
Потребуется -advanced-telemetry флаг.
Раньше нужен был специальный скрипт,
сейчас поддерживается компилятором
Позволяет профайлить rendering,
memory, calls, display lists и потоки
Часто придется использовать вместо
дебаггера
28.
29. Все так плохо?
Таки портировали же:
http://www.unrealengine.com/flash
Обещают интеграцию Clang вместо
GCC (читай: будет отладка и
нормальный build time)
Выпустили open-source версию FLASCC
– CrossBridge. Теперь можно не ныть и
править самому. Либо надеяться на
community
Есть конкурирующая технология:
emscripten