Как стать автором
Обновить

Разбираемся в особенностях графической подсистемы микроконтроллеров

Время на прочтение14 мин
Количество просмотров14K
Всего голосов 36: ↑34 и ↓2+32
Комментарии46

Комментарии 46

У микроконтроллера FPS больше чем у моего компа!
Если уж рендинг такой не оптимальный, то ПО для Nextion есть куда оптимизировать.

:)
Тут еще от размера видеопамяти (и, собственно, экрана) зависит. Когда перешли на 800x480 получили 25 FPS. Но в целом да, тоже удивились когда на микроконтроллере хорошего FPS около 60-70 достигли.
НЛО прилетело и опубликовало эту надпись здесь
Я думаю может получиться. Если взять какую-нибудь full-speed USB мышь (смотрю сейчас на свою), у нее есть interrupt эндпоинт с интервалом опроса 10 мс. То есть 100 прерываний в секунду, грубо говоря, что не очень-то и много. У нас на той же stm32f7 работает pjsip, а там нагрузка от прерываний по сети и прерываний аудио и DMA точно больше. То есть плавный drag'n'drop мышкой кажется вполне реальным. Но это все в теории, точно ответить можно, конечно, только после экспериментов.
Так вроде же можно в LTDC включить режим, изменения адреса буфера только по завершению вывода последней строки. То есть использовать два буфера, переключать заранее, а не по прерыванию. Просто уж странно выглядит FPS 25
Так вроде же можно в LTDC включить режим, изменения адреса буфера только по завершению вывода последней строки.

Я знаю только про line interrupt. Его можно запрограммировать, к примеру, на последнюю строку, это да. Вы не про него?
То есть использовать два буфера, переключать заранее, а не по прерыванию.

Два буфера и используется. Один для отрисовки сцены приложением, второй для LTDC. А заранее это когда?
Просто уж странно выглядит FPS 25

Было 60 FPS, увеличили размер видео памяти в 3 раза и получили 25 FPS. Или вы про что-то другое?

А, да, там есть режим, в котором обновление shadow регистров LTDC (того же адреса, например) происходит во время VBLANK периода. То есть вы правы, это еще один способ. Но тогда нужно за VSYNC битом сделать. Не уверен, что будет выигрыш в сравнении с прерыванием. Но можно проверить.
чтобы не следить за VSYNC, импользуйте 3 видео буфера.
Хм, а что это даст?
Типа будет задержка в один буфер? И тогда все гарантированно «успеет» обработаться? Но тогда по памяти затраты на один буфер больше.

ответ в начале моего комментария. А так всегда, за одно всегда надо расплачиваться другим. Еще как рариант, сднлайте 2 небольших буффера для отрисовки в sram, и их через DMA пересылайте в будующий видимый буффер (их тоже будет 2)

То что всегда нужно за одно расплачиваться другим это да. Тут другое — не понятен смысл третьего буфера, который еще и накладные расходы по памяти увеличивает. Синхронизация то все равно должна быть.

Еще как рариант, сднлайте 2 небольших буффера для отрисовки в sram, и их через DMA пересылайте в будующий видимый буффер (их тоже будет 2)

