From f3a568bb8e55bc6bd2582f777206b0be434dd7c9 Mon Sep 17 00:00:00 2001 From: Xuelian Bai Date: Wed, 29 May 2019 00:01:10 +0800 Subject: [PATCH] Fix resize issue Handle 1x1 issue for driimage When evas resize window after dequeue, then draw and swapbuffers, window is shown with old size until next makecurrent. Add validate_drawable function to check if resize happen each time makecurrent is called. For RPI4, render node is used, so buffer is allocated on another device, when 1x1 issue happen, we need to make sure if driimage size is changed, then created new if yes. Merged Commit: commit 2dc471b0e167693b81c24c9a3f89b985cb98249f Author: Zhaowei Yuan - Check if stdraw is NULL before access Variable "stdraw" could be NULL in some case, check it before access. commit cc2dc99365906ea52b645be3bb10f50708d67e84 Author: Xuelian Bai - Fix 1x1 issue of task-mgr Makecurrent is called just before resize callback is called, so we have to check if size is changed when drawcall. commit 670d77331c986a92bcf2459567ccd6dfc181bc66 Author: Xuelian Bai - Fix resize issue Change-Id: Ieaebe72661a081d496ab6214c1c1526f7d16f19b Signed-Off-by: Xuelian Bai - Handle 1x1 issue for driimage Change-Id: Id5a463a8db290ca5b80c130ebcdcb13c7786d70c Signed-off-by: Xuelian Bai --- include/GL/internal/dri_interface.h | 9 ++++++- src/egl/drivers/dri2/egl_dri2.h | 1 + src/egl/drivers/dri2/platform_tizen.c | 45 +++++++++++++++++++++++++++++--- src/gallium/frontends/dri/dri2.c | 34 +++++++++++++++++++++++- src/gallium/frontends/dri/dri_drawable.c | 17 ++++++++++++ src/gallium/frontends/dri/dri_drawable.h | 3 +++ src/gallium/include/frontend/api.h | 3 +++ src/mesa/state_tracker/st_atom.c | 23 +++++++++++++++- src/mesa/state_tracker/st_manager.c | 39 ++++++++++++++++++++++++++- src/mesa/state_tracker/st_manager.h | 5 ++++ 10 files changed, 172 insertions(+), 7 deletions(-) mode change 100644 => 100755 src/mesa/state_tracker/st_manager.c diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 7f1f482..126733d 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -41,7 +41,7 @@ #define DRI_INTERFACE_H #include - +#include /** * \name DRI interface structures * @@ -1055,6 +1055,9 @@ struct __DRIdri2LoaderExtensionRec { * \since 5 */ void (*destroyLoaderImageState)(void *loaderPrivate); +#ifdef HAVE_TIZEN_PLATFORM + bool (*validate)(__DRIdrawable *driDrawable, void *loaderPrivate); +#endif }; /** @@ -2053,6 +2056,10 @@ struct __DRIimageLoaderExtensionRec { * \since 4 */ void (*destroyLoaderImageState)(void *loaderPrivate); +#ifdef HAVE_TIZEN_PLATFORM + bool (*validate)(__DRIdrawable *driDrawable, void *loaderPrivate); +#endif + }; /** diff --git a/src/egl/drivers/dri2/egl_dri2.h b/src/egl/drivers/dri2/egl_dri2.h index 7eea735..c6d4c04 100644 --- a/src/egl/drivers/dri2/egl_dri2.h +++ b/src/egl/drivers/dri2/egl_dri2.h @@ -372,6 +372,7 @@ struct dri2_egl_surface __DRIimage *dri_image_front; int buffer_count; + bool valid; #endif #if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM) || defined(HAVE_TIZEN_PLATFORM) diff --git a/src/egl/drivers/dri2/platform_tizen.c b/src/egl/drivers/dri2/platform_tizen.c index 3838060..bde96936 100755 --- a/src/egl/drivers/dri2/platform_tizen.c +++ b/src/egl/drivers/dri2/platform_tizen.c @@ -176,6 +176,7 @@ tizen_window_dequeue_buffer(struct dri2_egl_surface *dri2_surf) if (!dri2_surf->tbm_surface) return EGL_FALSE; + dri2_surf->valid = true; tbm_surface_internal_ref(dri2_surf->tbm_surface); tpl_surface_get_size(dri2_surf->tpl_surface, &width, &height); @@ -342,7 +343,7 @@ tizen_create_surface(_EGLDisplay *disp, EGLint type, goto cleanup_surface; } dri2_surf->native_win = native_window; - + dri2_surf->valid = true; dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_DEPTH_SIZE, &depth); dri2_dpy->core->getConfigAttrib(config, __DRI_ATTRIB_ALPHA_SIZE, &alpha); @@ -473,6 +474,21 @@ update_buffers(struct dri2_egl_surface *dri2_surf) if (dri2_surf->base.Type != EGL_WINDOW_BIT) return 0; + if (dri2_surf->valid == false) { + int i; + if (dri2_surf->tbm_surface) { + tpl_surface_cancel_dequeued_buffer(dri2_surf->tpl_surface, + dri2_surf->tbm_surface); + tbm_surface_internal_unref(dri2_surf->tbm_surface); + for (i = 0; i < ARRAY_SIZE(dri2_surf->color_buffers); i++) { + dri2_surf->color_buffers[i].tbm_surface = NULL; + dri2_surf->color_buffers[i].age = 0; + } + + dri2_surf->back = NULL; + dri2_surf->tbm_surface = NULL; + } + } /* try to dequeue the next back buffer */ if (!dri2_surf->tbm_surface && !tizen_window_dequeue_buffer(dri2_surf)) { _eglLog(_EGL_WARNING, "Could not dequeue buffer from native window"); @@ -523,9 +539,20 @@ get_back_bo(struct dri2_egl_surface *dri2_surf, unsigned int format) int fourcc, pitch; int offset = 0, fd; tbm_surface_info_s surf_info; + EGLBoolean query; + int width, height; - if (dri2_surf->dri_image_back) - return 0; + if (dri2_surf->dri_image_back) { + query = dri2_dpy->image->queryImage(dri2_surf->dri_image_back, __DRI_IMAGE_ATTRIB_WIDTH, &width); + query &= dri2_dpy->image->queryImage(dri2_surf->dri_image_back, __DRI_IMAGE_ATTRIB_HEIGHT, &height); + + if (width == dri2_surf->base.Width && height == dri2_surf->base.Height) + return 0; + else { + dri2_dpy->image->destroyImage(dri2_surf->dri_image_back); + dri2_surf->dri_image_back = NULL; + } + } if (dri2_surf->base.Type == EGL_WINDOW_BIT) { if (!dri2_surf->tbm_surface) { @@ -1011,6 +1038,16 @@ tizen_flush_front_buffer(__DRIdrawable * driDrawable, void *loaderPrivate) { } +static bool +tizen_validate_drawable(__DRIdrawable * driDrawable, void *loaderPrivate) +{ + struct dri2_egl_surface *dri2_surf = loaderPrivate; + bool v = tpl_surface_validate(dri2_surf->tpl_surface); + + dri2_surf->valid = v; + return v; +} + static int tizen_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf, unsigned int *attachments, int count) @@ -1340,6 +1377,7 @@ static const __DRIdri2LoaderExtension tizen_dri2_loader_extension = { .getBuffers = NULL, .getBuffersWithFormat = tizen_get_buffers_with_format, .flushFrontBuffer = tizen_flush_front_buffer, + .validate = tizen_validate_drawable, }; static const __DRIimageLoaderExtension tizen_image_loader_extension = { @@ -1347,6 +1385,7 @@ static const __DRIimageLoaderExtension tizen_image_loader_extension = { .getBuffers = tizen_image_get_buffers, .flushFrontBuffer = tizen_flush_front_buffer, + .validate = tizen_validate_drawable, }; static const __DRIswrastLoaderExtension tizen_swrast_loader_extension = { diff --git a/src/gallium/frontends/dri/dri2.c b/src/gallium/frontends/dri/dri2.c index 2e5adf3..948fc54 100644 --- a/src/gallium/frontends/dri/dri2.c +++ b/src/gallium/frontends/dri/dri2.c @@ -431,6 +431,36 @@ handle_in_fence(__DRIcontext *context, __DRIimage *img) /* * Backend functions for st_framebuffer interface. */ +#ifdef HAVE_TIZEN_PLATFORM +static bool dri2_validate_drawable(struct dri_drawable *drawable) +{ + __DRIdrawable *dri_drawable = drawable->dPriv; + const __DRIdri2LoaderExtension *loader = drawable->sPriv->dri2.loader; + + if (loader && loader->validate != NULL) { + boolean valid = (loader->validate)(dri_drawable, dri_drawable->loaderPrivate); + if (valid == FALSE) /*drawable may be resized, not valid anymore*/ { + drawable->dPriv->lastStamp = drawable->dPriv->dri2.stamp; + drawable->texture_mask = 0; + } + return valid; + } + else { + const __DRIimageLoaderExtension *image_loader = drawable->sPriv->image.loader; + if (image_loader && image_loader->validate != NULL) { + boolean valid = (image_loader->validate)(dri_drawable, dri_drawable->loaderPrivate); + if (valid == FALSE) /*drawable may be resized, not valid anymore*/ { + drawable->dPriv->lastStamp = drawable->dPriv->dri2.stamp; + drawable->texture_mask = 0; + } + return valid; + } + return TRUE; + } + +} +#endif + static void dri2_allocate_textures(struct dri_context *ctx, @@ -2387,7 +2417,9 @@ dri2_create_buffer(__DRIscreen * sPriv, drawable->flush_frontbuffer = dri2_flush_frontbuffer; drawable->update_tex_buffer = dri2_update_tex_buffer; drawable->flush_swapbuffers = dri2_flush_swapbuffers; - +#ifdef HAVE_TIZEN_PLATFORM + drawable->validate_drawable = dri2_validate_drawable; +#endif return TRUE; } diff --git a/src/gallium/frontends/dri/dri_drawable.c b/src/gallium/frontends/dri/dri_drawable.c index 83ac525..fae9102 100644 --- a/src/gallium/frontends/dri/dri_drawable.c +++ b/src/gallium/frontends/dri/dri_drawable.c @@ -40,6 +40,20 @@ static uint32_t drifb_ID = 0; +#ifdef HAVE_TIZEN_PLATFORM +static bool +dri_st_framebuffer_validate_drawable(struct st_framebuffer_iface *stfbi) +{ + struct dri_drawable *drawable = + (struct dri_drawable *) stfbi->st_manager_private; + + if (drawable->validate_drawable == NULL) + return TRUE; + else + return drawable->validate_drawable(drawable); +} +#endif + static bool dri_st_framebuffer_validate(struct st_context_iface *stctx, struct st_framebuffer_iface *stfbi, @@ -169,6 +183,9 @@ dri_create_buffer(__DRIscreen * sPriv, drawable->base.flush_front = dri_st_framebuffer_flush_front; drawable->base.validate = dri_st_framebuffer_validate; drawable->base.flush_swapbuffers = dri_st_framebuffer_flush_swapbuffers; +#ifdef HAVE_TIZEN_PLATFORM + drawable->base.validate_drawable = dri_st_framebuffer_validate_drawable; +#endif drawable->base.st_manager_private = (void *) drawable; drawable->screen = screen; diff --git a/src/gallium/frontends/dri/dri_drawable.h b/src/gallium/frontends/dri/dri_drawable.h index f045309..3fe0984 100644 --- a/src/gallium/frontends/dri/dri_drawable.h +++ b/src/gallium/frontends/dri/dri_drawable.h @@ -81,6 +81,9 @@ struct dri_drawable struct pipe_resource *res); void (*flush_swapbuffers)(struct dri_context *ctx, struct dri_drawable *drawable); +#ifdef HAVE_TIZEN_PLATFORM + bool (*validate_drawable)(struct dri_drawable *drawable); +#endif }; static inline struct dri_drawable * diff --git a/src/gallium/include/frontend/api.h b/src/gallium/include/frontend/api.h index 4942b25..fd6de01 100644 --- a/src/gallium/include/frontend/api.h +++ b/src/gallium/include/frontend/api.h @@ -356,6 +356,9 @@ struct st_framebuffer_iface struct pipe_resource **out); bool (*flush_swapbuffers) (struct st_context_iface *stctx, struct st_framebuffer_iface *stfbi); +#ifdef HAVE_TIZEN_PLATFORM + bool (*validate_drawable)(struct st_framebuffer_iface *stfbi); +#endif }; /** diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index be2da23..34d9484 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -40,6 +40,7 @@ #include "util/u_cpu_detect.h" +#include "st_cb_fbo.h" typedef void (*update_func_t)(struct st_context *st); @@ -219,7 +220,16 @@ void st_validate_state( struct st_context *st, enum st_pipeline pipeline ) st->gfx_shaders_may_be_dirty = false; } +#ifdef HAVE_TIZEN_PLATFORM + struct st_framebuffer *stdraw = st_ws_framebuffer(st->ctx->DrawBuffer); + bool valid = TRUE; + + if (stdraw && stdraw->iface->validate_drawable) + valid = stdraw->iface->validate_drawable(stdraw->iface); + st_manager_validate_framebuffers(st, valid); +#else st_manager_validate_framebuffers(st); +#endif if (pipeline == ST_PIPELINE_RENDER) pipeline_mask = ST_PIPELINE_RENDER_STATE_MASK; @@ -228,7 +238,11 @@ void st_validate_state( struct st_context *st, enum st_pipeline pipeline ) break; case ST_PIPELINE_CLEAR: +#ifdef HAVE_TIZEN_PLATFORM + st_manager_validate_framebuffers(st, TRUE); +#else st_manager_validate_framebuffers(st); +#endif pipeline_mask = ST_PIPELINE_CLEAR_STATE_MASK; break; @@ -237,13 +251,20 @@ void st_validate_state( struct st_context *st, enum st_pipeline pipeline ) check_program_state(st); st->gfx_shaders_may_be_dirty = false; } - +#ifdef HAVE_TIZEN_PLATFORM + st_manager_validate_framebuffers(st, TRUE); +#else st_manager_validate_framebuffers(st); +#endif pipeline_mask = ST_PIPELINE_META_STATE_MASK; break; case ST_PIPELINE_UPDATE_FRAMEBUFFER: +#ifdef HAVE_TIZEN_PLATFORM + st_manager_validate_framebuffers(st, TRUE); +#else st_manager_validate_framebuffers(st); +#endif pipeline_mask = ST_PIPELINE_UPDATE_FB_STATE_MASK; break; diff --git a/src/mesa/state_tracker/st_manager.c b/src/mesa/state_tracker/st_manager.c old mode 100644 new mode 100755 index 575b729..9e0e6ac --- a/src/mesa/state_tracker/st_manager.c +++ b/src/mesa/state_tracker/st_manager.c @@ -217,7 +217,11 @@ st_set_ws_renderbuffer_surface(struct gl_renderbuffer *rb, */ static void st_framebuffer_validate(struct gl_framebuffer *stfb, - struct st_context *st) + struct st_context *st +#ifdef HAVE_TIZEN_PLATFORM + , bool valid +#endif + ) { struct pipe_resource *textures[ST_ATTACHMENT_COUNT]; uint width, height; @@ -226,7 +230,11 @@ st_framebuffer_validate(struct gl_framebuffer *stfb, int32_t new_stamp; new_stamp = p_atomic_read(&stfb->iface->stamp); +#ifdef HAVE_TIZEN_PLATFORM + if (valid == TRUE && stfb->iface_stamp == new_stamp) +#else if (stfb->iface_stamp == new_stamp) +#endif return; memset(textures, 0, stfb->num_statts * sizeof(textures[0])); @@ -1220,6 +1228,9 @@ st_api_make_current(struct st_context_iface *stctxi, struct st_context *st = (struct st_context *) stctxi; struct gl_framebuffer *stdraw, *stread; bool ret; +#ifdef HAVE_TIZEN_PLATFORM + bool valid = TRUE; +#endif if (st) { /* reuse or create the draw fb */ @@ -1241,10 +1252,24 @@ st_api_make_current(struct st_context_iface *stctxi, if ((stdrawi && !stdraw) || (streadi && !stread)) return false; +#ifdef HAVE_TIZEN_PLATFORM + if (stdraw && stdraw->iface->validate_drawable) + valid = stdraw->iface->validate_drawable(stdraw->iface); +#endif + if (stdraw && stread) { +#ifdef HAVE_TIZEN_PLATFORM + st_framebuffer_validate(stdraw, st, valid); +#else st_framebuffer_validate(stdraw, st); +#endif + if (stread != stdraw) +#ifdef HAVE_TIZEN_PLATFORM + st_framebuffer_validate(stread, st, TRUE); +#else st_framebuffer_validate(stread, st); +#endif ret = _mesa_make_current(st->ctx, stdraw, stread); @@ -1330,16 +1355,28 @@ st_manager_flush_frontbuffer(struct st_context *st) /** * Re-validate the framebuffers. */ +#ifdef HAVE_TIZEN_PLATFORM +void +st_manager_validate_framebuffers(struct st_context *st, bool valid) +#else void st_manager_validate_framebuffers(struct st_context *st) +#endif { struct gl_framebuffer *stdraw = st_ws_framebuffer(st->ctx->DrawBuffer); struct gl_framebuffer *stread = st_ws_framebuffer(st->ctx->ReadBuffer); +#ifdef HAVE_TIZEN_PLATFORM + if (stdraw) + st_framebuffer_validate(stdraw, st, valid); + if (stread && stread != stdraw) + st_framebuffer_validate(stread, st, TRUE); +#else if (stdraw) st_framebuffer_validate(stdraw, st); if (stread && stread != stdraw) st_framebuffer_validate(stread, st); +#endif st_context_validate(st, stdraw, stread); } diff --git a/src/mesa/state_tracker/st_manager.h b/src/mesa/state_tracker/st_manager.h index ec373cf..2819fba 100644 --- a/src/mesa/state_tracker/st_manager.h +++ b/src/mesa/state_tracker/st_manager.h @@ -43,8 +43,13 @@ struct pipe_surface; void st_manager_flush_frontbuffer(struct st_context *st); +#ifdef HAVE_TIZEN_PLATFORM +void +st_manager_validate_framebuffers(struct st_context *st, bool valid); +#else void st_manager_validate_framebuffers(struct st_context *st); +#endif bool st_manager_add_color_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, -- 2.7.4