Add Pbuffer support on Tizen platform
authorXuelian <xuelian.bai@samsung.com>
Mon, 17 Feb 2020 12:39:44 +0000 (20:39 +0800)
committerXuelian Bai <xuelian.bai@samsung.com>
Tue, 21 Feb 2023 06:32:45 +0000 (14:32 +0800)
Merged old commit:
commit f409ef598976a4fd4f74ab4695478b1fc1651c06
Author: Zhaowei Yuan <zhaowei.yuan@samsung.com>
    1. Add EGL_PBUFFER_BIT to surface_type if maskes match
    2. Alloc local buffer when render buffer type is
    "FRONT_LEFT" which will be used by Pbuffer

commit b0dec10d0d0fbc7f77623016f3d986122f718f8b
Author: Xuelian Bai <xuelian.bai@samsung.com>
    Fix crash when query a pbuffer surface
    Pbuffer is not created via TPL, so when query a pbuffer surface,
    we can only call _eglQuerySurface instead of TPL APIs.

Change-Id: Ib9990973f228374a95f60157a3b79069529a62b2
Signed-off-by: Xuelian Bai <xuelian.bai@samsung.com>
src/egl/drivers/dri2/platform_tizen.c

index bc18827..5e35eeb 100755 (executable)
@@ -49,6 +49,8 @@
 #include <wayland-client.h>
 #include <drm-uapi/drm_fourcc.h>
 
+#include <drm_fourcc.h>
+
 int tbm_bufmgr_fd = -1;
 
 static void tizen_free_local_buffers(struct dri2_egl_surface *dri2_surf);
@@ -363,6 +365,7 @@ tizen_create_surface(_EGLDisplay *disp, EGLint type,
          _eglError(EGL_BAD_NATIVE_PIXMAP, "tizen_create_surface needs valid native pixmap");
          goto cleanup_surface;
       }
+
       ret = tpl_display_get_native_pixmap_info(dri2_dpy->tpl_display,
                                                (tpl_handle_t)native_window,
                                                &dri2_surf->base.Width,
@@ -375,17 +378,16 @@ tizen_create_surface(_EGLDisplay *disp, EGLint type,
       }
 
       tpl_surf_type = TPL_SURFACE_TYPE_PIXMAP;
-   } else {
-      _eglError(EGL_BAD_NATIVE_WINDOW, "tizen_create_surface does not support PBuffer");
-      goto cleanup_surface;
    }
 
-   dri2_surf->tpl_surface = tpl_surface_create(dri2_dpy->tpl_display,
+   if(type == EGL_WINDOW_BIT || type == EGL_PIXMAP_BIT) {
+      dri2_surf->tpl_surface = tpl_surface_create(dri2_dpy->tpl_display,
                                                (tpl_handle_t)native_window,
                                                tpl_surf_type,
                                                dri2_surf->tbm_format);
-   if (!dri2_surf->tpl_surface)
-      goto cleanup_surface;
+      if (!dri2_surf->tpl_surface)
+         goto cleanup_surface;
+   }
 
    if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf)) {
       _eglError(EGL_BAD_ALLOC, "createNewDrawable");
@@ -455,7 +457,8 @@ tizen_destroy_surface(_EGLDisplay *disp, _EGLSurface *surf)
 
    dri2_dpy->core->destroyDrawable(dri2_surf->dri_drawable);
 
-   tpl_object_unreference((tpl_object_t *)dri2_surf->tpl_surface);
+   if (dri2_surf->tpl_surface)
+      tpl_object_unreference((tpl_object_t *)dri2_surf->tpl_surface);
 
    dri2_fini_surface(surf);
 
@@ -926,26 +929,28 @@ tizen_query_surface(_EGLDisplay *dpy, _EGLSurface *surf,
    struct dri2_egl_surface *dri2_surf = dri2_egl_surface(surf);
    int width = 0, height = 0;
 
-   if (tpl_display_get_native_window_info(dri2_dpy->tpl_display,
-                                          dri2_surf->native_win,
-                                          &width, &height, NULL, 0, 0) != TPL_ERROR_NONE)
-     return EGL_FALSE;
-
-   switch (attribute) {
-      case EGL_WIDTH:
-         if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->native_win) {
-            *value = width;
-            return EGL_TRUE;
-         }
-         break;
-      case EGL_HEIGHT:
-         if (dri2_surf->base.Type == EGL_WINDOW_BIT && dri2_surf->native_win) {
-            *value = height;
-            return EGL_TRUE;
-         }
-         break;
-      default:
-         break;
+   if (dri2_surf->base.Type == EGL_WINDOW_BIT) {
+           if (tpl_display_get_native_window_info(dri2_dpy->tpl_display,
+                                           dri2_surf->native_win,
+                                           &width, &height, NULL, 0, 0) != TPL_ERROR_NONE)
+                return EGL_FALSE;
+
+           switch (attribute) {
+                   case EGL_WIDTH:
+                           if (dri2_surf->native_win) {
+                                   *value = width;
+                                   return EGL_TRUE;
+                           }
+                           break;
+                   case EGL_HEIGHT:
+                           if (dri2_surf->native_win) {
+                                   *value = height;
+                                   return EGL_TRUE;
+                           }
+                           break;
+                   default:
+                           break;
+            }
    }
    return _eglQuerySurface(dpy, surf, attribute, value);
 }
@@ -1034,6 +1039,9 @@ tizen_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf,
             break;
          }
          /* fall through for pbuffers */
