Add DRI3 92/26292/1
authorRoman Marchenko <r.marchenko@samsung.com>
Wed, 20 Aug 2014 09:21:18 +0000 (12:21 +0300)
committerRoman Marchenko <r.marchenko@samsung.com>
Wed, 20 Aug 2014 09:21:29 +0000 (12:21 +0300)
Change-Id: I184adcaaf8cd7b78c8d03de0ca233c3f12ed8382
Signed-off-by: Roman Marchenko <r.marchenko@samsung.com>
packaging/xf86-video-exynos.spec
src/Makefile.am
src/accel/sec_accel.h
src/accel/sec_dri3.c [new file with mode: 0644]
src/sec.c
src/sec.h

index b8b4644..41af3e9 100755 (executable)
@@ -12,6 +12,7 @@ BuildRequires:  pkgconfig(xorg-macros)
 BuildRequires:  pkgconfig(xorg-server)
 BuildRequires:  pkgconfig(x11)
 BuildRequires:  pkgconfig(xproto)
+BuildRequires:  pkgconfig(dri3proto)
 BuildRequires:  pkgconfig(fontsproto)
 BuildRequires:  pkgconfig(randrproto)
 BuildRequires:  pkgconfig(renderproto)
index 6640cdd..df32e73 100644 (file)
@@ -25,6 +25,7 @@ exynos_drv_la_SOURCES += \
        accel/sec_exa.c \
        accel/sec_exa_sw.c \
        accel/sec_present.c \
+       accel/sec_dri3.c \
        accel/sec_dri2.c
 AM_CFLAGS += -I@top_srcdir@/src/accel
 
index 9ae42cd..6bd2b3d 100644 (file)
@@ -75,6 +75,10 @@ typedef struct
     /* Last update SBC */
     XID owner;
     CARD64 sbc;
+
+    /* for DRI3 */
+    int stride;
+
 } SECPixmapPriv;
 
 /* exa driver private infomation */
@@ -163,4 +167,11 @@ void secDri2Deinit            (ScreenPtr pScreen);
 void secDri2FrameEventHandler (unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, void *event_data);
 void secDri2FlipEventHandler  (unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, void *event_data, Bool flip_failed);
 
+/**************************************************************************
+ * DRI3
+ **************************************************************************/
+/* DRI3 */
+Bool secDri3ScreenInit   (ScreenPtr screen);
+
+
 #endif /* _SEC_ACCEL_H_ */