Ну это уже дополнительные оптимизации :) Там еще вопрос насколько оно вообще получится в эти небольшие буферы элементы отрисовывать (к примеру, если буфер небольшой, а графический элемент «большой», то отрисовывать в него как-то кусками нужно).
Хорошо, распишу подробнее о 3 буфере (но опять же, я не призываю так делать, все зависит от условий вашего проекта). Имеем 2 буфера — 1-ый и 2-ой. Пусть изначально 1-ый отображается, во 2-ой мы рендерим кард. Когда кард полностью отрисован, нам нужно сообщить LTDC о том, чтобы он сам переключил указатель адреса на буффер для отображения (используется особенность shadow регистров, т.е. новый адрес буффера мы укажем сразу, но переключение произойдет в момент VBLANK периода.

Теперь вопрос… А когда он произойдет, сколько нам ждать? LTDC ведь может только начинать показывать первую строчку из 1-ого буффера. Если мы сразу же начнем рендерить в 1-ый буффер, можно наблюдать артефакты. Ведь дисплей с разрешением в 480x272 пикселей будет рабоать на каких-то 6-10 Мгц-ах а ядро и перефирия на 180Mhz+. Тоесть как вы писали выше, нам надо ждать, пока LTDC дойдет до последней строчки и сменит адрес на буффер…

Так вот третий буфер позволит вам избавиться от такой задержки… И только.
Тоесть как вы писали выше, нам надо ждать, пока LTDC дойдет до последней строчки и сменит адрес на буффер…

Так вот третий буфер позволит вам избавиться от такой задержки… И только.

Не совсем. Если я правильно вас понял, вы предлагаете после отрисовки во второй буфер, не ждать когда LTDC закончит с первым, а сразу же переходить к третьему. Это хорошо, но в таком режиме, процессор в скором времени «догонит» LTDC (т.е. окажется на том же самом буфере) и рисовать станет некуда, и все опять сведется к ожиданию как и в случае с двумя буферами.
Верно, но это надо пробовать, обычно сама отрисовка бывает искуственно ограничена макс. количеством кадров в секунду, так как сам дисплей не сможет показывать например 200+ FPS.
Согласен, надо пробовать.

обычно сама отрисовка бывает искуственно ограничена макс. количеством кадров в секунду, так как сам дисплей не сможет показывать например 200+ FPS.

Это да. Можно как программно, по идее, ограничить — по таймеру, к примеру, рисовать в отдельном потоке, так и аппаратно — через проверку статуса VSYNC или прерывание. Но тут похоже тоже надо думать, а будет ли тогда выигрыш от дополнительного буфера. Потому как если LTDC в общем случае заканчивает работу с буфером раньше ЦПУ (мы же ЦПУ искусственно ограничили), то тогда у ЦПУ всегда будет по крайней мере один свободный буфер. Короче говоря, вопрос любопытный, надо экспериментировать.
Вероятно, тройная буферизация может помогать если в среднем, перерисовка экрана меньше времени отображения одного кадра, но иногда занимает больше времени чем один кадр.

И ещё вопрос. А в контроллере есть режим с 8-битной палитрой? Могло бы уменьшить требования к памяти, если не нужна фотореалистичная графика.
Да-да, мне тоже кажется что должно быть именно в «среднем». То есть если ЦПУ будет отрисовывать кадр то быстрей, то медленней чем LTDC грузит кадр в дисплей, то они гипотетически могут шаг в шаг идти. Может быть даже буфера может быть не три, а в зависимости от FPS как-то в динамике вычисляться.

И ещё вопрос. А в контроллере есть режим с 8-битной палитрой? Могло бы уменьшить требования к памяти, если не нужна фотореалистичная графика.

Да, палитра есть. Это и правда размер видео памяти раза в 4 уменьшит. Но есть нюанс — плагин rawfb в Nuklear, который мы используем, рисует только в RGBA8888. Соответственно, поэтому настроили и LTDC на этот формат. Но вы правы, если выбрать палитру, и научиться сразу рисовать в нее, а не в RGBA8888, то экономия памяти возрастет. Да и скорость стала бы выше — можно этот буфер уже в быструю память поместить (SRAM).
А как Вы рисуете в RGBA8888 если SDRAM в 746-jq Дискавери подключена по 16-ти битной шине (она не 32-х, а 16-ти разрядная)?
Ровно как и записываю 32битное число в обычную память. Тут же FMC к, которому подключена SDRAM, будет в нее команды генерировать.
В SRAM контроллера, например, Вы можете записать 32-х битное число и все 32 разряда его сохранятся, а тут только нижние 16 бит подключены, а остальные верхние 16 бит в «воздухе висят».
Может вы имеете ввиду, что физически у этой SDRAM 32 data линии, но подключена она через первые 16 линий? Если да, то там же FMC настраивается в 16 битный режим, и тогда не имеет значения, что старшие 16 data линии «в воздухе висят», как вы выразились.
Да, это имел ввиду. Тогда получается, что сам FMC отправляет «во внутрь контроллера» (а оттуда может пойти на LTDC и внешний RGB LCD например) сначала одно слово, а потом другое? Просто, на днях как раз, наткнулся на цитату в форуме (даже кажется не в одном месте), что дескать такое подключение внешней SDRAM ограничивает возможности LCD (в плане RGB цветов получается). И никто не опрестовал это высказывание. Даже могу поискать и привести тут ссылку на эту цитату.
Вот одна из ссылок (человек пишет, что теперь у него работает (т.е. он собрал и проверил все это) в режиме RGB565 и пришлось с этим смириться):
electronix.ru/forum/index.php?app=forums&module=forums&controller=topic&id=148422&do=findComment&comment=1586376
И еще в др. местах видел аналогичное утверждение и могу дальше поискать и выложить тут. Поэтому сомнения возникли.
Вот одна из ссылок (человек пишет, что теперь у него работает (т.е. он собрал и проверил все это) в режиме RGB565 и пришлось с этим смириться):
electronix.ru/forum/index.php?app=forums&module=forums&controller=topic&id=148422&page=2&tab=comments#comment-1586376

Сложно сказать, там про разводку плат обсуждение в основном… Да и непонятно по какой причине он RGB565 использует — вполне возможно что просто из соображений производительности.
По сути да, с точки зрения программиста это обычный регион памяти (memory-mapped i/o). При записи в этот регион данные попадают не напрямую в SDRAM, а проходят через FMC. Если шина данных 16 бит, то да — 32битное число выставится на нее не за раз, а за два. Это примерно как и с SPI-флэшкой — пишем по адресам в memory-mapped режиме, а данные реально передаются по одной линии данных (или по 4ем, если QSPI-флэшка).
Хорошо. Спасибо большое за разъяснения. Значит все-таки RGBA888. (насчет RGB565 сейчас вдобавок обнаружил и на ресурсе «narodstream», в его уроках про 746-ую Дискавери, аналогичный подход в предлагаемом драйвере для LCD дисплея — он тоже там почему-то RGB565 применил:
narodstream.ru/stm-urok-64-hal-ltdc-chast-1
и видел еще где-то на форуме электроникса недавно аналогичное утверждение — но лучше уже самому почитать/изучать как следует чем других слушать. Спасибо еще раз.)
насчет RGB565 сейчас вдобавок обнаружил и на ресурсе «narodstream», в его уроках про 746-ую Дискавери, аналогичный подход в предлагаемом драйвере для LCD дисплея — он тоже там почему-то RGB565 применил:

RGB565 лучше и в плане FPS и в плане расхода памяти. Хуже только в плане цвета, но для такого экрана вполне годится. Единственная причина, по которой мы делали RGBA8888 — это то что Nuklear rawfb только в таком формате уже подготавливает кадр в памяти, а конвертировать не хотелось (об этом писал выше). То есть если можно RGB565 применить, то я бы тоже его посоветовал. А можно и вообще палитру, как выше предложили. Но сути не меняет, наверное зависит от качества картинки.
border графика на спектруме навеяла )))

