Merge branch 'devel/dri3' into devel/tizen 48/28248/1
authorRoman Marchenko <r.marchenko@samsung.com>
Tue, 30 Sep 2014 13:37:07 +0000 (16:37 +0300)
committerRoman Marchenko <r.marchenko@samsung.com>
Wed, 1 Oct 2014 07:26:56 +0000 (10:26 +0300)
Conflicts:
src/crtcconfig/sec_crtc.c

Note that Present extension might don't work with "xdbg".
So for using Present you should disable "xdbg" (remove "#define USE_XDBG 1" in "sec.h")
or set the latest version of "xdbg" from tizen.org server

Change-Id: If6f68410d97b87555486187797c0d193771be0a7
Signed-off-by: Roman Marchenko <r.marchenko@samsung.com>
src/Makefile.am
src/accel/sec_accel.h
src/accel/sec_dri2.c
src/accel/sec_dri3.c [new file with mode: 0644]
src/accel/sec_present.c [new file with mode: 0644]
src/crtcconfig/sec_display.c
src/crtcconfig/sec_display.h
src/sec.c
src/sec.h
src/util/sec_util.h

index bb32148..6958ba3 100644 (file)
@@ -25,6 +25,8 @@ AM_CFLAGS += -I@top_srcdir@/src/crtcconfig
 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 f9808a3..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 */
@@ -144,6 +148,17 @@ void secExaG2dDeinit (ScreenPtr pScreen);
 
 
 /**************************************************************************
+ * Present
+ **************************************************************************/
+/* Present */
+Bool secPresentScreenInit              (ScreenPtr pScreen);
+/* Present event handlers (vblank, pageflip) */
+void secPresentVblankHandler   (unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, void* event_data);
+void secPresentFlipEventHandler        (unsigned int frame, unsigned int tv_sec, unsigned int tv_usec, void* event_data, Bool flip_failed);
+void secPresentVblankAbort             (ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void *data);
+void secPresentFlipAbort               (void* pageflip_data);
+
+/**************************************************************************
  * DRI2
  **************************************************************************/
 /* DRI2 */
