mirror of
https://github.com/lvgl/lvgl.git
synced 2026-05-30 15:17:33 +08:00
refactor(opengles): set texture id to layer head on disp creation (#9397)
This commit is contained in:
@@ -193,18 +193,13 @@ static int32_t dispatch(lv_draw_unit_t * draw_unit, lv_layer_t * layer)
|
|||||||
unsigned int texture = layer_get_texture(layer);
|
unsigned int texture = layer_get_texture(layer);
|
||||||
if(texture == 0) {
|
if(texture == 0) {
|
||||||
lv_display_t * disp = lv_refr_get_disp_refreshing();
|
lv_display_t * disp = lv_refr_get_disp_refreshing();
|
||||||
if(layer != disp->layer_head) {
|
LV_ASSERT(layer != disp->layer_head);
|
||||||
int32_t w = lv_area_get_width(&layer->buf_area);
|
int32_t w = lv_area_get_width(&layer->buf_area);
|
||||||
int32_t h = lv_area_get_height(&layer->buf_area);
|
int32_t h = lv_area_get_height(&layer->buf_area);
|
||||||
|
|
||||||
texture = create_texture(w, h, NULL);
|
texture = create_texture(w, h, NULL);
|
||||||
|
|
||||||
layer->user_data = (void *)(uintptr_t)texture;
|
layer->user_data = (void *)(uintptr_t)texture;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
layer->user_data = (void *)(uintptr_t)lv_opengles_texture_get_texture_id(disp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
|
t->state = LV_DRAW_TASK_STATE_IN_PROGRESS;
|
||||||
draw_opengles_unit->task_act = t;
|
draw_opengles_unit->task_act = t;
|
||||||
|
|||||||
@@ -124,19 +124,17 @@ lv_result_t lv_linux_drm_set_file(lv_display_t * display, const char * file, int
|
|||||||
|
|
||||||
/* Let the opengles texture driver handle the texture lifetime */
|
/* Let the opengles texture driver handle the texture lifetime */
|
||||||
ctx->texture.is_texture_owner = true;
|
ctx->texture.is_texture_owner = true;
|
||||||
lv_result_t res = lv_opengles_texture_create_draw_buffers(&ctx->texture, display);
|
/*Initialize the draw buffers and texture*/
|
||||||
|
lv_result_t res = lv_opengles_texture_reshape(&ctx->texture, display, ctx->drm_mode->hdisplay, ctx->drm_mode->vdisplay);
|
||||||
if(res != LV_RESULT_OK) {
|
if(res != LV_RESULT_OK) {
|
||||||
LV_LOG_ERROR("Failed to create draw buffers");
|
LV_LOG_ERROR("Failed to create draw buffers");
|
||||||
lv_opengles_egl_context_destroy(ctx->egl_ctx);
|
lv_opengles_egl_context_destroy(ctx->egl_ctx);
|
||||||
ctx->egl_ctx = NULL;
|
ctx->egl_ctx = NULL;
|
||||||
return LV_RESULT_INVALID;
|
return LV_RESULT_INVALID;
|
||||||
}
|
}
|
||||||
/* This creates the texture for the first time*/
|
|
||||||
lv_opengles_texture_reshape(display, ctx->drm_mode->hdisplay, ctx->drm_mode->vdisplay);
|
|
||||||
|
|
||||||
lv_display_set_flush_cb(display, flush_cb);
|
lv_display_set_flush_cb(display, flush_cb);
|
||||||
lv_display_set_render_mode(display, LV_DISPLAY_RENDER_MODE_DIRECT);
|
lv_display_set_render_mode(display, LV_DISPLAY_RENDER_MODE_DIRECT);
|
||||||
|
|
||||||
lv_display_add_event_cb(ctx->display, event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL);
|
lv_display_add_event_cb(ctx->display, event_cb, LV_EVENT_RESOLUTION_CHANGED, NULL);
|
||||||
lv_display_add_event_cb(ctx->display, event_cb, LV_EVENT_DELETE, NULL);
|
lv_display_add_event_cb(ctx->display, event_cb, LV_EVENT_DELETE, NULL);
|
||||||
|
|
||||||
@@ -172,9 +170,14 @@ static void event_cb(lv_event_t * e)
|
|||||||
lv_display_set_driver_data(display, NULL);
|
lv_display_set_driver_data(display, NULL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case LV_EVENT_RESOLUTION_CHANGED:
|
case LV_EVENT_RESOLUTION_CHANGED: {
|
||||||
lv_opengles_texture_reshape(display, lv_display_get_horizontal_resolution(display),
|
lv_result_t res = lv_opengles_texture_reshape(&ctx->texture, display, lv_display_get_horizontal_resolution(display),
|
||||||
lv_display_get_vertical_resolution(display));
|
lv_display_get_vertical_resolution(display));
|
||||||
|
|
||||||
|
if(res != LV_RESULT_OK) {
|
||||||
|
LV_LOG_ERROR("Failed to resize display");
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ void lv_opengles_render_fill(lv_color_t color, const lv_area_t * area, lv_opa_t
|
|||||||
void lv_opengles_render_display(lv_display_t * display, const lv_opengles_render_params_t * params)
|
void lv_opengles_render_display(lv_display_t * display, const lv_opengles_render_params_t * params)
|
||||||
{
|
{
|
||||||
LV_PROFILER_DRAW_BEGIN;
|
LV_PROFILER_DRAW_BEGIN;
|
||||||
unsigned int texture = *(unsigned int *)lv_display_get_driver_data(display);
|
unsigned int texture = (lv_uintptr_t)display->layer_head->user_data;
|
||||||
GL_CALL(glActiveTexture(GL_TEXTURE0));
|
GL_CALL(glActiveTexture(GL_TEXTURE0));
|
||||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, texture));
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, texture));
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
static lv_display_t * lv_opengles_texture_create_common(int32_t w, int32_t h);
|
static lv_display_t * lv_opengles_texture_create_common(int32_t w, int32_t h);
|
||||||
|
static lv_result_t lv_opengles_texture_create_draw_buffers(lv_opengles_texture_t * texture, lv_display_t * display);
|
||||||
|
static void lv_opengles_texture_attach_to_display(lv_opengles_texture_t * texture, lv_display_t * disp);
|
||||||
static unsigned int create_texture(int32_t w, int32_t h);
|
static unsigned int create_texture(int32_t w, int32_t h);
|
||||||
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
|
static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_map);
|
||||||
static void release_disp_cb(lv_event_t * e);
|
static void release_disp_cb(lv_event_t * e);
|
||||||
@@ -52,61 +54,79 @@ static void release_disp_cb(lv_event_t * e);
|
|||||||
|
|
||||||
lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h)
|
lv_display_t * lv_opengles_texture_create(int32_t w, int32_t h)
|
||||||
{
|
{
|
||||||
lv_display_t * disp = lv_opengles_texture_create_common(w, h);
|
lv_display_t * display = lv_opengles_texture_create_common(w, h);
|
||||||
if(!disp) {
|
if(!display) {
|
||||||
LV_LOG_ERROR("Failed to create display");
|
LV_LOG_ERROR("Failed to create display");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp);
|
lv_opengles_texture_t * texture = lv_display_get_driver_data(display);
|
||||||
unsigned int texture_id = create_texture(w, h);
|
unsigned int texture_id = create_texture(w, h);
|
||||||
dsc->texture_id = texture_id;
|
texture->texture_id = texture_id;
|
||||||
dsc->is_texture_owner = true;
|
texture->is_texture_owner = true;
|
||||||
return disp;
|
/* Attach the texture to the display after the texture id has been set*/
|
||||||
|
lv_opengles_texture_attach_to_display(texture, display);
|
||||||
|
return display;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_display_t * lv_opengles_texture_create_from_texture_id(int32_t w, int32_t h, unsigned int texture_id)
|
lv_display_t * lv_opengles_texture_create_from_texture_id(int32_t w, int32_t h, unsigned int texture_id)
|
||||||
{
|
{
|
||||||
lv_display_t * disp = lv_opengles_texture_create_common(w, h);
|
lv_display_t * display = lv_opengles_texture_create_common(w, h);
|
||||||
if(!disp) {
|
if(!display) {
|
||||||
LV_LOG_ERROR("Failed to create display");
|
LV_LOG_ERROR("Failed to create display");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp);
|
lv_opengles_texture_t * texture = lv_display_get_driver_data(display);
|
||||||
dsc->texture_id = texture_id;
|
texture->texture_id = texture_id;
|
||||||
dsc->is_texture_owner = false;
|
texture->is_texture_owner = false;
|
||||||
return disp;
|
/* Attach the texture to the display after the texture id has been set*/
|
||||||
|
lv_opengles_texture_attach_to_display(texture, display);
|
||||||
|
return display;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lv_opengles_texture_reshape(lv_display_t * disp, int32_t width, int32_t height)
|
lv_result_t lv_opengles_texture_reshape(lv_opengles_texture_t * texture, lv_display_t * display, int32_t width,
|
||||||
|
int32_t height)
|
||||||
{
|
{
|
||||||
lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp);
|
LV_ASSERT_NULL(display);
|
||||||
|
LV_ASSERT_NULL(texture);
|
||||||
unsigned int new_texture = create_texture(width, height);
|
unsigned int new_texture = create_texture(width, height);
|
||||||
if(new_texture == GL_NONE) {
|
if(new_texture == GL_NONE) {
|
||||||
LV_LOG_ERROR("Failed to reshape texture. Couldn't acquire new texture from GPU");
|
LV_LOG_ERROR("Failed to reshape texture. Couldn't acquire new texture from GPU");
|
||||||
return;
|
return LV_RESULT_INVALID;
|
||||||
}
|
}
|
||||||
#if !LV_USE_DRAW_OPENGLES
|
|
||||||
uint32_t stride = lv_draw_buf_width_to_stride(width, lv_display_get_color_format(disp));
|
#if LV_USE_DRAW_OPENGLES
|
||||||
|
static size_t LV_ATTRIBUTE_MEM_ALIGN dummy_buf;
|
||||||
|
lv_display_set_buffers(display, &dummy_buf, NULL, width * height * 4, LV_DISPLAY_RENDER_MODE_DIRECT);
|
||||||
|
#else
|
||||||
|
uint32_t stride = lv_draw_buf_width_to_stride(width, lv_display_get_color_format(display));
|
||||||
uint32_t buf_size = stride * height;
|
uint32_t buf_size = stride * height;
|
||||||
uint8_t * buffer = lv_realloc(dsc->fb1, buf_size);
|
uint8_t * buffer = lv_realloc(texture->fb1, buf_size);
|
||||||
LV_ASSERT_MALLOC(buffer);
|
LV_ASSERT_MALLOC(buffer);
|
||||||
if(!buffer) {
|
if(!buffer) {
|
||||||
GL_CALL(glDeleteTextures(1, &new_texture));
|
GL_CALL(glDeleteTextures(1, &new_texture));
|
||||||
LV_LOG_ERROR("Failed to reshape texture. Couldn't resize buffer");
|
LV_LOG_ERROR("Failed to reshape texture. Couldn't resize buffer");
|
||||||
return;
|
return LV_RESULT_INVALID;
|
||||||
}
|
}
|
||||||
dsc->fb1 = buffer;
|
texture->fb1 = buffer;
|
||||||
|
|
||||||
lv_display_set_buffers(disp, dsc->fb1, NULL, buf_size, lv_display_get_render_mode(disp));
|
lv_display_set_buffers(display, texture->fb1, NULL, buf_size, lv_display_get_render_mode(display));
|
||||||
#endif /*!LV_USE_DRAW_OPENGLES*/
|
#endif /*LV_USE_DRAW_OPENGLES*/
|
||||||
|
|
||||||
if(dsc->is_texture_owner && dsc->texture_id != 0) {
|
if(texture->is_texture_owner && texture->texture_id != 0) {
|
||||||
GL_CALL(glDeleteTextures(1, &dsc->texture_id));
|
GL_CALL(glDeleteTextures(1, &texture->texture_id));
|
||||||
}
|
}
|
||||||
dsc->texture_id = new_texture;
|
texture->texture_id = new_texture;
|
||||||
|
lv_opengles_texture_attach_to_display(texture, display);
|
||||||
|
return LV_RESULT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_result_t lv_opengles_texture_create_draw_buffers(lv_opengles_texture_t * texture, lv_display_t * display)
|
static void lv_opengles_texture_attach_to_display(lv_opengles_texture_t * texture, lv_display_t * display)
|
||||||
|
{
|
||||||
|
LV_ASSERT_NULL(display);
|
||||||
|
display->layer_head->user_data = (void *)(lv_uintptr_t)texture->texture_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
static lv_result_t lv_opengles_texture_create_draw_buffers(lv_opengles_texture_t * texture, lv_display_t * display)
|
||||||
{
|
{
|
||||||
int32_t w = lv_display_get_horizontal_resolution(display);
|
int32_t w = lv_display_get_horizontal_resolution(display);
|
||||||
int32_t h = lv_display_get_vertical_resolution(display);
|
int32_t h = lv_display_get_vertical_resolution(display);
|
||||||
@@ -141,10 +161,12 @@ void lv_opengles_texture_deinit(lv_opengles_texture_t * texture)
|
|||||||
|
|
||||||
unsigned int lv_opengles_texture_get_texture_id(lv_display_t * disp)
|
unsigned int lv_opengles_texture_get_texture_id(lv_display_t * disp)
|
||||||
{
|
{
|
||||||
lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp);
|
if(!disp) {
|
||||||
return dsc->texture_id;
|
LV_LOG_ERROR("Invalid display");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (unsigned int)(lv_uintptr_t)disp->layer_head->user_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_display_t * lv_opengles_texture_get_from_texture_id(unsigned int texture_id)
|
lv_display_t * lv_opengles_texture_get_from_texture_id(unsigned int texture_id)
|
||||||
{
|
{
|
||||||
lv_display_t * disp = NULL;
|
lv_display_t * disp = NULL;
|
||||||
@@ -238,20 +260,21 @@ static void flush_cb(lv_display_t * disp, const lv_area_t * area, uint8_t * px_m
|
|||||||
#if !LV_USE_DRAW_OPENGLES
|
#if !LV_USE_DRAW_OPENGLES
|
||||||
if(lv_display_flush_is_last(disp)) {
|
if(lv_display_flush_is_last(disp)) {
|
||||||
|
|
||||||
lv_opengles_texture_t * dsc = lv_display_get_driver_data(disp);
|
lv_opengles_texture_t * texture = lv_display_get_driver_data(disp);
|
||||||
lv_color_format_t cf = lv_display_get_color_format(disp);
|
lv_color_format_t cf = lv_display_get_color_format(disp);
|
||||||
uint32_t stride = lv_draw_buf_width_to_stride(lv_display_get_horizontal_resolution(disp), cf);
|
uint32_t stride = lv_draw_buf_width_to_stride(lv_display_get_horizontal_resolution(disp), cf);
|
||||||
|
|
||||||
GL_CALL(glBindTexture(GL_TEXTURE_2D, dsc->texture_id));
|
GL_CALL(glBindTexture(GL_TEXTURE_2D, texture->texture_id));
|
||||||
|
|
||||||
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
GL_CALL(glPixelStorei(GL_UNPACK_ALIGNMENT, 1));
|
||||||
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / lv_color_format_get_size(cf)));
|
GL_CALL(glPixelStorei(GL_UNPACK_ROW_LENGTH, stride / lv_color_format_get_size(cf)));
|
||||||
/*Color depth: 16 (RGB565), 32 (XRGB8888)*/
|
/*Color depth: 16 (RGB565), 32 (XRGB8888)*/
|
||||||
#if LV_COLOR_DEPTH == 16
|
#if LV_COLOR_DEPTH == 16
|
||||||
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, disp->hor_res, disp->ver_res, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
|
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB565, disp->hor_res, disp->ver_res, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
|
||||||
dsc->fb1));
|
texture->fb1));
|
||||||
#elif LV_COLOR_DEPTH == 32
|
#elif LV_COLOR_DEPTH == 32
|
||||||
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, disp->hor_res, disp->ver_res, 0, GL_RGBA, GL_UNSIGNED_BYTE, dsc->fb1));
|
GL_CALL(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, disp->hor_res, disp->ver_res, 0, GL_BGRA, GL_UNSIGNED_BYTE,
|
||||||
|
texture->fb1));
|
||||||
#else
|
#else
|
||||||
#error("Unsupported color format")
|
#error("Unsupported color format")
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -40,8 +40,8 @@ typedef struct {
|
|||||||
* GLOBAL PROTOTYPES
|
* GLOBAL PROTOTYPES
|
||||||
**********************/
|
**********************/
|
||||||
|
|
||||||
lv_result_t lv_opengles_texture_create_draw_buffers(lv_opengles_texture_t * texture, lv_display_t * display);
|
lv_result_t lv_opengles_texture_reshape(lv_opengles_texture_t * texture, lv_display_t * display,
|
||||||
void lv_opengles_texture_reshape(lv_display_t * disp, int32_t width, int32_t height);
|
int32_t width, int32_t height);
|
||||||
void lv_opengles_texture_deinit(lv_opengles_texture_t * texture);
|
void lv_opengles_texture_deinit(lv_opengles_texture_t * texture);
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
|||||||
Reference in New Issue
Block a user