summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbyungchul.so <byungchul.so@samsung.com>2021-12-13 12:05:48 +0900
committerbyungchul.so <byungchul.so@samsung.com>2021-12-21 13:39:21 +0900
commita3c51bd11da9896d651f82b4491b05b92922248c (patch)
treeda0e218c9566ecc2c637010a7f079dafcc3d5d5b
parenta360b4231df4e7c357616e6488f5dd8a7b450a53 (diff)
downloademulator-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.c5
-rw-r--r--EGL/yagl_context.h2
-rw-r--r--EGL/yagl_egl_calls.c2
-rw-r--r--EGL/yagl_onscreen_image_tizen_sfc.c35
-rw-r--r--EGL/yagl_render.c11
-rw-r--r--GLES_common/yagl_gles_calls.c11
-rw-r--r--GLES_common/yagl_gles_image.c7
-rw-r--r--GLES_common/yagl_gles_image.h6
-rw-r--r--GLES_common/yagl_gles_texture.c9
-rw-r--r--GLES_common/yagl_gles_texture.h5
-rw-r--r--GLESv2/yagl_gles2_context.c4
-rw-r--r--include/yagl_render.h12
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