mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
163 lines
12 KiB
C
163 lines
12 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
#pragma once
|
|
|
|
#include <stddef.h>
|
|
#include <stdint.h>
|
|
#include "esp_bit_defs.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
#define RGB_PANEL_SWAP_XY 0
|
|
#define RGB_PANEL_MIRROR_Y 1
|
|
#define RGB_PANEL_MIRROR_X 2
|
|
|
|
typedef enum {
|
|
ROTATE_MASK_SWAP_XY = BIT(RGB_PANEL_SWAP_XY),
|
|
ROTATE_MASK_MIRROR_Y = BIT(RGB_PANEL_MIRROR_Y),
|
|
ROTATE_MASK_MIRROR_X = BIT(RGB_PANEL_MIRROR_X),
|
|
} panel_rotate_mask_t;
|
|
|
|
__attribute__((always_inline))
|
|
static inline void copy_pixel_8bpp(uint8_t *to, const uint8_t *from)
|
|
{
|
|
*to++ = *from++;
|
|
}
|
|
|
|
__attribute__((always_inline))
|
|
static inline void copy_pixel_16bpp(uint8_t *to, const uint8_t *from)
|
|
{
|
|
*to++ = *from++;
|
|
*to++ = *from++;
|
|
}
|
|
|
|
__attribute__((always_inline))
|
|
static inline void copy_pixel_24bpp(uint8_t *to, const uint8_t *from)
|
|
{
|
|
*to++ = *from++;
|
|
*to++ = *from++;
|
|
*to++ = *from++;
|
|
}
|
|
|
|
#define COPY_PIXEL_CODE_BLOCK(_bpp) \
|
|
switch (rgb_panel->rotate_mask) \
|
|
{ \
|
|
case 0: \
|
|
{ \
|
|
uint8_t *to = fb + (y_start * h_res + x_start) * bytes_per_pixel; \
|
|
for (int y = y_start; y < y_end; y++) \
|
|
{ \
|
|
memcpy(to, from, copy_bytes_per_line); \
|
|
to += bytes_per_line; \
|
|
from += copy_bytes_per_line; \
|
|
} \
|
|
bytes_to_flush = (y_end - y_start) * bytes_per_line; \
|
|
flush_ptr = fb + y_start * bytes_per_line; \
|
|
} \
|
|
break; \
|
|
case ROTATE_MASK_MIRROR_X: \
|
|
for (int y = y_start; y < y_end; y++) \
|
|
{ \
|
|
uint32_t index = (y * h_res + (h_res - 1 - x_start)) * bytes_per_pixel; \
|
|
for (size_t x = x_start; x < x_end; x++) \
|
|
{ \
|
|
copy_pixel_##_bpp##bpp(to + index, from); \
|
|
index -= bytes_per_pixel; \
|
|
from += bytes_per_pixel; \
|
|
} \
|
|
} \
|
|
bytes_to_flush = (y_end - y_start) * bytes_per_line; \
|
|
flush_ptr = fb + y_start * bytes_per_line; \
|
|
break; \
|
|
case ROTATE_MASK_MIRROR_Y: \
|
|
{ \
|
|
uint8_t *to = fb + ((v_res - 1 - y_start) * h_res + x_start) * bytes_per_pixel; \
|
|
for (int y = y_start; y < y_end; y++) \
|
|
{ \
|
|
memcpy(to, from, copy_bytes_per_line); \
|
|
to -= bytes_per_line; \
|
|
from += copy_bytes_per_line; \
|
|
} \
|
|
bytes_to_flush = (y_end - y_start) * bytes_per_line; \
|
|
flush_ptr = fb + (v_res - y_end) * bytes_per_line; \
|
|
} \
|
|
break; \
|
|
case ROTATE_MASK_MIRROR_X | ROTATE_MASK_MIRROR_Y: \
|
|
for (int y = y_start; y < y_end; y++) \
|
|
{ \
|
|
uint32_t index = ((v_res - 1 - y) * h_res + (h_res - 1 - x_start)) * bytes_per_pixel; \
|
|
for (size_t x = x_start; x < x_end; x++) \
|
|
{ \
|
|
copy_pixel_##_bpp##bpp(to + index, from); \
|
|
index -= bytes_per_pixel; \
|
|
from += bytes_per_pixel; \
|
|
} \
|
|
} \
|
|
bytes_to_flush = (y_end - y_start) * bytes_per_line; \
|
|
flush_ptr = fb + (v_res - y_end) * bytes_per_line; \
|
|
break; \
|
|
case ROTATE_MASK_SWAP_XY: \
|
|
for (int y = y_start; y < y_end; y++) \
|
|
{ \
|
|
for (int x = x_start; x < x_end; x++) \
|
|
{ \
|
|
uint32_t j = y * copy_bytes_per_line + x * bytes_per_pixel - offset; \
|
|
uint32_t i = (x * h_res + y) * bytes_per_pixel; \
|
|
copy_pixel_##_bpp##bpp(to + i, from + j); \
|
|
} \
|
|
} \
|
|
bytes_to_flush = (x_end - x_start) * bytes_per_line; \
|
|
flush_ptr = fb + x_start * bytes_per_line; \
|
|
break; \
|
|
case ROTATE_MASK_SWAP_XY | ROTATE_MASK_MIRROR_X: \
|
|
for (int y = y_start; y < y_end; y++) \
|
|
{ \
|
|
for (int x = x_start; x < x_end; x++) \
|
|
{ \
|
|
uint32_t j = y * copy_bytes_per_line + x * bytes_per_pixel - offset; \
|
|
uint32_t i = (x * h_res + h_res - 1 - y) * bytes_per_pixel; \
|
|
copy_pixel_##_bpp##bpp(to + i, from + j); \
|
|
} \
|
|
} \
|
|
bytes_to_flush = (x_end - x_start) * bytes_per_line; \
|
|
flush_ptr = fb + x_start * bytes_per_line; \
|
|
break; \
|
|
case ROTATE_MASK_SWAP_XY | ROTATE_MASK_MIRROR_Y: \
|
|
for (int y = y_start; y < y_end; y++) \
|
|
{ \
|
|
for (int x = x_start; x < x_end; x++) \
|
|
{ \
|
|
uint32_t j = y * copy_bytes_per_line + x * bytes_per_pixel - offset; \
|
|
uint32_t i = ((v_res - 1 - x) * h_res + y) * bytes_per_pixel; \
|
|
copy_pixel_##_bpp##bpp(to + i, from + j); \
|
|
} \
|
|
} \
|
|
bytes_to_flush = (x_end - x_start) * bytes_per_line; \
|
|
flush_ptr = fb + (v_res - x_end) * bytes_per_line; \
|
|
break; \
|
|
case ROTATE_MASK_SWAP_XY | ROTATE_MASK_MIRROR_X | ROTATE_MASK_MIRROR_Y: \
|
|
for (int y = y_start; y < y_end; y++) \
|
|
{ \
|
|
for (int x = x_start; x < x_end; x++) \
|
|
{ \
|
|
uint32_t j = y * copy_bytes_per_line + x * bytes_per_pixel - offset; \
|
|
uint32_t i = ((v_res - 1 - x) * h_res + h_res - 1 - y) * bytes_per_pixel; \
|
|
copy_pixel_##_bpp##bpp(to + i, from + j); \
|
|
} \
|
|
} \
|
|
bytes_to_flush = (x_end - x_start) * bytes_per_line; \
|
|
flush_ptr = fb + (v_res - x_end) * bytes_per_line; \
|
|
break; \
|
|
default: \
|
|
break; \
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|