summaryrefslogtreecommitdiff
path: root/EGL/yagl_onscreen_image_tizen_sfc.c
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 /EGL/yagl_onscreen_image_tizen_sfc.c
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>
Diffstat (limited to 'EGL/yagl_onscreen_image_tizen_sfc.c')
-rw-r--r--EGL/yagl_onscreen_image_tizen_sfc.c112
1 files changed, 112 insertions, 0 deletions
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;