ESP Display Present
esp_display_present 用于连接渲染器生成的像素表面与 esp_lcd 面板,不依赖
场景、控件或输入语义。送屏路径从 GUI 中抽出,LVGL、GSP 或其他自绘 GUI 可以共用
同一套 Presenter。
它不是 esp_lvgl_adapter。LVGL 9 请使用
ESP LV Present。
渲染器负责逻辑脏区和像素生成;Presenter 负责物理缓冲区一致性和面板提交。
功能
校验显示目标并选择合适的呈现策略
租用渲染表面或有界绘制缓冲区
提交整帧或脏区更新
处理帧缓冲区所有权、TE 同步、旋转、字节序、缓存同步和可选硬件拷贝
按顺序跟踪完成状态,并在关闭时避免提前释放传输中的缓冲区
添加到工程
idf.py add-dependency "espressif/esp_display_present"
或在 idf_component.yml 中:
dependencies:
espressif/esp_display_present: "*"
公共 API
包含 esp_display_present.h 即可使用公共 API。配置和共享类型分别定义在
esp_display_present_config.h 和 esp_display_present_types.h 中。
主要对象为 esp_display_presenter_t。
面板初始化前,使用 esp_display_present_get_required_frame_buffer_count(),
按明确的面板类型、模式、旋转和 TE 配置查询驱动的 num_fbs。
查询与创建共用静态策略,不访问面板句柄。IO/GRAM 返回 0,绘制缓冲和
TE compose 缓冲另行管理。创建面板后填入句柄,用同一目标配置创建 Presenter。
使用驱动自有缓冲时,保持 target.fb.frame_buffer_count = 0。
渲染器随后按以下顺序工作:
使用
esp_display_present_target_config_t创建 Presenter获取帧契约
渲染请求的完整表面或分区
提交逻辑覆盖范围,或取消当前帧
等待生产端工作排空后停止并删除 Presenter
绘制契约:
契约 |
渲染器职责 |
|---|---|
PARTITION |
将请求区域渲染到 Presenter 持有的绘制缓冲区 |
DIRECT |
将脏区渲染到完整逻辑表面 |
FULL |
重绘完整逻辑表面 |
呈现模式通常应保持 ESP_DISPLAY_PRESENT_MODE_AUTO。在目标配置中提供准确的
面板类型、Framebuffer、TE、旋转和字节序信息,组件即可选择正确路径。
内部 RAM 充足时,PARTIAL 和 TE 模式会使用第二个绘制缓冲区,使条带拷贝与渲染
重叠。内存紧张的应用可设置 drawbuf.buffers = 1 保持单个绘制缓冲区。
关屏或拆除面板前,先停止帧生产并调用 esp_display_presenter_quiesce()。
在 quiesce 成功之前必须保持面板 IO 和完成中断有效,然后再关屏并删除 Presenter。
更多说明
参见组件 README:
LVGL benchmark example 位于 examples/display/gui/lvgl_present_benchmark。
GSP/LVGL 所有权切换 example 位于 examples/display/gui/gsp_lvgl_present_handoff。
Unity test app 位于 components/display/tools/esp_display_present/test_apps。
API 参考
Header File
Functions
-
esp_err_t esp_display_present_get_required_frame_buffer_count(const esp_display_present_target_config_t *config, uint8_t *out_count)
Query the minimum number of panel framebuffers before creating the panel.
Set an explicit RGB, MIPI-DSI or IO panel type. Only panel type, mode, rotation and TE configuration are read; handles, supplied framebuffers, pixel format and draw-buffer settings are ignored. This query performs static policy validation without accessing hardware or allocating memory.
IO/GRAM returns 0: draw buffers and TE compose buffers are separate. Presenter creation still validates the actual handles and buffer storage.
out_countis set to 0 on error when non-NULL.- 返回
ESP_OK on success, ESP_ERR_INVALID_ARG for invalid arguments, ESP_ERR_NOT_SUPPORTED for an unresolved panel type or unsupported mode, rotation or TE combination.
-
esp_err_t esp_display_presenter_create(const esp_display_presenter_config_t *config, esp_display_presenter_t **out_presenter)
Create a renderer endpoint and bind all required target callbacks.
Renderer calls are single-task and serialize acquire, submit and cancel. A control task may request stop, but delete has one exclusive owner and must not race another API call. Hardware callbacks run in ISR context; the component keeps their state alive until stop has drained them.
-
esp_err_t esp_display_presenter_stop(esp_display_presenter_t *presenter)
Enter CLOSING and stop after all asynchronous work has retired. New acquire calls fail with ESP_ERR_INVALID_STATE. An active lease must be cancelled by its renderer. Retry ESP_ERR_INVALID_STATE while renderer calls or hardware work are in flight. A terminal hardware fault never reopens the presenter.
-
esp_err_t esp_display_presenter_delete(esp_display_presenter_t *presenter)
Stop, detach callbacks and release the target and endpoint.
On ESP_ERR_INVALID_STATE the object remains owned by the caller and must be retained for a later retry. Do not call delete concurrently from two tasks.
-
esp_err_t esp_display_presenter_set_rotation(esp_display_presenter_t *presenter, esp_display_present_rotation_t rotation)
Reconfigure logical-to-physical rotation without changing panel scan mode.
The producer must first stop submitting and quiesce the presenter. The presenter object remains valid and keeps the same address; its target and endpoint are rebuilt so all rotation-dependent storage and transforms are updated consistently. On failure, the previous configuration is restored.
-
esp_err_t esp_display_presenter_get_caps(const esp_display_presenter_t *presenter, esp_display_presenter_caps_t *out_caps)
-
esp_err_t esp_display_presenter_get_drawbuf(const esp_display_presenter_t *presenter, esp_display_presenter_drawbuf_t *out_drawbuf)
-
esp_err_t esp_display_presenter_get_buffer_alignment(const esp_display_presenter_t *presenter, size_t *out_alignment)
Read the minimum base-address alignment of all buffers that this presenter can lease to its renderer. The result is a power of two, in bytes. Query again after changing rotation, which rebuilds the renderer storage.
-
esp_err_t esp_display_presenter_rebind_producer(esp_display_presenter_t *presenter)
Rebind the serial render-task owner after a platform session handoff. Valid only between frames; it retains pending hardware completion fences.
-
esp_err_t esp_display_presenter_get_state(const esp_display_presenter_t *presenter, esp_display_presenter_state_t *out_state)
Read the monotonic lifecycle state; FAULTED never reopens in place.
-
esp_err_t esp_display_presenter_get_fault_reason(const esp_display_presenter_t *presenter, esp_display_present_fault_reason_t *out_reason)
Read why the presenter faulted. ESP_DISPLAY_PRESENT_FAULT_NONE means no fault was recorded. A transfer timeout is recoverable by deleting and recreating the presenter only when the endpoint can prove that hardware no longer owns its buffers (for example the framebuffer endpoint’s fault-stop path). GRAM/TE endpoints must retain storage until their transfer callback arrives. A producer protocol fault is a producer bug.
-
esp_err_t esp_display_presenter_map_point(const esp_display_presenter_t *presenter, int32_t *x, int32_t *y)
Map physical input coordinates into the logical render orientation.
-
esp_err_t esp_display_presenter_begin_next_frame(esp_display_presenter_t *presenter, const esp_display_present_surface_request_t *request, esp_display_present_area_t *out_render_areas, size_t render_area_capacity, size_t *out_render_area_count, bool *out_full_coverage)
Begin a frame on the presenter-owned timeline and return the logical areas requiring rasterization. The asynchronous completion ticket is private to the presenter.
-
esp_err_t esp_display_presenter_acquire_buffer(esp_display_presenter_t *presenter, esp_display_presenter_buffer_t *out_buffer)
Lease producer storage without choosing a logical damage area.
-
esp_err_t esp_display_presenter_submit_buffer(esp_display_presenter_t *presenter, const esp_display_presenter_buffer_t *buffer, const esp_display_present_area_t *area, size_t stride_bytes)
Submit the rendered portion of a buffer lease.
Pixels start at buffer.surface.pixels and use
stride_bytes. The inclusive logicalareasupplies the destination position and rendered dimensions.
-
esp_err_t esp_display_presenter_commit_frame(esp_display_presenter_t *presenter, const esp_display_presenter_submit_t *submit)
Commit the active frame with explicit logical coverage.
-
void esp_display_presenter_cancel_frame(esp_display_presenter_t *presenter)
Cancel the active pre-commit frame and any held region from its bound producer task.
-
esp_err_t esp_display_presenter_quiesce(esp_display_presenter_t *presenter, uint32_t timeout_ms)
Wait until all work accepted before this call has completed transfer and presentation. The producer must already be stopped between frames.
Structures
-
struct esp_display_presenter_surface_t
Pixel surface description.
-
struct esp_display_presenter_config_t
Presenter creation parameters.
Public Members
-
uint16_t width
Logical display width in pixels.
-
uint16_t height
Logical display height in pixels.
-
esp_display_present_pixel_format_t pixel_format
Renderer output format; must match target.hw.input_pixel_format.
-
size_t max_damage_areas
Maximum dirty areas accepted per frame.
-
uint32_t transfer_timeout_ms
Per-push panel transfer completion budget in milliseconds; 0 selects ESP_DISPLAY_PRESENT_DEFAULT_TRANSFER_TIMEOUT_MS. A timeout faults the presenter with ESP_DISPLAY_PRESENT_FAULT_TRANSFER_TIMEOUT, so raise this for slow panels instead of accepting a terminal fault.
-
uint32_t pipeline_acquire_timeout_ms
FB pipeline free-buffer acquire budget in milliseconds; 0 selects ESP_DISPLAY_PRESENT_DEFAULT_PIPELINE_ACQUIRE_TIMEOUT_MS.
-
esp_display_present_target_config_t target
Panel hardware, present mode and endpoint memory configuration.
-
uint16_t width
-
struct esp_display_presenter_caps_t
Renderer-visible capabilities of a presenter.
Public Members
-
esp_display_present_contract_t contract
Public draw contract seen by GSP.
-
bool supports_coverage_areas
DIRECT/FULL only; true when submit may use COVERAGE_AREAS.
-
bool surface_retains_content
DIRECT/FULL only: pixels remain valid across frames for dirty rendering.
-
bool previous_surface_readable
DIRECT/FULL only: previous displayed surface can be read for scroll blits.
-
uint16_t width
Logical display width in pixels.
-
uint16_t height
Logical display height in pixels.
-
size_t stride_bytes
Preferred full-surface row stride in bytes.
-
esp_display_present_pixel_format_t pixel_format
Renderer output format.
-
size_t drawbuf_bytes
PARTITION only: bytes available in one acquired draw region.
-
size_t max_damage_areas
Maximum dirty areas accepted per frame.
-
esp_display_present_contract_t contract
-
struct esp_display_presenter_submit_t
Coverage supplied when submitting a DIRECT or FULL surface.
Public Members
-
esp_display_present_coverage_t coverage
Explicit coverage for a submitted surface. No-op updates are handled before acquire/submit. FULL ignores areas. AREAS requires non-empty areas.
-
const esp_display_present_area_t *areas
Covered logical areas for AREAS coverage.
-
size_t area_count
Number of entries in
areas.
-
esp_display_present_coverage_t coverage
-
struct esp_display_presenter_region_t
Drawable logical region leased for the current frame.
Public Members
-
esp_display_presenter_surface_t surface
Region pixel storage.
-
uint16_t origin_x
Logical X origin of the region.
-
uint16_t origin_y
Logical Y origin of the region.
-
esp_display_presenter_surface_t surface
-
struct esp_display_presenter_buffer_t
Producer-owned drawable-buffer lease.
Public Members
-
esp_display_presenter_surface_t surface
Preferred drawable surface layout.
-
size_t capacity_bytes
Authoritative writable storage capacity.
-
uint32_t lease_id
Identifier required by resolve, submit, or cancel.
-
esp_display_presenter_resolve_rows_cb_t resolve_rows
Resolve a legal row count after the producer chooses its stride.
-
void *resolve_rows_ctx
Opaque context for
resolve_rows.
-
esp_display_presenter_surface_t surface
-
struct esp_display_presenter_drawbuf_t
PARTITION only: borrow the presenter’s drawbuf pool pointers.
The pointers remain owned by the presenter for its lifetime. Producers such as LVGL may register them with lv_display_set_buffers() and render directly into them so flush can submit without an extra memcpy hop.
Macros
-
ESP_DISPLAY_PRESENT_DEFAULT_TRANSFER_TIMEOUT_MS
Default per-push panel transfer completion budget.
-
ESP_DISPLAY_PRESENT_DEFAULT_PIPELINE_ACQUIRE_TIMEOUT_MS
Default FB pipeline free-buffer acquire budget.
Type Definitions
-
typedef esp_err_t (*esp_display_presenter_resolve_rows_cb_t)(void *user_ctx, uint32_t lease_id, size_t stride_bytes, size_t requested_rows, size_t *out_rows)
Producer-neutral drawable buffer lease.
PARTITION/TE leases expose reusable scratch storage; FULL leases expose the complete logical surface. The producer chooses the logical area and the packed stride when submitting.
capacity_bytesis the authoritative storage limit; surface dimensions describe the presenter’s preferred full-width layout.
-
typedef struct esp_display_presenter esp_display_presenter_t
Enumerations
-
enum esp_display_present_contract_t
How GSP should talk to this presenter.
This is the public draw contract, not the transport implementation. Transport and framebuffer policy stay inside the presenter.
Values:
-
enumerator ESP_DISPLAY_PRESENT_CONTRACT_PARTITION
Submit partitioned areas through a shared draw buffer.
-
enumerator ESP_DISPLAY_PRESENT_CONTRACT_DIRECT
Submit dirty regions into a coherent draw surface.
-
enumerator ESP_DISPLAY_PRESENT_CONTRACT_FULL
Submit a full frame.
-
enumerator ESP_DISPLAY_PRESENT_CONTRACT_PARTITION
Header File
Structures
-
struct esp_display_present_te_sync_config_t
Optional panel TE sync. A zeroed config is disabled; gpio 0 is valid, so set
te_enabledwhen a TE line is wired.Frame/blanking/transfer timing is measured at runtime.
bus_freq_hzanddata_linesonly seed the first-frame transfer estimate before a real transfer duration has been observed.
-
struct esp_display_present_hw_config_t
Panel / bus hardware fact. Borrowed handles stay valid until presenter deletion.
RGB and MIPI-DPI have no distinct generic handle shape, so set
panel_typeexplicitly for them. Panel-IO/GRAM may use AUTO wheniois supplied.Public Members
-
esp_lcd_panel_handle_t panel
Borrowed initialized panel handle.
-
esp_lcd_panel_io_handle_t io
Required for panel-IO/GRAM transfers; otherwise optional.
-
esp_display_present_panel_t panel_type
Panel transport category.
-
esp_display_present_pixel_format_t input_pixel_format
Pixel format accepted by the initialized panel data path.
-
esp_display_present_rotation_t rotation
Logical-to-physical rotation.
-
bool swap_bytes
Whether RGB565 bytes are swapped on transfer.
-
bool te_enabled
Whether TE synchronization is enabled.
-
esp_display_present_te_sync_config_t te_sync
TE synchronization settings.
-
esp_lcd_panel_handle_t panel
-
struct esp_display_present_fb_config_t
Frame-buffer present profile (RGB / MIPI paths).
frame_buffers are borrowed for the presenter’s lifetime; each buffer must hold the resolved physical frame and satisfy the panel driver’s DMA/cache alignment contract. A zero frame_buffer_count asks the component to fetch driver-owned RGB/MIPI framebuffers. Ignored for GRAM partition targets.
Public Members
-
esp_display_present_mode_t mode
Requested presentation mode.
-
void *frame_buffers[ESP_DISPLAY_PRESENT_MAX_FRAME_BUFFERS]
Borrowed framebuffer addresses.
-
uint8_t frame_buffer_count
Number of valid framebuffer addresses.
-
esp_display_present_mode_t mode
-
struct esp_display_present_drawbuf_config_t
Shared producer drawbuf policy for every partition rendering mode.
Public Members
-
uint16_t lines
Preferred height of each partition draw buffer.
-
uint8_t buffers
Number of partition draw buffers (1 or 2). 0 selects two for GRAM without TE, and for FB repair and TE only on multi-core targets whose internal DMA heap keeps 128 KiB free after both; two buffers overlap tile copies with rendering at the cost of one more buffer and a 4 KiB worker stack.
-
bool in_psram
Allocate draw buffers in PSRAM when possible.
-
uint8_t te_compose_buffers
TE_SYNC full-screen compose buffers. 0/1 keeps the synchronous, single-buffer path; 2 enables a rotating compose pool so composition can overlap an in-flight GRAM transfer.
-
uint16_t lines
-
struct esp_display_present_target_config_t
Target hardware, presentation policy and endpoint memory configuration.
Public Members
-
esp_display_present_hw_config_t hw
Panel and bus configuration.
-
esp_display_present_fb_config_t fb
Framebuffer presentation policy.
-
esp_display_present_drawbuf_config_t drawbuf
Partition draw-buffer policy.
-
esp_display_present_hw_config_t hw
Macros
-
ESP_DISPLAY_PRESENT_MAX_FRAME_BUFFERS
-
ESP_DISPLAY_PRESENT_TE_SYNC_DISABLED()
Enumerations
-
enum esp_display_present_panel_t
Values:
-
enumerator ESP_DISPLAY_PRESENT_PANEL_AUTO
-
enumerator ESP_DISPLAY_PRESENT_PANEL_MIPI_DSI
-
enumerator ESP_DISPLAY_PRESENT_PANEL_RGB
-
enumerator ESP_DISPLAY_PRESENT_PANEL_IO
-
enumerator ESP_DISPLAY_PRESENT_PANEL_AUTO
-
enum esp_display_present_mode_t
Values:
-
enumerator ESP_DISPLAY_PRESENT_MODE_NONE
No tearing avoidance; single buffer or direct transfer.
-
enumerator ESP_DISPLAY_PRESENT_MODE_DOUBLE_FULL
Double buffering with full frame buffers.
-
enumerator ESP_DISPLAY_PRESENT_MODE_TRIPLE_FULL
Triple buffering with full frame buffers.
-
enumerator ESP_DISPLAY_PRESENT_MODE_DOUBLE_DIRECT
Double buffering with direct dirty-area rendering into full buffers.
-
enumerator ESP_DISPLAY_PRESENT_MODE_TRIPLE_PARTIAL
Triple buffering with partial/partition refresh.
-
enumerator ESP_DISPLAY_PRESENT_MODE_TE_SYNC
TE GPIO synchronized direct transfer for SPI/I80/QSPI panels.
-
enumerator ESP_DISPLAY_PRESENT_MODE_DOUBLE_PARTIAL
Double buffering with partial/partition refresh.
-
enumerator ESP_DISPLAY_PRESENT_MODE_AUTO
Let esp_display_present choose from panel type, TE config and buffers.
-
enumerator ESP_DISPLAY_PRESENT_MODE_NONE
Header File
Structures
-
struct esp_display_present_point_t
Logical pixel coordinate.
-
struct esp_display_present_size_t
Two-dimensional size in pixels.
-
struct esp_display_present_area_t
Inclusive logical pixel area.
-
struct esp_display_present_render_alignment_t
Producer raster-area requirements. Zero fields mean no extra alignment. The presenter expands damage conservatively and clips it to the logical display before returning render areas.
-
struct esp_display_present_surface_request_t
Logical damage supplied when preparing a surface frame.
The presenter may copy the previous displayed surface into the new draw surface and may conservatively request a full raster when scroll state or buffer history cannot be reused safely.
Public Members
-
const esp_display_present_area_t *dirty_areas
Logical dirty areas.
-
size_t dirty_area_count
Number of entries in
dirty_areas.
-
esp_display_present_render_alignment_t render_alignment
Producer raster alignment.
-
bool has_scroll
Whether this request contains a scroll operation.
-
esp_display_present_area_t scroll_viewport
Logical viewport affected by scrolling.
-
int16_t scroll_dx
Horizontal scroll displacement in pixels.
-
int16_t scroll_dy
Vertical scroll displacement in pixels.
-
const esp_display_present_area_t *dirty_areas
-
struct esp_display_present_frame_buffers_t
Framebuffer storage returned by a panel driver.
Enumerations
-
enum esp_display_present_panel_interface_t
Values:
-
enumerator ESP_DISPLAY_PRESENT_PANEL_IF_RGB
-
enumerator ESP_DISPLAY_PRESENT_PANEL_IF_MIPI_DSI
-
enumerator ESP_DISPLAY_PRESENT_PANEL_IF_OTHER
-
enumerator ESP_DISPLAY_PRESENT_PANEL_IF_RGB
-
enum esp_display_present_rotation_t
Values:
-
enumerator ESP_DISPLAY_PRESENT_ROTATE_0
-
enumerator ESP_DISPLAY_PRESENT_ROTATE_90
-
enumerator ESP_DISPLAY_PRESENT_ROTATE_180
-
enumerator ESP_DISPLAY_PRESENT_ROTATE_270
-
enumerator ESP_DISPLAY_PRESENT_ROTATE_0
-
enum esp_display_present_pixel_format_t
Values:
-
enumerator ESP_DISPLAY_PRESENT_PIXEL_FORMAT_RGB565
-
enumerator ESP_DISPLAY_PRESENT_PIXEL_FORMAT_RGB888
-
enumerator ESP_DISPLAY_PRESENT_PIXEL_FORMAT_RGB565
-
enum esp_display_present_fault_reason_t
Why a presenter latched a fault. A transfer timeout is a hardware-level condition (for example bus jitter or a slow panel) that the application may recover from by deleting and recreating the presenter; a producer protocol fault is a producer-side bug and has no in-place recovery.
Values:
-
enumerator ESP_DISPLAY_PRESENT_FAULT_NONE
-
enumerator ESP_DISPLAY_PRESENT_FAULT_PRODUCER_PROTOCOL
Ticket/order violation in the producer build or fence protocol.
-
enumerator ESP_DISPLAY_PRESENT_FAULT_TRANSFER_TIMEOUT
A panel transfer failed to complete within the configured budget.
-
enumerator ESP_DISPLAY_PRESENT_FAULT_NONE
Header File
Functions
-
static inline bool esp_display_present_geometry_area_is_valid(const esp_display_present_area_t *area, uint16_t width, uint16_t height)
-
esp_err_t esp_display_present_geometry_align_area(esp_display_present_size_t logical_size, const esp_display_present_area_t *area, const esp_display_present_render_alignment_t *alignment, esp_display_present_area_t *out_area)
Conservatively expand an inclusive logical area to producer raster alignment and clip it to
logical_size. Zero alignment fields mean 1. Alignments need not be powers of two.
-
esp_err_t esp_display_present_geometry_map_logical_point_to_physical(esp_display_present_rotation_t rotation, esp_display_present_size_t logical_size, const esp_display_present_point_t *logical_point, esp_display_present_point_t *out_physical_point)
-
esp_err_t esp_display_present_geometry_map_physical_point_to_logical(esp_display_present_rotation_t rotation, esp_display_present_size_t logical_size, const esp_display_present_point_t *physical_point, esp_display_present_point_t *out_logical_point)
-
esp_err_t esp_display_present_geometry_map_logical_area_to_physical(esp_display_present_rotation_t rotation, esp_display_present_size_t logical_size, const esp_display_present_area_t *logical, esp_display_present_area_t *out_physical)