diff --git a/src/accel/sec_dri3.c b/src/accel/sec_dri3.c
new file mode 100644 (file)
index 0000000..cc9b6b3
--- /dev/null
@@ -0,0 +1,194 @@
+/*
+ * Copyright © 2013 Keith Packard
+ * Copyright 2010 - 2014 Samsung Electronics co., Ltd. All Rights Reserved.
+ *
+ * Contact: Roman Marchenko <r.marchenko@samsung.com>
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission.  The copyright holders make no representations
+ * about the suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/time.h>
+#include <time.h>
+#include <errno.h>
+
+#include <tbm_bufmgr.h>
+
+#include "xorg-server.h"
+#include "xf86.h"
+
+#include "xf86drm.h"
+
+#include "dri3.h"
+
+#include "sec.h"
+#include "sec_accel.h"
+
+// -------------------------- Private functions--------------------------------
+/* TODO : _boCreateFromFd and  int _tbm_bo_import_fd mast be moved to _tbm_bo_export_fd */
+
+tbm_bo _tbm_bo_import_fd(int drm_fd, tbm_bufmgr bufmgr, int prime_fd, int size)
+{
+       //getting handle from fd
+       unsigned int gem = 0;
+       if (drmPrimeFDToHandle(drm_fd, prime_fd, &gem))
+       {
+               return NULL;
+       }
+
+       //getting name from handle(gem)
+    struct drm_gem_flink arg_flink = {0,};
+    arg_flink.handle = gem;
+    if (drmIoctl(drm_fd, DRM_IOCTL_GEM_FLINK, &arg_flink))
+    {
+       return NULL;
+    }
+
+    //creating tbm_bo from name
+    return tbm_bo_import(bufmgr, arg_flink.name);
+}
+
+int _tbm_bo_export_fd(tbm_bo bo, int *fd)
+{
+       tbm_bo_handle handle = tbm_bo_get_handle(bo, TBM_DEVICE_MM);
+       *fd = handle.s32;
+       return 0;
+}
+
+
+// -------------------------- Callback functions--------------------------------
+static int
+SECDRI3Open(ScreenPtr screen, RRProviderPtr provider, int *fdp) {
+       ScrnInfoPtr pScrn = xf86ScreenToScrn(screen);
+       SECPtr pExynos = SECPTR(pScrn);
+       drm_magic_t magic;
+       int fd;
+
+       /* Open the device for the client */
+       fd = open(pExynos->drm_device_name, O_RDWR | O_CLOEXEC);
+       if (fd == -1 && errno == EINVAL) {
+               fd = open(pExynos->drm_device_name, O_RDWR);
+               if (fd != -1)
+                       fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
+       }
+
+       if (fd < 0)
+               return BadAlloc;
+
+       /* Go through the auth dance locally */
+       if (drmGetMagic(fd, &magic) < 0) {
+               close(fd);
+               return BadMatch;
+       }
+
+       /* And we're done */
+       *fdp = fd;
+       return Success;
+}
+
+static PixmapPtr SECDRI3PixmapFromFd (ScreenPtr pScreen,
+                                      int fd,
+                                      CARD16 width,
+                                      CARD16 height,
+                                      CARD16 stride,
+                                      CARD8 depth,
+                                      CARD8 bpp)
+{
+       ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+       SECPtr pSec = SECPTR(pScrn);
+
+
+       PixmapPtr pPixmap = NULL;
+
+       if (depth == 1)
+               return NULL;
+
+    //create bo
+    tbm_bo tbo = _tbm_bo_import_fd(pSec->drm_fd, pSec->tbm_bufmgr,
+                                                               fd, (uint32_t) height * stride);
+
+    if (tbo == NULL)
+       goto no_bo;
+
+    pPixmap = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth,
+                                                                       CREATE_PIXMAP_USAGE_SUB_FB);
+
+    if (!pPixmap)
+       goto no_pixmap;
+
+       tbm_bo_ref(tbo);
+    if (!pScreen->ModifyPixmapHeader(pPixmap, width, height, 0, 0, stride, tbo))
+       goto no_modify;
+
+    return pPixmap;
+
+no_modify:
+       (*pScreen->DestroyPixmap)(pPixmap);
+no_pixmap:
+       tbm_bo_unref(tbo);
+no_bo:
+    return NULL;
+}
+
+static int SECDRI3FdFromPixmap (ScreenPtr pScreen,
+                                PixmapPtr pPixmap,
+                                CARD16 *stride,
+                                CARD32 *size)
+{
+       SECPixmapPriv * priv = NULL;
+       int fd;
+       int ret;
+
+       priv = exaGetPixmapDriverPrivate(pPixmap);
+       if (!priv)
+               return -1;
+       ret = _tbm_bo_export_fd(priv->bo, &fd);
+       if (ret < 0)
+               return -1;
+       *stride = priv->stride;
+       *size = tbm_bo_size(priv->bo);
+       return fd;
+}
+
+static dri3_screen_info_rec sec_dri3_screen_info = {
+        .version = DRI3_SCREEN_INFO_VERSION,
+
+        .open = SECDRI3Open,
+        .pixmap_from_fd = SECDRI3PixmapFromFd,
+        .fd_from_pixmap = SECDRI3FdFromPixmap
+};
+
+// -------------------------- Public functions--------------------------------
+Bool
+secDri3ScreenInit(ScreenPtr screen)
+{
+    return dri3_screen_init(screen, &sec_dri3_screen_info);
+}
+
index fab1559..4dc2ffc 100644 (file)
--- a/src/sec.c
+++ b/src/sec.c
@@ -112,6 +112,7 @@ typedef enum
     OPTION_SCANOUT,
     OPTION_ACCEL2D,
     OPTION_PRESENT,
+    OPTION_DRI3,
     OPTION_PARTIAL_UPDATE,
 } SECOpts;
 
@@ -130,6 +131,7 @@ static const OptionInfoRec SECOptions[] =
     { OPTION_SCANOUT,  "scanout",    OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_ACCEL2D,  "accel_2d",   OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_ACCEL2D,  "present",    OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_ACCEL2D,  "dri3",          OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_PARTIAL_UPDATE,  "partial_update",    OPTV_BOOLEAN, {0}, FALSE },
     { -1,              NULL,         OPTV_NONE,    {0}, FALSE }
 };
@@ -511,6 +513,12 @@ _checkDriverOptions (ScrnInfoPtr pScrn)
     {
         pSec->is_present = TRUE;
     }
+    
+    /* dri3 */
+    if (xf86ReturnOptValBool (pSec->Options, OPTION_DRI3, FALSE))
+    {
+       pSec->is_dri3 = TRUE;
+    }
 
     /* rotate */
     pSec->rotate = RR_Rotate_0;
@@ -1042,6 +1050,16 @@ SECScreenInit (ScreenPtr pScreen, int argc, char **argv)
                                 "Present initialization failed\n");
                 }
             }
+
+            /* init the dri3 */
+            if (pSec->is_dri3)
+            {
+                if (!secDri3ScreenInit (pScreen))
+                {
+                    xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
+                                "DRI3 initialization failed\n");
+                }
+            }
         }
     }
 
index b0e82d2..992f60e 100644 (file)
--- a/src/sec.h
+++ b/src/sec.h
@@ -99,6 +99,7 @@ typedef struct
     Bool is_exa;
     Bool is_dri2;
     Bool is_present;
+    Bool is_dri3;
     Bool is_sw_exa;
     Bool is_accel_2d;
     Bool is_wb_clone;