Перейти к содержанию

Обзор

Спроектируйте графическую архитектуру

В этом руководстве рассматриваются принципы создания отзывчивых графических интерфейсов на устройствах SF32. Основное внимание уделено практическим решениям, которые влияют на готовое изделие: выбору дисплея и стратегии работы с кадровым буфером (framebuffer), интеграции LVGL, аппаратному ускорению ePicasso, размещению данных в памяти и обновлению экрана.

Устройства SF32 предназначены для компактных AIoT-изделий и носимой электроники. Интерфейс в них должен работать плавно при строгих ограничениях по энергопотреблению, памяти и площади печатной платы. Графический тракт разделяет обработку ресурсов, композицию пикселей, возможное сжатие кадрового буфера и вывод на панель. Чтобы выбрать подходящую оптимизацию, важно не смешивать эти функции.

Используйте эту страницу для предварительных архитектурных решений, которые трудно изменить позднее: типа панели и интерфейса, стратегии кадровой буферизации, глубины цвета, прозрачности, размещения ресурсов и политики обновления. В связанных статьях раздела «Графика» подробно описаны отдельные этапы этого процесса.

Графический тракт SF32

Типичный путь от графических ресурсов до дисплея выглядит так:

Схема: путь графических ресурсов до дисплея
Source images, fonts, and animations
        │
        ▼
GraphicsTool converts supported resources to eZip or eZip-A
        │
        ▼
Compressed assets in NOR Flash, PSRAM, NAND, or file storage
        │
        ▼
eZip hardware decoder expands an asset when required
        │
        ▼
LVGL or another UI framework + graphics/display driver
        │
        ├── CPU fallback rendering
        │
        └── ePicasso pixel acceleration
        │
        ▼
Final rendered bitmap in a draw buffer or framebuffer
        │
        ├── Uncompressed display path
        │
        └── Optional: extDMA compresses it into TurboPixel
                    │
                    ▼
             TurboPixel framebuffer in PSRAM
        │
        ▼
Display controller transfers pixels to the panel
        │
        ▼
SPI / QSPI / 8080 / RGB / MIPI DSI / EPD / JDI panel

Этот тракт можно настраивать под конкретное изделие: eZip, ePicasso, TurboPixel и полноэкранный кадровый буфер нужны не всегда. Доступность и взаимодействие функций зависят от выбранного устройства, SDK, интерфейса дисплея, панели и конфигурации драйвера. Текущий заголовочный файл LCDC в OpenSiFli определяет LCDC_SUPPORTED_COMPRESSED_LAYER, только если включён HAL_EXTDMA_MODULE_ENABLED и это допускает условие для семейства; SF32LB52x и SF32LB57x исключены. В комментарии к исходному коду также отмечено, что тракт LCPU не включён. В опубликованной таблице возможностей LCDC в SDK декомпрессия сжатых слоёв для SF32LB55x помечена как неподдерживаемая. Поэтому поддержку 55x следует считать условной, а не проверенной для полного тракта на работающем устройстве. Проверьте точную версию SDK, ядро, конфигурацию сборки и целевое оборудование; см. раздел TurboPixel.

Роли этапов графического тракта SF32
Блок Этап тракта Основная функция Что он не заменяет
eZip / eZip-A До отрисовки, при чтении сохранённых ресурсов Без потерь распаковывает поддерживаемые графические ресурсы eZip, включая статические изображения и анимацию. Средство отрисовки, итоговый кадровый буфер или контроллер дисплея.
ePicasso Во время отрисовки и композиции Ускоряет поддерживаемые операции копирования, заливки, смешивания, преобразования и композиции пикселей в памяти. Сжатие ресурсов или передачу данных на панель.
TurboPixel После отрисовки, перед выводом на панель — на поддерживаемых устройствах С помощью extDMA сжимает итоговое растровое изображение с потерями и фиксированным коэффициентом, уменьшая требуемый объём PSRAM и чтение данных для дисплея. Текущий заголовок предоставляет поддержку сжатых слоёв для SF32LB55x, SF32LB56x и SF32LB58x при включённом extDMA и исключает SF32LB52x и SF32LB57x; в комментарии указано, что тракт LCPU не включён. В опубликованной таблице SDK 55x отмечен как неподдерживаемый, поэтому перед использованием проверьте ядро, конфигурацию SDK и тракт на целевом устройстве. Сжатие ресурсов без потерь или отрисовку пикселей.
Контроллер дисплея Финальный этап вывода При включённом тракте TurboPixel декодирует эти данные и передаёт подготовленные пиксели по интерфейсу панели. Декодирование ресурсов eZip или композицию графики.

