Портирование c++ приложений на flascc: опыт unreal engine 3. Павел...

Post on 15-Jun-2015

1.173 Views

Category:

Documents

5 Downloads

Preview:

Click to see full reader

DESCRIPTION

Павел Наказненко, разработчик, freelance (Красноярск) На основе нашего опыта портирования Unreal Engine 3 и Free Heroes 2 на Flash, расскажу немного о технологии FLASCC, а также тонкостях портирования С++ игр с помощью нее.

TRANSCRIPT

Портирование C++ Портирование C++ приложений на FLASCC:приложений на FLASCC:

Опыт Unreal Engine 3Опыт Unreal Engine 3

Павел Наказненко, 2013Павел Наказненко, 2013p.nakaznenko@gmail.comp.nakaznenko@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/

Бонусный котейка (за терпение)

top related