31
Портирование C++ Портирование C++ приложений на FLASCC: приложений на FLASCC: Опыт Unreal Engine 3 Опыт Unreal Engine 3 Павел Наказненко, 2013 Павел Наказненко, 2013 [email protected] [email protected]

Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

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

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

Павел Наказненко, 2013Павел Наказненко, [email protected]@gmail.com

Page 2: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Это вообще о чем?

О технологии Adobe Flash О том, что такое Alchemy\FLASCC О том, как происходит портирование

на Flash с помощью FLASCC О моей коллекции граблей

Все это на основе опыта портирования Unreal Engine 3

Page 3: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

А Вы, собственно, кто?

Павел Наказненко, Красноярск сМагистр в области микропроцессорных

систем Почти Настоящий Сварщик В геймдеве 7 лет Зашипил всякого на мобилы, браузер,

PC, mac, Xbox360, PS3 Работал в США 2 года Руки по локоть в Flash'е

Page 4: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Adobe Flash

Кросс-платформенная технология Большая база пользователей Flash Player – работает как standalone

или как plugin Action Script 3 – ECMAscript 4 AVM2 исполняет файлы SWF (abc-

bytecode)

Page 5: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Adobe Flash 11.4

3D Аппартное ускорение Поддержка шейдеров (AGAL) Многопоточность

Page 6: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

С++ → Flash – Зачем?

Есть готовая игра\демо Хочется расширить userbase\привести

траффик Хочется на все платформы И при этом чтоб одна codebase И при этом чтоб с минимальными

затратами

Page 7: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

С++ → Flash – Как?

Вручную = долго и дорого Codegen + Flash Wrapper = дорого и

забагованно Как то иначе?

Page 8: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

С помощью LLVM!

Page 9: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

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 и продолжают появляться

Page 10: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Как поможет LLVM?

Компилируем С++ код в промежуточные LLVM инструкции

LLVM тулсет собирает промежуточные файлы под конкретную платформу в родной для платформы машинный код

GCC, Clang

Page 11: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Adobe FLASCC (Alchemy)

Это GCC тулсет с поддержкой LLVM Компилирует C++ в байткод LLVM Производит LLVM compile- and link-time

оптимизацию Собирает LLVM байткод в AVM2 байткод

(ABC) Отдает результат обычному Flash build-

pipeline

Page 12: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Подробнее о 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

Page 13: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Портирование на Flash за 7 шагов

1) Скачать FLASCC sdk

2) Прочесть ReadMe

3) С помощью туториалов по I/O, многопоточности и рендеру соорудить каркас

4) Написать makefile

5) Профайлить Scout'ом

6) Использовать GDB для отладки

7) Профит!

Page 14: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013
Page 15: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Не все так просто

Сырой стек технологий Тулсет часто падает с OutOfMemoryException

при попытке сбилдить debug версию большого проекта (размером с UE3)

Изменил строчку в .cpp = 15 минут жди билд Чуть меньше при -O0

При разных -Ox – разные build pipeline Компилируй в голове! Профайлер очень долго не работал

Page 16: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Не все так просто – часть 2

Портирование происходило на дорелизных версиях FLASCC. Поломки с каждым новым дропом

В AVM2 нет такого понятия как многопоточность

Очень большой оверхед на потоки и memory sharing

Asset Pipeline придется писать свой Надо написать кучу врапперов (RHI, I/O, Net

итд)

Page 17: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

VFS или кстати о врапперах

VFS – Virtual File System, унифицированный, POSIX-подобный интерфейс доступа к файлам

Часть стандарта FLASCC sdk Для справки: Flash не может совершать

произвольные I/O операции с локальной файловой системой

Два способа заполнения VFS: embed data и загрузка run-time

Page 18: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

VFS или кстати о врапперах, ч. 2

Для общих случаев FLASCC SDK предоставляет свои имлементации (InMemoryBackingStore для Embed, LSOBackingStore для хранения в кеше, HTTPBackingSTore для динамической подгрузки c WWW, итп)

Загрузка происходит в основном потоке, а к файлам обращаются второстепенные потоки

Надо шарить память или перепоручать I\O главному потоку

Page 19: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

ES2APIили кстати о врапперах, ч. 3

Оборачивает Stage3D API аля GLES1.0 API

Часть Adobe in-house codebase (публике не доступен)

Все еще в разработке

Page 20: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Сетьили кстати о врапперах, ч. 4

Flash не поддерживает UDP Придется написать UDP over TCP

прослойку, либо менять приложение под TCP

Нет возможности прямого Peer-to-Peer соединения

Cross-domain policy hell

Page 21: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Особенности многопоточности в 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

Page 22: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Моя коллекция граблей Worker не имеет доступа к Stage3d

Worker не может совершать I\O операции с локальной или удаленной файловой системой из-за security sandbox restrictions

Через startBackground точка входа не работает из-за бага с конструкторами статическихобъектов

Доступ к общей памяти через сообщения = сериализовать и десериализовать данные на каждый чих

Костыль: Перепоручение доступа к памяти главному потоку

Page 23: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Моя коллекция граблей – ч. 2 Точка входа через startAsync, а затем создаем поток с

логикой (обход проблемы с startBackground)

Каждое перепоручение команды главному потоку занимает frame interval, т.е. 16ms в среднем

while (true); на главном потоке вешает Flash Player

Чтобы перепоручить главному потоку исполнение команды, ее нужно обернуть:void* function(void *args);

Из за all-purpose встроенного аллокатора сильная фрагментация памяти. Обходится трюком с утечкой памяти

Маленький лимит памяти – около 600 Mb на приложение, 1.4Gb на весь Flash Player (Windows)

Page 24: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Моя коллекция граблей – ч. 3

Нет memory page protection. Т.е. вполне работает: *((int*)0) = 100;

Оверхед на каждый созданный поток в среднем 120 Мб

AlcZIP не освобождает память после декомпрессии

Чтобы профайлить приложение нужно добавлять специальный тег телеметрии сторонним питон скриптом

Page 25: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Отладка (общее) GDB, но только для небольшой codebase Для большой codebase отладочную

версию не собрать. Так что никаких breakpoint, step-by-step и проч.

Множество inline_as3(“trace((new Error()).getStackTrace());\n”);

Включаем мозг. Компилируем в уме (т.к. билд в среднем 15 мин)

Мониторим лог Flash Player с помощью “tail” или подобного, например, “Baretail”

Page 26: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Отладка (render)

Flash Stage3D использует DirectX renderer на Windows

Stage3D API вызовы ≈ DirectX API вызовы

AGAL ≈ HLSL Windows Standalone Flash Player -

обычное DirectX приложение Используйте PIX для отладки рендера!

Page 27: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Профайлинг

Adobe Scout Потребуется -advanced-telemetry флаг.

Раньше нужен был специальный скрипт, сейчас поддерживается компилятором

Позволяет профайлить rendering, memory, calls, display lists и потоки

Часто придется использовать вместо дебаггера

Page 28: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013
Page 29: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Все так плохо? Таки портировали же:

http://www.unrealengine.com/flash Обещают интеграцию Clang вместо

GCC (читай: будет отладка и нормальный build time)

Выпустили open-source версию FLASCC – CrossBridge. Теперь можно не ныть и править самому. Либо надеяться на community

Есть конкурирующая технология: emscripten

Page 30: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

Бонусные ссылки

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/

Page 31: Портирование C++ приложений на FLASCC: опыт Unreal Engine 3. Павел Наказненко. Unigine Open Air 2013

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