Skip to content

Commit 88716d0

Browse files
committed
Merge branch 'refactor/reduce_bin_size_when_dsi_without_dma2d_v6.0' into 'release/v6.0'
feat(lcd): support draw bitmap hook function (v6.0) See merge request espressif/esp-idf!44047
2 parents 5ee94fa + 20bb7a2 commit 88716d0

File tree

20 files changed

+678
-80
lines changed

20 files changed

+678
-80
lines changed

components/esp_driver_i3c/i3c_master.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -768,7 +768,7 @@ static esp_err_t i3c_master_prepare_transaction(i3c_master_i2c_device_handle_t d
768768

769769
// Check if async transaction requires DMA
770770
if (dev_handle->bus_handle->async_transaction && !dev_handle->bus_handle->dma_initialized) {
771-
ESP_LOGE(TAG, "Async transaction requires DMA, please call i3c_master_bus_decorate_dma() first");
771+
ESP_LOGE(TAG, "Async transaction requires DMA, please call `i3c_master_bus_decorate_dma()` first");
772772
return ESP_ERR_INVALID_STATE;
773773
}
774774

components/esp_driver_parlio/src/parlio_tx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ static esp_err_t parlio_tx_create_trans_queue(parlio_tx_unit_t *tx_unit, const p
4949
static esp_err_t parlio_destroy_tx_unit(parlio_tx_unit_t *tx_unit)
5050
{
5151
if (tx_unit->bs_handle) {
52-
ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "please call parlio_tx_unit_undecorate_bitscrambler() before delete the tx unit");
52+
ESP_RETURN_ON_FALSE(false, ESP_ERR_INVALID_STATE, TAG, "please call `parlio_tx_unit_undecorate_bitscrambler()` before deleting the tx unit");
5353
}
5454
if (tx_unit->intr) {
5555
ESP_RETURN_ON_ERROR(esp_intr_free(tx_unit->intr), TAG, "delete interrupt service failed");

components/esp_lcd/dsi/esp_lcd_panel_dpi.c

Lines changed: 175 additions & 59 deletions
Large diffs are not rendered by default.

components/esp_lcd/dsi/include/esp_lcd_mipi_dsi.h

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,6 @@ typedef struct {
9393
esp_lcd_video_timing_t video_timing; /*!< Video timing */
9494
/// Extra configuration flags for MIPI DSI DPI panel
9595
struct extra_dpi_panel_flags {
96-
uint32_t use_dma2d: 1; /*!< Use DMA2D to copy user buffer to the frame buffer when necessary */
9796
uint32_t disable_lp: 1;/*!< Disable low-power for DPI */
9897
} flags; /*!< Extra configuration flags */
9998
} esp_lcd_dpi_panel_config_t;
@@ -200,6 +199,92 @@ typedef struct {
200199
*/
201200
esp_err_t esp_lcd_dpi_panel_register_event_callbacks(esp_lcd_panel_handle_t dpi_panel, const esp_lcd_dpi_panel_event_callbacks_t *cbs, void *user_ctx);
202201

202+
/**
203+
* @brief Type of draw bitmap hook data
204+
*/
205+
typedef struct {
206+
void *dst_data; /*!< Destination buffer (usually frame buffer) */
207+
int dst_x_size; /*!< Destination bitmap width */
208+
int dst_y_size; /*!< Destination bitmap height */
209+
int dst_x_start; /*!< Destination start x coordinate */
210+
int dst_y_start; /*!< Destination start y coordinate */
211+
int dst_x_end; /*!< Destination end x coordinate (exclusive) */
212+
int dst_y_end; /*!< Destination end y coordinate (exclusive) */
213+
const void *src_data; /*!< Source bitmap data */
214+
int src_x_size; /*!< Source bitmap width */
215+
int src_y_size; /*!< Source bitmap height */
216+
int src_x_start; /*!< Source start x coordinate */
217+
int src_y_start; /*!< Source start y coordinate */
218+
int src_x_end; /*!< Source end x coordinate (exclusive) */
219+
int src_y_end; /*!< Source end y coordinate (exclusive) */
220+
int bits_per_pixel; /*!< Bits per pixel */
221+
bool (*on_hook_end)(esp_lcd_panel_handle_t panel); /*!< Callback to be invoked when the hook completes its operation */
222+
} esp_lcd_draw_bitmap_hook_data_t;
223+
224+
/**
225+
* @brief draw bitmap hook function type for custom pixel processing operations
226+
*
227+
* This hook allows users to implement custom operations like scaling, rotation,
228+
* color space conversion, etc. using hardware accelerators like PPA or DMA2D.
229+
*
230+
* @note The hook should ensure the synchronization of draw operations on its own.
231+
*
232+
* @param[in] panel LCD panel handle
233+
* @param[in] hook_data Hook data
234+
* @param[in] hook_ctx Hook context
235+
* @return
236+
* - ESP_OK on success
237+
* - Other error codes on failure
238+
*/
239+
typedef esp_err_t (*esp_lcd_panel_draw_bitmap_hook_t)(esp_lcd_panel_handle_t panel, const esp_lcd_draw_bitmap_hook_data_t *hook_data, void* hook_ctx);
240+
241+
/**
242+
* @brief Type of LCD panel hooks
243+
*/
244+
typedef struct {
245+
esp_lcd_panel_draw_bitmap_hook_t draw_bitmap_hook; /*!< Draw bitmap hook function */
246+
} esp_lcd_panel_hooks_t;
247+
248+
/**
249+
* @brief Register panel hooks to the DPI panel
250+
*
251+
* @note You can register panel hooks to implement custom operations like scaling, rotation, color space conversion, etc.
252+
* with hardware accelerators like PPA or DMA2D.
253+
* The hook will be overridden when this function is called multiple times.
254+
*
255+
* @param[in] dpi_panel LCD DPI panel handle, which is returned from esp_lcd_new_panel_dpi()
256+
* @param[in] hooks Panel hooks
257+
* @param[in] hook_ctx Hook context
258+
* @return
259+
* - ESP_OK: Register hooks successfully
260+
* - Other error codes on failure
261+
*/
262+
esp_err_t esp_lcd_dpi_panel_register_hooks(esp_lcd_panel_handle_t dpi_panel, const esp_lcd_panel_hooks_t *hooks, void *hook_ctx);
263+
264+
/**
265+
* @brief Enable DMA2D for DPI panel
266+
*
267+
* @note The function will register a built-in DMA2D draw bitmap hook to perform draw bitmap operations using DMA2D.
268+
*
269+
* @param[in] dpi_panel LCD DPI panel handle, which is returned from esp_lcd_new_panel_dpi()
270+
* @return
271+
* - ESP_OK: Enable DMA2D successfully
272+
* - Other error codes on failure
273+
*/
274+
esp_err_t esp_lcd_dpi_panel_enable_dma2d(esp_lcd_panel_handle_t dpi_panel);
275+
276+
/**
277+
* @brief Disable DMA2D for DPI panel
278+
*
279+
* @note The function will unregister the built-in DMA2D draw bitmap hook.
280+
*
281+
* @param[in] dpi_panel LCD DPI panel handle, which is returned from esp_lcd_new_panel_dpi()
282+
* @return
283+
* - ESP_OK: Disable DMA2D successfully
284+
* - Other error codes on failure
285+
*/
286+
esp_err_t esp_lcd_dpi_panel_disable_dma2d(esp_lcd_panel_handle_t dpi_panel);
287+
203288
#ifdef __cplusplus
204289
}
205290
#endif

components/esp_lcd/include/esp_lcd_panel_ops.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,31 @@ esp_err_t esp_lcd_panel_del(esp_lcd_panel_handle_t panel);
5858
*/
5959
esp_err_t esp_lcd_panel_draw_bitmap(esp_lcd_panel_handle_t panel, int x_start, int y_start, int x_end, int y_end, const void *color_data);
6060

61+
/**
62+
* @brief Draw partial source bitmap on LCD panel
63+
*
64+
* This function allows drawing a portion of a source bitmap to a specific area on the LCD panel.
65+
*
66+
* @param[in] panel LCD panel handle, which is created by other factory API like `esp_lcd_new_panel_st7789()`
67+
* @param[in] x_start Start pixel index in the target frame buffer, on x-axis (x_start is included)
68+
* @param[in] y_start Start pixel index in the target frame buffer, on y-axis (y_start is included)
69+
* @param[in] x_end End pixel index in the target frame buffer, on x-axis (x_end is not included)
70+
* @param[in] y_end End pixel index in the target frame buffer, on y-axis (y_end is not included)
71+
* @param[in] color_data Source bitmap data
72+
* @param[in] src_x_size Size of the source bitmap in the x-axis
73+
* @param[in] src_y_size Size of the source bitmap in the y-axis
74+
* @param[in] src_x_start Start pixel index in the source bitmap, on x-axis (src_x_start is included)
75+
* @param[in] src_y_start Start pixel index in the source bitmap, on y-axis (src_y_start is included)
76+
* @param[in] src_x_end End pixel index in the source bitmap, on x-axis (src_x_end is not included)
77+
* @param[in] src_y_end End pixel index in the source bitmap, on y-axis (src_y_end is not included)
78+
* @return
79+
* - ESP_OK on success
80+
* - ESP_ERR_INVALID_ARG if parameters are invalid
81+
* - ESP_ERR_NOT_SUPPORTED if this function is not supported by the panel
82+
*/
83+
esp_err_t esp_lcd_panel_draw_bitmap_2d(esp_lcd_panel_handle_t panel, int x_start, int y_start, int x_end, int y_end, const void *color_data,
84+
size_t src_x_size, size_t src_y_size, int src_x_start, int src_y_start, int src_x_end, int src_y_end);
85+
6186
/**
6287
* @brief Mirror the LCD panel on specific axis
6388
*

components/esp_lcd/interface/esp_lcd_panel_interface.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -59,6 +59,27 @@ struct esp_lcd_panel_t {
5959
*/
6060
esp_err_t (*draw_bitmap)(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end, const void *color_data);
6161

62+
/**
63+
* @brief Draw partial bitmap on LCD panel
64+
*
65+
* @param[in] panel LCD panel handle, which is created by other factory API like `esp_lcd_new_panel_st7789()`
66+
* @param[in] x_start Start pixel index in the target frame buffer, on x-axis (x_start is included)
67+
* @param[in] y_start Start pixel index in the target frame buffer, on y-axis (y_start is included)
68+
* @param[in] x_end End pixel index in the target frame buffer, on x-axis (x_end is not included)
69+
* @param[in] y_end End pixel index in the target frame buffer, on y-axis (y_end is not included)
70+
* @param[in] src_data Source bitmap data
71+
* @param[in] src_x_size Size of the source bitmap in the x-axis
72+
* @param[in] src_y_size Size of the source bitmap in the y-axis
73+
* @param[in] src_x_start Start pixel index in the source bitmap, on x-axis (src_x_start is included)
74+
* @param[in] src_y_start Start pixel index in the source bitmap, on y-axis (src_y_start is included)
75+
* @param[in] src_x_end End pixel index in the source bitmap, on x-axis (src_x_end is not included)
76+
* @param[in] src_y_end End pixel index in the source bitmap, on y-axis (src_y_end is not included)
77+
* @return
78+
* - ESP_OK on success
79+
*/
80+
esp_err_t (*draw_bitmap_2d)(esp_lcd_panel_t *panel, int x_start, int y_start, int x_end, int y_end,
81+
const void *src_data, size_t src_x_size, size_t src_y_size, int src_x_start, int src_y_start, int src_x_end, int src_y_end);
82+
6283
/**
6384
* @brief Mirror the LCD panel on specific axis
6485
*

components/esp_lcd/src/esp_async_fbcpy.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -188,6 +188,13 @@ esp_err_t esp_async_fbcpy(esp_async_fbcpy_handle_t mcp, esp_async_fbcpy_trans_de
188188
mcp->memcpy_done_cb = memcpy_done_cb;
189189
mcp->cb_args = cb_args;
190190

191+
// write back the user's draw buffer, so that the DMA can see the correct data
192+
// Note, the user src buffer may not be contiguous, writeback from the head to the tail anyways
193+
size_t bits_per_pixel = color_hal_pixel_format_fourcc_get_bit_depth(transaction->pixel_format_fourcc_id);
194+
size_t copy_head = (transaction->src_offset_x + transaction->src_offset_y * transaction->src_buffer_size_x) * bits_per_pixel / 8;
195+
size_t copy_size = (transaction->copy_size_x + transaction->copy_size_y * transaction->src_buffer_size_x) * bits_per_pixel / 8;
196+
ESP_RETURN_ON_ERROR(esp_cache_msync((void *)transaction->src_buffer + copy_head, copy_size, ESP_CACHE_MSYNC_FLAG_DIR_C2M | ESP_CACHE_MSYNC_FLAG_UNALIGNED), TAG, "writeback draw buffer failed");
197+
191198
// mount the data to the DMA descriptor
192199
async_memcpy_setup_dma2d_descriptor(mcp, transaction);
193200

components/esp_lcd/src/esp_lcd_panel_ops.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -37,6 +37,16 @@ esp_err_t esp_lcd_panel_draw_bitmap(esp_lcd_panel_handle_t panel, int x_start, i
3737
return panel->draw_bitmap(panel, x_start, y_start, x_end, y_end, color_data);
3838
}
3939

40+
esp_err_t esp_lcd_panel_draw_bitmap_2d(esp_lcd_panel_handle_t panel, int x_start, int y_start, int x_end, int y_end,
41+
const void *color_data, size_t src_x_size, size_t src_y_size, int src_x_start, int src_y_start, int src_x_end, int src_y_end)
42+
{
43+
ESP_RETURN_ON_FALSE(panel, ESP_ERR_INVALID_ARG, TAG, "invalid panel handle");
44+
ESP_RETURN_ON_FALSE(panel->draw_bitmap_2d, ESP_ERR_NOT_SUPPORTED, TAG, "draw_bitmap_2d is not supported by this panel");
45+
ESP_RETURN_ON_FALSE((x_start < x_end) && (y_start < y_end), ESP_ERR_INVALID_ARG, TAG, "start position must be smaller than end position");
46+
ESP_RETURN_ON_FALSE((src_x_start < src_x_end) && (src_y_start < src_y_end), ESP_ERR_INVALID_ARG, TAG, "source start position must be smaller than end position");
47+
return panel->draw_bitmap_2d(panel, x_start, y_start, x_end, y_end, color_data, src_x_size, src_y_size, src_x_start, src_y_start, src_x_end, src_y_end);
48+
}
49+
4050
esp_err_t esp_lcd_panel_mirror(esp_lcd_panel_handle_t panel, bool mirror_x, bool mirror_y)
4151
{
4252
ESP_RETURN_ON_FALSE(panel, ESP_ERR_INVALID_ARG, TAG, "invalid panel handle");

components/esp_lcd/test_apps/mipi_dsi_lcd/main/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,5 @@ endif()
99
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
1010
# the component can be registered as WHOLE_ARCHIVE
1111
idf_component_register(SRCS ${srcs}
12-
PRIV_REQUIRES esp_lcd unity
12+
PRIV_REQUIRES esp_lcd unity esp_driver_ppa
1313
WHOLE_ARCHIVE)

components/esp_lcd/test_apps/mipi_dsi_lcd/main/test_mipi_dsi_iram.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
#include "test_mipi_dsi_board.h"
1919
#include "esp_lcd_ek79007.h"
2020

21-
IRAM_ATTR static bool test_rgb_panel_count_in_callback(esp_lcd_panel_handle_t panel, esp_lcd_dpi_panel_event_data_t *edata, void *user_ctx)
21+
IRAM_ATTR static bool test_dpi_panel_count_in_callback(esp_lcd_panel_handle_t panel, esp_lcd_dpi_panel_event_data_t *edata, void *user_ctx)
2222
{
2323
uint32_t *count = (uint32_t *)user_ctx;
2424
*count = *count + 1;
@@ -91,7 +91,7 @@ TEST_CASE("MIPI DSI draw bitmap (EK79007) IRAM Safe", "[mipi_dsi]")
9191

9292
uint32_t callback_calls = 0;
9393
esp_lcd_dpi_panel_event_callbacks_t cbs = {
94-
.on_refresh_done = test_rgb_panel_count_in_callback,
94+
.on_refresh_done = test_dpi_panel_count_in_callback,
9595
};
9696
TEST_ESP_OK(esp_lcd_dpi_panel_register_event_callbacks(mipi_dpi_panel, &cbs, &callback_calls));
9797

0 commit comments

Comments
 (0)