Add handling of new format XBGR 85/180585/5 accepted/tizen/unified/20180731.140010 submit/tizen/20180731.005737
authorVladislav Andresov <v.andresov@partner.samsung.com>
Thu, 31 May 2018 04:43:52 +0000 (07:43 +0300)
committerVladislav Andresov <v.andresov@partner.samsung.com>
Wed, 27 Jun 2018 15:09:46 +0000 (18:09 +0300)
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>
12 files changed:
EGL/yagl_context.c
EGL/yagl_context.h
EGL/yagl_display.c
EGL/yagl_display.h
EGL/yagl_image.h
EGL/yagl_onscreen_image_tizen_sfc.c
EGL/yagl_onscreen_image_tizen_sfc.h
EGL/yagl_render.c
GLES_common/yagl_gles_framebuffer.c
GLES_common/yagl_gles_framebuffer.h
GLESv2/yagl_gles2_context.c
include/yagl_client_image.h

index 81ef29d4425f894dc01645aa299501893e81c16d..2e0feaeddf017235b0086d8747de45ebef99cfa0 100644 (file)
@@ -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);
+}
index 4d11f7674775c505f2dcc7db616488207d9f7f45..1ea2dd45388c905f649291df12725bd088c61911 100644 (file)
@@ -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
index 1433c8a4f72d548a4079c3861f67e0e374aa6dcf..4aec2823d0e52a6ca5f94a960f00ac7747bb975f 100644 (file)
@@ -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)
 {
index b1ee7b3e82a5f54f50a6387a3e74e07cae6a7894..5aee5d0160795535afbfce55c5a76f3cffb7d2a3 100644 (file)
@@ -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);
 /*
  * @}
  */
index 7a63c791537c41591a6e15ea216211ab004fb4c8..2ab8e2b21d3c937e19039dbd177ee0f8fcaa2e0a 100644 (file)
@@ -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,
index 4f3395947a555f95316108a80d96206d77212392..acd43d88135c5c475dba9d65e06e9bd3f8019a99 100644 (file)
@@ -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;
 
index e7af41bc575d7f81cc9da87df384649f539917a4..f7332dc466d617fcd4be0862c2e9eb6e446b7f50 100644 (file)
@@ -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;
index 0bcf932971ebeccaba4dd1f5b28824f3308e8e69..de117b12ec8766471af4803ac23f8bbeb90cd963 100644 (file)
@@ -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);
 }
index a1c2235f877818dde85c87872386099a00dd58b3..954e9dafa7a83df7d520f2fd12bbd3085c25ed30 100644 (file)
@@ -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)
index 8a3e3da03b4d857c18634eadcb9278ffa8b106d1..0ed6e2fc7d376f274ad9e0717ce578619b06a143 100644 (file)
@@ -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,
index 46e39915d0dd50951841ba2cf7186d66f8e26635..8eec42d74f3615017be22da606933fb3c0b69a15 100644 (file)
@@ -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
index 08c979c5e7da62b1beaf9a820de06f8f450e9c41..15e42b6d8571033d531d1f8b96030001c7c2873c 100644 (file)
@@ -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*/,