do not delay flips, wait for vsync
authorGrazvydas Ignotas <notasas@gmail.com>
Sun, 17 Jun 2012 17:39:57 +0000 (20:39 +0300)
committerGrazvydas Ignotas <notasas@gmail.com>
Sun, 17 Jun 2012 17:39:57 +0000 (20:39 +0300)
services4/3rdparty/dc_omap3_linux/omaplfb.h
services4/3rdparty/dc_omap3_linux/omaplfb_displayclass.c
services4/3rdparty/dc_omap3_linux/omaplfb_linux.c

index a0a8369..f43e6e5 100644 (file)
@@ -223,10 +223,6 @@ void *OMAPLFBAllocKernelMem(unsigned long ulSize);
 void OMAPLFBFreeKernelMem(void *pvMem);
 OMAP_ERROR OMAPLFBGetLibFuncAddr(char *szFunctionName, PFN_DC_GET_PVRJTABLE *ppfnFuncTable);
 void OMAPLFBWaitForVSync(void);
-#if defined (CONFIG_OMAP2_DSS)
-IMG_VOID OMAPLFBFlipDSS2(OMAPLFB_SWAPCHAIN *psSwapChain,
-                                                 IMG_UINT32 aPhyAddr);
-#endif
 void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr);
 OMAPLFB_DEVINFO * GetAnchorPtr(void);
 
index 521de95..db74293 100644 (file)
@@ -51,6 +51,44 @@ static int fb_idx = 0;
 static PFN_DC_GET_PVRJTABLE pfnGetPVRJTable = 0;
 static void OMAPLFBVSyncIHandler(struct work_struct*);
 
+#define OMAPLFB_PAGE_SIZE 4096
+
+/* Greatest common divisor */
+static unsigned long gcd(unsigned long a, unsigned long b)
+{
+       unsigned long r;
+
+       if (a < b) {
+               r = a;
+               a = b;
+               b = r;
+       }
+
+       while ((r = a % b) != 0) {
+               a = b;
+               b = r;
+       }
+
+       return b;
+}
+
+/*
+ * Workout the smallest size that is aligned to both 4K (for the SGX)
+ * and line length (for the fbdev driver).
+ */
+static unsigned int sgx_buffer_align(unsigned stride, unsigned size)
+{
+       unsigned lcm;
+
+       if (!stride || !size)
+               return 0;
+
+       lcm = stride * OMAPLFB_PAGE_SIZE / gcd(stride,
+                                              OMAPLFB_PAGE_SIZE);
+
+       return roundup(size, lcm);
+}
+
 OMAPLFB_DEVINFO * GetAnchorPtr(void)
 {
        return (OMAPLFB_DEVINFO *)gpvAnchor;
@@ -248,6 +286,7 @@ static OMAP_ERROR UnblankDisplay(OMAPLFB_DEVINFO *psDevInfo)
 }
 
 #if defined (CONFIG_OMAP2_DSS)
+#include <linux/omapfb.h>
 #include <linux/workqueue.h>
 struct wq_flip {
         struct fb_var_screeninfo var;
@@ -271,16 +310,32 @@ static void dss2_pan_display (struct work_struct *work)
         Flip implementation for DSS2 using fb_pan_display
 */
 IMG_VOID OMAPLFBFlipDSS2(OMAPLFB_SWAPCHAIN *psSwapChain,
-                                                 IMG_UINT32 aPhyAddr)
+                                                 IMG_UINT32 aPhyAddr, int now)
 {
        OMAPLFB_DEVINFO *psDevInfo = GetAnchorPtr ();
        struct fb_info *psLINFBInfo = psDevInfo->psLINFBInfo;
        memcpy ( &wq_flipdss2.var, &psLINFBInfo->var, sizeof(struct fb_var_screeninfo)); 
     wq_flipdss2.var.yoffset = (aPhyAddr-psLINFBInfo->fix.smem_start)/psLINFBInfo->fix.line_length;
        wq_flipdss2.psLINFBInfo = psLINFBInfo;
-       schedule_work (&wq_flipdss2.work);
+       if (now)
+               dss2_pan_display(&wq_flipdss2.work);
+       else
+               schedule_work (&wq_flipdss2.work);
+}
+#endif
+
+void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
+{
+       OMAPLFBFlipDSS2 (psSwapChain, aPhyAddr, 0);
 }
+
+void OMAPLFBWaitForVSync(void)
+{
+#if 0
+       if (lcd_mgr && lcd_mgr->device) 
+               lcd_mgr->device->wait_vsync(lcd_mgr->device);
 #endif
+}
 
 static OMAP_ERROR EnableLFBEventNotification(OMAPLFB_DEVINFO *psDevInfo)
 {
@@ -665,6 +720,8 @@ static PVRSRV_ERROR CreateDCSwapChain(IMG_HANDLE hDevice,
                goto ErrorDisableDisplayRegisters;
        }
 
+       /* this is often 2 but could be 3, why oh why? */
+       printk(KERN_INFO "CreateDCSwapChain ui32BufferCount: %u\n", (u32)ui32BufferCount);
        
        *phSwapChain = (IMG_HANDLE)psSwapChain;
 
@@ -998,13 +1055,16 @@ static IMG_BOOL ProcessFlip(IMG_HANDLE  hCmdCookie,
 
 #if defined(SYS_USING_INTERRUPTS)
        
-       if(psFlipCmd->ui32SwapInterval == 0 || psSwapChain->bFlushCommands == OMAP_TRUE)
+//     if(psFlipCmd->ui32SwapInterval == 0 || psSwapChain->bFlushCommands == OMAP_TRUE)
        {
 #endif
                
-               OMAPLFBFlip(psSwapChain, (unsigned long)psBuffer->sSysAddr.uiAddr);
+               OMAPLFBFlipDSS2(psSwapChain, psBuffer->sSysAddr.uiAddr, 1);
+
+               if (psSwapChain->ulBufferCount == 2)
+                       psDevInfo->psLINFBInfo->fbops->fb_ioctl(
+                               psDevInfo->psLINFBInfo, OMAPFB_WAITFORGO, 0);
 
-               
                psSwapChain->psPVRJTable->pfnPVRSRVCmdComplete(hCmdCookie, IMG_TRUE);
 
 #if defined(SYS_USING_INTERRUPTS)
@@ -1140,11 +1200,9 @@ static OMAP_ERROR InitDev(OMAPLFB_DEVINFO *psDevInfo)
        psPVRFBInfo->ulFBSize = FBSize;
        psPVRFBInfo->ulBufferSize = psPVRFBInfo->ulHeight * psPVRFBInfo->ulByteStride;
 
-#ifdef CONFIG_OMAP2_DSS        
-    psPVRFBInfo->ulRoundedBufferSize = psPVRFBInfo->ulBufferSize;
-#else
-       psPVRFBInfo->ulRoundedBufferSize = OMAPLFB_PAGE_ROUNDUP(psPVRFBInfo->ulBufferSize);
-#endif
+       psPVRFBInfo->ulRoundedBufferSize =
+               sgx_buffer_align(psPVRFBInfo->ulByteStride,
+                                psPVRFBInfo->ulBufferSize);
 
        if(psLINFBInfo->var.bits_per_pixel == 16)
        {
index 4a80f1c..66cc3e7 100644 (file)
@@ -103,20 +103,6 @@ static void GetLcdManager(void){
 }
 
 
-void OMAPLFBFlip(OMAPLFB_SWAPCHAIN *psSwapChain, unsigned long aPhyAddr)
-{
-       OMAPLFBFlipDSS2 (psSwapChain, aPhyAddr);
-}
-
-void OMAPLFBWaitForVSync(void)
-{
-#if 0
-       if (lcd_mgr && lcd_mgr->device) 
-               lcd_mgr->device->wait_vsync(lcd_mgr->device);
-#endif
-}
-
-
 #if defined(LDM_PLATFORM)
 
 static volatile OMAP_BOOL bDeviceSuspended;