@@ -152,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_ */
index 178439b..5af5421 100644 (file)
@@ -966,7 +966,9 @@ _doPageFlip (DrawablePtr pDraw, int crtc_pipe, xf86CrtcPtr pCrtc, DRI2FrameEvent
     /* Reset buffer position */
     secRenderBoSetPos(pBackExaPixPriv->bo, pDraw->x, pDraw->y);
 
-    if (!secModePageFlip (pScrn, NULL, pEvent, crtc_pipe, pBackExaPixPriv->bo))
+    if (!secModePageFlip (pScrn, NULL, pEvent, crtc_pipe, pBackExaPixPriv->bo,
+               pEvent->pRegion, pEvent->client_idx, pEvent->drawable_id,
+               secDri2FlipEventHandler))
     {
         XDBG_WARNING (MDRI2, "fail to secModePageFlip\n");
         return FALSE;
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);
+}
+
diff --git a/src/accel/sec_present.c b/src/accel/sec_present.c
new file mode 100644 (file)
index 0000000..436df23
--- /dev/null
@@ -0,0 +1,337 @@
+/*
+ *
+ * xserver-xorg-video-sec
+ *
+ * Copyright © 2013 Keith Packard
+ * Copyright 2010 - 2014 Samsung Electronics co., Ltd. All Rights Reserved.
+ *
+ * Contact: Roman Marchenko <r.marchenko@samsung.com>
+ * Contact: Roman Peresipkyn<r.peresipkyn@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 <sys/types.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include <tbm_bufmgr.h>
+
+#include "xorg-server.h"
+#include "xf86.h"
+#include "xf86drm.h"
+
+#include "windowstr.h"
+
+#include "present.h"
+
+#include "sec.h"
+#include "sec_accel.h"
+#include "sec_display.h"
+#include "sec_crtc.h"
+
+
+/*-------------------------- Private structures -----------------------------*/
+typedef struct _presentVblankEvent {
+
+       uint64_t event_id;
+
+       RRCrtcPtr pRRcrtc;      //jast for info
+
+} PresentVblankEventRec, *PresentVblankEventPtr;
+
+/*-------------------------- Private functions -----------------------------*/
+
+
+/*-------------------------- Public functions -----------------------------*/
+/*
+ * Called when the queued vblank event has occurred
+ */
+void
+secPresentVblankHandler(unsigned int frame, unsigned int tv_sec,
+                                       unsigned int tv_usec, void *event_data)
+{
+       uint64_t usec = (uint64_t) tv_sec * 1000000 + tv_usec;
+
+       PresentVblankEventRec *pEvent = event_data;
+
+       XDBG_DEBUG(MDRI3, "event_id %lld\n", pEvent->event_id);
+       present_event_notify(pEvent->event_id, usec, frame);
+    free(pEvent);
+}
+
+/*
+ * Called when the queued vblank is aborted
+ */
+void
+secPresentVblankAbort(ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void *data)
+{
+       PresentVblankEventRec *pEvent = data;
+    free(pEvent);
+}
+
+/*
+ * Once the flip has been completed on all pipes, notify the
+ * extension code telling it when that happened
+ */
+
+void
+secPresentFlipEventHandler(unsigned int frame, unsigned int tv_sec,
+                         unsigned int tv_usec, void *event_data, Bool flip_failed)
+{
+
+       PresentVblankEventRec *pEvent = event_data;
+       uint64_t ust = (uint64_t) tv_sec * 1000000 + tv_usec;
+       uint64_t msc = (uint64_t)frame;
+       XDBG_DEBUG(MDRI3, "event_id %lld\n", pEvent->event_id);
+       present_event_notify(pEvent->event_id, ust, msc);
+       free(pEvent);
+}
+
+/*
+ * The flip has been aborted, free the structure
+ */
+void
+secPresentFlipAbort(void *pageflip_data)
+{
+       PresentVblankEventRec *pEvent = pageflip_data;
+       free(pEvent);
+}
+
+/*-------------------------- Callback functions -----------------------------*/
+static RRCrtcPtr
+SECPresentGetCrtc(WindowPtr pWindow)
+{
+       XDBG_RETURN_VAL_IF_FAIL (pWindow != NULL, NULL);
+
+       ScreenPtr pScreen = pWindow->drawable.pScreen;
+       ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+       BoxRec box, crtcbox;
+       xf86CrtcPtr pCrtc = NULL;
+       RRCrtcPtr pRandrCrtc = NULL;
+
+       box.x1 = pWindow->drawable.x;
+       box.y1 = pWindow->drawable.y;
+       box.x2 = box.x1 + pWindow->drawable.width;
+       box.y2 = box.y1 + pWindow->drawable.height;
+
+       pCrtc = secModeCoveringCrtc( pScrn, &box, NULL, &crtcbox );
+
+       /* Make sure the CRTC is valid and this is the real front buffer */
+       if (pCrtc != NULL && !pCrtc->rotatedData ) //TODO what is pCrtc->rotatedData pointing on?
+                       pRandrCrtc = pCrtc->randr_crtc;
+
+       XDBG_DEBUG(MDRI3, "%s\n", pRandrCrtc ?  "OK" : "ERROR");
+
+       return pRandrCrtc;
+}
+
+/*
+ * The kernel sometimes reports bogus MSC values, especially when
+ * suspending and resuming the machine. Deal with this by tracking an
+ * offset to ensure that the MSC seen by applications increases
+ * monotonically, and at a reasonable pace.
+ */
+static int
+SECPresentGetUstMsc(RRCrtcPtr pRRcrtc, CARD64 *ust, CARD64 *msc)
+{
+       XDBG_RETURN_VAL_IF_FAIL (pRRcrtc != NULL, 0);
+
+       xf86CrtcPtr pCrtc = pRRcrtc->devPrivate;
+       ScreenPtr pScreen = pRRcrtc->pScreen;
+       ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+
+       SECCrtcPrivPtr pCrtcPriv = pCrtc->driver_private;
+
+       //Get the current msc/ust value from the kernel
+       Bool ret = secDisplayGetCurMSC(pScrn, pCrtcPriv->pipe, ust, msc);
+
+       XDBG_DEBUG(MDRI3, "%s: pipe:%d ust:%lld msc:%lld()\n",
+                       (ret?"OK":"ERROR"), pCrtcPriv->pipe, *ust, *msc);
+       return (int)ret;
+}
+
+static int
+SECPresentQueueVblank(RRCrtcPtr                pRRcrtc,
+                                                uint64_t               event_id,
+                                                uint64_t               msc)
+{
+                                                xf86CrtcPtr    pCrtc                   = pRRcrtc->devPrivate;
+                                                ScreenPtr              pScreen                 = pRRcrtc->pScreen;
+                                                ScrnInfoPtr    pScrn                   = xf86ScreenToScrn(pScreen);
+                                                int                    pipe                    = secModeGetCrtcPipe(pCrtc);
+                                                PresentVblankEventPtr pEvent   = NULL;
+
+       pEvent = calloc(sizeof(PresentVblankEventRec), 1);
+       if (!pEvent) {
+               XDBG_ERROR(MDRI3, "fail to Vblank: event_id %lld msc %llu \n", event_id, msc);
+               return BadAlloc;
+       }
+       pEvent->event_id = event_id;
+       pEvent->pRRcrtc = pRRcrtc;
+
+
+       /* flip is 1 to avoid to set DRM_VBLANK_NEXTONMISS */
+       if (!secDisplayVBlank(pScrn, pipe, &msc, 1, VBLANK_INFO_PRESENT,  pEvent)) {
+               XDBG_WARNING(MDRI3, "fail to Vblank: event_id %lld msc %llu \n", event_id, msc);
+               secPresentVblankAbort(pScrn, pCrtc, pEvent);
+               return BadAlloc;
+       }
+
+       XDBG_DEBUG(MDRI3, "OK to Vblank event_id:%lld msc:%llu \n", event_id, msc);
+       return Success;
+}
+
+static void
+SECPresentAbortVblank(RRCrtcPtr pRRcrtc, uint64_t event_id, uint64_t msc)
+{
+       XDBG_INFO(MDRI3, "isn't implamentation\n");
+
+}
+
+static void
+SECPresentFlush(WindowPtr window)
+{
+       XDBG_INFO(MDRI3, "isn't implamentation\n");
+}
+
+static Bool
+SECPresentCheckFlip(RRCrtcPtr  pRRcrtc,
+                                       WindowPtr       pWin,
+                                       PixmapPtr       pPixmap,
+                                       Bool            sync_flip)
+{
+       ScrnInfoPtr pScrn = xf86ScreenToScrn(pRRcrtc->pScreen);
+       SECPixmapPriv *pExaPixPriv = exaGetPixmapDriverPrivate (pPixmap);
+
+       if (pExaPixPriv->isFrameBuffer == FALSE)
+    {
+       XDBG_RETURN_VAL_IF_FAIL (secSwapToRenderBo(pScrn, pWin->drawable.width, pWin->drawable.height, pExaPixPriv->bo), FALSE);
+
+       pExaPixPriv->owner = pWin->drawable.id;
+        pExaPixPriv->isFrameBuffer = TRUE;
+        pExaPixPriv->sbc = 0;
+        pExaPixPriv->size = pPixmap->drawable.height * pPixmap->devKind;
+    }
+       return TRUE;
+}
+
+static Bool
+SECPresentFlip(RRCrtcPtr               pRRcrtc,
+                   uint64_t            event_id,
+                   uint64_t            target_msc,
+                   PixmapPtr   pPixmap,
+                   Bool                        sync_flip)
+{
+
+       xf86CrtcPtr pCrtc = pRRcrtc->devPrivate;
+       ScreenPtr pScreen = pRRcrtc->pScreen;
+       ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+       int pipe = secModeGetCrtcPipe(pCrtc);
+       PresentVblankEventPtr pEvent = NULL;
+
+       Bool ret;
+
+       pEvent = calloc(sizeof(PresentVblankEventRec), 1);
+       if (!pEvent) {
+               XDBG_ERROR(MDRI3, "fail to flip\n");
+               return BadAlloc;
+       }
+       pEvent->event_id = event_id;
+       pEvent->pRRcrtc = pRRcrtc;
+
+    SECPixmapPriv *pExaPixPriv = exaGetPixmapDriverPrivate (pPixmap);
+
+       /*FIXME - get client id by draw id*/
+       unsigned int client_idx = 0;
+       XID drawable_id = pExaPixPriv->owner;
+
+       ret = secModePageFlip (pScrn, NULL, pEvent, pipe, pExaPixPriv->bo, 
+                                                  NULL, client_idx, drawable_id,
+                                                  secPresentFlipEventHandler);
+       if (!ret) {
+               secPresentFlipAbort(pEvent);
+               XDBG_WARNING(MDRI3, "fail to flip\n");
+       }
+       else 
+       {
+               XDBG_DEBUG(MDRI3, "flip OK\n");
+       }
+       
+       return ret;
+}
+
+static void
+SECPresentUnflip(ScreenPtr pScreen, uint64_t event_id)
+{
+       XDBG_INFO(MDRI3, "isn't implamentation\n");
+}
+
+
+/* The main structure which contains callback functions */
+static present_screen_info_rec secPresentScreenInfo = {
+
+               .version = PRESENT_SCREEN_INFO_VERSION,
+
+           .get_crtc = SECPresentGetCrtc,
+           .get_ust_msc = SECPresentGetUstMsc,
+           .queue_vblank = SECPresentQueueVblank,
+           .abort_vblank = SECPresentAbortVblank,
+           .flush = SECPresentFlush,
+           .capabilities = PresentCapabilityNone,
+           .check_flip = SECPresentCheckFlip,
+           .flip = SECPresentFlip,
+           .unflip = SECPresentUnflip,
+};
+
+static Bool
+_hasAsyncFlip(ScreenPtr pScreen)
+{
+#ifdef DRM_CAP_ASYNC_PAGE_FLIP
+       ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);;
+       SECPtr          pExynos = SECPTR (pScrn);
+       int         ret = 0;
+       uint64_t    value = 0;
+
+       ret = drmGetCap(pExynos->drm_fd, DRM_CAP_ASYNC_PAGE_FLIP, &value);
+       if (ret == 0)
+               return value == 1;
+#endif
+       return FALSE;
+}
+
+Bool
+secPresentScreenInit( ScreenPtr pScreen )
+{
+
+       if (_hasAsyncFlip(pScreen))
+               secPresentScreenInfo.capabilities |= PresentCapabilityAsync;
+
+       int ret = present_screen_init( pScreen, &secPresentScreenInfo );
+       if(!ret)
+               return FALSE;
+
+       return TRUE;
+}
+
+
index b72f0b8..545ddc7 100644 (file)
@@ -308,6 +308,12 @@ SECModeVblankHandler(int fd, unsigned int frame, unsigned int tv_sec,
     }
     else if (vblank_type == VBLANK_INFO_PLANE)
         secLayerVBlankEventHandler (frame, tv_sec, tv_usec, data);
+    else if (vblank_type == VBLANK_INFO_PRESENT)
+    {
+        XDBG_TRACE (MDISP, "vblank handler (%p, %ld, %ld)\n",
+                    pVblankInfo, pVblankInfo->time, GetTimeInMillis () - pVblankInfo->time);
+       secPresentVblankHandler(frame, tv_sec, tv_usec, data);
+    }
     else
         XDBG_ERROR (MDISP, "unknown the vblank type\n");
 
@@ -416,8 +422,9 @@ SECModePageFlipHandler(int fd, unsigned int frame, unsigned int tv_sec,
         secCrtcCountFps(pCrtc);
 
         /* Deliver cached msc, ust from reference crtc to flip event handler */
-        secDri2FlipEventHandler (pCrtcPriv->fe_frame, pCrtcPriv->fe_tv_sec,
-                                 pCrtcPriv->fe_tv_usec, pCrtcPriv->flip_info, flip->flip_failed);
+        if (flip->handler)
+               flip->handler(pCrtcPriv->fe_frame, pCrtcPriv->fe_tv_sec,
+                         pCrtcPriv->fe_tv_usec, pCrtcPriv->flip_info, flip->flip_failed);
     }
 
     free (flip);
@@ -705,7 +712,9 @@ int secModeGetCrtcPipe (xf86CrtcPtr pCrtc)
 }
 
 Bool
-secModePageFlip (ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void* flip_info, int pipe, tbm_bo back_bo)
+secModePageFlip (ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void* flip_info, int pipe, tbm_bo back_bo,
+                                RegionPtr pFlipRegion, unsigned int client_idx, XID drawable_id,
+                                SECFlipEventHandler handler)
 {
     SECPageFlipPtr pPageFlip = NULL;
     SECFbBoDataPtr bo_data;
@@ -716,7 +725,6 @@ secModePageFlip (ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void* flip_info, int pipe
     SECPtr pSec = SECPTR(pScrn);
     int ret;
     int fb_id = 0;
-    DRI2FrameEventPtr pEvent = (DRI2FrameEventPtr) flip_info;
 
     BoxRec b1;
     int retBox, found=0;
@@ -757,6 +765,7 @@ secModePageFlip (ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void* flip_info, int pipe
             pPageFlip->back_bo = secRenderBoRef (back_bo);
             pPageFlip->data = flip_info;
             pPageFlip->flip_failed = FALSE;
+            pPageFlip->handler = handler;
 
             /* accessilitity */
             if (pCrtcPriv->bAccessibility || pCrtcPriv->screen_rotate_degree > 0)
@@ -789,7 +798,7 @@ secModePageFlip (ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void* flip_info, int pipe
                 secCrtcTurn (pCrtcPriv->pCrtc, TRUE, FALSE, FALSE);
 
 #if DBG_DRM_EVENT
-            pPageFlip->xdbg_log_pageflip = xDbgLogDrmEventAddPageflip (pipe, pEvent->client_idx, pEvent->drawable_id);
+            pPageFlip->xdbg_log_pageflip = xDbgLogDrmEventAddPageflip (pipe, client_idx, drawable_id);
 #endif
 
             XDBG_DEBUG (MSEC, "dump_mode(%x)\n", pSec->dump_mode);
@@ -802,12 +811,12 @@ secModePageFlip (ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void* flip_info, int pipe
             pPageFlip->time = GetTimeInMillis ();
 
             /*Set DirtyFB*/
-            if(pSec->use_partial_update && pEvent->pRegion)
+            if(pSec->use_partial_update && pFlipRegion)
             {
                 int nBox;
                 BoxPtr pBox;
                 RegionRec new_region;
-                RegionPtr pRegion = pEvent->pRegion;
+                RegionPtr pRegion = pFlipRegion;
 
                 for (nBox = RegionNumRects(pRegion),
                      pBox = RegionRects(pRegion); nBox--; pBox++)
@@ -818,7 +827,7 @@ secModePageFlip (ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void* flip_info, int pipe
 
                 if (pCrtcPriv->screen_rotate_degree > 0)
                 {
-                    RegionCopy (&new_region, pEvent->pRegion);
+                    RegionCopy (&new_region, pFlipRegion);
                     secUtilRotateRegion (pCrtc->mode.HDisplay, pCrtc->mode.VDisplay,
                                          &new_region, pCrtcPriv->screen_rotate_degree);
                     pRegion = &new_region;
@@ -1667,6 +1676,7 @@ Bool secDisplayUpdateRequest(ScrnInfoPtr pScrn)
             pPageFlip->flip_failed = FALSE;
             pPageFlip->xdbg_log_pageflip = NULL;
             pPageFlip->time = GetTimeInMillis ();
+            pPageFlip->handler = secDri2FlipEventHandler;
 
             /* accessilitity */
             if (pCrtcPriv->bAccessibility || pCrtcPriv->screen_rotate_degree > 0)
index 810c92e..ff4207d 100644 (file)
@@ -60,6 +60,7 @@ typedef enum
     VBLNAK_INFO_NONE,
     VBLANK_INFO_SWAP,
     VBLANK_INFO_PLANE,
+    VBLANK_INFO_PRESENT,
     VBLANK_INFO_MAX
 } SECVBlankInfoType;
 
@@ -118,6 +119,9 @@ typedef struct _secDrmMode
     int unset_connector_type;
 } SECModeRec, *SECModePtr;
 
+typedef void (*SECFlipEventHandler) (unsigned int frame, unsigned int tv_exynos,
+                                unsigned int tv_uexynos, void *event_data, Bool flip_failed);
+
 typedef struct _secPageFlip
 {
     xf86CrtcPtr pCrtc;
@@ -131,6 +135,8 @@ typedef struct _secPageFlip
     void *data;
     CARD32 time;
 
+    SECFlipEventHandler handler;
+
 #if DBG_DRM_EVENT
     void *xdbg_log_pageflip;
 #endif
@@ -160,7 +166,7 @@ void        secModeInit (ScrnInfoPtr pScrn);
 void        secModeDeinit (ScrnInfoPtr pScrn);
 xf86CrtcPtr secModeCoveringCrtc (ScrnInfoPtr pScrn, BoxPtr pBox, xf86CrtcPtr pDesiredCrtc, BoxPtr pBoxCrtc);
 int         secModeGetCrtcPipe (xf86CrtcPtr pCrtc);
-Bool        secModePageFlip (ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void* flip_info, int pipe, tbm_bo back_bo);
+Bool        secModePageFlip (ScrnInfoPtr pScrn, xf86CrtcPtr pCrtc, void* flip_info, int pipe, tbm_bo back_bo, RegionPtr pFlipRegion, unsigned int client_idx, XID drawable_id, SECFlipEventHandler handler);
 void        secModeLoadPalette (ScrnInfoPtr pScrn, int numColors, int* indices, LOCO* colors, VisualPtr pVisual);
 
 void        secDisplaySwapModeFromKmode(ScrnInfoPtr pScrn, drmModeModeInfoPtr kmode, DisplayModePtr    pMode);
index ce12104..ae933ec 100644 (file)
--- a/src/sec.c
+++ b/src/sec.c
@@ -111,6 +111,8 @@ typedef enum
     OPTION_CACHABLE,
     OPTION_SCANOUT,
     OPTION_ACCEL2D,
+    OPTION_PRESENT,
+    OPTION_DRI3,
     OPTION_PARTIAL_UPDATE,
 } SECOpts;
 
@@ -128,6 +130,8 @@ static const OptionInfoRec SECOptions[] =
     { OPTION_CACHABLE, "cachable",   OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_SCANOUT,  "scanout",    OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_ACCEL2D,  "accel_2d",   OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_PRESENT,  "present",    OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_DRI3,        "dri3",       OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_PARTIAL_UPDATE,  "partial_update",    OPTV_BOOLEAN, {0}, FALSE },
     { -1,              NULL,         OPTV_NONE,    {0}, FALSE }
 };
@@ -504,6 +508,18 @@ _checkDriverOptions (ScrnInfoPtr pScrn)
         }
     }
 
+    /* present */
+    if (xf86ReturnOptValBool (pSec->Options, OPTION_PRESENT, FALSE))
+    {
+        pSec->is_present = TRUE;
+    }
+    
+    /* dri3 */
+    if (xf86ReturnOptValBool (pSec->Options, OPTION_DRI3, FALSE))
+    {
+        pSec->is_dri3 = TRUE;
+    }
+
     /* rotate */
     pSec->rotate = RR_Rotate_0;
     if (( s= xf86GetOptValString (pSec->Options, OPTION_ROTATE)))
@@ -1025,6 +1041,25 @@ SECScreenInit (ScreenPtr pScreen, int argc, char **argv)
                                 "DRI2 initialization failed\n");
                 }
             }
+            
+            if (pSec->is_present)
+            {
+               if(!secPresentScreenInit(pScreen))
+               {
+                    xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
+                                "Present initialization failed\n");
+                }
+            }
+
+            /* init the dri3 */
+            if (pSec->is_dri3)
+            {
+                if (!secDri3ScreenInit (pScreen))
+                {
+                    xf86DrvMsg (pScrn->scrnIndex, X_WARNING,
+                                "DRI3 initialization failed\n");
+                }
+            }
         }
     }
 
@@ -1244,9 +1279,8 @@ _secFbFreeBoData(void* data)
     bo_data = NULL;
 }
 
-
 static tbm_bo
-_secFbCreateBo (SECFbPtr pFb, int x, int y, int width, int height)
+_secFbCreateBo2 (SECFbPtr pFb, int x, int y, int width, int height, tbm_bo prev_bo)
 {
     XDBG_RETURN_VAL_IF_FAIL ((pFb != NULL), NULL);
     XDBG_RETURN_VAL_IF_FAIL ((width > 0), NULL);
@@ -1271,6 +1305,18 @@ _secFbCreateBo (SECFbPtr pFb, int x, int y, int width, int height)
 
     bo = tbm_bo_alloc (pSec->tbm_bufmgr, pitch*height, flag);
     XDBG_GOTO_IF_FAIL (bo != NULL, fail);
+    
+    if (prev_bo != NULL)
+    {
+       tbm_bo_swap(bo, prev_bo);
+       
+       //delete prev bo(naw _bo contains an old GEM object)
+       tbm_bo_unref(bo);
+       //delete TBM_BO_DATA_FB if present, because the new will be created in here
+       tbm_bo_delete_user_data(prev_bo, TBM_BO_DATA_FB);
+       
+       bo = prev_bo;
+    }
 
     /* memset 0x0 */
     bo_handle1 = tbm_bo_map (bo, TBM_DEVICE_CPU, TBM_OPTION_WRITE);
@@ -1336,6 +1382,12 @@ fail:
 }
 
 static tbm_bo
+_secFbCreateBo (SECFbPtr pFb, int x, int y, int width, int height)
+{
+       return _secFbCreateBo2 (pFb, x, y, width, height, NULL);
+}
+
+static tbm_bo
 _secFbRefBo (tbm_bo bo)
 {
     return tbm_bo_ref(bo);
@@ -1757,6 +1809,14 @@ secRenderBoCreate (ScrnInfoPtr pScrn, int width, int height)
     return _secFbCreateBo(pSec->pFb, -1, -1, width, height);
 }
 
+int
+secSwapToRenderBo(ScrnInfoPtr pScrn, int width, int height, tbm_bo carr_bo)
+{
+    SECPtr pSec = SECPTR (pScrn);
+
+    return _secFbCreateBo2(pSec->pFb, -1, -1, width, height, carr_bo);
+}
+
 tbm_bo
 secRenderBoRef (tbm_bo bo)
 {
index 5e5a642..296e099 100644 (file)
--- a/src/sec.h
+++ b/src/sec.h
@@ -98,6 +98,8 @@ typedef struct
     OptionInfoPtr Options;
     Bool is_exa;
     Bool is_dri2;
+    Bool is_present;
+    Bool is_dri3;
     Bool is_sw_exa;
     Bool is_accel_2d;
     Bool is_wb_clone;
@@ -224,6 +226,7 @@ tbm_bo    secFbFindBoByPoint (SECFbPtr pFb, int x, int y);
 tbm_bo    secFbSwapBo        (SECFbPtr pFb, tbm_bo back_bo);
 
 tbm_bo    secRenderBoCreate    (ScrnInfoPtr pScrn, int width, int height);
+int      secSwapToRenderBo        (ScrnInfoPtr pScrn, int width, int height, tbm_bo carr_bo);
 tbm_bo    secRenderBoRef       (tbm_bo bo);
 void          secRenderBoUnref     (tbm_bo bo);
 void          secRenderBoSetPos    (tbm_bo bo, int x, int y);
index a0a0907..f654d41 100644 (file)
@@ -52,6 +52,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #define MEXAS   XDBG_M('E','X','A','S')
 #define MEVT    XDBG_M('E','V','T',0)
 #define MDRI2   XDBG_M('D','R','I','2')
+#define MDRI3   XDBG_M('D','R','I','3')
 #define MCRS    XDBG_M('C','R','S',0)
 #define MFLIP   XDBG_M('F','L','I','P')
 #define MDPMS   XDBG_M('D','P','M','S')