Отличная юмористическая статья! 5+! Давно так не смеялся. Жаль только смех был сквозь слезы… Даже хорошо, что автор так ничего и не рассказал про "особенности графической подсистемы мокроконтроллеров", как обещал в названии статьи. От Embox буду держаться как можно дальше.

Неаргументированную критику всерьез не воспринимаю, не старайтесь.
Ну чтоже, тогда придется аргументировать. Только чур не обижаться — будет не очень приятно.

Начну с положительного момента. «Первое что можно попробовать — сэкономить на всем.» — это действительно шорошая шутка, на мой взгляд. Возьму ее на вооружение.

Теперь отрицательные моменты:

"… доступ к памяти SDRAM синхронизируется, даже память так и называется Synchronous Dynamic Random Access Memory (SDRAM), поэтому такой вариант лишь добавляет дополнительную синхронизацию… Немного поразмыслив, мы поняли, что ничего удивительного тут нет, ведь память то одна, и циклы записи и чтения генерируются к одной микросхеме (по одной шине), ..., то арбитру, который и разруливает обращения по шине, нужно смешивать циклы команд от разных DMA каналов."

Synchronous в названии памяти не имеет вообще никакого отношения к синхронизации доступа, о котором вы дальше пишите. Дело тут в физическом интерфейсе,
которые бывают синхронные и асинхронные. Так вот, слово Synchronous говорит лишь о том, что данный тип памяти использует синхронный физический интерфейс
передачи данных.