+      case __DRI_BUFFER_FRONT_LEFT:
+         if (dri2_surf->base.Type != EGL_PBUFFER_BIT)
+            break;
       case __DRI_BUFFER_DEPTH:
       case __DRI_BUFFER_STENCIL:
       case __DRI_BUFFER_ACCUM:
@@ -1046,7 +1054,6 @@ tizen_get_buffers_parse_attachments(struct dri2_egl_surface *dri2_surf,
             num_buffers++;
          }
          break;
-      case __DRI_BUFFER_FRONT_LEFT:
       case __DRI_BUFFER_FRONT_RIGHT:
       case __DRI_BUFFER_FAKE_FRONT_LEFT:
       case __DRI_BUFFER_FAKE_FRONT_RIGHT:
@@ -1217,6 +1224,16 @@ tizen_add_configs(_EGLDisplay *dpy)
 {
    struct dri2_egl_display *dri2_dpy = dri2_egl_display(dpy);
    int count, i;
+   struct rgba_masks {
+      unsigned int red;
+      unsigned int green;
+      unsigned int blue;
+      unsigned int alpha;
+   } pbuffer_masks[] = {
+         { 0xff0000, 0xff00, 0xff, 0xff000000 }, /* ARGB8888 */
+         { 0xff0000, 0xff00, 0xff, 0x0 },        /* RGB888 */
+         { 0x00f800, 0x07e0, 0x1f, 0x0 },        /* RGB565 */
+   };
 
    for (i = 0, count = 0; dri2_dpy->driver_configs[i]; i++) {
       struct dri2_egl_config *dri2_cfg;
@@ -1228,6 +1245,8 @@ tizen_add_configs(_EGLDisplay *dpy)
          EGL_NONE,
       };
       tpl_result_t res;
+      struct rgba_masks masks;
+      int j;
 
       dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
                                       __DRI_ATTRIB_RED_SIZE, &red);
@@ -1252,6 +1271,27 @@ tizen_add_configs(_EGLDisplay *dpy)
       if (res == TPL_ERROR_NONE)
         surface_type |= EGL_PIXMAP_BIT;
 
+      dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
+                                      __DRI_ATTRIB_RED_MASK, &masks.red);
+      dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
+                                      __DRI_ATTRIB_GREEN_MASK, &masks.green);
+      dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
+                                      __DRI_ATTRIB_BLUE_MASK, &masks.blue);
+      dri2_dpy->core->getConfigAttrib(dri2_dpy->driver_configs[i],
+                                      __DRI_ATTRIB_ALPHA_MASK, &masks.alpha);
+
+      for (j = 0; j < ARRAY_SIZE(pbuffer_masks); j++) {
+         const struct rgba_masks *pbuffer_mask = &pbuffer_masks[j];
+
+         if (pbuffer_mask->red   == masks.red &&
+             pbuffer_mask->green == masks.green &&
+             pbuffer_mask->blue  == masks.blue &&
+             pbuffer_mask->alpha == masks.alpha) {
+            surface_type |= EGL_PBUFFER_BIT;
+            break;
+         }
+      }
+
       if (!surface_type)
         continue;