Код приложения задаёт состояние и поведение интерфейса. UI-фреймворк управляет виджетами, областями перерисовки и отрисовкой. Графический драйвер определяет, выполнять поддерживаемые операции на CPU или ePicasso, и координирует работу с буферами; контроллер дисплея отвечает за передачу данных на панель. Подробности реализации отдельных блоков см. в статьях ePicasso, eZip и TurboPixel.

Сначала выберите дисплей

Выбор дисплея влияет почти на все графические решения. Прежде чем оптимизировать код, чётко определите требования к панели:

  • Разрешение.
  • Глубина цвета.
  • Частота обновления.
  • Тип интерфейса.
  • Требования к контроллеру сенсорного ввода.
  • Подсветка и линии питания дисплея.
  • Поддержка частичного обновления.
  • Наличие встроенной GRAM у панели.
  • Требуется ли постоянно включённый дисплей с низким энергопотреблением.

Небольшой AMOLED с интерфейсом SPI или QSPI работает совсем не так, как RGB-, MIPI DSI-, JDI-панель с технологией Memory-in-Pixel или EPD-панель. Один и тот же UI-фреймворк может использоваться с разными типами дисплеев, но стратегию буферизации и обновления нужно выбирать с учётом конкретной панели.

Подробнее о выборе интерфейса, передаче обновлённых областей (flush) и запуске панели см. в статье Контроллер дисплея.

Начните с проверенного примера LVGL

Прежде чем собирать экраны, выберите пример SDK, который проверяет наиболее рискованный для изделия участок графического тракта. В статье Примеры LVGL для SiFli-SDK официальные базовые примеры, средства проектирования, виджеты, сжатые ресурсы, анимация и мультимедиа, компас, игры и интерфейс часов сгруппированы по решаемым инженерным задачам. Там также указано, какие предположения о плате, версии, дисплее, памяти и производительности нужно повторно проверить при адаптации к изделию.

Выберите подходящее устройство SF32

Выбирайте микросхему с учётом дисплея и графической нагрузки, а не только частоты CPU.

Таблица: выбор устройства SF32
Требование Типичный выбор устройства
Простое Bluetooth-изделие с небольшим интерфейсом SF32LB52x
Начальный уровень смарт-часов, бейдж, метка или простая HMI SF32LB52x
Носимое BLE-устройство с насыщенным интерфейсом и множеством датчиков SF32LB55x
RGB-дисплей или более сложный интерфейс LVGL SF32LB56x
Аудио- и графические задачи, подходящие для переноса на ACPU SF32LB57x; проверьте поддержку SDK и распределение задач
Дисплей высокого разрешения или расширенная графика SF32LB56x или SF32LB58x
Дисплей MIPI DSI SF32LB55x или SF32LB58x — в зависимости от панели и класса изделия
Флагманский интерфейс с графикой, аудио, ИИ и большим объёмом памяти SF32LB58x

Ключевые ограничения — интерфейс и разрешение дисплея, объём памяти, поколение графического ускорителя, доступные выводы и бюджет энергопотребления.

Рассчитайте объём кадрового буфера и пропускную способность

Оцените требования к памяти и передаче данных до выбора панели или стиля анимации:

framebuffer bytes = width x height x bytes_per_pixel
raw full-frame bandwidth = framebuffer bytes x frames_per_second

Примеры:

Таблица: объём кадрового буфера и трафик кадров
Панель Формат Один полный буфер Трафик полных кадров при 30 fps
240 x 240 RGB565 ~113 KiB ~3,46 MB/s
390 x 390 RGB565 ~297 KiB ~9,13 MB/s
454 x 454 RGB565 ~403 KiB ~12,37 MB/s
480 x 480 RGB888 ~675 KiB ~20,74 MB/s