На вашей отладочной плате действительно установлена одна микросхема SDRAM, но транзакции на внутренней шине контроллеры DMA генерируют не для нее
(микросхема SDRAM к внутренней шине не может быть подлючена по причине полной несовместимости физических интерфейсов). Транзакции генерируются для
встроенного контроллера внешней памяти — FMC (Flexible memory controller). По этой причине установка 2 и более микросхем SDRAM ситуацию не меняет.

По этой же причине контроллеры DMA никаких циклов команд для SDRAM не генерируют, а арбитр шины, соответственно, их никаким образом не смешивает.

Когда несколько Master-ов хотят обратиться к одному и тому же одноканальному Slave арбитр просто определяет очередность доступа.

DMA ничего не знает ни о том чтО за данные он передает, ни о том от кого и кому он передает. Для DMA что внутренняя SRAM, что FMC — все едино.

Для DMA есть начальный адрес «откуда», начальный адрес «куда», сколько, как формировать последующие адреса, разрядность данных и (для некоторых
DMA) как обрабатывать передаваемые данные (0-ми дополнить, знаком расширить, среднее арифметическое посчитать и т.д.).

Ваше пояснение в скобках, что циклы записи и чтения генерируются "...(по одной шине)..." неверное т.к. это в совсем маленьких микроконтроллерах есть одна шина
на которой «висят» все Master-ы и все Slave-ы. В таких монстрах как F7 шин много и применяется Bus Matrix.

Итак: 1) один Master (CPU) отрисовывает в буфере, находящимся в SDRAM и затем с копирует в «видеопамять», которая тоже находится SDRAM. — 45 FPS
2)вы добавляете еще один буфер и заменяете memcopy на DMA (2 Master-а к одному Slave) — 48 FPS
3)вы добавляете 2-ой DMA (3 Master-а к одному Slave) — 30 FPS

Результаты вас удивляют, а ваши объяснения "… циклы записи и чтения генерируются к одной микросхеме (по одной шине)...", «Я не хочу сказать, что DMA оказался бесполезен...» не выдерживают никакой критики. И это происходит потому, что вы совсем не понимаете что именно и в каких местах происходит.

А происходит следующее. Во всех трех вариантах количество транзакций по внутренним шинам одинаковое, из-за того, что slave (FMC) один и для обмена данными у него всего один канал, все транзакции выстраиваются в «очередь» и происходят последовательно. С точки зрения шин и Bus Matrix в этом случае большой разницы между 1-м, 2-мя и 3-мя Master-ами нет. Расходы на арбитраж не очень большие. Поэтому, если бы дело было в «одной микросхеме (по одной шине)», то замена memcopy на DMA дала бы существенное ускорение (DMA существенно быстрее memcopy), добавление второго DMA — незначительное замедление.

Проблема в особенностях работы SDRAM — причем не конкретной микросхемы, а SDRAM как таковой. Но об этом вы, явно, мало что знаете. SDRAM очень даже шустрая, если читать или писать большой объем данных, расположенных последовательно. Как только начинается произвольный доступ скорость катастрофически падает. Поэтому, если бы вместо SDRAM к FMC подключили SRAM ситуация была бы иной.

При 1) сутуацию во время прорисовки улучшает внутренний буфер FMC, правда memcopy он уже помочь не может.

