hostsupport/hostegl/src/win32/EGLOs.cpp
branchbug235_bringup_0
changeset 53 c2ef9095503a
child 56 40cc73c24bf8
equal deleted inserted replaced
52:39e5f73667ba 53:c2ef9095503a
       
     1 /* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2  *
       
     3  * Permission is hereby granted, free of charge, to any person obtaining a
       
     4  * copy of this software and /or associated documentation files
       
     5  * (the "Materials "), to deal in the Materials without restriction,
       
     6  * including without limitation the rights to use, copy, modify, merge,
       
     7  * publish, distribute, sublicense, and/or sell copies of the Materials,
       
     8  * and to permit persons to whom the Materials are furnished to do so,
       
     9  * subject to the following conditions:
       
    10  *
       
    11  * The above copyright notice and this permission notice shall be included
       
    12  * in all copies or substantial portions of the Materials.
       
    13  *
       
    14  * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
       
    15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
       
    16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
       
    17  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
       
    18  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
       
    19  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR
       
    20  * THE USE OR OTHER DEALINGS IN THE MATERIALS.
       
    21  *
       
    22  * Initial Contributors:
       
    23  * Nokia Corporation - initial contribution.
       
    24  *
       
    25  * Contributors:
       
    26  *
       
    27  * Description:
       
    28  *
       
    29  */
       
    30 
       
    31 #include "EGLOs.h"
       
    32 #include "EGLState.h"
       
    33 #include "EGLProcess.h"
       
    34 #include "EGLThread.h"
       
    35 #include "EGLWindowSurface.h"
       
    36 #include "EGLDisplay.h"
       
    37 #include "EGLContext.h"
       
    38 
       
    39 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
    40 void doBlit( EGLIOsWindowContext* context, void* buf, int width, int height, int stride )
       
    41     {
       
    42     if( !context->osBuffer || !context->pixmap || context->width != width || context->height != height )
       
    43         {
       
    44             if( context->pixmap )
       
    45                 DeleteObject( context->pixmap );
       
    46             context->osBuffer = NULL;
       
    47             context->pixmap = NULL;
       
    48 
       
    49             context->width = width;
       
    50             context->height = height;
       
    51 
       
    52             struct
       
    53             {
       
    54                 BITMAPINFOHEADER	header;
       
    55                 DWORD				rMask;
       
    56                 DWORD				gMask;
       
    57                 DWORD				bMask;
       
    58             } bmi;
       
    59             bmi.header.biSize			= sizeof( BITMAPINFOHEADER );
       
    60             bmi.header.biWidth			= width;
       
    61             bmi.header.biHeight			= height;
       
    62             bmi.header.biPlanes			= 1;
       
    63             bmi.header.biBitCount		= (WORD)32;
       
    64             bmi.header.biCompression	= BI_BITFIELDS;
       
    65             bmi.rMask = 0x00FF0000;
       
    66             bmi.gMask = 0x0000FF00;
       
    67             bmi.bMask = 0x000000FF;
       
    68             
       
    69             context->pixmap = CreateDIBSection( context->vgDisplay, (BITMAPINFO*)&bmi, DIB_RGB_COLORS, (void**)&context->osBuffer, NULL, 0 );
       
    70             if( !context->pixmap )
       
    71             {
       
    72                 context->osBuffer = NULL;
       
    73                 return;
       
    74             }
       
    75         }
       
    76      
       
    77         if( context->osBuffer )
       
    78             {
       
    79             HDC winDC = GetDC( context->window );
       
    80 			GdiFlush();
       
    81             memcpy( context->osBuffer, buf, stride*height );
       
    82             SelectObject( context->vgDisplay, context->pixmap );
       
    83             EGLI_ASSERT( BitBlt(winDC, 0, 0, width, height, context->vgDisplay, 0, 0, SRCCOPY) );
       
    84             ReleaseDC( context->window, winDC );
       
    85             SelectObject( context->vgDisplay, NULL );
       
    86         }
       
    87     }
       
    88 #endif
       
    89 
       
    90 LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
       
    91 {
       
    92    switch (message)
       
    93     {
       
    94     case WM_CLOSE:
       
    95     case WM_DESTROY:
       
    96         //PostQuitMessage(0);
       
    97         return 0;
       
    98     case WM_PAINT:
       
    99         {
       
   100         /*CEGLState* state = getState();
       
   101         if( state )
       
   102             {
       
   103             CEGLThread* thread = state->GetCurrentProcess()->CurrentThread();
       
   104             if( thread && thread->CurrentVGSurface() )
       
   105                 {
       
   106                 if( thread->CurrentVGSurface()->Type() == CEGLSurface::WINDOW_SURFACE )
       
   107                     {
       
   108                     CEGLWindowSurface* surface = (CEGLWindowSurface*)thread->CurrentVGSurface();
       
   109                     InvalidateRect(hwnd, NULL, 0);
       
   110                     doBlit( surface->OsContext(), surface->VGColorBuffer(), surface->Width(), surface->Height(), surface->Stride() );
       
   111                     }
       
   112                 }
       
   113             }*/
       
   114         return 0;
       
   115         }
       
   116     default:
       
   117         break;
       
   118         }
       
   119         return DefWindowProc(hwnd, message, wParam, lParam);
       
   120 }
       
   121 
       
   122 void CEGLOs::InitializeLock( EGLI_LOCK *lock )
       
   123     {
       
   124 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   125     InitializeCriticalSection( lock );
       
   126 #endif
       
   127     }
       
   128 
       
   129 void CEGLOs::GetLock( EGLI_LOCK *lock )
       
   130     {
       
   131 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   132     EnterCriticalSection( lock );
       
   133 #endif
       
   134     }
       
   135 
       
   136 void CEGLOs::ReleaseLock(EGLI_LOCK *lock )
       
   137     {
       
   138 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   139     LeaveCriticalSection( lock );
       
   140 #endif
       
   141     }
       
   142 
       
   143 void CEGLOs::DestroyLock( EGLI_LOCK *lock )
       
   144     {
       
   145 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   146     DeleteCriticalSection( lock );
       
   147 #endif
       
   148     }
       
   149 
       
   150 void CEGLOs::ConfigToNativePixelFormat( const CEGLConfig& config, EGLINativePixelFormatType* nativeFormat )
       
   151     {
       
   152     EGLI_ASSERT( nativeFormat != NULL );
       
   153     memset( nativeFormat, 0, sizeof(PIXELFORMATDESCRIPTOR) );
       
   154     nativeFormat->nSize = sizeof( PIXELFORMATDESCRIPTOR );
       
   155     nativeFormat->nVersion = 1;
       
   156     nativeFormat->dwFlags = PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; // always support OGL
       
   157     
       
   158     // \todo Do we need color index?
       
   159     nativeFormat->iPixelType = PFD_TYPE_RGBA;
       
   160     
       
   161     // \todo overlay/underlay?
       
   162     nativeFormat->iLayerType = PFD_MAIN_PLANE;
       
   163 
       
   164     EGLint surfaceType = config.GetAttribute( EGL_SURFACE_TYPE );
       
   165     if( surfaceType & EGL_WINDOW_BIT )
       
   166         {
       
   167         nativeFormat->dwFlags |= PFD_DRAW_TO_WINDOW;
       
   168         }
       
   169     if( surfaceType & EGL_PIXMAP_BIT )
       
   170         {
       
   171         nativeFormat->dwFlags |= PFD_DRAW_TO_BITMAP;
       
   172         }
       
   173     nativeFormat->cColorBits = config.GetAttribute( EGL_RED_SIZE ) +
       
   174                                config.GetAttribute( EGL_GREEN_SIZE ) +
       
   175                                config.GetAttribute( EGL_BLUE_SIZE );
       
   176 
       
   177     nativeFormat->cAlphaBits = config.GetAttribute( EGL_ALPHA_SIZE );
       
   178     nativeFormat->cDepthBits = config.GetAttribute( EGL_DEPTH_SIZE );
       
   179     nativeFormat->cStencilBits = config.GetAttribute( EGL_STENCIL_SIZE );
       
   180 
       
   181     // \todo Aux buffers, accumulation buffers?
       
   182     }
       
   183 
       
   184 EGLINativeContextType CEGLOs::CreateNativeContext( const CEGLConfig& config, EGLINativeDisplayType display, EGLINativeContextType shareContext )
       
   185     {
       
   186     EGLINativeContextType ret = NULL;
       
   187     DWORD error = ERROR_SUCCESS;
       
   188 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   189     PIXELFORMATDESCRIPTOR pfd;
       
   190     memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));
       
   191     CEGLOs::ConfigToNativePixelFormat( config, &pfd );
       
   192 	int pixelFormat = ChoosePixelFormat( display, &pfd );
       
   193 	if( !pixelFormat )
       
   194 		{
       
   195         return ret;
       
   196 		}
       
   197     int currentPixelFormat = GetPixelFormat( display );
       
   198 	if( !currentPixelFormat && !SetPixelFormat( display, pixelFormat, &pfd ) )
       
   199 		{
       
   200         error = GetLastError();
       
   201 		return ret;
       
   202 		}
       
   203     ret = wglCreateContext( display );
       
   204 	if( ret != NULL && shareContext != NULL)
       
   205 		{
       
   206 		// Share context data
       
   207 		if( !wglShareLists( shareContext, ret ) )
       
   208 			{
       
   209 			wglDeleteContext( ret );
       
   210 			ret = NULL;
       
   211 			}
       
   212 		}
       
   213 #endif
       
   214     return ret;
       
   215     }
       
   216 
       
   217 EGLINativeContextType CEGLOs::CurrentNativeContext()
       
   218     {
       
   219     return wglGetCurrentContext();
       
   220     }
       
   221 
       
   222 EGLINativeDisplayType CEGLOs::CurrentNativeSurface()
       
   223     {
       
   224 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   225     return wglGetCurrentDC();
       
   226 #else
       
   227     return NULL;
       
   228 #endif
       
   229     }
       
   230 
       
   231 bool CEGLOs::MakeNativeContextCurrent( struct EGLINativeGLFunctions* func, EGLINativeDisplayType draw, EGLINativeDisplayType read, EGLINativeContextType context )
       
   232     {
       
   233     bool ret = true;
       
   234 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   235     DWORD err;
       
   236     EGLINativeContextType prevContext = wglGetCurrentContext();
       
   237     EGLINativeDisplayType prevDraw = wglGetCurrentDC();
       
   238     EGLINativeDisplayType prevRead = NULL;
       
   239     if( prevDraw ) prevRead = func->wglGetCurrentReadDCARB();
       
   240     if( context == NULL )
       
   241         {
       
   242         if( wglGetCurrentContext() != NULL )
       
   243             {
       
   244             //warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
       
   245             ret = (wglMakeCurrent( NULL, context ) != 0);
       
   246             }
       
   247         }
       
   248     else
       
   249         {
       
   250         //warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
       
   251         ret = (func->wglMakeContextCurrentARB( draw, read, context ) != 0);
       
   252         }
       
   253     if( !ret )
       
   254         {
       
   255         // \todo Handle error
       
   256         err = GetLastError();
       
   257         // Restore previous context/surface on failure
       
   258         func->wglMakeContextCurrentARB( prevDraw, prevRead, prevContext );        
       
   259         }
       
   260 #endif
       
   261     return ret;
       
   262     }
       
   263 
       
   264 bool CEGLOs::DestroyNativeContext( EGLINativeContextType context )
       
   265     {
       
   266     bool ret = true;
       
   267 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   268     if( context != NULL )
       
   269         {
       
   270         //warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
       
   271         ret = (wglDeleteContext( context ) != 0);
       
   272         }
       
   273 #endif
       
   274     return ret;
       
   275     }
       
   276 
       
   277 bool CEGLOs::InitializeNativeGLFunctions( struct EGLINativeGLFunctions* func, EGLINativeDisplayType display, EGLINativeContextType context )
       
   278     {
       
   279     bool ret = true;
       
   280     DWORD error = ERROR_SUCCESS;
       
   281 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   282     HDC currentDC = wglGetCurrentDC();
       
   283     HGLRC currentContext = wglGetCurrentContext();
       
   284     
       
   285 	ret = !!wglMakeCurrent( display, context );
       
   286     if( ret )
       
   287         {
       
   288         func->wglMakeContextCurrentARB = (PFNWGLMAKECONTEXTCURRENTARBPROC)wglGetProcAddress( "wglMakeContextCurrentARB" );
       
   289         func->wglGetCurrentReadDCARB = (PFNWGLGETCURRENTREADDCARBPROC)wglGetProcAddress ( "wglGetCurrentReadDCARB" );
       
   290         func->wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress( "wglChoosePixelFormatARB" );
       
   291         func->wglCreatePbufferARB = (PFNWGLCREATEPBUFFERARBPROC)wglGetProcAddress( "wglCreatePbufferARB" );
       
   292         func->wglDestroyPbufferARB = (PFNWGLDESTROYPBUFFERARBPROC)wglGetProcAddress( "wglDestroyPbufferARB" );
       
   293         func->wglGetPbufferDCARB = (PFNWGLGETPBUFFERDCARBPROC)wglGetProcAddress( "wglGetPbufferDCARB" );
       
   294         func->wglReleasePbufferDCARB = (PFNWGLRELEASEPBUFFERDCARBPROC)wglGetProcAddress( "wglReleasePbufferDCARB" );
       
   295         func->wglQueryPbufferARB = (PFNWGLQUERYPBUFFERARBPROC)wglGetProcAddress( "wglQueryPbufferARB" );
       
   296 
       
   297         if( !(func->wglChoosePixelFormatARB &&
       
   298               func->wglCreatePbufferARB &&
       
   299               func->wglDestroyPbufferARB &&
       
   300               func->wglGetPbufferDCARB &&
       
   301               func->wglMakeContextCurrentARB &&
       
   302               func->wglGetCurrentReadDCARB &&
       
   303               func->wglQueryPbufferARB &&
       
   304               func->wglReleasePbufferDCARB) )
       
   305               ret = false;
       
   306         }
       
   307 
       
   308     // \todo Other needed extensions.
       
   309 
       
   310     if( !(wglMakeCurrent( currentDC, currentContext )) )
       
   311         {
       
   312         error = GetLastError();
       
   313         if( error == ERROR_INVALID_HANDLE )
       
   314             {
       
   315             // For some reason the current DC or current wgl context was invalid.
       
   316             // Just set them NULL for now.
       
   317             wglMakeCurrent(NULL, NULL);
       
   318             }
       
   319         else
       
   320             {
       
   321             ret = false;
       
   322             }
       
   323         }
       
   324 #endif //EGLI_USE_PLATSIM_EXTENSIONS
       
   325     return ret;
       
   326     }
       
   327 
       
   328 struct EGLINativePbufferContainer* CEGLOs::CreateNativePbuffer( EGLINativeDisplayType display,
       
   329         const CEGLConfig& config, EGLint width, EGLint height, EGLBoolean largestPbuffer, 
       
   330         EGLint textureFormat, EGLint textureTarget )
       
   331     {
       
   332     struct EGLINativePbufferContainer* ret = EGLI_NEW EGLINativePbufferContainer;
       
   333     if( !ret ) return NULL;
       
   334     memset( ret, 0, sizeof(struct EGLINativePbufferContainer) );
       
   335 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   336     EGLINativeContextType context = CEGLOs::CreateNativeContext( config, display, NULL );
       
   337     if( !context )
       
   338         {
       
   339         delete ret;
       
   340         ret = NULL;
       
   341         return ret;
       
   342         }
       
   343     ret->copyContext = context;
       
   344     if( !(CEGLOs::InitializeNativeGLFunctions( &(ret->functions), display, ret->copyContext )) )
       
   345         {
       
   346         CEGLOs::DestroyNativePbuffer( ret );
       
   347         delete ret;
       
   348         ret = NULL;
       
   349         return ret;
       
   350         }
       
   351     
       
   352     int redSize = config.GetAttribute( EGL_RED_SIZE );
       
   353     int greenSize = config.GetAttribute( EGL_GREEN_SIZE );
       
   354     int blueSize = config.GetAttribute( EGL_BLUE_SIZE );
       
   355     int alphaSize = config.GetAttribute( EGL_ALPHA_SIZE );
       
   356     int depthSize = config.GetAttribute( EGL_DEPTH_SIZE );
       
   357     int stencilSize = config.GetAttribute( EGL_STENCIL_SIZE );
       
   358     
       
   359     // \todo Map EGL config properly to WGL config.
       
   360     int attributes[] =
       
   361         {
       
   362         WGL_SUPPORT_OPENGL_ARB, TRUE,
       
   363         WGL_DRAW_TO_PBUFFER_ARB, TRUE,
       
   364         WGL_RED_BITS_ARB, redSize,
       
   365         WGL_GREEN_BITS_ARB, greenSize,
       
   366         WGL_BLUE_BITS_ARB, blueSize,
       
   367         WGL_ALPHA_BITS_ARB, alphaSize,
       
   368         WGL_DEPTH_BITS_ARB, depthSize,
       
   369         WGL_STENCIL_BITS_ARB, stencilSize,
       
   370         WGL_DOUBLE_BUFFER_ARB, TRUE,
       
   371         0
       
   372         };
       
   373     unsigned int formatCount = 0;
       
   374     int pixelFormat = 0;
       
   375     if( !(ret->functions.wglChoosePixelFormatARB( display, attributes, NULL, 1, &pixelFormat, &formatCount )) )
       
   376         {
       
   377         EGLI_ASSERT(false);
       
   378         DWORD err = GetLastError();
       
   379         CEGLOs::DestroyNativePbuffer( ret );
       
   380         delete ret;
       
   381         ret = NULL;
       
   382         return ret;
       
   383         }
       
   384     if( formatCount == 0 )
       
   385         {
       
   386         EGLI_ASSERT(false);
       
   387         DWORD err = GetLastError();
       
   388         CEGLOs::DestroyNativePbuffer( ret );
       
   389         delete ret;
       
   390         ret = NULL;
       
   391         return ret;
       
   392         }
       
   393     int wglTextureFormat = WGL_NO_TEXTURE_ARB;
       
   394     switch( textureFormat )
       
   395         {
       
   396         case EGL_TEXTURE_RGB:
       
   397             {
       
   398             wglTextureFormat = WGL_TEXTURE_RGB_ARB;
       
   399             break;
       
   400             }
       
   401         case EGL_TEXTURE_RGBA:
       
   402             {
       
   403             wglTextureFormat = WGL_TEXTURE_RGBA_ARB;
       
   404             break;
       
   405             }
       
   406         }
       
   407     int wglTextureTarget = WGL_NO_TEXTURE_ARB;
       
   408     switch( textureTarget )
       
   409         {
       
   410         case EGL_TEXTURE_2D:
       
   411             {
       
   412             wglTextureTarget = WGL_TEXTURE_2D_ARB;
       
   413             break;
       
   414             }      
       
   415         }
       
   416     int pbufferAttributes[] =
       
   417         {
       
   418         WGL_TEXTURE_FORMAT_ARB, wglTextureFormat,
       
   419         WGL_TEXTURE_TARGET_ARB, wglTextureTarget,
       
   420         WGL_PBUFFER_LARGEST_ARB, largestPbuffer,
       
   421         0
       
   422         };
       
   423     ret->pbuffer = ret->functions.wglCreatePbufferARB( display, pixelFormat,
       
   424         width, height, pbufferAttributes );
       
   425     if( !(ret->pbuffer) )
       
   426         {
       
   427         EGLI_ASSERT(false);
       
   428         DWORD err = GetLastError();
       
   429         CEGLOs::DestroyNativePbuffer( ret );
       
   430         delete ret;
       
   431         ret = NULL;
       
   432         return ret;
       
   433         }
       
   434     ret->display = ret->functions.wglGetPbufferDCARB( ret->pbuffer );
       
   435     if( !(ret->display) )
       
   436         {
       
   437         EGLI_ASSERT(false);
       
   438         DWORD err = GetLastError();
       
   439         CEGLOs::DestroyNativePbuffer( ret );
       
   440         delete ret;
       
   441         ret = NULL;
       
   442         return ret;
       
   443         }
       
   444 #endif // EGLI_USE_PLATSIM_EXTENSIONS
       
   445     return ret;
       
   446     }
       
   447 
       
   448 bool CEGLOs::DestroyNativePbuffer( struct EGLINativePbufferContainer* container )
       
   449     {
       
   450     // \todo Handle errors!
       
   451     bool ret = true;
       
   452 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   453     DWORD err;
       
   454     if( container->display && container->pbuffer && container->functions.wglReleasePbufferDCARB )
       
   455         {
       
   456         if( !(container->functions.wglReleasePbufferDCARB(container->pbuffer, container->display)) )
       
   457             {
       
   458             err = GetLastError();
       
   459             ret = false;
       
   460             }
       
   461         }
       
   462     if( container->pbuffer && container->functions.wglDestroyPbufferARB )
       
   463         {
       
   464         if( !(container->functions.wglDestroyPbufferARB(container->pbuffer)) )
       
   465             {
       
   466             err = GetLastError();
       
   467             ret = false;
       
   468             }
       
   469         }
       
   470     if( container->copyContext )
       
   471         {
       
   472         ret = CEGLOs::DestroyNativeContext( container->copyContext );
       
   473         if( !ret )
       
   474             {
       
   475             err = GetLastError();
       
   476             }
       
   477         }
       
   478 #endif //EGLI_USE_PLATSIM_EXTENSIONS
       
   479     return ret;
       
   480     }
       
   481 
       
   482 EGLINativeDisplayType CEGLOs::CreateDefaultDisplay()
       
   483     {
       
   484     // \todo It seems that we can't use any of these DC-functions.
       
   485     //       Problems with pixel format selection etc. at least with
       
   486     //       NVidia and Intel GPUs, ATI/AMD seems to work with GetDC(NULL)
       
   487     //       or CreateDC(). No idea how to create EGL_DEFAULT_DISPLAY for
       
   488     //       NV/Intel GPUs. For now CEGLDisplay::Initialize() creates dummy
       
   489     //       window and uses DC from that window.
       
   490     //return (EGLINativeDisplayType)CreateDC(TEXT("DISPLAY"), TEXT("DISPLAY")/*NULL*/, NULL, NULL);
       
   491     //return (EGLINativeDisplayType)GetDC(NULL);
       
   492     //return GetWindowDC(NULL);
       
   493     return NULL;
       
   494     }
       
   495 
       
   496 void CEGLOs::DestroyDefaultDisplay( EGLINativeDisplayType display )
       
   497     {
       
   498 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   499     // no-op
       
   500 #else
       
   501     DeleteDC( display );
       
   502 #endif
       
   503     }
       
   504 
       
   505 EGLINativeWindowType CEGLOs::CreateNativeWindow( int width, int height )
       
   506     {
       
   507     int xBorder = GetSystemMetrics( SM_CXBORDER );
       
   508     int yBorder = GetSystemMetrics( SM_CYBORDER );
       
   509     int caption = GetSystemMetrics( SM_CYCAPTION );
       
   510     
       
   511 
       
   512     WNDCLASS wndclass;
       
   513     wndclass.style		   = 0;
       
   514     wndclass.lpfnWndProc   = WndProc;
       
   515     wndclass.cbClsExtra    = 0;
       
   516     wndclass.cbWndExtra    = 0;
       
   517     wndclass.hInstance	   = (HINSTANCE)GetModuleHandle(NULL);
       
   518     wndclass.hIcon		   = LoadIcon(wndclass.hInstance, MAKEINTRESOURCE(101));
       
   519     wndclass.hCursor	   = LoadCursor(NULL, IDC_ARROW);
       
   520     wndclass.hbrBackground = NULL;
       
   521     wndclass.lpszMenuName  = NULL;
       
   522     wndclass.lpszClassName = "EGLMainWndClass";
       
   523     if (!wndclass.hIcon)
       
   524         wndclass.hIcon = LoadIcon(NULL, IDI_EXCLAMATION);
       
   525     
       
   526     // \todo We should store this class somewhere
       
   527     RegisterClass(&wndclass);
       
   528 
       
   529     EGLINativeWindowType window = CreateWindow(
       
   530         "EGLMainWndClass",
       
   531         "Platsim EGL window",
       
   532         WS_OVERLAPPEDWINDOW,
       
   533         0, 0,
       
   534         width /*+ 2*xBorder*/,
       
   535         height /*+ 2*yBorder + caption*/,
       
   536         NULL,
       
   537         NULL,
       
   538         (HINSTANCE)GetModuleHandle(NULL),
       
   539         NULL);
       
   540     return window;
       
   541     }
       
   542 
       
   543 void CEGLOs::DestroyNativeWindow( EGLINativeWindowType wnd )
       
   544     {
       
   545 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   546     if( wnd )
       
   547         EGLI_ASSERT( DestroyWindow( wnd ) );
       
   548     // \todo Should use stored WNDCLASS to unregister, see CEGLOs::CreateNativeWindow()
       
   549     UnregisterClass( "EGLMainWndClass", (HINSTANCE)GetModuleHandle(NULL) );
       
   550 #endif
       
   551     }
       
   552 
       
   553 bool CEGLOs::IsValidNativeDisplay( EGLINativeDisplayType dsp )
       
   554     {
       
   555 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   556     // we can't validate symbian display
       
   557     return true;
       
   558 #else
       
   559     // Check if we have invalid handle or handle is not display
       
   560     bool ret = true;
       
   561     DWORD err = GetLastError();
       
   562     SetLastError( ERROR_SUCCESS );
       
   563     int technology = GetDeviceCaps( dsp, TECHNOLOGY );
       
   564     if( GetLastError() == ERROR_INVALID_HANDLE || technology != DT_RASDISPLAY )
       
   565         {
       
   566         ret = false;
       
   567         }
       
   568     SetLastError( err );
       
   569     return ret;
       
   570 #endif
       
   571     }
       
   572 
       
   573 bool CEGLOs::IsValidNativeWindow( EGLINativeWindowType wnd )
       
   574     {
       
   575 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   576     // We can't validate symbian window
       
   577     return true;
       
   578 #else
       
   579     bool ret = false;
       
   580     if( wnd )
       
   581         {
       
   582         // \todo should we skip thread id check?
       
   583         DWORD processId = GetCurrentProcessId();
       
   584         DWORD threadId = GetCurrentThreadId();
       
   585         DWORD windowProcessId;
       
   586         DWORD windowThreadId = GetWindowThreadProcessId( wnd, &windowProcessId );
       
   587         ret = ((threadId == windowThreadId) && (processId == windowProcessId));
       
   588         }
       
   589     return ret;
       
   590 #endif //EGLI_USE_PLATSIM_EXTENSIONS
       
   591     }
       
   592 
       
   593 bool CEGLOs::GetNativeWindowSize( EGLINativeWindowType wnd, int& width, int& height )
       
   594     {
       
   595 #if defined( EGLI_USE_PLATSIM_EXTENSIONS )
       
   596     // Window size is transferred through eglPlatsimSetSurfaceParameters()
       
   597     return true;
       
   598 
       
   599 #else
       
   600     bool ret = false;
       
   601     RECT rect;
       
   602     ret = !!GetClientRect( wnd, &rect );
       
   603     if( ret )
       
   604         {
       
   605         width = rect.right - rect.left;
       
   606         height = rect.bottom - rect.top;
       
   607         }
       
   608     return ret;
       
   609 #endif
       
   610     }
       
   611 
       
   612 EGLIOsWindowContext* CEGLOs::CreateOSWindowContext( EGLINativeWindowType wnd, const CEGLConfig& config )
       
   613     {
       
   614     EGLIOsWindowContext* ctx = NULL;
       
   615     ctx = EGLI_NEW EGLIOsWindowContext;
       
   616     if( !ctx )
       
   617         {
       
   618         return NULL;
       
   619         }
       
   620     ctx->window = wnd;
       
   621     ctx->vgDisplay = NULL;
       
   622     ctx->glesDisplay = NULL;
       
   623     ctx->pixmap = NULL;
       
   624     ctx->osBuffer = NULL;
       
   625     ctx->width = 0;
       
   626     ctx->height = 0;
       
   627     ctx->colorBuf = NULL;
       
   628 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   629     // no-op
       
   630 #else
       
   631     if( ctx->window )
       
   632         {
       
   633         EGLint renderableType = config.GetAttribute( EGL_RENDERABLE_TYPE );
       
   634         if( renderableType & EGL_OPENVG_BIT )
       
   635             {
       
   636             HDC winDC = GetDC(ctx->window);
       
   637             ctx->vgDisplay = CreateCompatibleDC(winDC);
       
   638             ReleaseDC(ctx->window, winDC);
       
   639             if(!ctx->vgDisplay)
       
   640                 {
       
   641                 delete ctx;
       
   642                 return NULL;
       
   643                 }
       
   644             }
       
   645         if( renderableType & EGL_OPENGL_ES_BIT )
       
   646             {
       
   647             HDC winDC = GetDC(ctx->window);
       
   648             ctx->glesDisplay = winDC;
       
   649             if(!ctx->glesDisplay)
       
   650                 {
       
   651                 delete ctx;
       
   652                 return NULL;
       
   653                 }
       
   654             PIXELFORMATDESCRIPTOR pfd;
       
   655             CEGLOs::ConfigToNativePixelFormat( config, &pfd );
       
   656 
       
   657 	        int pixelFormat = ChoosePixelFormat( ctx->glesDisplay, &pfd );
       
   658 	        if( !pixelFormat )
       
   659 		        {
       
   660                 EGLI_ASSERT( false );
       
   661 		        }
       
   662 	        if( !SetPixelFormat(ctx->glesDisplay, pixelFormat, &pfd ) )
       
   663 		        {
       
   664 		        EGLI_ASSERT( false );
       
   665 		        }
       
   666             }
       
   667         }
       
   668 #endif
       
   669     return ctx;
       
   670     }
       
   671 
       
   672 void CEGLOs::DestroyOSWindowContext( EGLIOsWindowContext* context )
       
   673     {
       
   674 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   675     if(!context->vgDisplay)
       
   676         {
       
   677         SelectObject(context->vgDisplay, NULL);
       
   678         DeleteDC(context->vgDisplay);
       
   679         }
       
   680     if( context->glesDisplay )
       
   681         {
       
   682         ReleaseDC( context->window, context->glesDisplay );
       
   683         }
       
   684     if( context->pixmap )
       
   685         DeleteObject( context->pixmap );
       
   686     if( context->colorBuf )
       
   687         free( context->colorBuf );
       
   688     delete context;
       
   689 #else
       
   690     delete context;
       
   691 #endif
       
   692     }
       
   693 
       
   694 void CEGLOs::BlitToOSWindow( EGLenum api, CEGLDisplay* display, EGLIOsWindowContext* context, void* buf, int width, int height, int stride )
       
   695     {
       
   696 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   697     // \todo GLES
       
   698     CEGLState* state = getState();
       
   699     if( !state )
       
   700         return;
       
   701     CEGLThread* thread = state->GetCurrentProcess()->CurrentThread();
       
   702     switch( api )
       
   703         {
       
   704         case EGL_OPENVG_API:
       
   705             {
       
   706             if( thread && state->VGInterface() )
       
   707                 {                
       
   708                 if( thread->CurrentVGSurface() )
       
   709                     {
       
   710                     CEGLSurface* surface = thread->CurrentVGSurface();
       
   711                     EGLI_ASSERT( surface->Type() == CEGLSurface::WINDOW_SURFACE );
       
   712                     state->VGInterface()->CopyBuffers( buf, -stride, surface->VGClientSurface() );
       
   713                     }
       
   714                 }
       
   715             break;
       
   716             }
       
   717         case EGL_OPENGL_ES_API:
       
   718             {
       
   719                 if (state->GLESInterface(thread->CurrentGLESContext()->ClientVersion()))
       
   720                 {
       
   721                 // \todo
       
   722                 }
       
   723             break;
       
   724             }
       
   725         }
       
   726 #else
       
   727     if( api == EGL_OPENGL_ES_API )
       
   728         {
       
   729         SwapBuffers( context->glesDisplay );
       
   730         }
       
   731     else
       
   732         {
       
   733         doBlit(context, buf, width, height, stride);
       
   734         }
       
   735 #endif
       
   736     }
       
   737 
       
   738 EGLILibraryHandle CEGLOs::LoadHostGL()
       
   739     {
       
   740     return LoadLibrary( TEXT("opengl32.dll") );
       
   741     }
       
   742 
       
   743 void* CEGLOs::GetGLProcAddress(EGLILibraryHandle& libraryHandle, const char* proc)
       
   744     {
       
   745     void* addr = GetProcAddress(libraryHandle, proc);
       
   746 	if(!addr)
       
   747 		{
       
   748 		addr = wglGetProcAddress(proc);
       
   749 		}
       
   750 
       
   751 	return addr;
       
   752     }
       
   753 
       
   754 bool CEGLOs::FreeClientLibrary(EGLILibraryHandle& libraryHandle)
       
   755     {
       
   756     // != 0 added to expression below because of
       
   757     // warning C4800: 'BOOL' : forcing value to bool 'true' or 'false' (performance warning)
       
   758     return (FreeLibrary( libraryHandle ) != 0);
       
   759     }
       
   760 
       
   761 IEGLtoVGInterface* CEGLOs::LoadVGInterface( EGLILibraryHandle& libraryHandle )
       
   762     {
       
   763     IEGLtoVGInterface* iFace = NULL;
       
   764     fpGetVGInterface proc;
       
   765     libraryHandle = LoadLibrary( TEXT("libOpenVG.dll") );
       
   766     if( libraryHandle != NULL )
       
   767         {
       
   768         proc = (fpGetVGInterface)GetProcAddress( libraryHandle, "getVGInterface" );
       
   769         if( proc != NULL )
       
   770             {
       
   771             iFace = proc();
       
   772             }
       
   773         }
       
   774     return iFace;
       
   775     }
       
   776 
       
   777 IEGLtoGLESInterface* CEGLOs::LoadGLES1Interface( EGLILibraryHandle& libraryHandle )
       
   778     {
       
   779     IEGLtoGLESInterface* iFace = NULL;
       
   780     fpGetGLES1Interface proc;
       
   781     libraryHandle = LoadLibrary( TEXT("libGLESv1.dll") );
       
   782     if( libraryHandle != NULL )
       
   783         {
       
   784         proc = (fpGetGLES1Interface)GetProcAddress( libraryHandle, "getGLESInterface" );
       
   785         if( proc != NULL )
       
   786             {
       
   787             iFace = proc();
       
   788             }
       
   789         }
       
   790     return iFace;
       
   791     }
       
   792 
       
   793 IEGLtoGLES2Interface* CEGLOs::LoadGLES2Interface( EGLILibraryHandle& libraryHandle )
       
   794     {
       
   795     IEGLtoGLES2Interface* iFace = NULL;
       
   796     fpGetGLES2Interface proc;
       
   797     libraryHandle = LoadLibrary( TEXT("libGLESv2.dll") );
       
   798     if( libraryHandle != NULL )
       
   799         {
       
   800         proc = (fpGetGLES2Interface)GetProcAddress( libraryHandle, "getGLES2Interface" );
       
   801         if( proc != NULL )
       
   802             {
       
   803             iFace = proc();
       
   804             }
       
   805         }
       
   806     return iFace;
       
   807     }