Я работаю над проектом встроенного Linux, использующим LVGL с драйвером DRM. Мне нужно повернуть отображаемый контент на 90 градусов, поскольку мой физический экран имеет разрешение 1080x1920 (книжная ориентация), но контент должен отображаться в ландшафтном режиме.
Драйвер DRM не поддерживает аппаратный поворот, поэтому я реализую вращение программно во время операции очистки кадрового буфера. Основная проблема заключается в том, что при этом создается несмежный шаблон копирования памяти, что существенно влияет на производительность (увеличивает потребление ресурсов ЦП и снижает частоту кадров).
Текущая реализация
Вот упрощенная версия моей функции сброса:
Код: Выделить всё
void drm_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
struct drm_buffer *fbuf = drm_dev.cur_bufs[1];
lv_coord_t w = (area->x2 - area->x1 + 1);
lv_coord_t h = (area->y2 - area->y1 + 1);
// For each pixel in the source buffer
for (int y = area->y1; y y2; y++) {
for (int x = area->x1; x x2; x++) {
// Rotate coordinates 90 degrees
int new_x = drm_dev.width - y - 1;
int new_y = x;
// Copy pixel to rotated position
uint8_t *dst = (uint8_t *)fbuf->map +
(new_x * (LV_COLOR_SIZE/8)) +
(fbuf->pitch * new_y);
lv_color_t *src = &color_p[(y - area->y1) * w + (x - area->x1)];
memcpy(dst, src, LV_COLOR_SIZE/8);
}
}
}
- Распараллеливание OpenMP;
- Буферизация строк для уменьшения фрагментации памяти;
- Инструкции SIMD (NEON на ARM);
- Частичные обновления для минимизации копируемой области;
Вопрос
< ol>
[*]Есть ли более эффективный способ справиться с такой операцией копирования памяти с поворотом?
[*]Поскольку угол поворота фиксирован (90 градусов), есть ли какие-либо какую математическую оптимизацию мы могли бы применить?
[*]Можем ли мы оптимизировать шаблон доступа к памяти, чтобы лучше использовать кэш?
[*]Существуют ли какие-либо известные алгоритмы или структуры данных, которые могли бы помочь снизить сложность ниже O(n)?< /li>
Сведения о системе
- Платформа: встроенный Linux (RV1126)
- Дисплей: Физическое разрешение 1080x1920.
- Глубина цвета: 32-битный ARGB8888.
Хотя я мог бы решить эту проблему, переделав пользовательский интерфейс в разрешении 1080x1920, я считаю это неразумным, поскольку для разработки программы мне придется наклонять шею.
Мы будем очень признательны за любые ответы и комментарии. Спасибо!
Подробнее здесь: https://stackoverflow.com/questions/791 ... inux-drm-d
Мобильная версия