При 2) степень произвольности доступа растет и производительность SDRAM падает. Это происходит потому, что DMA не гонит все ваши 256 кБ одной транзакцией, а выполняет множество burst транзакций по 16 beats и т.к. происходит это одновременно с отрисовкой, транзакции от CPU перемежаются с транзакциями от DMA. Проблема в том, что каждый мастер обращается к своей области памяти в SDRAM (их получается 3 — buf1, buf2, video). Тут на время работы DMA FMC уже помочь ничем не может. Но засчет того, что DMA работает значительно быстрее и эффективнее memcopy, транзакции DMA идут чаще транзакций CPU, в сумме получается даже небольшой выигрыш.

При 3) все существенно существенно ухудшается — оба DMA работают одинаково быстро и каждый работает со свими областями (их теперь 5 — buf1, buf2_a, buf2_b, video_a, video_b). Теперь уже речи не идет о том, что степень произвольности доступа растет — теперь на время работы обеих DMA доступ чисто произвольный. Производительность SDRAM падает примерно до плинтуса.

Итого:

Про организацию шин внутри микроконтоллера и про их работу вы мало что знаете.
Про SDRAM вы мало что знаете.
Про DMA вы мало что знаете.

Про кэш вы тоже мало что знаете, но про это вы пока еще, похоже, не знаете — об этом я вам расскажу в следующем сообщении к концу недели.

У вас для разработчика OS недопустимо низкий уровень знаний.
Во-первых, в любом случае спасибо за информацию.

Во-вторых, вот вы написали сейчас полотно, которое просто вышло бы за рамки статьи — соответствнно, объяснять все это было бы нерезонно (да, признаю, часть для меня новое, но 70% того что вы написали я знаю). Про FMC я знаю тоже. Знаете почему? А вы посмотрите на каком адресе расположена память SDRAM — 0x60000000. Мы ее переключаем с 0xc0000000 на 0x60000000 через SWP_FMC, это было нужно для выравнивания на 4 байта. Далее, я не утверждал я что DMA генерирует команды к SDRAM в обход FMC. Но почему я обязан о всех этих деталях с FMC рассказывать в статье?

Единственное, я бы может просто заменил мою неточную формулировку в статье на вашу:
Проблема в особенностях работы SDRAM — причем не конкретной микросхемы, а SDRAM как таковой. Но об этом вы, явно, мало что знаете. SDRAM очень даже шустрая, если читать или писать большой объем данных, расположенных последовательно. Как только начинается произвольный доступ скорость катастрофически падает. Поэтому, если бы вместо SDRAM к FMC подключили SRAM ситуация была бы иной.

Да, тут более четко сказано про особенность SDRAM. И этой особенностью, действительно, много объясняется. И этого было бы достаточно. Но нет же…

В остальном, серьезно, вот зачем это все в статье про детали с FMC и Bus Matrix? Вот вы похоже железом занимаетесь (аппаратчик, верилог, FPGA наверное), но к примеру, зачем вам в статье по железу рассказывать как устроены workqueue или timer wheel в Линукс. Могу вам точно так же сказать, если вы этого не знаете, то железячник из вас никудышний.
А что касается:

Про кэш вы тоже мало что знаете, но про это вы пока еще, похоже, не знаете — об этом я вам расскажу в следующем сообщении к концу недели.

Конечно пишите, мне будет интересно чего я не знаю.

p.s.
Кстати, я тоже хотел в относительно недалеком будущем отдельную статью про кэши написать, как раз потому что это вышло за рамки текущей статьи про графику, даже черновик уже есть (но очень-очень сырой). Так что если вдруг не хотите мне «подсказывать», то можете ее дождаться и раскритиковать в пух и прах :)))
Кстати, я тоже хотел в относительно недалеком будущем отдельную статью про кэши написать

Там будет что-то выходящее за рамки этих статей?
https://habr.com/ru/post/328542/
https://habr.com/ru/post/179647/
https://habr.com/ru/post/183834/
https://habr.com/ru/post/187654/