Размеры буферов указаны в KiB (1 024 байта), пропускная способность — в десятичных MB/s (1 000 000 байт/с). Это расчёт только для исходных данных пикселей: в нём не учтены накладные расходы команд, выравнивание, обслуживание кэша, чтение ресурсов, смешивание и другие потоки данных в системе. Если одновременно работают Bluetooth-аудио или ИИ либо используется внешняя PSRAM, закладывайте дополнительный запас.

Разберитесь в типах буферов

В конечном счёте интерфейс представлен пикселями в памяти. Основные типы буферов:

Таблица: типы графических буферов
Тип буфера Назначение
Буфер отрисовки Временная область, где LVGL или графический драйвер формирует изменившиеся участки изображения.
Кадровый буфер Память с пикселями всего экрана, служащая источником для вывода на дисплей.
Частичный кадровый буфер Буфер меньшей области, применяемый, когда полноэкранная буферизация слишком затратна.
Буфер ресурсов Данные изображений, шрифтов, значков или уже декодированных ресурсов.
Промежуточный слой Временная поверхность для смешивания, анимации или композиции.

Полноэкранный кадровый буфер удобен, но на больших панелях может занимать слишком много SRAM. Буфер RGB565 размером 454 x 454 содержит 412 232 байта (около 412 kB или 403 KiB); для двух буферов требуется вдвое больше. При увеличении разрешения и глубины цвета объём памяти быстро растёт.

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

Тщательно выбирайте глубину цвета

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

Таблица: форматы и глубина цвета
Формат Байтов на пиксель Примечания
RGB565 2 Распространённый баланс для встроенных интерфейсов: эффективно использует память и пропускную способность.
RGB666 3 или в упакованном виде Более высокая точность цвета, но выше требования к пропускной способности.
RGB888 3 Более высокое качество при больших затратах памяти и трафика.
RGB111 / монохромные форматы Зависит от устройства Подходят для простых дисплеев и экранов со сверхнизким энергопотреблением, например EPD/JDI.

Для большинства носимых устройств и компактных HMI RGB565 — разумный вариант по умолчанию, если панель, требования к качеству изображения или изделие не требуют другого формата.

Прозрачность, alpha и композиция слоёв

Прозрачность задаётся коэффициентом alpha, который определяет, насколько пиксель переднего плана влияет на изображение при наложении на фон. Alpha не зависит от каналов RGB. У непрозрачного пикселя alpha равен 1 (или 255 для 8-битного канала alpha), у полностью прозрачного — 0.

При композиции source-over на непрозрачном фоне, когда RGB переднего плана не умножен заранее на alpha, а alpha нормирован в диапазоне 0–1, каждый выходной канал RGB вычисляется по следующей формуле. Эта упрощённая формула не определяет выходной канал alpha при прозрачном фоне:

output = foreground × alpha + background × (1 − alpha)

Например, пиксель значка с alpha 50 % вносит половину своего цвета, а другая половина фона остаётся видимой. Повторение этой операции формирует слои интерфейса: фон, изображения, текст, полупрозрачные элементы управления, тени и анимацию. Итоговое составное растровое изображение затем проходит этапы кадрового буфера и контроллера дисплея, показанные выше.

Таблица: режимы alpha и области применения
Режим alpha Значение Типичное применение Особенности интеграции
Alpha для каждого пикселя У каждого пикселя есть собственное значение alpha. Сглаженные значки и текст, мягкие края, тени, ресурсы в формате наподобие PNG. Точно передаёт прозрачность, но увеличивает размер исходных данных и объём операций смешивания.
Глобальный alpha Одно значение alpha действует на весь объект или слой. Плавное появление/исчезновение экрана, диалога или изображения. Эффективен для равномерного затухания, но не задаёт мягкие края внутри объекта.
Бинарный alpha Пиксель либо полностью виден, либо полностью прозрачен. Маски и простые глифы. Требует меньше вычислений, но без сглаживания края могут быть ступенчатыми.

