summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Andresov <v.andresov@partner.samsung.com>2018-05-31 07:43:52 +0300
committerVladislav Andresov <v.andresov@partner.samsung.com>2018-06-27 18:09:46 +0300
commit3639edafe715673a090150b7e93ce53b3a4b2f0e (patch)
tree979201db8ea238f7d9b0b3244048fbfc86c06f76
parentcdac3d6f415e99d96c984f525b480b130d4fc0ae (diff)
downloademulator-yagl-3639edafe715673a090150b7e93ce53b3a4b2f0e.tar.gz
emulator-yagl-3639edafe715673a090150b7e93ce53b3a4b2f0e.tar.bz2
emulator-yagl-3639edafe715673a090150b7e93ce53b3a4b2f0e.zip
Currently this format can be used only for output images which would be product of rendering. Change-Id: Ic3a7c5fe2e2c528059dc41a4df868268720c94a9 Signed-off-by: Vladislav Andresov <v.andresov@partner.samsung.com>
-rw-r--r--EGL/yagl_context.c5
-rw-r--r--EGL/yagl_context.h2
-rw-r--r--EGL/yagl_display.c28
-rw-r--r--EGL/yagl_display.h1
-rw-r--r--EGL/yagl_image.h2
-rw-r--r--EGL/yagl_onscreen_image_tizen_sfc.c112
-rw-r--r--EGL/yagl_onscreen_image_tizen_sfc.h2
-rw-r--r--EGL/yagl_render.c3
-rw-r--r--GLES_common/yagl_gles_framebuffer.c2
-rw-r--r--GLES_common/yagl_gles_framebuffer.h2
-rw-r--r--GLESv2/yagl_gles2_context.c48
-rw-r--r--include/yagl_client_image.h2
12 files changed, 209 insertions, 0 deletions
diff --git a/EGL/yagl_context.c b/EGL/yagl_context.c
index 81ef29d..2e0feae 100644
--- a/EGL/yagl_context.c
+++ b/EGL/yagl_context.c
@@ -131,3 +131,8 @@ void yagl_context_release(struct yagl_context *ctx)
yagl_resource_release(&ctx->res);
}
}
+
+void yagl_context_finish(struct yagl_context *ctx)
+{
+ yagl_display_finalize_images(ctx->dpy);
+}
diff --git a/EGL/yagl_context.h b/EGL/yagl_context.h
index 4d11f76..1ea2dd4 100644
--- a/EGL/yagl_context.h
+++ b/EGL/yagl_context.h
@@ -83,4 +83,6 @@ void yagl_context_acquire(struct yagl_context *ctx);
*/
void yagl_context_release(struct yagl_context *ctx);
+void yagl_context_finish(struct yagl_context *ctx);
+
#endif
diff --git a/EGL/yagl_display.c b/EGL/yagl_display.c
index 1433c8a..4aec282 100644
--- a/EGL/yagl_display.c
+++ b/EGL/yagl_display.c
@@ -42,6 +42,7 @@
#include "yagl_fence.h"
#include "yagl_native_display.h"
#include "yagl_native_platform.h"
+#include "yagl_client_image.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
@@ -534,6 +535,33 @@ int yagl_display_image_remove(struct yagl_display *dpy,
return 0;
}
+void yagl_display_finalize_images(struct yagl_display *dpy)
+{
+ struct yagl_resource *res;
+
+ pthread_mutex_lock(&dpy->mutex);
+
+ yagl_list_for_each(struct yagl_resource, res, &dpy->images, list) {
+ struct yagl_image *image = (struct yagl_image *)res;
+ int need_finalize;
+
+ yagl_image_acquire(image);
+
+ yagl_client_image_acquire(image->client_image);
+ need_finalize = image->client_image->need_finalize;
+ image->client_image->need_finalize = 0;
+ yagl_client_image_release(image->client_image);
+
+ if (need_finalize && image->finalize) {
+ image->finalize(image);
+ }
+
+ yagl_image_release(image);
+ }
+
+ pthread_mutex_unlock(&dpy->mutex);
+}
+
void yagl_display_fence_add(struct yagl_display *dpy,
struct yagl_fence *fence)
{
diff --git a/EGL/yagl_display.h b/EGL/yagl_display.h
index b1ee7b3..5aee5d0 100644
--- a/EGL/yagl_display.h
+++ b/EGL/yagl_display.h
@@ -179,6 +179,7 @@ struct yagl_image *yagl_display_image_acquire(struct yagl_display *dpy,
int yagl_display_image_remove(struct yagl_display *dpy,
EGLImageKHR handle);
+void yagl_display_finalize_images(struct yagl_display *dpy);
/*
* @}
*/
diff --git a/EGL/yagl_image.h b/EGL/yagl_image.h
index 7a63c79..2ab8e2b 100644
--- a/EGL/yagl_image.h
+++ b/EGL/yagl_image.h
@@ -56,6 +56,8 @@ struct yagl_image
struct yagl_client_image *client_image;
void (*update)(struct yagl_image */*image*/);
+
+ void (*finalize)(struct yagl_image */*image*/);
};
void yagl_image_init(struct yagl_image *image,
diff --git a/EGL/yagl_onscreen_image_tizen_sfc.c b/EGL/yagl_onscreen_image_tizen_sfc.c
index 4f33959..acd43d8 100644
--- a/EGL/yagl_onscreen_image_tizen_sfc.c
+++ b/EGL/yagl_onscreen_image_tizen_sfc.c
@@ -68,6 +68,15 @@ static inline uint32_t yuv2argb(float y, float u, float v)
return (0xff000000 | (r << 16) | (g << 8) | b);
}
+static inline uint32_t argb2xbgr(uint32_t argb)
+{
+ uint32_t r = (argb & 0xff0000) >> 16;
+ uint32_t g = (argb & 0xff00) >> 8;
+ uint32_t b = (argb & 0xff);
+
+ return (0xff000000) | (b << 16) | (g << 8) | (r);
+}
+
static bool yagl_onscreen_image_tizen_sfc_convert(struct yagl_onscreen_image_tizen_sfc *image)
{
uint32_t *dst;
@@ -150,6 +159,60 @@ static bool yagl_onscreen_image_tizen_sfc_convert(struct yagl_onscreen_image_tiz
return true;
}
+static bool yagl_onscreen_image_tizen_sfc_convert_back(struct yagl_onscreen_image_tizen_sfc *image)
+{
+ uint32_t *dst;
+ int i, j;
+ tbm_surface_info_s info;
+ int ret;
+
+ YAGL_LOG_FUNC_SET(yagl_onscreen_image_tizen_sfc_convert_back);
+
+ ret = tbm_surface_map(image->sfc, TBM_SURF_OPTION_WRITE, &info);
+
+ if (ret != TBM_SURFACE_ERROR_NONE) {
+ YAGL_LOG_ERROR("tbm_surface_map failed: %d", ret);
+ return false;
+ }
+
+ ret = vigs_drm_surface_start_access(image->drm_sfc, VIGS_DRM_SAF_READ);
+
+ if (ret) {
+ YAGL_LOG_ERROR("vigs_drm_surface_start_access failed: %s", strerror(-ret));
+ tbm_surface_unmap(image->sfc);
+ return false;
+ }
+
+ dst = image->drm_sfc->gem.vaddr;
+ dst += info.width * info.height - info.width;
+
+ switch (info.format) {
+ case TBM_FORMAT_XBGR8888:
+ for (i = 0; i < info.height; i++) {
+ for (j = 0; j < info.width; j++) {
+ uint32_t argb = *(dst - i * info.width + j);
+ ((uint32_t *)info.planes[0].ptr)[i * info.width + j] = argb2xbgr(argb);
+ }
+ }
+
+ YAGL_LOG_ERROR("cpu converting: %p[0] = 0x%x", info.planes[0].ptr,
+ ((uint32_t *)info.planes[0].ptr)[0]);
+
+ break;
+ }
+
+ ret = vigs_drm_surface_end_access(image->drm_sfc, 1);
+
+ if (ret) {
+ YAGL_LOG_ERROR("vigs_drm_surface_end_access failed: %s", strerror(-ret));
+ return false;
+ }
+
+ tbm_surface_unmap(image->sfc);
+
+ return true;
+}
+
static void yagl_onscreen_image_tizen_sfc_update(struct yagl_image *image)
{
struct yagl_onscreen_image_tizen_sfc *tizen_sfc_image =
@@ -213,6 +276,46 @@ static void yagl_onscreen_image_tizen_sfc_update(struct yagl_image *image)
yagl_onscreen_image_tizen_sfc_convert(tizen_sfc_image);
}
+static void yagl_onscreen_image_tizen_sfc_finalize(struct yagl_image *image)
+{
+ struct yagl_onscreen_image_tizen_sfc *tizen_sfc_image =
+ (struct yagl_onscreen_image_tizen_sfc *)image;
+
+ tbm_bo bo;
+ struct vigs_drm_surface *dst;
+ int ret;
+
+ YAGL_LOG_FUNC_SET(yagl_onscreen_image_tizen_sfc_finalize);
+
+ vigs_drm_surface_set_gpu_dirty(tizen_sfc_image->drm_sfc);
+
+ if (!tizen_sfc_image->need_convert_back) {
+ return;
+ }
+
+ 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,
+ 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;
+ }
+
+ yagl_onscreen_image_tizen_sfc_convert_back(tizen_sfc_image);
+}
+
static void yagl_onscreen_image_tizen_sfc_destroy(struct yagl_ref *ref)
{
struct yagl_onscreen_image_tizen_sfc *image = (struct yagl_onscreen_image_tizen_sfc *)ref;
@@ -240,6 +343,7 @@ struct yagl_onscreen_image_tizen_sfc
tbm_bo bo;
tbm_surface_info_s info;
bool need_convert;
+ bool need_convert_back;
int ret;
YAGL_LOG_FUNC_SET(yagl_onscreen_image_tizen_sfc_create);
@@ -260,12 +364,18 @@ struct yagl_onscreen_image_tizen_sfc
case TBM_FORMAT_RGB888:
case TBM_FORMAT_XRGB8888:
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_XBGR8888:
+ need_convert = true;
+ need_convert_back = true;
break;
default:
YAGL_LOG_ERROR("bad format: 0x%X", info.format);
@@ -344,8 +454,10 @@ struct yagl_onscreen_image_tizen_sfc
yagl_client_image_release(client_image);
image->base.update = &yagl_onscreen_image_tizen_sfc_update;
+ image->base.finalize = &yagl_onscreen_image_tizen_sfc_finalize;
image->sfc = sfc;
image->need_convert = need_convert;
+ image->need_convert_back = need_convert_back;
image->drm_sfc = drm_sfc;
image->format = info.format;
diff --git a/EGL/yagl_onscreen_image_tizen_sfc.h b/EGL/yagl_onscreen_image_tizen_sfc.h
index e7af41b..f7332dc 100644
--- a/EGL/yagl_onscreen_image_tizen_sfc.h
+++ b/EGL/yagl_onscreen_image_tizen_sfc.h
@@ -49,6 +49,8 @@ struct yagl_onscreen_image_tizen_sfc
bool need_convert;
+ bool need_convert_back;
+
struct vigs_drm_surface *drm_sfc;
uint32_t format;
diff --git a/EGL/yagl_render.c b/EGL/yagl_render.c
index 0bcf932..de117b1 100644
--- a/EGL/yagl_render.c
+++ b/EGL/yagl_render.c
@@ -62,6 +62,7 @@ void yagl_render_invalidate(int throttle)
void yagl_render_finish()
{
struct yagl_surface *draw_sfc = yagl_get_draw_surface();
+ struct yagl_context *ctx = yagl_get_context();
if (draw_sfc) {
draw_sfc->wait_gl(draw_sfc);
@@ -73,4 +74,6 @@ void yagl_render_finish()
*/
yagl_transport_flush(yagl_get_transport(), NULL);
}
+
+ yagl_context_finish(ctx);
}
diff --git a/GLES_common/yagl_gles_framebuffer.c b/GLES_common/yagl_gles_framebuffer.c
index a1c2235..954e9da 100644
--- a/GLES_common/yagl_gles_framebuffer.c
+++ b/GLES_common/yagl_gles_framebuffer.c
@@ -219,6 +219,8 @@ void yagl_gles_framebuffer_bind(struct yagl_gles_framebuffer *fb,
yagl_host_glBindFramebuffer(target, fb->global_name);
fb->was_bound = 1;
+
+ fb->target = target;
}
int yagl_gles_framebuffer_was_bound(struct yagl_gles_framebuffer *fb)
diff --git a/GLES_common/yagl_gles_framebuffer.h b/GLES_common/yagl_gles_framebuffer.h
index 8a3e3da..0ed6e2f 100644
--- a/GLES_common/yagl_gles_framebuffer.h
+++ b/GLES_common/yagl_gles_framebuffer.h
@@ -72,6 +72,8 @@ struct yagl_gles_framebuffer
GLenum read_buffer;
int was_bound;
+
+ GLenum target;
};
int yagl_gles_framebuffer_attachment_internalformat(struct yagl_gles_framebuffer_attachment_state *attachment_state,
diff --git a/GLESv2/yagl_gles2_context.c b/GLESv2/yagl_gles2_context.c
index 46e3991..8eec42d 100644
--- a/GLESv2/yagl_gles2_context.c
+++ b/GLESv2/yagl_gles2_context.c
@@ -42,6 +42,8 @@
#include "yagl_gles_texture_unit.h"
#include "yagl_gles_vertex_array.h"
#include "yagl_gles_utils.h"
+#include "yagl_gles_framebuffer.h"
+#include "yagl_gles_image.h"
#include "yagl_log.h"
#include "yagl_malloc.h"
#include "yagl_state.h"
@@ -237,6 +239,50 @@ static int yagl_gles2_context_pre_link_program(struct yagl_gles2_context *ctx,
return 1;
}
+static void yagl_gles2_context_prepare_framebuffer(struct yagl_gles2_context *ctx,
+ struct yagl_gles_framebuffer *fb)
+{
+ int i = 0;
+ struct yagl_gles_framebuffer_attachment_state state;
+
+ if (fb == NULL) {
+ return;
+ }
+
+ yagl_gles_framebuffer_acquire(fb);
+
+ /*
+ * Currently we don't support depth and stencil attachments for
+ * texture images
+ */
+
+ for (i = 0; i < YAGL_MAX_GLES_FRAMEBUFFER_COLOR_ATTACHMENTS; i++) {
+ state = fb->attachment_states[yagl_gles_framebuffer_attachment_color0 + i];
+
+ if (state.type == GL_TEXTURE && state.texture) {
+ 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_framebuffer_texture2d(fb,
+ fb->target,
+ GL_COLOR_ATTACHMENT0 + i,
+ yagl_gles_framebuffer_attachment_color0,
+ state.textarget,
+ 0,
+ state.texture);
+ }
+
+ yagl_gles_texture_release(state.texture);
+ }
+ }
+
+ yagl_gles_framebuffer_release(fb);
+}
+
void yagl_gles2_context_init(struct yagl_gles2_context *ctx,
yagl_client_api client_api,
struct yagl_sharegroup *sg)
@@ -431,6 +477,8 @@ void yagl_gles2_context_pre_draw(struct yagl_gles2_context *ctx,
{
YAGL_LOG_FUNC_SET(yagl_gles2_context_pre_draw);
+ yagl_gles2_context_prepare_framebuffer(ctx, ctx->base.fbo_draw);
+
/*
* 'count' can be <= 0 in case of integer overflows, this is
* typically user problem, just don't simulate vertex attribute array 0
diff --git a/include/yagl_client_image.h b/include/yagl_client_image.h
index 08c979c..15e42b6 100644
--- a/include/yagl_client_image.h
+++ b/include/yagl_client_image.h
@@ -42,6 +42,8 @@ struct yagl_client_image
{
struct yagl_object base;
+ int need_finalize;
+
void (*update)(struct yagl_client_image */*image*/,
uint32_t /*width*/,
uint32_t /*height*/,