Большое спасибо за ссылки! Уже просмотрел (пока по диагонали). На первый взгляд будет. Сейчас там про write-back vs write-through + write-allocate + как можно управлять кэшируемостью памяти через MPU (т.е. помечать как некэшируюмую память под DMA, например, для сетевой карты), а когда стоит применить clean/inval (например, для той же видеопамяти). Да и упор хочется сделать, опять же, с точки зрения программиста — что, зачем и как использовать. Но как я сказал, статья пока очень сырая, там просто лежат те заметки о вещах, с которыми мы лично столкнулись. Еще надо pjsip и другие вещи с кэшем проверить. Но спешить, конечно, не буду. Да и как-то не в наших правилах анонсы статей делать, так как очень много работы, и статьи пишутся только по факту какого-то, пусть и небольшого, осмысленного успеха, а не ради статей. Это я наверное погорячился про анонс, отвечая товарищу выше…

Может, надо сначала внимательно почитать документацию и теорию, а потом экспериментировать? Что Вы в итоге измеряли: пропускную способность памяти? Скорость DMA?

Может, надо сначала внимательно почитать документацию и теорию, а потом экспериментировать?

В процессе разработки все это, конечно же, изучал. Если есть какие-то замечания по делу — высказывайте. Если нет — не тратьте мое время, пожалуйста.

Измерялось FPS (frame rate). Эта характеристика зависит не только от аппаратных, но и от программных факторов. Скорость DMA и пропускная способность памятей это вещи сугубо аппаратные, все есть в документации, нечего измерять. Они конечно влияют на итоговый FPS.
Ну, если изучали, тогда бы не было:
Обсудив ситуацию, мы решили отложить унификацию до более глубокой проработки графического стека.

Попробуйте сделать тройной буфер, как рекомендовали выше. Это классика. Тогда не будет проблем с маленькими или большими разрешениями. И не надо ловить «обратный ход луча» или как принято сейчас называть — «вертикальный бланк».
Ваш первый способ (с переключением слоев) работает только, когда скорость формирования кадра выше скорости вывода, второй (переключение буферов) — наоборот.
Возможно, это мое мнение, но fps замерять не очень корректно, более правдиво — время, затраченное на формирование кадра. Тогда можно оценить свободное процессорное время для других задач.
Спасибо за замечания.

Попробуйте сделать тройной буфер, как рекомендовали выше. Это классика. Тогда не будет проблем с маленькими или большими разрешениями. И не надо ловить «обратный ход луча» или как принято сейчас называть — «вертикальный бланк».

Разве тройная буферизация всегда исключает необходимость проверки вертикального бланка? Если у вас ЦПУ отрисовывает кадр всегда быстрее, чем контроллер дисплея грузит кадр в экран, то тройная буферизация теряет смысл перед двойной буферизацией. Ну и, собственно, когда контроллер дисплея всегда быстрее грузит кадр нежели система его отрисовывает та же история. При этом, я понимаю как это может помочь «в среднем». Вы же читали обсуждения про тройную буферизацию выше (случаи когда кто-то из ЦПУ или LTDC быстрей)? Было бы интересно вас выслушать.

Ваш первый способ (с переключением слоев) работает только, когда скорость формирования кадра выше скорости вывода, второй (переключение буферов) — наоборот.

Можете пояснить? Казалось бы, ни один их этих способов не должен зависеть от соотношения скоростей формирования кадра/отображения кадра. При любом соотношении, оба способа должны давать адекватную картинку (без дрожания), ведь переключение буферов в обоих методах происходит исключительно внутри VBLANK.

Возможно, это мое мнение, но fps замерять не очень корректно, более правдиво — время, затраченное на формирование кадра. Тогда можно оценить свободное процессорное время для других задач.