В RGB565 нет канала alpha, поэтому этот формат обычно используют для непрозрачных буферов отрисовки и итоговых кадровых буферов. Для исходных ресурсов и промежуточных слоёв с прозрачностью обычно применяют формат с каналом alpha, например ARGB8888, либо цветное изображение с отдельной alpha-маской. Драйвер должен использовать только форматы, поддерживаемые выбранными SDK, трактом дисплея и ускорителем.

Распространены два представления alpha. При обычном alpha (straight alpha) RGB хранит исходный цвет, а alpha применяется во время смешивания. При предварительно умноженном alpha (premultiplied alpha) значения RGB уже умножены на alpha; формула source-over принимает вид output = premultiplied_foreground + background × (1 − alpha). Не смешивайте эти представления: если интерпретировать обычные данные как предварительно умноженные или наоборот, по краям появятся тёмные либо светлые ореолы.

Alpha-смешивание считывает пиксели переднего плана и целевого буфера, а затем записывает результат. Поэтому трафик памяти выше, чем при обычном непрозрачном копировании или заливке. Используйте ePicasso, если драйвер поддерживает выбранную операцию смешивания и форматы пикселей; в остальных случаях оставляйте обработку на CPU. Ограничивайте полноэкранные полупрозрачные слои, обновляйте только области, требующие перерисовки, и не создавайте лишние промежуточные поверхности, если ограничены пропускная способность PSRAM или энергопотребление.

Интеграция LVGL

LVGL подходит для интерфейсов на устройствах SF32: он предоставляет виджеты, стили, обработку ввода, анимацию, инвалидацию областей и точки подключения драйвера дисплея.

Для типичной интеграции LVGL нужны:

  • Функция обратного вызова передачи дисплею (flush) в драйвере.
  • Один или несколько буферов отрисовки.
  • Источник системных тиков для LVGL.
  • Драйверы устройств ввода: сенсорного экрана, кнопок, энкодеров или жестов.
  • Обработка ресурсов, таких как изображения и шрифты.
  • Необязательные точки подключения аппаратного ускорения ePicasso.

Функция обратного вызова передачи дисплею (flush) задаёт границу между отрисовкой и выводом изображения. Поведение контроллера и DMA описано в статье Контроллер дисплея.

Решения при переносе LVGL

До окончательной настройки экранов определите следующие параметры интеграции LVGL:

Таблица: решения при переносе LVGL
Решение Рекомендуемый подход
Источник тиков Стабильный системный тик, корректно продолжающийся после сна и пробуждения.
Функция обратного вызова flush Передача с учётом области обновления и сигналом завершения от DMA или драйвера дисплея.
Число буферов отрисовки Один или два — в зависимости от задержки и бюджета памяти.
Области, требующие перерисовки Объединяйте небольшие области только тогда, когда это снижает общие затраты на передачу.
Устройства ввода Подключайте сенсорный экран, кнопки и энкодер через драйверы ввода LVGL, а не циклы опроса в приложении.
Аппаратное ускорение Включайте только операции, поддерживаемые SDK/драйвером, и сохраняйте вариант отрисовки на CPU.
Работа с кэшем Очищайте или инвалидируйте общие буферы на границе между фреймворком и драйвером.

При качественном переносе LVGL код экранов описывает интерфейс, а драйвер отвечает за передачу данных, синхронизацию, ускорение и работу с кэшем.

Использование ускорения ePicasso

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

  • Заливка прямоугольников.
  • Копирование и blit изображений.
  • Alpha-смешивание.
  • Масштабирование изображений.
  • Поворот или преобразование поддерживаемых областей изображения.
  • Композиция слоёв.
  • Преобразование формата пикселей, если оно поддерживается драйвером.

При хорошем переносе ускоряются часто используемые операции с большим объёмом данных, а для неподдерживаемых случаев сохраняется обработка на CPU. Не предполагайте, что аппаратно ускоряется любой эффект стиля или виджет LVGL. Измеряйте те экраны, которые важны для изделия.

Когда ускорение наиболее эффективно

ePicasso обычно приносит наибольшую пользу, когда:

  • Нужно заливать, копировать, смешивать, масштабировать или преобразовывать большие области.
  • В интерфейсе есть прозрачные значки, маски текста, тени, наложения или анимированные переходы.
  • Без ускорения CPU тратит значительную часть времени каждого кадра на обработку пикселей.
  • Размещение в памяти и форматы пикселей подходят ускорителю.

Когда ускорение может почти не помочь

Аппаратное ускорение может дать ограниченный эффект, если:

  • Обновляемая область очень мала.
  • Ограничением является пропускная способность интерфейса панели, а не отрисовка.
  • Ресурсы имеют неподдерживаемый формат или требуют затратного преобразования.
  • Буферы размещены в медленной памяти с недостаточной пропускной способностью.
  • Затраты на обслуживание кэша преобладают в общей стоимости операции.

Стратегия размещения данных в памяти

Производительность графики часто ограничивает перемещение данных. Продуманно размещайте буферы:

  • По возможности храните часто используемые буферы отрисовки в быстрой SRAM.
  • Размещайте большие кадровые буферы в PSRAM только при недостатке SRAM.
  • Храните крупные изображения и шрифты во флеш-памяти или PSRAM, учитывая задержку доступа.
  • Не преобразуйте ресурсы повторно во время работы программы.
  • Выравнивайте буферы, к которым обращается DMA, согласно рекомендациям SDK.
  • Используйте сжатые или индексированные ресурсы, если это сокращает общий трафик и затраты на декодирование.

Когда CPU и графические блоки или контроллер дисплея совместно используют буферы, соблюдайте правила SDK по обслуживанию кэша и владению буфером. Перед чтением аппаратурой данных CPU выполните clean соответствующих строк кэша и необходимую синхронизацию. Перед аппаратной записью подготовьте буфер так, чтобы изменённые строки кэша CPU не были позднее записаны в память поверх результата. Дождитесь завершения передачи, затем инвалидируйте устаревшие строки кэша перед чтением результата CPU. Учитывайте выравнивание по строкам кэша и соседние данные; не изменяйте буфер, пока им владеет аппаратура. Используйте предусмотренные SDK функции: clean и invalidate не взаимозаменяемы.

О частичном обновлении, особенностях панелей и последовательности запуска см. в статье Контроллер дисплея.

Подготовка графических ресурсов

Подготовка ресурсов может ускорить интерфейс ещё до оптимизации кода.

Практические рекомендации:

  • Используйте изображения фактического размера, в котором они будут показаны на экране.
  • Не масштабируйте большие изображения на каждом кадре.
  • По возможности заранее формируйте сложные тени, градиенты и фоны.
  • Используйте alpha только там, где нужна прозрачность.
  • Предпочитайте общие наборы значков и подмножества шрифтов.
  • Удаляйте из шрифтов неиспользуемые глифы.
  • Выбирайте форматы ресурсов, эффективно обрабатываемые графическим трактом.

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

Стратегия анимации

Плавность анимации зависит от бюджета кадра, пропускной способности панели, затрат на отрисовку и энергопотребления.

Практический подход:

  • Анимируйте только то, что заметно пользователю.
  • Ограничивайте площадь анимируемых областей.
  • Предпочитайте преобразования или изменение прозрачности, подходящие для ускорения.
  • Не применяйте размытие, тени или прозрачность ко всему экрану на каждом кадре.
  • Снижайте частоту кадров для второстепенных эффектов.
  • Останавливайте анимацию, когда экран затемнён, перекрыт или неактивен.

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

Матрица проверки графики

Используйте воспроизводимые тестовые экраны, а не субъективную оценку «достаточно плавно»:

Таблица: матрица проверки графики
Тестовый экран Что он проверяет
Сплошная заливка и цветовые полосы Формат пикселей, порядок байтов и путь передачи обновлённой области (flush).
Экран с большим объёмом текста Память шрифтов, кэш глифов и частичное обновление.
Сетка значков с alpha Смешивание, трафик ресурсов и путь ePicasso.
Прокручиваемый список Области перерисовки, пропускная способность передачи и задержка ввода.
Полноэкранный переход Бюджет кадра, двойная буферизация и пропускная способность панели.
Затемнённый/неактивный экран Политику остановки анимации, подсветку и запросы управления питанием (PM vote).
Наихудший сценарий совместной работы Одновременную работу Bluetooth, аудио или ИИ при обновлении интерфейса.

