uifw/ganes/src/HgVgEGL.cpp
branchRCL_3
changeset 20 d48ab3b357f1
child 21 978afdc0236f
equal deleted inserted replaced
19:aecbbf00d063 20:d48ab3b357f1
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:    
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "HgVgEGL.h"
       
    21 #include "HgVgConstants.h"
       
    22 #include <coecntrl.h>
       
    23 
       
    24 
       
    25 using namespace HgVgConstants;
       
    26 
       
    27 // ============================ MEMBER FUNCTIONS ===============================
       
    28 // -----------------------------------------------------------------------------
       
    29 // CHgVgEGL::NewL()
       
    30 // Two-phased constructor.
       
    31 // -----------------------------------------------------------------------------
       
    32 //
       
    33 CHgVgEGL* CHgVgEGL::NewL(RWindow& aWindow)
       
    34     {
       
    35     CHgVgEGL* self = new ( ELeave ) CHgVgEGL();
       
    36     CleanupStack::PushL (self );
       
    37     self->ConstructL(aWindow);
       
    38     CleanupStack::Pop (self );
       
    39     return self;
       
    40     }
       
    41 
       
    42 // -----------------------------------------------------------------------------
       
    43 // CHgVgEGL::ConstructL()
       
    44 // Symbian 2nd phase constructor can leave.
       
    45 // -----------------------------------------------------------------------------
       
    46 //
       
    47 void CHgVgEGL::ConstructL (RWindow& aWindow)
       
    48     {
       
    49     InitEGL(aWindow);
       
    50     }
       
    51 
       
    52 // -----------------------------------------------------------------------------
       
    53 // CHgVgEGL::CHgVgEGL()
       
    54 // C++ default constructor can NOT contain any code, that might leave.
       
    55 // -----------------------------------------------------------------------------
       
    56 //
       
    57 CHgVgEGL::CHgVgEGL()
       
    58     {
       
    59     }
       
    60         
       
    61 // -----------------------------------------------------------------------------
       
    62 // CHgVgEGL::~CHgVgEGL()
       
    63 // Destructor.
       
    64 // -----------------------------------------------------------------------------
       
    65 //
       
    66 CHgVgEGL::~CHgVgEGL ( )
       
    67     {
       
    68     DestroyEGL();
       
    69     }
       
    70 
       
    71 // ---------------------------------------------------------------------------
       
    72 // CHgVgEGL::InitWindowSurfaceL()
       
    73 // ---------------------------------------------------------------------------
       
    74 //     
       
    75 void CHgVgEGL::InitWindowSurfaceL(RWindow& aWindow)
       
    76     {
       
    77     //RDebug::Print(_L("CHgVgEGL::InitWindowSurface"));
       
    78 
       
    79     InitEGL(aWindow);
       
    80     }
       
    81 
       
    82 // ---------------------------------------------------------------------------
       
    83 // CHgVgEGL::FreeWindowSurface()
       
    84 // ---------------------------------------------------------------------------
       
    85 //     
       
    86 void CHgVgEGL::FreeWindowSurface()
       
    87     {
       
    88     //RDebug::Print(_L("CHgVgEGL::FreeWindowSurface"));
       
    89 
       
    90     // make sure there is nothing pending.
       
    91     vgFinish();
       
    92     
       
    93     // unbind current surface.
       
    94     eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, iContextVg);
       
    95 
       
    96     // destroy surface
       
    97     eglDestroySurface(iDisplay, iSurface);
       
    98     iSurface = VG_INVALID_HANDLE;
       
    99     }
       
   100 
       
   101 // ---------------------------------------------------------------------------
       
   102 // CHgVgEGL::ReadyToRender()
       
   103 // ---------------------------------------------------------------------------
       
   104 //     
       
   105 TBool CHgVgEGL::ReadyToRender() const
       
   106     {
       
   107     return iSurface && iDisplay && iContextVg;
       
   108     }
       
   109 
       
   110 // ---------------------------------------------------------------------------
       
   111 // CHgVgEGL::SwapBuffers()
       
   112 // ---------------------------------------------------------------------------
       
   113 //     
       
   114 void CHgVgEGL::SwapBuffers()
       
   115     {
       
   116     eglSwapBuffers(iDisplay, iSurface);
       
   117     }
       
   118 
       
   119 // ---------------------------------------------------------------------------
       
   120 // CHgVgEGL::Display()
       
   121 // ---------------------------------------------------------------------------
       
   122 //     
       
   123 EGLDisplay CHgVgEGL::Display() const
       
   124     {
       
   125     return iDisplay;
       
   126     }
       
   127 
       
   128 // ---------------------------------------------------------------------------
       
   129 // CHgVgEGL::Surface
       
   130 // ---------------------------------------------------------------------------
       
   131 //     
       
   132 EGLSurface CHgVgEGL::Surface() const
       
   133     {
       
   134     return iSurface;
       
   135     }
       
   136 
       
   137 // ---------------------------------------------------------------------------
       
   138 // CHgVgEGL::Context()
       
   139 // ---------------------------------------------------------------------------
       
   140 //     
       
   141 EGLContext CHgVgEGL::Context() const
       
   142     {
       
   143     return iContextVg;
       
   144     }
       
   145 
       
   146 // ---------------------------------------------------------------------------
       
   147 // CHgVgEGL::CurrentConfig()
       
   148 // ---------------------------------------------------------------------------
       
   149 //     
       
   150 EGLConfig CHgVgEGL::CurrentConfig() const
       
   151     {
       
   152     return iChosenConfig;
       
   153     }
       
   154 
       
   155 // ---------------------------------------------------------------------------
       
   156 // CHgVgEGL::InitEGL()
       
   157 // ---------------------------------------------------------------------------
       
   158 //     
       
   159 void CHgVgEGL::InitEGL(RWindow& aWindow)
       
   160     {
       
   161     
       
   162     // if we are just resizing or recreating
       
   163     if (iContextVg != VG_INVALID_HANDLE)
       
   164         {
       
   165 
       
   166         
       
   167         // save old surface
       
   168         EGLSurface oldSurface = VG_INVALID_HANDLE;
       
   169         if (iSurface != VG_INVALID_HANDLE)
       
   170             {        
       
   171             // make sure there is nothing pending.
       
   172             vgFinish();
       
   173 
       
   174             oldSurface = iSurface;
       
   175         
       
   176             // unbind current surface.
       
   177             eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, iContextVg);            
       
   178             }
       
   179         
       
   180         // create new surface
       
   181         InitEGLWindowSurfaceL(aWindow);
       
   182         
       
   183         // bind new surface
       
   184         eglMakeCurrent(iDisplay, iSurface, iSurface, iContextVg);
       
   185         
       
   186         if (oldSurface != VG_INVALID_HANDLE)
       
   187             {
       
   188             // free old surface
       
   189             eglDestroySurface(iDisplay,oldSurface);
       
   190             }
       
   191 
       
   192         }
       
   193     else
       
   194         {
       
   195 
       
   196         // get display
       
   197         iDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
       
   198         
       
   199         // intialize egl
       
   200         eglInitialize(iDisplay, NULL, NULL);
       
   201         
       
   202         // find suitable display config
       
   203         EGLint numConfigs;
       
   204         iChosenConfig = 0;
       
   205         
       
   206         const EGLint    KColorAttribList[] =
       
   207                 {
       
   208                 EGL_RED_SIZE,           KSurfaceRedBits,
       
   209                 EGL_GREEN_SIZE,         KSurfaceGreenBits,
       
   210                 EGL_BLUE_SIZE,          KSurfaceBlueBits,
       
   211                 EGL_ALPHA_SIZE,         KSurfaceAlphaBits,
       
   212                 EGL_SURFACE_TYPE,       EGL_WINDOW_BIT,
       
   213                 EGL_RENDERABLE_TYPE,    EGL_OPENVG_BIT,
       
   214                 EGL_NONE
       
   215                 };
       
   216         
       
   217         eglChooseConfig(iDisplay, KColorAttribList, &iChosenConfig, 1, &numConfigs);
       
   218     
       
   219         // we need openvg
       
   220         eglBindAPI(EGL_OPENVG_API);
       
   221     
       
   222         InitEGLWindowSurfaceL(aWindow);
       
   223             
       
   224         // Create context for our thread.
       
   225         iContextVg = eglCreateContext(iDisplay, iChosenConfig, EGL_NO_CONTEXT, NULL);    
       
   226                
       
   227         // bind surface to context
       
   228         eglMakeCurrent(iDisplay, iSurface, iSurface, iContextVg);
       
   229 
       
   230         }
       
   231     
       
   232     }
       
   233 
       
   234 // ---------------------------------------------------------------------------
       
   235 // CHgVgEGL::InitEGLWindowSurfaceL()
       
   236 // ---------------------------------------------------------------------------
       
   237 //
       
   238 void CHgVgEGL::InitEGLWindowSurfaceL(RWindow& aWindow)
       
   239     {
       
   240 
       
   241 
       
   242     // Create surface with premodulated alpha.
       
   243     const EGLint KAttriblist[] = 
       
   244             {
       
   245             EGL_VG_ALPHA_FORMAT, EGL_VG_ALPHA_FORMAT_PRE,
       
   246             EGL_NONE
       
   247             };
       
   248     iSurface = eglCreateWindowSurface(iDisplay, iChosenConfig, &aWindow, KAttriblist);
       
   249     EGLint error = eglGetError();
       
   250     if (error == EGL_BAD_ALLOC)
       
   251         {
       
   252         //RDebug::Print(_L("CHgVgEGL:: Can't create surface! (out of memory)"));
       
   253         User::Leave(KErrNoMemory);
       
   254         }
       
   255     else if (error == EGL_BAD_SURFACE || iSurface == EGL_NO_SURFACE)
       
   256         {
       
   257         //RDebug::Print(_L("CHgVgEGL:: Can't create surface! (general)"));
       
   258         User::Leave(KErrGeneral);
       
   259         }
       
   260     
       
   261     eglSurfaceAttrib(iDisplay, iSurface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED);
       
   262     
       
   263     }
       
   264 
       
   265 // ---------------------------------------------------------------------------
       
   266 // CHgVgEGL::DestroyEGL()
       
   267 // ---------------------------------------------------------------------------
       
   268 //     
       
   269 void CHgVgEGL::DestroyEGL()
       
   270     {
       
   271     // deinitialize egl
       
   272     eglMakeCurrent(iDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
       
   273     eglDestroySurface(iDisplay,iSurface);
       
   274     eglDestroyContext( iDisplay, iContextVg );
       
   275     eglTerminate(iDisplay);
       
   276     eglReleaseThread();
       
   277     }
       
   278 
       
   279 
       
   280 // ---------------------------------------------------------------------------
       
   281 // CHgVgEGL::GetSurfaceToBitmap()
       
   282 // ---------------------------------------------------------------------------
       
   283 //     
       
   284 CFbsBitmap* CHgVgEGL::GetSurfaceToBitmap(const TRect& aRect, TBool aLandscape) const
       
   285     {
       
   286     // make sure every thing is in back buffer
       
   287     vgFinish();
       
   288 
       
   289     
       
   290     CFbsBitmap* bitmap = new CFbsBitmap();        
       
   291     
       
   292     if (bitmap)
       
   293         {
       
   294         // create temporary buffer for data
       
   295         RBuf8 buf;
       
   296         TInt bufCreateErr = buf.Create(aRect.Width() * aRect.Height() * 4);
       
   297         if(bufCreateErr != KErrNone) {
       
   298             buf.Close(); //just in case
       
   299             delete bitmap;
       
   300             bitmap = NULL;
       
   301             return NULL;
       
   302         }
       
   303         buf.Fill(0xFF);
       
   304 
       
   305         // read data back from vg (this is sloooww)
       
   306         VGint dataStride = 0;
       
   307         if (aLandscape)
       
   308             {
       
   309             dataStride = 4 * aRect.Height();
       
   310             vgReadPixels((void*)buf.Ptr(), 
       
   311                          dataStride, VG_sARGB_8888, 0, 0, aRect.Height(), aRect.Width());
       
   312             }
       
   313         else
       
   314             {
       
   315             dataStride = 4 * aRect.Width();
       
   316             vgReadPixels((void*)buf.Ptr(), 
       
   317                          dataStride, VG_sARGB_8888, 0, 0, aRect.Width(), aRect.Height());
       
   318             }
       
   319 
       
   320         // because of bug in vg driver we need to swap memory using for loop, because
       
   321         // negative datastrides cause crash
       
   322         TInt bitmapCreateErr = bitmap->Create(TSize(aRect.Width(), aRect.Height()), EColor16MA);
       
   323         if(bitmapCreateErr != KErrNone) {
       
   324             buf.Close();
       
   325             delete bitmap;
       
   326             bitmap = NULL;
       
   327             return NULL;
       
   328         }
       
   329         
       
   330         bitmap->BeginDataAccess();
       
   331         if (!aLandscape)
       
   332             {
       
   333             TUint8* ptrTrg = (TUint8*)bitmap->DataAddress();
       
   334             TUint8* ptrSrc = (TUint8*)buf.Ptr();
       
   335             for (TInt i = 0; i < aRect.Height(); i++)
       
   336                 {
       
   337                 Mem::Copy(ptrTrg + dataStride * i, 
       
   338                         ptrSrc + dataStride * (aRect.Height() - i - 1), dataStride);
       
   339                 }
       
   340             }
       
   341         else
       
   342             {
       
   343             TUint32* ptrTrg = (TUint32*)bitmap->DataAddress();
       
   344             TUint32* ptrSrc = (TUint32*)buf.Ptr();
       
   345             for (TInt i = 0; i < aRect.Height(); i++)
       
   346                 {
       
   347                 for (TInt j = 0; j < aRect.Width(); j++)
       
   348                     {
       
   349                     ptrTrg[(aRect.Height() - i - 1)*aRect.Width()+(aRect.Width()-j-1)] = ptrSrc[j*aRect.Height()+i];
       
   350                     }
       
   351                 }
       
   352             }
       
   353         bitmap->EndDataAccess();
       
   354         buf.Close();
       
   355         }
       
   356     
       
   357     return bitmap;    
       
   358     }
       
   359 
       
   360 // End of File