GPU Accelerated ускорение в Chrome.
Эта статья содержит справочную и подробную информацию о реализации аппаратного ускорения композиции в Chrome .Традиционно, веб-браузеры полагаются целиком на процессор для отображения содержимого веб-страниц. Cпособность графических процессоров становится неотъемлемой частью даже наименьшего из устройств и с богатыми медиа, таких как видео и 3D-графика и играет всё более важную роль для работы в Сети, разработчики Crome обратили своё внимание на поиск путей более эффективного использования базового оборудования для достижения более высокой производительности и энергосбережения.
Явный признак того, что GPU принимает непосредственное участие в композиции содержания веб-страницы может привести к очень значительным ускорениям. Самые значительные успехи должны были придти от устранения ненужных (и очень медленных) копий больших объемов данных, особенно копии с видео памятью в системную память. Наиболее очевидные кандидаты для такой оптимизации <video> элементы и WebGL, оба из которых могут генерировать свои результаты в области памяти, поэтому процессор не имеет быстрый доступ к ним.
Делегирование композиции на этой странице слоёв GPU обеспечивает и другие преимущества. В большинстве случаев, графический процессор может достичь гораздо большей эффективности, чем процессор (с точки зрения скорости и мощности Draw) в разработке и композиции операций, включающих большое количество пикселей, оборудование, разработанные специально для этих типов рабочих нагрузок.
Основы WebKit .
Исходным кодом для рендеринга WebKit обширный и сложный ( документально!). Для целей настоящего документа я извлеку некоторые важные основные блоки.
Узлы и дерево DOM .
В WebKit, содержание веб-страницы хранится во внутренней памяти в виде дерева объектов Узел называется дерево DOM. Каждый элемент HTML на странице, а также текст, который происходит между элементами связан с узлом. Верхний узел уровня дерева DOM всегда узел документа.
RenderObjects, дерево Render и GraphicsContext
Каждый узел в дереве DOM, который производит визуальный выход имеет соответствующие RenderObject. RenderObject хранится в параллельной структуре дерева, называемого Render дерева. RenderObject означает,что в настоящее время содержимого узла на поверхности дисплея. Он делает это путём выдачи необходимых обратных вызовов, связанных с страницей визуализации GraphicsContext. GraphicsContext в конечном счёте отвечает за написание пикселей на растровом изображении, которое отображается на экране.
RenderLayers
Каждый RenderObject связан с RenderLayer прямо или косвенно через RenderObject. RenderObjects, имеет одни и те же координаты пространства (например, CSS преобразования) обычно принадлежит к той же RenderLayer. RenderLayers существуют так, что элементы страницы собраны в правильном порядке, чтобы правильно отображать перекрывающиеся, полупрозрачные элементы и т. д. В частности в ряду условий, которые будут вызывать создание новых RenderLayer для RenderObject, как это определено inRenderBoxModelObject : requiresLayer будут перезаписаны для некоторых производных классов. В общем RenderObject создают RenderLayer, если:
•Это корневой объекта для страницы
•Это явная CSS позиция свойств (относительное, абсолютное или преобразования)
•Она прозрачна
•С переполнением, маской и альфа отражения
•Соответствует <canvas> элементу, который имеет 3D (WebGL) контекст
•Соответствует <video> элементу
Обратите внимание, что не существует однозначного соответствия между RenderObject и RenderLayer`s. Частности RenderObject связан либо с RenderLayer, что был создан для него, если есть хоть один RenderLayer.
RenderLayers имеет форму дерева иерархии. Корневым узлом является RenderLayer соответствующий корневому элементу страницы и потомкам каждого визуального узла слоев, содержащиеся в родительском слое. Каждый последующий RenderLayer хранится в двух отсортированных списках и отсортированы в порядке возрастания, negZOrderList содержащие первоначальные слои с отрицательной Z-индексацией(и, следовательно, слои, которые идут ниже текущего слоя) и младшие posZOrderList слои containt с положительным Z-индексом ( слои, которые идут выше текущего слоя).
WebKit принципиально делает веб-страницы путём обхода иерархии RenderLayer начиная с корневого слоя. Код WebKit содержит два различных пути кода для сканирования содержания страницы, программное обеспечение и аппаратное ускорение пути. Как следует из названия, аппаратное ускорение нужно, чтобы сделать использование аппаратного ускорения для композиции некоторых из RenderLayer и кода для его жизни за ACCELERATED_COMPOSITING время компиляции флага. В настоящее время Chrome использует программное обеспечение исключительного пути. Safari на Mac (и, скорее всего IOS) аппаратное ускорение пути, которое широко использует собственные CoreAnimation Apple API. Стоит также отметить, что доступны преобразования 3D CSS только с аппаратным ускорением пути, а чисто программная реализация будет существенно замедлена.
Программное обеспечение пути.
В программном обеспечении пути, страница отображает картину последовательно RenderLayers, от задней к передней, прямо в одном растровом назначении. Иерархии RenderLayer проходят рекурсивно, начиная с корней и основная часть работы выполняется в RenderLayer: paintLayer , которая выполняет следующие основные этапы (для ясности список шагов здесь упрощается):
1 Определяет, является ли слой пересекаемым прямоугольником .
2.Делает рекурсивно слои красок ниже по paintLayer для слоев в negZOrderList.
3.Спрашивает RenderObjects, связанные с этим RenderLayer что бы нарисовать себя. Это делается путём рекурсии вниз RenderTree начиная с RenderObject который создал слой. Traversal останавливается, когда RenderObject, связан с различными не найденными RenderLayer.
4.Рекурсивно меняет краски слоев над вызовом paintLayer для слоев в posZOrderList.
RenderObjects окрашивается в пункт растровых назначений путём выдачи обратных слоёв и ставит под общим GraphicsContext (реализована в Chrome через Skia для Win / Linux). Обратите внимание, что GraphicsContext не имеет понятия о слоях, за исключением случая, когда слой полупрозрачный. В этом случае RenderLayer обращается к GraphicsContext: beginTransparencyLayer , прежде чем просить RenderObjects рисовать. В реализации Skia, вызов beginTransparencyLayer вызывает все последующие обращения привлечь для отображения картинки в отдельном растровом изображении, которое получается в композиции с исходным слоем, когда слой рисунка, является полным и соответствует вызову endTransparencyLayer который производится GraphicsLayer.
Аппаратное ускорение пути.
Разница между аппаратным ускорением пути и программным обеспечением пути в том, что, когда аппаратное ускорение включено, некоторые (но не все) RenderLayer получают свою собственную поверхность поддержку (композиционный слой), в котором они рисуют вместо рисования непосредственно в общем растровом на странице. Последующие композиции композитов пройдут поддержку поверхностей на назначение растрового изображения. Наборщик несёт ответственность за применение необходимых преобразований (как указано в свойства слоя CSS преобразованиях) для каждой растровой композиции. Так как картина слоёв отделена от композиции, недействительности одного из этих слоев только результаты для перекраски содержимого этого слоя в одиночку и recompositing. В противоположность этому, с программным обеспечением пути, недействительности любого слоя требуют перекраску всех слоёв (по крайней мере части перекрытия из них) ниже и выше которой излишняя нагрузка на процессор.
Хотя теоретически каждый RenderLayer может сам красить отдельные поверхности, чтобы избежать ненужной перерисовки, на практике это может быть довольно расточительно с точки зрения памяти (особенно VRAM). В текущей реализации WebKit, для RenderLayer должны быть выполнены одни из следующих условий, чтобы получить свои композиции слоя (см. RenderLayerCompositor: requiresCompositingLayer ):
1.Слой имеет 3D или перспективы преобразования CSS свойств
2.Слой использует элементы <video> с помощью ускоренного декодирования видео
3.Слой использует элемент <canvas> с 3D контекстом
4.Слой использует CSS анимацию для его непрозрачности или использует анимированные WebKit преобразования
5 Слой имеет композиции слоя
6.Слой имеет нижний Z-индекс, который имеет композиции слоя (другими словами слой оказывается на верхней части собранного слоя)
Для реализации существенного ускорения WebKit нужно:
•Даже включенным аппаратным ускорением, страницы, которые не содержат <video> или WebGL элементы и не используют 3D CSS преобразования / анимацию использование программного обеспечения пути.
•Страницы с собранным RenderLayer будут всегда работать через композиции.
H / W ускорение.
Кодекс, связанный с композициями живёт внутри WebCore, используя (ACCELERATED_COMPOSITING). Часть кода является общей для всех платформ и конкретно часть Chrome. К счастью, код WebKit структурирован так, что осуществление композиции для Chrome не требует никаких изменений в основном коде WebKit и все Chrome имеют конкретный код приведённый в платформы исходных файлов, которые живут в платформе / Графика / Chrome так же, как сделано с GraphicsContext и GraphicsContextSkia.
Ускоренная композиция, в целях устранения дорогостоящей памяти,переводится окончательно в рендеринг на вкладке области браузера и обрабатывается непосредственно на GPU. Это существенно отличается от текущей модели, в которой процесс проходит Renderer (через МПК и разделяемую память) над растровым изображением содержимого страницы, чтобы браузер отображал процесс:
С текущим ООН-ускорениме осуществляются композиции из RenderLayer и занимают место в коде WebKit (через Skia или CG). В архитектуре H / W ускорения, композиции из H / W ускоренных слоёв смешиваются с остальным содержимым страницы происходит обращение к GPU на платформе 3D API (GL / D3D). Код в конечном счёте, отвечает за принятие этих вызовов заключённых в библиотеке и работает внутри процесса Renderer. Библиотека существенно повышает использование GPU для композитных прямоугольных областей страницы в одном растрового изображения.
Процесс GPU.
Ограниченный в sandbox , процесс Renderer (где находятся WebKit и композитор) не может быть требованием к 3D API, предоставляемых ОС (GL/D3D). По этой причине мы используем отдельный процесс, чтобы сделать рендеринг. Мы называем этот процесс GPU процессом. GPU процесс специально предназначен для обеспечения доступа к 3D API-интерфейсу системы изнутри sandbox Renderer.Он работает с помощью модели клиент-сервер с клиентом во время выполнения программы, работающей в ограниченной среде и серверным кодом, который фактически делает обращения к графике API, которая работает следующим образом:
•клиент (программы, работающие в Renderer или внутри модуля NaCl), вместо выдачи обращений к системе API, сериализует их и помещает в кольцевой буфер (Ctrl буфера), находящихся в памяти, совместно используемыми между собой и процессом сервера.
•Сервер (GPU процесс, запущенный с меньшим ограничением sandbox, что позволяет получить доступ к платформе 3D API,) поднимает сериализованные команды из общей памяти, анализирует их и выполняет соответствующие вызовы графики, выводя их непосредственно в окне.
Команды принятые GPU процессом тесно связаны с GL ES 2.0 API (например, есть команда соответствующая glClear, от одного до другого glDrawArrays и т.д.). Так как большинство GL обращений не возвращают значения, клиент и сервер могут работать в основном асинхронно,это содержит расходы процесса на низком уровне. Вся необходимая синхронизация между клиентом и сервером, такие как уведомления клиент сервера, есть дополнительная работа, которую предстоит сделать, осуществляется через механизм IPC. Стоит также отметить, что в дополнение для хранения общей памяти буфера команд, используется для передачи больших ресурсов, таких как растровые изображения для текстур, вершины массивов и т.д. между клиентом и сервером. С точки зрения клиента, приложение имеет возможность либо писать команды непосредственно в команду буфера или использовать GL ES 2.0 API с помощью библиотеки на стороне клиента, которые мы предоставляем и который обрабатывает сериализации.Для удобства WebGL в настоящее время используется клиентом GL ES библиотеки. На стороне сервера, команды, полученные с помощью буфера команд преобразуются в обращения к любому рабочему столу GL (на Mac и Linux) или D3D (в окнах).
В настоящее время Chrome использует единый процесс GPU в браузере, например, запросы от всех процессов визуализации и любой процесс выполнения плагинов. GPU процесс однопоточный, его можно мультиплексировать между несколькими буферами команд, каждая из которых связана с её собственным контекстом рендеринга.
Архитектура GPU процесса предлагает несколько преимуществ, включая:
•Безопасность: часть логики остаётся в изолированных процессах рендеринга.
•Надежность: аварии GPU процесса (например, из-за неисправных драйверов) не сбивают браузер.
•Однородность: Стандартизация на OpenGL ES 2.0 в качестве оказания API для браузера независимо от платформы позволяет быть проще в обслуживании кода по всем портам ОС Chrome.
Наборщик кода
Основная часть кода Chrome для осуществления композиции находится в платформе WebCore`s / Графика / Chrome каталога. Логика композиции в основном в LayerRendererChromium.cpp и реализация различных типов собранного слоя в {Содержание | Видео | Фото} файлов LayerChromium.cpp. Набор осуществляется в верхней части GL ES 2.0 клиентской библиотеки, которая использует прокси графики вызова GPU процесса.
Все пиксели страницы рисуются прямо в окне с помощью GPU процесса. Наборщик поддерживает иерархию GraphicsLayers которая строится путем обхода дерева RenderLayer и обновляется по мере изменения страницы. За исключением WebGL и видео слоев, содержание каждого из слоя сначала обращается в растровом изображении системной памяти, а затем загружается в текстуру. Наборщик отслеживает, какие слои были изменены с момента последнего времени когда они были составлены и обновляет текстуры по мере необходимости. Содержание страницы делается после первого обхода иерархии GraphicsLayer и рисования текстур Quad для каждого слоя с соответствующим преобразованием.
Как минимум один графический контекст, при выполнении H / W ускорения, GPU процесс, используется в наборщике. Но, в присутствии GPU-ускоренного содержания страницы (например, WebGL или Pepper3D плагин), GPU процесс должен быть в состоянии жонглировать mutliple в контекстах графики, каждый из которых связан со своим собственным буфером команд, в общей памяти IPC канала и контекста GL. Состав GraphicsLayers, содержимое которых создаётся непосредственно на GPU работает так, что вместо них оказывается прямо в backbuffer,в котором они превращаются в текстуру (с использованием Frame Buffer Object), который контекст хватает и использует при рендеринге слоя. Важно отметить, что для того, чтобы GL контекст имел доступ к текстуре порожденной закадровым контекстом GL, GL всех контекстов должен использовать GPU процесс при котором создаются такие ресурсы. В результате архитектура выглядит следующим образом:
Используйте — включить ускорение композиции флага в командной строке, с тем чтобы наборщик сработал на любой из трёх платформ и вверху страницы Как упоминалось ранее, ускорение в WebKit (и Chrome) умирает только тогда, когда есть определенные типы контента на странице. Лёгкий трюк, чтобы заставить страницы перейти к композиции является установка WebKit-преобразования: translateZ (0) для элемента на странице.