У нас в этом примере только графическое приложение исполнялось. Помимо этого разве что системный таймер. Поэтому полученные 85 FPS это когда система только графикой и занимается. Если экран 60 Гц, то можно прикинуть какая часть свободного времени остается.
Разве тройная буферизация всегда исключает необходимость проверки вертикального бланка? Если у вас ЦПУ отрисовывает кадр всегда быстрее, чем контроллер дисплея грузит кадр в экран, то тройная буферизация теряет смысл перед двойной буферизацией. Ну и, собственно, когда контроллер дисплея всегда быстрее грузит кадр нежели система его отрисовывает та же история. При этом, я понимаю как это может помочь «в среднем». Вы же читали обсуждения про тройную буферизацию выше (случаи когда кто-то из ЦПУ или LTDC быстрей)? Было бы интересно вас выслушать.

1. один буфер используется, когда поцессор успевает отрисовать кадр во время бланка (вертикального) или перерисовывается малая часть кадра, не заметная для глаза
2. два буфера используется, когда процессор не успевает отрисовать кадр во время бланка. при этом отрисовка нового кадра начинается, когда освободился буфер. т.е. программа (поток) отрисовки должна ожидать.
3. тройная буферизация используется когда идет непрерывный поток формирования кадров (например, камера или Ваш случай, где пытаетесь достичь много fps)
да, я читал выше про тройную буферизацию. там за бланками следить не надо, только контролеру видео сообщить, с какого адреса начинать следующий кадр.
почитайте как делается тройная буферизация, там не сложно. главное, не запутаться какой буфер на вывод, какой в очереди, а какой свободный.

Можете пояснить? Казалось бы, ни один их этих способов не должен зависеть от соотношения скоростей формирования кадра/отображения кадра. При любом соотношении, оба способа должны давать адекватную картинку (без дрожания), ведь переключение буферов в обоих методах происходит исключительно внутри VBLANK.

я код не видел, из контекста понял, что Вы формируете кадры не синхронно с выводом и переключением буферов (см. выше п.2)
У нас в этом примере только графическое приложение исполнялось. Помимо этого разве что системный таймер. Поэтому полученные 85 FPS это когда система только графикой и занимается. Если экран 60 Гц, то можно прикинуть какая часть свободного времени остается.

ну, тут у каждого свое мнение.
тройная буферизация используется когда идет непрерывный поток формирования кадров (например, камера или Ваш случай, где пытаетесь достичь много fps)
да, я читал выше про тройную буферизацию. там за бланками следить не надо, только контролеру видео сообщить, с какого адреса начинать следующий кадр.
почитайте как делается тройная буферизация, там не сложно. главное, не запутаться какой буфер на вывод, какой в очереди, а какой свободный.

Спасибо, попробую! Из любопытсва, вы тройную буферизацию на практике реализовывали, или разбирали в теории?
да, реализовывал тройную, когда работал с tms320dm643. делал для камеры и для дисплея.
Я хочу сказать, что главное преимущество тройной буферизации — это повышение FPS. И если даже отрисовка происходит всегда быстрее загрузки кадра в экран, система может просто «перерисовывать» один из двух буферов, и уже, например, по v-sync или еще как-то отдаст в контроллер дисплея наиболее свежий отрисованный кадр. То есть тут важный момент, что вместо ожидания v-sync, всегда можно перерисовать буфер, в котором находится наиболее старый кадр. А вот в двойной же буферизации, перерисовывать самый старый кадр (он же текущий) — нельзя.

Благодаря этим обсуждениям здесь и выше, я лучше понял тройную буферизацию, признаю, спасибо :)

Но еще раз, та фраза, на которую вы сосласись:
Обсудив ситуацию, мы решили отложить унификацию до более глубокой проработки графического стека.

не относится к оптимизации FPS.
Я хочу сказать, что главное преимущество тройной буферизации — это повышение FPS.

нет. это упрощение синхронизации.
не относится к оптимизации FPS.

да, не относится к оптимизации, а относится к невнимательности или непониманию принципов формирования кадров.
да, не относится к оптимизации, а относится к невнимательности или непониманию принципов формирования кадров.

Да, так и оказалось :) Была ошибка в коде в том моменте когда nukear отрисовывал очередной кадр и запрашивает смену буфера. Я понимаю, что смотреть вероятно не будете, но на всякий случай оставляю ссылку на правку.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий