diff options
author | byungchul.so <byungchul.so@samsung.com> | 2021-12-13 12:05:48 +0900 |
---|---|---|
committer | byungchul.so <byungchul.so@samsung.com> | 2021-12-21 13:39:21 +0900 |
commit | a3c51bd11da9896d651f82b4491b05b92922248c (patch) | |
tree | da0e218c9566ecc2c637010a7f079dafcc3d5d5b | |
parent | a360b4231df4e7c357616e6488f5dd8a7b450a53 (diff) | |
download | emulator-yagl-a3c51bd11da9896d651f82b4491b05b92922248c.tar.gz emulator-yagl-a3c51bd11da9896d651f82b4491b05b92922248c.tar.bz2 emulator-yagl-a3c51bd11da9896d651f82b4491b05b92922248c.zip |
Support offscreen rendering for TBM_FORMAT_ARGB8888 tbm buffer
- Assume below events:
...
// Use TBM_FORMAT_ARGB8888 tbm buffer for offscreen rendering. The tbm buffer is used as
// native buffer for an eglImage and the texture binded with the eglImage is attached to
// framebuffer object.
tbm_buffer = tbm_surface_create(w, h, TBM_FORMAT_ARGB8888);
EvasGLImage *evas_image = evasglCreateImageForContext(evas_gl, evas_gl_ctx,
EVAS_GL_NATIVE_SURFACE_TIZEN, tbm_surface, attrs);
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glEvasGLImageTargetTexture2DOES(GL_TEXTURE_2D, evas_image);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
Rendering something here...
// Bind default framebuffer after rendering...
glBindFramebuffer(GL_FRAMEBUFFER, old_framebuffer);
...
- The TBM_FORMAT_ARGB8888 tbm buffer should have rendering result after
finishing rendering but it's not because offscreen rendering for TBM_FORMAT_ARGB8888
tbm buffer not supported yet in the YAGL. This patch fixes this issue.
Change-Id: I0af2253e9d69fd20b45280a4c3380e5da1488d2a
-rw-r--r-- | EGL/yagl_context.c | 5 | ||||
-rw-r--r-- | EGL/yagl_context.h | 2 | ||||
-rw-r--r-- | EGL/yagl_egl_calls.c | 2 | ||||
-rw-r--r-- | EGL/yagl_onscreen_image_tizen_sfc.c | 35 | ||||
-rw-r--r-- | EGL/yagl_render.c | 11 | ||||
-rw-r--r-- | GLES_common/yagl_gles_calls.c | 11 | ||||
-rw-r--r-- | GLES_common/yagl_gles_image.c | 7 | ||||
-rw-r--r-- | GLES_common/yagl_gles_image.h | 6 | ||||
-rw-r--r-- | GLES_common/yagl_gles_texture.c | 9 | ||||
-rw-r--r-- | GLES_common/yagl_gles_texture.h | 5 | ||||
-rw-r--r-- | GLESv2/yagl_gles2_context.c | 4 | ||||
-rw-r--r-- | include/yagl_render.h | 12 |
12 files changed, 92 insertions, 17 deletions
diff --git a/EGL/yagl_context.c b/EGL/yagl_context.c index 2e0feae..e6c65a4 100644 --- a/EGL/yagl_context.c +++ b/EGL/yagl_context.c @@ -136,3 +136,8 @@ void yagl_context_finish(struct yagl_context *ctx) { yagl_display_finalize_images(ctx->dpy); } + +void yagl_context_flush(struct yagl_context *ctx) +{ + yagl_display_finalize_images(ctx->dpy); +} diff --git a/EGL/yagl_context.h b/EGL/yagl_context.h index 1ea2dd4..809be4d 100644 --- a/EGL/yagl_context.h +++ b/EGL/yagl_context.h @@ -85,4 +85,6 @@ void yagl_context_release(struct yagl_context *ctx); void yagl_context_finish(struct yagl_context *ctx); +void yagl_context_flush(struct yagl_context *ctx); + #endif diff --git a/EGL/yagl_egl_calls.c b/EGL/yagl_egl_calls.c index 66eb55b..2e7bf99 100644 --- a/EGL/yagl_egl_calls.c +++ b/EGL/yagl_egl_calls.c @@ -1638,6 +1638,8 @@ YAGL_API EGLBoolean eglSwapBuffers(EGLDisplay dpy_, EGLSurface surface_) goto out; } + yagl_render_flush(); + res = EGL_TRUE; #ifdef YAGL_PLATFORM_X11 diff --git a/EGL/yagl_onscreen_image_tizen_sfc.c b/EGL/yagl_onscreen_image_tizen_sfc.c index acd43d8..8c3dfa4 100644 --- a/EGL/yagl_onscreen_image_tizen_sfc.c +++ b/EGL/yagl_onscreen_image_tizen_sfc.c @@ -293,27 +293,36 @@ static void yagl_onscreen_image_tizen_sfc_finalize(struct yagl_image *image) return; } + bo = tbm_surface_internal_get_bo(tizen_sfc_image->sfc, 0); + dst = bo ? (struct vigs_drm_surface *)tbm_bo_get_handle(bo, TBM_DEVICE_3D).ptr : NULL; + switch (tizen_sfc_image->format) { case TBM_FORMAT_XBGR8888: - bo = tbm_surface_internal_get_bo(tizen_sfc_image->sfc, 0); - dst = bo ? (struct vigs_drm_surface *)tbm_bo_get_handle(bo, TBM_DEVICE_3D).ptr : NULL; - - ret = vigs_drm_surface_convert(tizen_sfc_image->drm_sfc, + ret = !vigs_drm_surface_convert(tizen_sfc_image->drm_sfc, DRM_FORMAT_ARGB8888, dst, DRM_FORMAT_XBGR8888, true); - - if (ret == 0) { - return; - } - - YAGL_LOG_ERROR("vigs_drm_surface_convert failed %s\n", strerror(-ret)); - + break; + case TBM_FORMAT_ARGB8888: + /* + * No actual format conversion in ARGB8888 case. We just need to + * y-invert the image. + */ + ret = !vigs_drm_surface_convert(tizen_sfc_image->drm_sfc, + DRM_FORMAT_ARGB8888, + dst, + DRM_FORMAT_ARGB8888, + true); + break; + default: + ret = yagl_onscreen_image_tizen_sfc_convert_back(tizen_sfc_image); break; } - yagl_onscreen_image_tizen_sfc_convert_back(tizen_sfc_image); + if (!ret) { + YAGL_LOG_ERROR("vigs_drm_surface_convert failed %s\n", strerror(-ret)); + } } static void yagl_onscreen_image_tizen_sfc_destroy(struct yagl_ref *ref) @@ -366,13 +375,13 @@ struct yagl_onscreen_image_tizen_sfc need_convert = false; need_convert_back = false; break; - case TBM_FORMAT_ARGB8888: case TBM_FORMAT_RGBA8888: case TBM_FORMAT_NV21: case TBM_FORMAT_YUV420: need_convert = true; need_convert_back = false; break; + case TBM_FORMAT_ARGB8888: case TBM_FORMAT_XBGR8888: need_convert = true; need_convert_back = true; diff --git a/EGL/yagl_render.c b/EGL/yagl_render.c index e67925a..73e817c 100644 --- a/EGL/yagl_render.c +++ b/EGL/yagl_render.c @@ -79,3 +79,14 @@ void yagl_render_finish() yagl_context_finish(ctx); } } + +void yagl_render_flush() +{ + struct yagl_context *ctx = yagl_get_context(); + + yagl_transport_flush(yagl_get_transport(), NULL); + + if (ctx) { + yagl_context_flush(ctx); + } +} diff --git a/GLES_common/yagl_gles_calls.c b/GLES_common/yagl_gles_calls.c index 6181ff9..7e5d763 100644 --- a/GLES_common/yagl_gles_calls.c +++ b/GLES_common/yagl_gles_calls.c @@ -1259,7 +1259,16 @@ YAGL_API void glFinish() YAGL_LOG_FUNC_EXIT(NULL); } -YAGL_IMPLEMENT_API_NORET0(glFlush) +YAGL_API void glFlush() +{ + YAGL_LOG_FUNC_ENTER_SPLIT0(glFlush); + + yagl_host_glFlush(); + + yagl_render_flush(); + + YAGL_LOG_FUNC_EXIT(NULL); +} void glFramebufferRenderbuffer(GLenum target, GLenum attachment, diff --git a/GLES_common/yagl_gles_image.c b/GLES_common/yagl_gles_image.c index 7139f36..c9f0944 100644 --- a/GLES_common/yagl_gles_image.c +++ b/GLES_common/yagl_gles_image.c @@ -129,3 +129,10 @@ void yagl_gles_image_release(struct yagl_gles_image *image) yagl_client_image_release(&image->base); } } + +void yagl_gles_set_finalize(struct yagl_gles_image *image) +{ + if (image) { + image->base.need_finalize = 1; + } +} diff --git a/GLES_common/yagl_gles_image.h b/GLES_common/yagl_gles_image.h index 83436f4..4dda60e 100644 --- a/GLES_common/yagl_gles_image.h +++ b/GLES_common/yagl_gles_image.h @@ -67,4 +67,10 @@ void yagl_gles_image_acquire(struct yagl_gles_image *image); */ void yagl_gles_image_release(struct yagl_gles_image *image); +/* + * Set need_finalize flag to update original surface of drm surface. + * Passing NULL won't hurt, this is for convenience. + */ +void yagl_gles_set_finalize(struct yagl_gles_image *image); + #endif diff --git a/GLES_common/yagl_gles_texture.c b/GLES_common/yagl_gles_texture.c index 0a20e56..4a93ed4 100644 --- a/GLES_common/yagl_gles_texture.c +++ b/GLES_common/yagl_gles_texture.c @@ -340,3 +340,12 @@ void yagl_gles_texture_release_tex_image(struct yagl_gles_texture *texture) */ yagl_host_glGenTextures(&texture->global_name, 1); } + +void yagl_gles_texture_set_finalize_image(struct yagl_gles_texture *texture) +{ + if (texture && texture->image) { + yagl_gles_image_acquire(texture->image); + yagl_gles_set_finalize(texture->image); + yagl_gles_image_release(texture->image); + } +} diff --git a/GLES_common/yagl_gles_texture.h b/GLES_common/yagl_gles_texture.h index bf5e1eb..c5cd501 100644 --- a/GLES_common/yagl_gles_texture.h +++ b/GLES_common/yagl_gles_texture.h @@ -116,4 +116,9 @@ void yagl_gles_texture_bind_tex_image(struct yagl_gles_texture *texture, */ void yagl_gles_texture_release_tex_image(struct yagl_gles_texture *texture); +/* + * Set finalize flag to image binded the texture. + */ +void yagl_gles_texture_set_finalize_image(struct yagl_gles_texture *texture); + #endif diff --git a/GLESv2/yagl_gles2_context.c b/GLESv2/yagl_gles2_context.c index 2959308..fa67c75 100644 --- a/GLESv2/yagl_gles2_context.c +++ b/GLESv2/yagl_gles2_context.c @@ -265,9 +265,7 @@ static void yagl_gles2_context_prepare_framebuffer(struct yagl_gles2_context *ct yagl_gles_texture_acquire(state.texture); if (state.texture->image) { - yagl_gles_image_acquire(state.texture->image); - state.texture->image->base.need_finalize = 1; - yagl_gles_image_release(state.texture->image); + yagl_gles_texture_set_finalize_image(state.texture); yagl_gles_framebuffer_texture2d(fb, fb->target, diff --git a/include/yagl_render.h b/include/yagl_render.h index 244a513..eae10b7 100644 --- a/include/yagl_render.h +++ b/include/yagl_render.h @@ -76,4 +76,16 @@ YAGL_API void yagl_render_invalidate(int throttle); */ YAGL_API void yagl_render_finish(); +/* + * Some tbm buffers that has format such as TBM_FORMAT_ARGB8888 and TBM_FORMAT_XBGR8888 + * are necessary to update original surface from drm surface after finishing rendering for + * consistency. YAGL already finalizes images by using yagl_render_finish() in glFinish() + * but if an application that uses eglimage binded with tbm buffer that created with + * TBM_FORMAT_ARGB8888 or TBM_FORMAT_XBGR8888 format doesn't invoke glFinish() in their + * source code then the consistency can be breaked. Therefore, it needs to finalize images + * additionally after flushing rendering commands. Callers of this should probably include + * glFlush, eglSwapBuffers, etc. + */ +YAGL_API void yagl_render_flush(); + #endif |