- Русские Блоги
- SurfaceFlinger и хореограф в Android
- SurfaceFlinger
- запускать
- Генерация и распространение VSYNC
- VSYNC прием
- Choreographer
- подводить итоги
- Android SurfaceFlinger
- ОТВЕТЫ
- Ответ 1
- Ответ 2
- Ответ 3
- Русские Блоги
- Android Surfaceflinger Research-Surface механизм
- 1. Поверхностный механизм статического взаимодействия
- 1.1 ViewRoot и WMS совместно используют поверхность
- 1.2SurfaceSession
- 1.3 Форма поверхности
- 1.3.1 Форма клиентской поверхности
- 1.3.2 SurfaceFlinger Surface
- 1.4 Layer
- 1.4.1 Классификация слоев
- 1.4.2 Управление слоями
- 2. Поверхностное управление хранением буфера дисплея
- 2.1 окно рисования
- 2.2 Инициализация поверхности клиента
- 2.2.1SharedClient
- 2.2.2 SharedBufferStack
- 2.2.3 Запрос клиента Surace GraphicBuffer
Русские Блоги
SurfaceFlinger и хореограф в Android
SurfaceFlinger и Choreographer являются основными частями графической системы Android. Они оба являются подписчиками сигнала VSYNC; SurfaceFlinger интегрирует различные источники данных, которые он получает, и, наконец, обновляет буфер кадра для отображения; а Choreographer, наконец, отправляет сообщение в ViewRootImpl для измерения интерфейса. и рисовать и т. д.
SurfaceFlinger
SurfaceFlinger’s role is to accept buffers of data from multiple sources, composite them, and send them to the display. Once upon a time this was done with software blitting to a hardware framebuffer (e.g. /dev/graphics/fb0), but those days are long gone.
Официальная документация GoogleЗдесь четко указаны обязанности SurfaceFlinger и способы их выполнения.
запускать
Когда Android запускает процесс SystemServer, он вызывает функцию system_init в frameworks \ base \ cmds \ system_server \ library \ system_init.cpp
И если атрибут system_init.startsurfaceflinger равен 0, служба SurfaceFlinger будет настроена в init.rc, и первый процесс инициализации Linux запустит SurfaceFlinger как независимый процесс.
Генерация и распространение VSYNC
Независимо от того, как вы запускаете SurfaceFlinger, метод init будет вызываться после создания экземпляра SurfaceFlinger:
Метод init сначала инициализирует устройство отображения по умолчанию, а затем создает два экземпляра EventThread и HWComposer.
После Android4.4 центром распределения сигнала VSYNC стал SurfaceFlinger. После получения сигнала VSYNC, сгенерированного аппаратным или программным моделированием HWComposer, он вызывает собственный метод onVSyncReceived для инициализации EventControlThread и других задач. EventControlThread в основном используется SurfaceFlinger для управления сигналом VSYNC, генерируемым оборудованием.
mEventThread — это удаленный СОКЕТНЫЙ сервер уровня приложения, представленного Choreographer, а mSFEventThread соответствует собственной обработке VSYNC SurfaceFlinger. Все они содержат mPrimaryDispSync через свой соответствующий DispSyncSource.
mPrimaryDispSync — это экземпляр DispSync, который внутренне содержит DispSyncThread. EventThread вызывает метод addEventListener DispSync через метод setVsyncEnable DispSyncSource после того, как клиент успешно подписывается на VSYNC, и передает mPhaseOffset и обратный вызов в DispSync. DispSync использует это смещение и период обновления экрана для управления временем обратного вызова методом DispSyncEvent в потоке. EventThread вызывается через метод onDispSyncEvent SurfaceFlinger.
Затем инициализируйте отображаемую информацию.В setPowerMode или setPeriod будет установлен период обновления Period для mPrimaryDispSync. После инициализацииDisplays модуль отображения готов, и вызывается startBootAnim для запуска анимации загрузки.
VSYNC прием
В SurfaceFlinger метод onFirstRef вызывается при первом создании экземпляра:
Прием VSYNC SurfaceFlinger достигается через MessageQueue, а его метод инициализации выглядит следующим образом:
Как мы упоминали выше, в методе инициализации SurfaceFlinger mSFEventThread соответствует обработке VSYNC самого SurfaceFlinger, поскольку вызывается метод mEventQueue.setEventThread (mSFEventThread).
BitTube создает два дескриптора Socket через SocketPair и метод getFd:
Возвращается mReceiveFd, MessageQueue добавляет дескриптор в Looper с помощью метода addFD Looper. Когда указанное выше время VSYNC распределяется, когда данные записываются в mSendFd с помощью метода отправки, он запускает механизм epoll в Looper, таким образом вызывая обратный вызов MessageQueue :: cb_eventReceiver метод. Если вы не знаете о Looper, см. ЗдесьLooper и epoll в Android。
Наконец, метод cb_eventReceiver объекта MessageQueue вызывается в метод onMessageReceived объекта SurfaceFlinger через SendMessage Looper, а тип сообщения — MessageQueue :: REFRESH:
Наконец, с помощью метода handleMessageRefresh SurfaceFlinger последний слой, заполненный приложением, вычисляется и синтезируется в фреймбуфер для отображения графической картой.
Choreographer
Как хореограф, Хореограф находится непосредственно в ViewRootImpl и контролирует ритм рисования пользовательского интерфейса приложения.
В конструкторе Choreographer он определит, следует ли включить механизм Vsync, оценив значение debug.choreographer.vsync в файле системных свойств. Если он включен, он создаст тип FrameDisplayEventReceiver и вызовет конструктор его родительского класса DisplayEventReceiver.java. :
Затем вызовите метод nativeInit в android_view_DisplayEventReceiver.cpp через jni nativeInit, вызовите его родительский DisplayEventDispatcher, создав NativeDisplayEventReceiver, и получите Looper основного потока приложения через MessageQueue, переданный в nativeInit, и передайте его DisplayEventDispatcher, а затем вызовите инициализацию метода DisplayEventDispatcher:
Можно видеть, что он также отслеживает поступление сигнала VSYNC через addFd. А mReceiver соответствует DisplayEventReceiver, который можно понимать как локальный агент удаленных объектов между процессами.
DisplayEventReceiver сначала создает локальный агент SurfaceFlinger через ComposerService, а затем получает соединение, удерживаемое EventThread, через createDisplayEventConnection.Метод подписки BitTube, поддерживаемый этим соединением, такой же, как SurfaceFlinger выше.
Метод createDisplayEventConnection находится в SurfaceFlinger:
Как видите, это действительно соединение, установленное через mEventThread, а не через mSFEventThread. Таким образом, хореограф успешно подписался на сигнал VSYNC.
Когда приходит сигнал Vsync, поскольку DisplayEventDispatcher наследует LooperCallback, он вызывает свой метод handleEvent, а затем вызывает метод dispatchVsync для NativeDisplayEventReceiver:
Сторона jni вызовет метод dispatchVsync DisplayEventReceiver на стороне java через метод CallVoidMethod, затем вызовет метод onVsync FrameDisplayEventReceiver и, наконец, начнет работу по рисованию пользовательского интерфейса на стороне приложения, вызвав метод doFrame из Choreographer.
подводить итоги
До Android 4.4, когда поступал сигнал VSYNC, Choreographer и SurfaceFlinger перезванивали одновременно, а механизма Offset не было, поэтому Choreographer подготовил новый кадр данных, и SurfaceFlinger не был сформирован в фреймбуфер до прибытия следующего VSYNC. ., И устройство отображения должно дождаться следующего VSYNC, чтобы, наконец, отобразить его. Это не только тратит время (требуется 2 цикла VSYNC), но также вызывает конкуренцию за ресурсы, такие как CPU, одновременно. Весь Google представил механизм смещения после 4.4, надеясь максимально оптимизировать эту проблему.Официальный документ GoogleЭто также объясняет.
Application and SurfaceFlinger render loops should be synchronized to the hardware VSYNC. On a VSYNC event, the display begins showing frame N while SurfaceFlinger begins compositing windows for frame N+1. The app handles pending input and generates frame N+2.
Synchronizing with VSYNC delivers consistent latency. It reduces errors in apps and SurfaceFlinger and the drifting of displays in and out of phase with each other. This, however, does assume application and SurfaceFlinger per-frame times don’t vary widely. Nevertheless, the latency is at least two frames.
To remedy this, you may employ VSYNC offsets to reduce the input-to-display latency by making application and composition signal relative to hardware VSYNC. This is possible because application plus composition usually takes less than 33 ms.
Источник
Android SurfaceFlinger
Я хотел бы спросить, всегда ли SurfaceFlinger вызывается для любого типа чертежа на экране? Пример: отображение файла JPG на экране.
ОТВЕТЫ
Ответ 1
SurfaceFlinger не то, что рисует ваше окно. Он выделяет буфер кадра для вашего окна, к которому работает фреймворк, запущенный в вашем приложении, без взаимодействия с SurfaceFlinger. Единственное взаимодействие SurfaceFlinger связано с тем, когда вы нарисовываете свое окно, чтобы скомпоновать последний буфер нового кадра на экран, как только вы закончите рисовать кадр.
Ответ 2
Да, SurfaceFlinger — это Android-композитор, поэтому он отображает все, что будет отображаться, и выяснит, как будет выглядеть результирующий кадр, а затем отправит его на экран с помощью интерфейса EGL графической карты.
Вы можете понять, что он контролирует результат всего, что вы видите в сообщении разработчика Android Jeff Sharkey, где он отображает весь экран для ночного режима. Я также нашел презентацию лучей, которая хорошо описывает этот раздел.
Ответ 3
SurfaceFlinger — это системный сервис Android, отвечающий за составление всех поверхностей приложения и системы в одном буфер, который, наконец, будет отображаться контроллером дисплея.
Позвольте увеличить изображение выше.
SurfaceFlinger — это системный сервис, но он не напрямую доступный разработчику приложения, поскольку датчик или другие службы могут быть. Каждый раз, когда вы хотите обновить свой интерфейс, SurfaceFlinger будет пинать Это объясняет, почему SurfaceFlinger — это сливной аккумулятор.
Помимо поверхностей вашего приложения, есть системные поверхности, включая строку состояния, навигационную панель и, когда происходит поворот, поверхностей, созданных системой для анимации вращения. Наиболее приложения имеют только одну активную поверхность — переднего плана, другие имеют более одного, когда SurfaceView используется в иерархии представлений или в режиме презентации.
SurfaceFlinger отвечает за СОСТАВЛЕНИЕ всех этих поверхностей. Общее недоразумение заключается в том, что SurfaceFinger предназначен для ЧЕРТЕЖЕЙ. это не верно. Рисование — это работа OpenGL. Интересно, что SurfaceFlinger также использовал openGL для компоновки.
Результат композиции будет помещен в системный буфер или собственный окно, которое является источником для контроллера отображения для извлечения данных. Это то, что вы видите на экране.
Источник
Русские Блоги
Android Surfaceflinger Research-Surface механизм
В предыдущей статье была представлена система отображения Android.В этой статье мы перемещаем перспективу на верхний уровень и изучаем, как фреймворк взаимодействует с Surfaceflinger для бизнеса. Как создать поверхность, как отобразить окно и т. Д. Все это делается с помощью системных служб WindowManagerService и surfaceflinger.
Механизм Surface в android сложен для понимания. Существует только три класса, называемых Surface, поэтому в этой статье он анализируется из двух частей: во-первых, если вы хотите понять механизм Surface, вам все же нужно уточнить различные классы. отношения между ними. Во-вторых, после понимания классовых отношений всего механизма Surface, мы затем объединим введение системы отображения в предыдущей статье, чтобы изучить, как Surface устанавливает соединение с системой отображения. Это соединение в основном относится к Surface Показать управление буферным хранилищем. В следующей статье я проанализирую, как SurfaceFlinger отображает буфер Surface , в котором хранятся графические данные окна в системе отображения. ,
1. Поверхностный механизм статического взаимодействия
1.1 ViewRoot и WMS совместно используют поверхность
Из вышесказанного видно, что Surface, определенный в ViewRoot, является просто пустой оболочкой, так где же инициализируется реальная поверхность? Большая экономка в WMS! Когда ViewRoot запрашивает ретрансляцию WMS, Surface в ViewSurface будет передан WMS для инициализации. В WMS, соответствующем каждому объекту WindowState, при создании окна также создается поверхность. Фактически инициализируется поверхность в wms, а затем поверхность WMS копируется на поверхность в ViewRoot. Целью этого является обеспечение того, чтобы ViewRoot и WMS совместно использовали одну и ту же поверхность. ViewRoot рисует поверхность, а WMS инициализирует и управляет поверхностью. Очень гармонично!
1.2SurfaceSession
SurfaceSession может рассматриваться как слой сеанса между WMS и SurfaceFlinger при создании Surface. SurfaceSession реализует создание Surface.
SurfaceSession — это концепция слоя JAVA, @ SurfaceSession.java. Соответствующая ему нативная сущность является объектом SurfaceComposerClient.
SurfaceComposerClient получает интерфейс IBinder для SurfaceFlinger через класс ComposerService, но этого недостаточно просто для получения интерфейса IBinder для SurfaceFlinger. Чтобы запросить SurfaceFlinger для создания Surface, вам также необходимо получить интерфейс IBinder ISurfaceComposerClient из SurfaceFlinger и запросить SurfaceFlinger для этого SurfaceFurlingerCerCerCerCerCerCerCerentCerviceFerCerperCerperCerCerCerCerCerCentCerCentCerCentCerCentCerCentCerCentCerCentCerentCerentCerCentCerCerCentCerCerCentCerCerCerCer. Зачем так ходить, почему бы просто не позволить SurfaceFlinger напрямую создавать Surface?
С точки зрения SurfaceFlinger, для SurfaceFlinger может быть несколько Клиентов, запрашивающих бизнес SurfaceFlinger. Каждый Клиент может запросить SurfaceFlinger для создания нескольких Surfaces. Затем SurfaceFlinger должен предоставить набор механизмов для локального сохранения каждого клиентского запроса. Для созданного Surface SurfaceFlinger реализует этот механизм путем создания объекта Client для каждого клиента и возвращает клиентский интерфейс IBinder, ISurfaceComposerClient, в объект SurfaceComposerClient. Объект SurfaceComposerClient запрашивает создание поверхности через ISurfaceComposerClient.
На следующем рисунке описана внутренняя структура и рабочий процесс всей SurfaceSession.
Где синяя стрелка S urfaceComposerClient через ComposerService получает интерфейс ISurfaceComposer интерфейса SurfaceFlinger IBinder;
Красная стрелка указывает S SurfaceComposerClient запрашивает SurfaceFlinger для создания клиента через IPC и получает клиентский интерфейс IBinder ISurfaceComposerClient;
Зеленая стрелка указывает S urfaceComposerClient запрашивает у клиента создание Surface через IPC.
1.3 Форма поверхности
В предыдущем разделе мы проанализировали статическую структуру SurfaceSession. Мы узнали, что процесс создания Surface был создан путем запроса SurfaceFlinger через SurfaceSession, промежуточный слой сеанса. В этой статье мы долго говорили о Surface, так что именно нам нужно создать? Что это за поверхность, и какова ее конкретная форма? В этом разделе мы проанализируем следующие формы поверхности.
1.3.1 Форма клиентской поверхности
Во-первых, давайте посмотрим на код, определенный Surface в WMS
Мы можем видеть, что он передал объект SurfaceSession в качестве параметра конструктору Surface. Посмотрите на конструктор Surface.
Этот конструктор отличается от конструктора Surface, который мы видели в ViewRoot.Этот конструктор не является пустой оболочкой, он выполняет инициализацию локальной сущности, поэтому эта Surface является настоящим Suface.
Нативная функция инициализации обратного вызова S Функция createSurface () в urfaceComposerClient четко описана на рисунке в предыдущем разделе, и процесс не представлен. В то же время нам не важно, что Surface создает SurfaceFlinger для SurfaceComposerClient, давайте взглянем на SurfaceComposerClient Что было создано для WMS?
Из приведенного выше кода мы видим, что SurfaceComposerClient возвращает объект SurfaceControl для WMS. Этот объект SurfaceControl содержит поверхность, созданную SurfaceFlinger для SurfaceComposerClient. Поверхность, созданная SurfaceFlinge на стороне клиента, — это ISurface , Этот процесс будет виден при анализе формы поверхности на стороне SurfaceFlinger.
Существует также очень важный член в классе SurfaceControl, его тип также называется Surface, который определяется в frameworks/base/ libs / surfaceflinger / Surface.h. Эта поверхность обеспечивает управление буферами отображения. Позже в статье.
1.3.2 SurfaceFlinger Surface
Когда клиент запрашивает SurfaceFlinger для создания поверхности, Сначала SurfaceFlinger Согласно свойствам окна, предоставленным WMS Объект с именем Layer concept, а затем создайте его объект подкласса LayerBaseClient :: Surface на основе Layer. В этот момент появляется третий класс с именем Поверхность, и в следующем разделе мы представляем концепцию этого слоя.
1.4 Layer
1.4.1 Классификация слоев
В настоящее время существует 4 типа слоев в Android, как показано выше.
1.Слой, обычный слой, который создает буфер отображения для каждой поверхности, запрошенной клиентом.
2.LayerBuffer, этот слой не создает буфер отображения, он просто использует существующий буфер в качестве буфера отображения, например, предварительный просмотр камеры;
3.LayerBlur, этот слой также Не создает буфер отображения, он просто запутывает данные в исходном FrameBuffer через этот слой;
4.LayerDim, Этот слой также Буфер отображения не будет создан, он только затемнит данные в исходном FrameBuffer через этот слой;
Из этого слоя мы видим, что в центре нашего анализа находится первый тип слоев, ниже мы сосредоточимся на анализе обычных слоев. Конкретный бизнес Layer мы проанализируем в следующей статье
1.4.2 Управление слоями
Когда мы проанализировали SurfaceSession выше, мы также проанализировали, что Клиент может создать несколько Surfaces, то есть создать несколько слоев, так как SurfaceFlinger управляет этим слоем записи? SurfaceFlinger поддерживает 2 вектора для управления слоем.
Во-первых, мы знаем, что SurfaceFlinger создаст объект Client для каждой сессии SurfaceSession. Первый способ — сохранить все слои, созданные для определенной SurfacSession, в соответствующем объекте Client.
Второй способ — сохранить все созданные обычные слои, чтобы клиентская поверхность могла идентифицировать уровень, соответствующий клиентской поверхности, при запросе реализации буфера.
2. Поверхностное управление хранением буфера дисплея
Во введении формы Surface на стороне клиента мы упоминали, что SurfaceControl также поддерживает объект Surface, который определен в frameworks / base / libs / surfaceflinger / Surface.h. Он отвечает за запрос отображения LayerBaseClient :: Surface. Поместите буфер и передайте буфер отображения на холст поверхности JAVA, чтобы нарисовать окно. Мы называем эту поверхность какClient Surface。
2.1 окно рисования
Приведенный выше код показывает, что JAVA Surface заблокирует холст. и В этом процессе создается клиентская поверхность, то есть первая строка в следующем коде getSurface (). Создание клиентской поверхности, сначала посмотрите, как Canvas взаимодействует с Буфер отображения клиентской поверхности связан.
Из приведенного выше кода мы видим, что устройство Canvas Bitmap установило буфер отображения поверхности клиента в качестве своего пространства хранения растровых пикселей.
Это дает Canvas пространство для рисования. Следующий шаг — нарисовать окно.
MView в ViewRoot — это DecorView всего окна.
2.2 Инициализация поверхности клиента
Создание клиентской поверхности было выполнено, когда ViewRoot впервые заблокировал холст.Целью этого также может быть экономия места и сокращение ненужных расходов.
Процесс управления клиентской инициализацией Surface и буфером отображения более сложен. На следующем рисунке показана диаграмма статической структуры этой части. Некоторые вещи не могут быть выражены на диаграмме. Я кратко представлю это ниже.
2.2.1SharedClient
Основное назначение объекта SharedClient на самом деле очень простое — предоставить системе SharedBufferStack :: NUM_LAYERS_MAX (31 на ГБ) SharedBufferStack. То есть система в настоящее время поддерживает создание 31 клиентских поверхностей. Давайте поговорим о SharedBufferStack ниже.
Почему SharedClient является общей памятью? Требуется для каждой клиентской поверхности SharedBufferStack хранится по адресу SharedClient, и для каждого SharedBufferStack, с одной стороны, клиенту Surface необходимо установить некоторый размер области и т. Д. С другой стороны, при рендеринге Layer необходимо получить текущий Информация о настройке, такая как размер области, получается в SharedBufferStack.
2.2.2 SharedBufferStack
2.2.3 Запрос клиента Surace GraphicBuffer
Здесь процесс создания GraphicBuffer клиентской поверхности показан в виде диаграммы последовательности.
Здесь следует отметить, что два из поверхности клиента GraphicBuffer создается только при создании lock (), а не при создании клиентской поверхности.
Источник