diff options
author | Vladislav Andresov <v.andresov@partner.samsung.com> | 2018-05-31 07:43:52 +0300 |
---|---|---|
committer | Vladislav Andresov <v.andresov@partner.samsung.com> | 2018-06-27 18:09:46 +0300 |
commit | 3639edafe715673a090150b7e93ce53b3a4b2f0e (patch) | |
tree | 979201db8ea238f7d9b0b3244048fbfc86c06f76 /EGL/yagl_onscreen_image_tizen_sfc.c | |
parent | cdac3d6f415e99d96c984f525b480b130d4fc0ae (diff) | |
download | emulator-yagl-3639edafe715673a090150b7e93ce53b3a4b2f0e.tar.gz emulator-yagl-3639edafe715673a090150b7e93ce53b3a4b2f0e.tar.bz2 emulator-yagl-3639edafe715673a090150b7e93ce53b3a4b2f0e.zip |
Add handling of new format XBGRsubmit/tizen/20180731.005737accepted/tizen/unified/20180731.140010
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.c | 112 |
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; |