Для каждого экрана записывайте время отрисовки, время передачи обновлённой области (flush), загрузку CPU и энергопотребление. Если измерять только полное время кадра, сложно понять, ограничивает ли производительность LVGL, ePicasso, память или интерфейс панели.

Диагностика производительности графики

Если интерфейс работает медленно, сначала найдите узкое место, а затем меняйте проект.

Таблица: диагностика производительности графики
Симптом Что проверить в первую очередь
Высокая загрузка CPU при отрисовке Отсутствие аппаратного ускорения, избыток программных операций с пикселями или сложные виджеты.
Отрисовка завершена, но дисплей обновляется медленно Пропускную способность интерфейса панели, размер передаваемой области и путь передачи драйвера дисплея.
Разрывы изображения или мерцание Стратегию буферизации, синхронизацию и время частичного обновления.
Случайные артефакты Когерентность кэша, срок жизни буфера или несовпадение шага строки (stride) и формата пикселей.
Простые экраны работают хорошо, а анимация — плохо Перерисовку всего экрана, крупные alpha-смешивания, масштабирование ресурсов и пропускную способность панели.
Высокое потребление при неподвижном интерфейсе Лишнюю перерисовку, таймеры, анимацию или настройки дисплея/подсветки.

Измеряйте отдельно:

  • Время отрисовки LVGL.
  • Время операций ePicasso.
  • Время передачи данных дисплею (flush).
  • Загрузку CPU.
  • Нагрузку на пропускную способность памяти.
  • Потребление в активном режиме, простое и сне.

Типичные ошибки

Избегайте ошибок, исправление которых на позднем этапе обходится дорого:

  • Выбирать интерфейс панели без оценки пропускной способности.
  • Перерисовывать весь экран при небольших изменениях интерфейса.
  • Хранить все ресурсы в медленной памяти без профилирования.
  • Использовать RGB888, когда достаточно RGB565.
  • Масштабировать крупные изображения на каждом кадре.
  • Забывать об обслуживании кэша для общих с аппаратурой буферов.
  • Считать, что ePicasso автоматически ускоряет любую операцию интерфейса.
  • Использовать слишком много таймеров и анимаций, не давая CPU перейти в сон.
  • Игнорировать задержку сенсорного ввода, оптимизируя только частоту кадров.
  • Откладывать проверку инициализации панели до запуска платы.

Контрольный список запуска

Используйте этот список при начале графического проекта на SF32:

  • Подтвердите разрешение, глубину цвета, интерфейс и микросхему контроллера панели.
  • Проверьте, поддерживает ли выбранное устройство SF32 нужный интерфейс дисплея.
  • Оцените требования к памяти для кадрового буфера и буферов отрисовки.
  • Выберите стратегию: полный или частичный буфер, один или два буфера.
  • Проверьте сброс, линии питания, подсветку и последовательность инициализации панели.
  • Реализуйте системный тик LVGL, передачу обновлённых областей (flush) и драйверы устройств ввода.
  • Проверьте заливку, вывод изображений и текста, а также сенсорный ввод.
  • Включите ускорение ePicasso, если оно поддерживается SDK и драйвером.
  • Проверьте очистку/инвалидацию кэша для общих буферов.
  • Измерьте время отрисовки, время передачи обновлённых областей (flush), загрузку CPU и энергопотребление.
  • Проверьте сложные экраны, анимацию, активность Bluetooth, переходы в сон и пробуждение.

Основные выводы

  • Начинайте проектирование графики с интерфейса дисплея, разрешения, глубины цвета и требований к обновлению.
  • Используйте LVGL или похожий фреймворк для управления виджетами, областями перерисовки, отрисовкой и вводом.
  • Применяйте ePicasso для поддерживаемых операций с пикселями, сохраняя резервный путь на CPU.
  • Уделяйте размещению памяти и стратегии буферизации не меньше внимания, чем коду отрисовки.
  • Предпочитайте частичное обновление на панелях с ограниченной пропускной способностью и статичных экранах носимых устройств.
  • Рассматривайте производительность интерфейса как системную задачу: CPU, ePicasso, память, контроллер дисплея, интерфейс панели, сенсорный ввод и политика управления питанием.

Последнее обновление: