src/plugins/gfxdrivers/powervr/QWSWSEGL/pvrqwswsegl.c
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the plugins of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include <GLES/egltypes.h>
       
    43 #include <wsegl.h>
       
    44 #include <pvr2d.h>
       
    45 #include <string.h>
       
    46 #include <sys/mman.h>
       
    47 #include "pvrqwsdrawable_p.h"
       
    48 
       
    49 #define WSEGL_UNUSED(x) (void)x;
       
    50 
       
    51 // If the PVR2D version is not specified, then assume MBX-style headers.
       
    52 // If the version is defined, then we assume that we have SGX-style headers.
       
    53 #if !defined(PVR2D_REV_MAJOR)
       
    54 #define WSEGL_CAP_WINDOWS_USE_HW_SYNC WSEGL_CAP_WINDOWS_USE_MBX_SYNC
       
    55 #define WSEGL_CAP_PIXMAPS_USE_HW_SYNC WSEGL_CAP_PIXMAPS_USE_MBX_SYNC
       
    56 #endif
       
    57 
       
    58 /* Capability information for the display */
       
    59 static WSEGLCaps const wseglDisplayCaps[] = {
       
    60     {WSEGL_CAP_WINDOWS_USE_HW_SYNC, 1},
       
    61     {WSEGL_CAP_PIXMAPS_USE_HW_SYNC, 1},
       
    62     {WSEGL_NO_CAPS, 0}
       
    63 };
       
    64 
       
    65 /* Configuration information for the display */
       
    66 static WSEGLConfig wseglDisplayConfigs[] = {
       
    67     {WSEGL_DRAWABLE_WINDOW, WSEGL_PIXELFORMAT_565, WSEGL_FALSE,
       
    68      0, 0, 0, WSEGL_OPAQUE, 0},
       
    69     {WSEGL_DRAWABLE_PIXMAP, WSEGL_PIXELFORMAT_565, WSEGL_FALSE,
       
    70      0, 0, 0, WSEGL_OPAQUE, 0},
       
    71     {WSEGL_NO_DRAWABLE, 0, 0, 0, 0, 0, 0, 0}
       
    72 };
       
    73 
       
    74 /* Determine if nativeDisplay is a valid display handle */
       
    75 static WSEGLError wseglIsDisplayValid(NativeDisplayType nativeDisplay)
       
    76 {
       
    77     /* We only have the default display in this system */
       
    78     if (nativeDisplay == WSEGL_DEFAULT_DISPLAY)
       
    79         return WSEGL_SUCCESS;
       
    80     else
       
    81         return WSEGL_BAD_NATIVE_DISPLAY;
       
    82 }
       
    83 
       
    84 /* Initialize a native display for use with WSEGL */
       
    85 static WSEGLError wseglInitializeDisplay
       
    86     (NativeDisplayType nativeDisplay, WSEGLDisplayHandle *display,
       
    87      const WSEGLCaps **caps, WSEGLConfig **configs)
       
    88 {
       
    89     WSEGLPixelFormat pixelFormat;
       
    90 
       
    91     /* Bail out if the native display is incorrect */
       
    92     if (nativeDisplay != WSEGL_DEFAULT_DISPLAY)
       
    93         return WSEGL_CANNOT_INITIALISE;
       
    94 
       
    95     /* Open the PVR/QWS display, which will initialize the framebuffer */
       
    96     if (!pvrQwsDisplayOpen())
       
    97         return WSEGL_CANNOT_INITIALISE;
       
    98 
       
    99     /* Convert the PVR2D pixel format into a WSEGL pixel format */
       
   100     switch (pvrQwsDisplay.screens[0].pixelFormat) {
       
   101         case PVR2D_RGB565:
       
   102             pixelFormat = WSEGL_PIXELFORMAT_565;
       
   103             break;
       
   104 
       
   105 	case PVR2D_ARGB4444:
       
   106             pixelFormat = WSEGL_PIXELFORMAT_4444;
       
   107             break;
       
   108 
       
   109 	case PVR2D_ARGB8888:
       
   110             pixelFormat = WSEGL_PIXELFORMAT_8888;
       
   111             break;
       
   112 
       
   113         default:
       
   114             pvrQwsDisplayClose();
       
   115             return WSEGL_CANNOT_INITIALISE;
       
   116     }
       
   117     wseglDisplayConfigs[0].ePixelFormat = pixelFormat;
       
   118     wseglDisplayConfigs[1].ePixelFormat = pixelFormat;
       
   119 
       
   120     /* The display has been initialized */
       
   121     *display = (WSEGLDisplayHandle)&pvrQwsDisplay;
       
   122     *caps = wseglDisplayCaps;
       
   123     *configs = wseglDisplayConfigs;
       
   124     return WSEGL_SUCCESS;
       
   125 }
       
   126 
       
   127 /* Close the WSEGL display */
       
   128 static WSEGLError wseglCloseDisplay(WSEGLDisplayHandle display)
       
   129 {
       
   130     if (display == (WSEGLDisplayHandle)&pvrQwsDisplay)
       
   131         pvrQwsDisplayClose();
       
   132     return WSEGL_SUCCESS;
       
   133 }
       
   134 
       
   135 static WSEGLRotationAngle wseglRotationValue(int degrees)
       
   136 {
       
   137     switch (degrees) {
       
   138     case 90:  return WSEGL_ROTATE_90;
       
   139     case 180: return WSEGL_ROTATE_180;
       
   140     case 270: return WSEGL_ROTATE_270;
       
   141     default:  return WSEGL_ROTATE_0;
       
   142     }
       
   143 }
       
   144 
       
   145 /* Create the WSEGL drawable version of a native window */
       
   146 static WSEGLError wseglCreateWindowDrawable
       
   147     (WSEGLDisplayHandle display, WSEGLConfig *config,
       
   148      WSEGLDrawableHandle *drawable, NativeWindowType nativeWindow,
       
   149      WSEGLRotationAngle *rotationAngle)
       
   150 {
       
   151     PvrQwsDrawable *draw;
       
   152 
       
   153     WSEGL_UNUSED(display);
       
   154     WSEGL_UNUSED(config);
       
   155 
       
   156     /* Check for special handles that indicate framebuffer screens */
       
   157     if (nativeWindow >= (NativeWindowType)0 &&
       
   158             nativeWindow < (NativeWindowType)PVRQWS_MAX_SCREENS) {
       
   159         PvrQwsDrawable *screen = pvrQwsScreenWindow((int)nativeWindow);
       
   160         if (!screen)
       
   161             return WSEGL_OUT_OF_MEMORY;
       
   162         *drawable = (WSEGLDrawableHandle)screen;
       
   163         if (!pvrQwsAllocBuffers(screen))
       
   164             return WSEGL_OUT_OF_MEMORY;
       
   165         *rotationAngle = wseglRotationValue(screen->rotationAngle);
       
   166         return WSEGL_SUCCESS;
       
   167     }
       
   168 
       
   169     /* The native window is the winId - fetch the underlying drawable */
       
   170     draw = pvrQwsFetchWindow((long)nativeWindow);
       
   171     if (!draw)
       
   172         return WSEGL_BAD_DRAWABLE;
       
   173 
       
   174     /* The drawable is ready to go */
       
   175     *drawable = (WSEGLDrawableHandle)draw;
       
   176     *rotationAngle = wseglRotationValue(draw->rotationAngle);
       
   177     if (!pvrQwsAllocBuffers(draw))
       
   178         return WSEGL_OUT_OF_MEMORY;
       
   179     return WSEGL_SUCCESS;
       
   180 }
       
   181 
       
   182 /* Create the WSEGL drawable version of a native pixmap */
       
   183 static WSEGLError wseglCreatePixmapDrawable
       
   184     (WSEGLDisplayHandle display, WSEGLConfig *config,
       
   185      WSEGLDrawableHandle *drawable, NativePixmapType nativePixmap,
       
   186      WSEGLRotationAngle *rotationAngle)
       
   187 {
       
   188     WSEGL_UNUSED(display);
       
   189     WSEGL_UNUSED(config);
       
   190     if (!nativePixmap)
       
   191         return WSEGL_BAD_NATIVE_PIXMAP;
       
   192     if (!pvrQwsAllocBuffers((PvrQwsDrawable *)nativePixmap))
       
   193         return WSEGL_OUT_OF_MEMORY;
       
   194     *drawable = (WSEGLDrawableHandle)nativePixmap;
       
   195     *rotationAngle = WSEGL_ROTATE_0;
       
   196     return WSEGL_SUCCESS;
       
   197 }
       
   198 
       
   199 /* Delete a specific drawable */
       
   200 static WSEGLError wseglDeleteDrawable(WSEGLDrawableHandle _drawable)
       
   201 {
       
   202     PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
       
   203     if (!drawable || drawable->type == PvrQwsScreen)
       
   204         return WSEGL_SUCCESS;
       
   205     pvrQwsFreeBuffers(drawable);
       
   206     if (pvrQwsReleaseWindow(drawable))
       
   207         pvrQwsDestroyDrawable(drawable);
       
   208     return WSEGL_SUCCESS;
       
   209 }
       
   210 
       
   211 /* Swap the contents of a drawable to the screen */
       
   212 static WSEGLError wseglSwapDrawable
       
   213     (WSEGLDrawableHandle _drawable, unsigned long data)
       
   214 {
       
   215     WSEGL_UNUSED(data);
       
   216     PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
       
   217     if (drawable->type != PvrQwsPixmap && !pvrQwsSwapBuffers(drawable, 0))
       
   218         return WSEGL_BAD_DRAWABLE;
       
   219     else
       
   220         return WSEGL_SUCCESS;
       
   221 }
       
   222 
       
   223 /* Set the swap interval of a window drawable */
       
   224 static WSEGLError wseglSwapControlInterval
       
   225     (WSEGLDrawableHandle drawable, unsigned long interval)
       
   226 {
       
   227     WSEGL_UNUSED(drawable);
       
   228     if (pvrQwsDisplay.flipChain) {
       
   229         PVR2DSetPresentFlipProperties
       
   230             (pvrQwsDisplay.context, pvrQwsDisplay.flipChain,
       
   231              PVR2D_PRESENT_PROPERTY_INTERVAL, 0, 0, 0, NULL, interval);
       
   232     }
       
   233     return WSEGL_SUCCESS;
       
   234 }
       
   235 
       
   236 /* Flush native rendering requests on a drawable */
       
   237 static WSEGLError wseglWaitNative
       
   238     (WSEGLDrawableHandle drawable, unsigned long engine)
       
   239 {
       
   240     WSEGL_UNUSED(drawable);
       
   241     if (engine == WSEGL_DEFAULT_NATIVE_ENGINE)
       
   242         return WSEGL_SUCCESS;
       
   243     else
       
   244         return WSEGL_BAD_NATIVE_ENGINE;
       
   245 }
       
   246 
       
   247 /* Copy color data from a drawable to a native pixmap */
       
   248 static WSEGLError wseglCopyFromDrawable
       
   249     (WSEGLDrawableHandle _drawable, NativePixmapType nativePixmap)
       
   250 {
       
   251     PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
       
   252     PvrQwsDrawable *pixmap = (PvrQwsDrawable *)nativePixmap;
       
   253     PVR2DBLTINFO blit;
       
   254 
       
   255     if (!drawable || !drawable->backBuffersValid)
       
   256         return WSEGL_BAD_NATIVE_WINDOW;
       
   257     if (!pixmap || !pixmap->backBuffersValid)
       
   258         return WSEGL_BAD_NATIVE_PIXMAP;
       
   259 
       
   260     memset(&blit, 0, sizeof(blit));
       
   261 
       
   262     blit.CopyCode = PVR2DROPcopy;
       
   263     blit.BlitFlags = PVR2D_BLIT_DISABLE_ALL;
       
   264 
       
   265     blit.pSrcMemInfo = drawable->backBuffers[drawable->currentBackBuffer];
       
   266     blit.SrcStride = drawable->strideBytes;
       
   267     blit.SrcX = 0;
       
   268     blit.SrcY = 0;
       
   269     blit.SizeX = drawable->rect.width;
       
   270     blit.SizeY = drawable->rect.height;
       
   271     blit.SrcFormat = drawable->pixelFormat;
       
   272 
       
   273     blit.pDstMemInfo = pixmap->backBuffers[pixmap->currentBackBuffer];
       
   274     blit.DstStride = pixmap->strideBytes;
       
   275     blit.DstX = 0;
       
   276     blit.DstY = 0;
       
   277     blit.DSizeX = pixmap->rect.width;
       
   278     blit.DSizeY = pixmap->rect.height;
       
   279     blit.DstFormat = pixmap->pixelFormat;
       
   280 
       
   281     PVR2DBlt(pvrQwsDisplay.context, &blit);
       
   282     PVR2DQueryBlitsComplete
       
   283         (pvrQwsDisplay.context, pixmap->backBuffers[pixmap->currentBackBuffer], 1);
       
   284 
       
   285     return WSEGL_SUCCESS;
       
   286 }
       
   287 
       
   288 /* Copy color data from a PBuffer to a native pixmap */
       
   289 static WSEGLError wseglCopyFromPBuffer
       
   290     (void *address, unsigned long width, unsigned long height,
       
   291      unsigned long stride, WSEGLPixelFormat format,
       
   292      NativePixmapType nativePixmap)
       
   293 {
       
   294     PvrQwsDrawable *pixmap = (PvrQwsDrawable *)nativePixmap;
       
   295     PVR2DFORMAT pixelFormat;
       
   296 
       
   297     if (!pixmap)
       
   298         return WSEGL_BAD_NATIVE_PIXMAP;
       
   299 
       
   300     /* We can only copy under certain conditions */
       
   301     switch (format) {
       
   302 	case WSEGL_PIXELFORMAT_565:
       
   303             pixelFormat = PVR2D_RGB565; break;
       
   304 	case WSEGL_PIXELFORMAT_4444:
       
   305             pixelFormat = PVR2D_ARGB4444; break;
       
   306 	case WSEGL_PIXELFORMAT_8888:
       
   307             pixelFormat = PVR2D_ARGB8888; break;
       
   308         default:
       
   309             return WSEGL_BAD_CONFIG;
       
   310     }
       
   311     if (width > (unsigned long)(pixmap->rect.width) ||
       
   312         height > (unsigned long)(pixmap->rect.height) ||
       
   313         pixelFormat != pixmap->pixelFormat) {
       
   314         return WSEGL_BAD_CONFIG;
       
   315     }
       
   316 
       
   317     /* We'd like to use PVR2DBlt to do this, but there is no easy way
       
   318        to map the virtual "address" into physical space to be able
       
   319        to use the hardware assist.  Use memcpy to do the work instead.
       
   320        Note: PBuffer's are upside down, so we copy from the bottom up */
       
   321     char *srcaddr = (char *)address;
       
   322     char *dstaddr = (char *)(pixmap->backBuffers[pixmap->currentBackBuffer]->pBase);
       
   323     int dststride = pixmap->strideBytes;
       
   324     int srcwidth = ((int)width) * pvrQwsDisplay.screens[0].bytesPerPixel;
       
   325     srcaddr += height * stride;
       
   326     while (height > 0) {
       
   327         srcaddr -= (int)stride;
       
   328         memcpy(dstaddr, srcaddr, srcwidth);
       
   329         dstaddr += dststride;
       
   330         --height;
       
   331     }
       
   332     return WSEGL_SUCCESS;
       
   333 }
       
   334 
       
   335 /* Return the parameters of a drawable that are needed by the EGL layer */
       
   336 static WSEGLError wseglGetDrawableParameters
       
   337     (WSEGLDrawableHandle _drawable, WSEGLDrawableParams *sourceParams,
       
   338      WSEGLDrawableParams *renderParams)
       
   339 {
       
   340     PvrQwsDrawable *drawable = (PvrQwsDrawable *)_drawable;
       
   341     PVR2DMEMINFO *source, *render;
       
   342     WSEGLPixelFormat pixelFormat;
       
   343 
       
   344     if (!pvrQwsGetBuffers(drawable, &source, &render))
       
   345         return WSEGL_BAD_DRAWABLE;
       
   346 
       
   347     switch (drawable->pixelFormat) {
       
   348         case PVR2D_RGB565:
       
   349         default:
       
   350             pixelFormat = WSEGL_PIXELFORMAT_565;
       
   351             break;
       
   352 
       
   353 	case PVR2D_ARGB4444:
       
   354             pixelFormat = WSEGL_PIXELFORMAT_4444;
       
   355             break;
       
   356 
       
   357 	case PVR2D_ARGB8888:
       
   358             pixelFormat = WSEGL_PIXELFORMAT_8888;
       
   359             break;
       
   360     }
       
   361 
       
   362     sourceParams->ui32Width = drawable->rect.width;
       
   363     sourceParams->ui32Height = drawable->rect.height;
       
   364     sourceParams->ui32Stride = drawable->stridePixels;
       
   365     sourceParams->ePixelFormat = pixelFormat;
       
   366     sourceParams->pvLinearAddress = source->pBase;
       
   367     sourceParams->ui32HWAddress = source->ui32DevAddr;
       
   368     sourceParams->hPrivateData = source->hPrivateData;
       
   369 
       
   370     renderParams->ui32Width = drawable->rect.width;
       
   371     renderParams->ui32Height = drawable->rect.height;
       
   372     renderParams->ui32Stride = drawable->stridePixels;
       
   373     renderParams->ePixelFormat = pixelFormat;
       
   374     renderParams->pvLinearAddress = render->pBase;
       
   375     renderParams->ui32HWAddress = render->ui32DevAddr;
       
   376     renderParams->hPrivateData = render->hPrivateData;
       
   377 
       
   378     return WSEGL_SUCCESS;
       
   379 }
       
   380 
       
   381 static WSEGL_FunctionTable const wseglFunctions = {
       
   382     WSEGL_VERSION,
       
   383     wseglIsDisplayValid,
       
   384     wseglInitializeDisplay,
       
   385     wseglCloseDisplay,
       
   386     wseglCreateWindowDrawable,
       
   387     wseglCreatePixmapDrawable,
       
   388     wseglDeleteDrawable,
       
   389     wseglSwapDrawable,
       
   390     wseglSwapControlInterval,
       
   391     wseglWaitNative,
       
   392     wseglCopyFromDrawable,
       
   393     wseglCopyFromPBuffer,
       
   394     wseglGetDrawableParameters
       
   395 };
       
   396 
       
   397 /* Return the table of WSEGL functions to the EGL implementation */
       
   398 const WSEGL_FunctionTable *WSEGL_GetFunctionTablePointer(void)
       
   399 {
       
   400     return &wseglFunctions;
       
   401 }