hostsupport/hostegl/src/eglapi.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 <string.h>
       
    32 #include <algorithm>
       
    33 #include <EGL/egl.h>
       
    34 #include "eglDefinitions.h"
       
    35 #include "eglInternal.h"
       
    36 #include "EGLState.h"
       
    37 #include "EGLProcess.h"
       
    38 #include "EGLDisplay.h"
       
    39 #include "EGLThread.h"
       
    40 #include "EGLContext.h"
       
    41 #include "EGLConfig.h"
       
    42 #include "EGLWindowSurface.h"
       
    43 #include "EGLPbufferSurface.h"
       
    44 #include "ColorDescriptor.h"
       
    45 #include "SurfaceDescriptor.h"
       
    46 #include "EGLExtension.h"
       
    47 #include "EGLOs.h"
       
    48 
       
    49 #if defined(_WIN32)
       
    50 #include <windows.h>
       
    51 #else
       
    52     // \todo other platforms
       
    53 #endif
       
    54 
       
    55 #if defined(_WIN32) && !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
    56 static DWORD g_tlsIndex = TLS_OUT_OF_INDEXES;
       
    57 #endif
       
    58 
       
    59 static CEGLState* g_eglState = NULL;
       
    60 static bool g_lockInitialized = false;
       
    61 EGLI_LOCK g_eglLock;
       
    62 
       
    63 CEGLState* getState()
       
    64     {
       
    65 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
    66     if( !g_eglState )
       
    67         {
       
    68         g_eglState = EGLI_NEW CEGLState();
       
    69         if( !g_eglState )
       
    70             {
       
    71             return NULL;
       
    72             }
       
    73         if( !(g_eglState->Initialize()) )
       
    74             {
       
    75             delete g_eglState;
       
    76             g_eglState = NULL;
       
    77             return NULL;
       
    78             }
       
    79         g_eglState->AddRef();
       
    80         }
       
    81     return g_eglState;
       
    82 #elif defined(_WIN32)
       
    83     CEGLOs::GetLock( &g_eglLock );
       
    84     if( !g_eglState )
       
    85         {
       
    86         g_eglState = EGLI_NEW CEGLState();
       
    87         if( !g_eglState )
       
    88             {
       
    89             CEGLOs::ReleaseLock( &g_eglLock );
       
    90             return NULL;
       
    91             }
       
    92         if( !(g_eglState->Initialize()) )
       
    93             {
       
    94             delete g_eglState;
       
    95             g_eglState = NULL;
       
    96             CEGLOs::ReleaseLock( &g_eglLock );
       
    97             return NULL;
       
    98             }
       
    99         }
       
   100     EGLI_ASSERT( g_tlsIndex != TLS_OUT_OF_INDEXES );
       
   101     if( g_tlsIndex == TLS_OUT_OF_INDEXES )
       
   102         {
       
   103         CEGLOs::ReleaseLock( &g_eglLock );
       
   104         return NULL;
       
   105         }
       
   106     CEGLThread* thread = (CEGLThread*)TlsGetValue( g_tlsIndex );
       
   107     if( g_eglState && !thread )
       
   108         {
       
   109         // \todo Remove CEGLProcess when platsim extensions are not needed any more
       
   110         thread = g_eglState->GetCurrentProcess()->AddThread( GetCurrentThreadId(), true, g_eglState->SupportedApis() );
       
   111         if( !thread ) 
       
   112             {
       
   113             CEGLOs::ReleaseLock( &g_eglLock );
       
   114             return NULL;
       
   115             }
       
   116         if( !(TlsSetValue( g_tlsIndex, (void *)thread )) )
       
   117             {
       
   118             CEGLOs::ReleaseLock( &g_eglLock );
       
   119             return NULL;
       
   120             }
       
   121         g_eglState->AddRef();
       
   122         }
       
   123     CEGLOs::ReleaseLock( &g_eglLock );
       
   124     return g_eglState;
       
   125 #else // Linux
       
   126     // \todo
       
   127     return NULL;
       
   128 #endif
       
   129     }
       
   130 
       
   131 static void releaseState()
       
   132     {
       
   133 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   134     if( g_eglState )
       
   135         {
       
   136         if( g_eglState->RemoveRef() )
       
   137             {
       
   138             delete g_eglState;
       
   139             g_eglState = NULL;
       
   140             }
       
   141         }
       
   142 #elif defined(_WIN32)
       
   143     CEGLOs::GetLock( &g_eglLock );
       
   144     if( g_eglState )
       
   145         {
       
   146         g_eglState->GetCurrentProcess()->RemoveThread( GetCurrentThreadId() );
       
   147         EGLI_ASSERT( g_tlsIndex != TLS_OUT_OF_INDEXES );
       
   148         if( g_tlsIndex != TLS_OUT_OF_INDEXES )
       
   149             {
       
   150             TlsSetValue( g_tlsIndex, 0 );
       
   151             }
       
   152         }
       
   153     if( g_eglState && g_eglState->RemoveRef() )
       
   154         {
       
   155         delete g_eglState;
       
   156         g_eglState = NULL;
       
   157         }
       
   158     CEGLOs::ReleaseLock( &g_eglLock );
       
   159 #else // Linux
       
   160     // \todo
       
   161     EGLI_ASSERT( false );
       
   162 #endif
       
   163     }
       
   164 
       
   165 /*static*/ CEGLThread* getThread()
       
   166     {
       
   167 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   168     CEGLState* state = getState();
       
   169     CEGLProcess* process = state->GetCurrentProcess();
       
   170     if( process )
       
   171         {
       
   172         return process->CurrentThread();
       
   173         }
       
   174     return NULL;
       
   175 #elif defined(_WIN32)
       
   176     EGLI_ASSERT( g_tlsIndex != TLS_OUT_OF_INDEXES );
       
   177     if( g_tlsIndex == TLS_OUT_OF_INDEXES )
       
   178         return NULL;
       
   179     CEGLThread* thread = (CEGLThread*)TlsGetValue( g_tlsIndex );
       
   180     if( !thread && GetLastError() == ERROR_SUCCESS )
       
   181         {
       
   182         // TlsGetValue() succeeded but didn't have thread => create one now
       
   183         CEGLState* state = getState();
       
   184         if( state ) 
       
   185             {
       
   186             thread = (CEGLThread*)TlsGetValue( g_tlsIndex );
       
   187             }
       
   188         }
       
   189     return thread;
       
   190 #else // Linux
       
   191     // \todo
       
   192     EGLI_ASSERT( false );
       
   193 #endif
       
   194     } 
       
   195 
       
   196 void setEGLError( EGLint error )
       
   197     {
       
   198     CEGLThread* thread = getThread();
       
   199     if( thread )
       
   200         {
       
   201         thread->SetError( error );
       
   202         }
       
   203     }
       
   204 
       
   205 #define EGLI_GET_DISPLAY_RET(id,ret)\
       
   206     CEGLDisplay* display = state->GetDisplay( id );\
       
   207     if( !display )\
       
   208         {\
       
   209         EGLI_LEAVE_RET( ret, EGL_BAD_DISPLAY );\
       
   210         }\
       
   211     EGLI_ASSERT( display->ProcessId() == process->Id() );\
       
   212     if( !(display->IsInitialized()) )\
       
   213         {\
       
   214         EGLI_LEAVE_RET( ret, EGL_NOT_INITIALIZED );\
       
   215         }
       
   216 
       
   217 #ifdef __cplusplus
       
   218 extern "C" {
       
   219 #endif
       
   220 /*When there is no status to return (in other words, when eglGetError is called
       
   221 as the first EGL call in a thread, or immediately after calling eglReleaseThread),
       
   222 EGL_SUCCESS will be returned.*/
       
   223 EGLAPI EGLint EGLAPIENTRY eglGetError(void)
       
   224     {
       
   225     EGLint err = EGL_SUCCESS;
       
   226     CEGLThread* thread = getThread();
       
   227     if( thread )
       
   228         {
       
   229         err = thread->Error();
       
   230         thread->SetError( EGL_SUCCESS );
       
   231         }
       
   232     else
       
   233         {
       
   234         err = EGL_BAD_ALLOC;
       
   235         }
       
   236     return err;
       
   237     }
       
   238 
       
   239 EGLAPI EGLDisplay EGLAPIENTRY eglGetDisplay(EGLNativeDisplayType display_id)
       
   240     {
       
   241     EGLI_ENTER_RET( EGL_NO_DISPLAY );
       
   242 
       
   243 	if( display_id == EGL_DEFAULT_DISPLAY )
       
   244 		{
       
   245 		display_id = (EGLNativeDisplayType)state->DefaultDisplay();
       
   246 		}
       
   247 
       
   248     CEGLDisplay* display = state->GetDisplayByNativeType( (EGLINativeDisplayType)display_id, process->Id() );
       
   249     if( !display )
       
   250         {
       
   251         if( !(CEGLOs::IsValidNativeDisplay( (EGLINativeDisplayType)display_id )) )
       
   252             {
       
   253             EGLI_LEAVE_RET( EGL_NO_DISPLAY, EGL_BAD_PARAMETER );
       
   254             }
       
   255         display = state->AddDisplay( (EGLINativeDisplayType)display_id, process->Id() );
       
   256         if( !display )
       
   257             {
       
   258             EGLI_LEAVE_RET( EGL_NO_DISPLAY, EGL_BAD_ALLOC );
       
   259             }
       
   260 		display->AddRef();
       
   261         }
       
   262     EGLI_LEAVE_RET( (EGLDisplay)display, EGL_SUCCESS );
       
   263     }
       
   264 
       
   265 EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
       
   266     {
       
   267     EGLI_ENTER_RET( EGL_FALSE );
       
   268 
       
   269     CEGLDisplay* display = state->GetDisplay( dpy );
       
   270     if( !display )
       
   271         {
       
   272         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_DISPLAY );
       
   273         }
       
   274 
       
   275     if( !(display->IsInitialized()) && !(display->Initialize()) )
       
   276         {
       
   277         EGLI_LEAVE_RET( EGL_FALSE, EGL_NOT_INITIALIZED );
       
   278         }
       
   279 
       
   280     if( major ) *major = 1;
       
   281     if( minor ) *minor = 4;
       
   282 
       
   283     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
   284     }
       
   285 
       
   286 EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay dpy)
       
   287     {
       
   288     EGLI_ENTER_RET( EGL_FALSE );
       
   289     CEGLDisplay* display = state->GetDisplay( dpy );
       
   290 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   291     if( display && display->ProcessId() != process->Id() )
       
   292         {
       
   293         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_DISPLAY );
       
   294         }
       
   295 #endif
       
   296     if( !display )
       
   297         {
       
   298         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_DISPLAY );
       
   299         }
       
   300 
       
   301     if( !(display->IsInitialized()) )
       
   302         {
       
   303         EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
   304         }
       
   305     display->RemoveRef();
       
   306     if( display->TerminateDisplay() )
       
   307         {
       
   308         state->RemoveDisplay( display );
       
   309         }
       
   310 
       
   311     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
   312     }
       
   313 
       
   314 /*
       
   315     eglQueryString returns a pointer to a static, zero-terminated string describing
       
   316     some aspect of the EGL implementation running on the specified display. name
       
   317     may be one of EGL_CLIENT_APIS, EGL_EXTENSIONS, EGL_VENDOR, or EGL_-
       
   318     VERSION.
       
   319     The EGL_CLIENT_APIS string describes which client rendering APIs are
       
   320     supported. It is zero-terminated and contains a space-separated list of API
       
   321     names, which must include at least one of ‘‘OpenGL’’, ‘‘OpenGL_ES’’ or
       
   322     ‘‘OpenVG’’.
       
   323     The EGL_EXTENSIONS string describes which EGL extensions are supported
       
   324     by the EGL implementation running on the specified display. The string is zeroterminated
       
   325     and contains a space-separated list of extension names; extension names
       
   326     themselves do not contain spaces. If there are no extensions to EGL, then the empty
       
   327     string is returned.
       
   328     The format and contents of the EGL_VENDOR string is implementation dependent.
       
   329     The format of the EGL_VERSION string is:
       
   330     <major version.minor version><space><vendor specific info>
       
   331 */
       
   332 
       
   333 EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name)
       
   334     {
       
   335     EGLI_ENTER_RET( NULL );
       
   336     EGLI_GET_DISPLAY_RET( dpy, NULL );
       
   337 
       
   338     const char* ret = NULL;
       
   339     switch(name)
       
   340         {
       
   341         case EGL_CLIENT_APIS:
       
   342             {
       
   343             switch( state->SupportedApis() )
       
   344                 {
       
   345                 case EGL_OPENVG_BIT | EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT:
       
   346                     {
       
   347                     ret = "OpenVG OpenGL_ES OpenGL_ES2";
       
   348                     break;
       
   349                     }
       
   350 
       
   351                 case EGL_OPENVG_BIT | EGL_OPENGL_ES_BIT:
       
   352                     {
       
   353                     ret = "OpenVG OpenGL_ES";
       
   354                     break;
       
   355                     }
       
   356 
       
   357                 case EGL_OPENVG_BIT | EGL_OPENGL_ES2_BIT:
       
   358                     {
       
   359                     ret = "OpenVG OpenGL_ES2";
       
   360                     break;
       
   361                     }
       
   362 
       
   363                 case EGL_OPENVG_BIT:
       
   364                     {
       
   365                     ret = "OpenVG";
       
   366                     break;
       
   367                     }
       
   368 
       
   369                 case EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT:
       
   370                     {
       
   371                     ret = "OpenGL_ES OpenGL_ES2";
       
   372                     break;
       
   373                     }
       
   374 
       
   375                 case EGL_OPENGL_ES_BIT:
       
   376                     {
       
   377                     ret = "OpenGL_ES";
       
   378                     break;
       
   379                     }
       
   380 
       
   381                 case EGL_OPENGL_ES2_BIT:
       
   382                     {
       
   383                     ret = "OpenGL_ES2";
       
   384                     break;
       
   385                     }
       
   386 
       
   387                 default:
       
   388                     {
       
   389                     ret = "";
       
   390                     break;
       
   391                     }
       
   392                 }
       
   393             break;
       
   394             }
       
   395         case EGL_EXTENSIONS:
       
   396             {
       
   397             // TODO
       
   398             ret = "EGL_KHR_image_base";
       
   399             break;
       
   400             }
       
   401         case EGL_VENDOR:
       
   402             {
       
   403             ret = "Nokia";
       
   404             break;
       
   405             }
       
   406         case EGL_VERSION:
       
   407             {
       
   408             ret ="1.4 PlatSim";
       
   409             break;
       
   410             }
       
   411 
       
   412         default:
       
   413             {
       
   414             EGLI_LEAVE_RET( NULL, EGL_BAD_PARAMETER );
       
   415             break;
       
   416             }
       
   417         }
       
   418     EGLI_LEAVE_RET( ret, EGL_SUCCESS );
       
   419     }
       
   420 
       
   421 EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
       
   422 			 EGLint config_size, EGLint *num_config)
       
   423     {
       
   424     EGLI_ENTER_RET( EGL_FALSE );
       
   425     if( !num_config )
       
   426         {
       
   427         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_PARAMETER );
       
   428         }
       
   429     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
   430 
       
   431     EGLint configCount = state->ConfigCount();
       
   432     if( !configs )
       
   433         {
       
   434         *num_config = configCount;
       
   435         EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
   436         }
       
   437 
       
   438     *num_config = EGLI_MIN( configCount, config_size );
       
   439 
       
   440     state->FillConfigs( configs, *num_config );
       
   441 
       
   442     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
   443     }
       
   444 
       
   445 EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,
       
   446 			   EGLConfig *configs, EGLint config_size,
       
   447 			   EGLint *num_config)
       
   448     {
       
   449     EGLI_ENTER_RET( EGL_FALSE );
       
   450     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
   451 
       
   452     CColorDescriptor* colorDesc = EGLI_NEW CColorDescriptor( 0, 0, 0, 0, true, 0, false, 0, 0 );
       
   453     if( !colorDesc )
       
   454         {
       
   455         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ALLOC );
       
   456         }
       
   457     colorDesc->SetAttribute( EGL_COLOR_BUFFER_TYPE, EGL_RGB_BUFFER );
       
   458     CEGLConfig* filter = EGLI_NEW CEGLConfig(
       
   459                     *colorDesc,
       
   460                     EGL_DONT_CARE,  
       
   461                     EGL_DONT_CARE,
       
   462                     EGL_DONT_CARE,
       
   463                     EGL_DONT_CARE,
       
   464                     0, 0, 0,
       
   465                     EGL_DONT_CARE,
       
   466                     EGL_DONT_CARE,
       
   467                     EGL_DONT_CARE,
       
   468                     EGL_DONT_CARE,
       
   469                     EGL_OPENGL_ES_BIT,
       
   470                     0, 0, 0,
       
   471                     EGL_WINDOW_BIT,
       
   472                     NULL );          // transparent color    
       
   473     delete colorDesc;
       
   474     colorDesc = NULL;
       
   475     if( !filter )
       
   476         {
       
   477         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ALLOC );
       
   478         }
       
   479 
       
   480     EGLint configId = 0;
       
   481     EGLint matchPixmap = EGL_NONE;
       
   482 
       
   483     if( attrib_list && attrib_list[0] != EGL_NONE )
       
   484         {
       
   485         for( EGLint i=0; attrib_list[i] != EGL_NONE && configId == 0; i+=2 )
       
   486             {
       
   487             switch( attrib_list[i] )
       
   488                 {
       
   489                 case EGL_NATIVE_VISUAL_ID:
       
   490                 case EGL_MAX_PBUFFER_HEIGHT:
       
   491                 case EGL_MAX_PBUFFER_PIXELS:
       
   492                 case EGL_MAX_PBUFFER_WIDTH:
       
   493                     {
       
   494                     // IGNORED
       
   495                     break;
       
   496                     }
       
   497 
       
   498                 case EGL_CONFIG_ID:
       
   499                     {
       
   500                     configId = attrib_list[i+1];
       
   501                     break;
       
   502                     }
       
   503                     
       
   504                 case EGL_MATCH_NATIVE_PIXMAP:
       
   505                     {
       
   506                     matchPixmap = attrib_list[i+1];
       
   507                     break;
       
   508                     }
       
   509                 default:
       
   510                     {
       
   511                     if( !(filter->SetAttribute(attrib_list[i], attrib_list[i+1])) )
       
   512                         {
       
   513                         delete filter;
       
   514                         filter = NULL;
       
   515                         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ATTRIBUTE );
       
   516                         }
       
   517                     }
       
   518                 }
       
   519             }
       
   520         }
       
   521 
       
   522     if( configId > 0 )
       
   523         {
       
   524         CEGLConfig* config = state->FindConfigById( configId );
       
   525         if( !config )
       
   526             {
       
   527             delete filter;
       
   528             filter = NULL;
       
   529             // TODO: is this correct error code? 
       
   530             EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ALLOC ); 
       
   531             }
       
   532         *num_config = 1;
       
   533         configs[0] = (EGLConfig)config;
       
   534         delete filter;
       
   535         filter = NULL;
       
   536         EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
   537         }
       
   538 
       
   539     if( matchPixmap != EGL_NONE )
       
   540         {
       
   541         // eglChooseConfig – only pbuffer supported, so no need for EGL_MATCH_NATIVE_PIXMAP
       
   542         }
       
   543     
       
   544     *num_config = state->MatchConfigs( filter, configs, config_size );
       
   545     delete filter;
       
   546     filter = NULL;
       
   547     
       
   548     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
   549     }
       
   550 
       
   551 EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig configId,
       
   552 			      EGLint attribute, EGLint *value)
       
   553     {
       
   554     EGLI_ENTER_RET( EGL_FALSE );
       
   555     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
   556     if( !value )
       
   557         {
       
   558         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_PARAMETER );
       
   559         }
       
   560     CEGLConfig* config = state->GetConfig( configId );
       
   561     if( !config )
       
   562         {
       
   563         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_CONFIG );
       
   564         }
       
   565     EGLint val = config->GetAttribute( attribute );
       
   566     if( val == EGL_BAD_ATTRIBUTE )
       
   567         {
       
   568         EGLI_LEAVE_RET( EGL_FALSE, val );
       
   569         }
       
   570     *value = val;
       
   571     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
   572     }
       
   573 
       
   574 
       
   575 EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig configId,
       
   576 				  EGLNativeWindowType win,
       
   577 				  const EGLint *attrib_list)
       
   578     {
       
   579     EGLI_ENTER_RET( EGL_NO_SURFACE );
       
   580     EGLI_GET_DISPLAY_RET ( dpy, EGL_NO_SURFACE );
       
   581     // \todo eglCreateWindowSurface – EGL_BAD_MATCH raised (as no window-supporting configs)
       
   582     CEGLConfig* config = state->GetConfig( configId );
       
   583     if( !config )
       
   584         {
       
   585         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_CONFIG );
       
   586         }
       
   587     EGLint surfaceType = config->GetAttribute( EGL_SURFACE_TYPE );
       
   588     if( !(surfaceType & EGL_WINDOW_BIT) )
       
   589         {
       
   590         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_MATCH );
       
   591         }
       
   592     CEGLSurface* surface = display->GetSurfaceByNativeType( (EGLINativeWindowType)win );
       
   593     if( surface && surface->Config() == config )
       
   594         {
       
   595         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
   596         }
       
   597 
       
   598 	EGLint renderBuffer = EGL_BACK_BUFFER;
       
   599 	EGLint colorSpace = EGL_VG_COLORSPACE_sRGB;
       
   600 	EGLint alphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
       
   601     EGLint renderableType = config->GetAttribute( EGL_RENDERABLE_TYPE );
       
   602 	if( attrib_list && attrib_list[0] != EGL_NONE )
       
   603 	    {
       
   604 		for( int i=0; attrib_list[i] != EGL_NONE; i+=2 )
       
   605 		    {
       
   606 			switch( attrib_list[i] )
       
   607 			    {
       
   608 			    case EGL_RENDER_BUFFER:
       
   609 				    renderBuffer = attrib_list[i+1];
       
   610 				    break;
       
   611 
       
   612 			    case EGL_VG_COLORSPACE:
       
   613                     if( !(renderableType & EGL_OPENVG_BIT) )
       
   614                         {
       
   615                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
   616                         }
       
   617 				    colorSpace = attrib_list[i+1];
       
   618 				    break;
       
   619 
       
   620 			    case EGL_VG_ALPHA_FORMAT:
       
   621                     if( !(renderableType & EGL_OPENVG_BIT) )
       
   622                         {
       
   623                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
   624                         }
       
   625 				    alphaFormat = attrib_list[i+1];
       
   626 				    break;
       
   627 
       
   628 			    default:
       
   629 				    EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
   630                 }
       
   631             }
       
   632         }
       
   633 	
       
   634     if( !(surfaceType & colorSpace) || !(surfaceType & alphaFormat) )
       
   635         {
       
   636         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_MATCH );
       
   637         }
       
   638     
       
   639     if( !CEGLOs::IsValidNativeWindow( win ) )
       
   640         {
       
   641         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_NATIVE_WINDOW );
       
   642         }
       
   643 
       
   644     EGLIOsWindowContext* osContext = CEGLOs::CreateOSWindowContext( win, *config );
       
   645     if( !osContext )
       
   646         {
       
   647         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
   648         }
       
   649     
       
   650     surface = EGLI_NEW CEGLWindowSurface( config, colorSpace, alphaFormat, renderBuffer, osContext );
       
   651     if( !surface )
       
   652         {
       
   653         CEGLOs::DestroyOSWindowContext( osContext );
       
   654         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
   655         }
       
   656     // \note AddSurface() will destroy the object if it fails to take ownership
       
   657     surface = display->AddSurface( surface );
       
   658     if( !surface )
       
   659         {
       
   660         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
   661         }
       
   662 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
   663     int width = 0;
       
   664     int height = 0;
       
   665     if( !CEGLOs::GetNativeWindowSize( win, width, height ) ||
       
   666         !(surface->Resize( width, height )) )
       
   667         {
       
   668         // \note RemoveSurface() will destroy the object
       
   669         display->RemoveSurface( surface );
       
   670         // \todo Is this correct error?
       
   671         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
   672         }
       
   673     if( (state->SupportedApis() & EGL_OPENVG_BIT) && (renderableType & EGL_OPENVG_BIT) )
       
   674         {
       
   675         SurfaceDescriptor* surfaceDesc = surface->Descriptor();
       
   676         if( !(state->VGInterface()->CreateSurface( surfaceDesc, surface->VGBuffers(), NULL )) )
       
   677             {
       
   678             // \note RemoveSurface() will destroy the object
       
   679             display->RemoveSurface( surface );
       
   680             EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
   681             }
       
   682         }
       
   683 #endif // EGLI_USE_PLATSIM_EXTENSIONS
       
   684 
       
   685     surface->AddRef();
       
   686 
       
   687     EGLI_LEAVE_RET( (EGLSurface)surface, EGL_SUCCESS );
       
   688     }
       
   689 
       
   690 EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig configId,
       
   691 				   const EGLint *attrib_list)
       
   692     {
       
   693     // \todo combine with eglCreatePbufferFromClientBuffer()
       
   694     EGLI_ENTER_RET( EGL_NO_SURFACE );
       
   695     EGLI_GET_DISPLAY_RET( dpy, EGL_NO_SURFACE );
       
   696     CEGLConfig* config = state->GetConfig( configId );
       
   697     if( !config )
       
   698         {
       
   699         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_CONFIG );
       
   700         }
       
   701 
       
   702     if( !(config->GetAttribute( EGL_SURFACE_TYPE ) & EGL_PBUFFER_BIT) )
       
   703         {
       
   704         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_MATCH );
       
   705         }
       
   706     
       
   707     EGLint width = 0;
       
   708     EGLint height = 0;
       
   709     EGLint textureFormat = EGL_NO_TEXTURE;
       
   710     EGLint textureTarget = EGL_NO_TEXTURE;
       
   711     EGLint mipmapTexture = EGL_FALSE;
       
   712     EGLint largestPbuffer = EGL_FALSE;
       
   713     EGLint colorSpace = EGL_VG_COLORSPACE_sRGB;
       
   714     EGLint alphaFormat = EGL_VG_ALPHA_FORMAT_NONPRE;
       
   715 
       
   716     EGLint renderableType = config->GetAttribute( EGL_RENDERABLE_TYPE );
       
   717     if( attrib_list && attrib_list[0] != EGL_NONE )
       
   718         {
       
   719         for( int i=0; attrib_list[i] != EGL_NONE; i+=2 )
       
   720             {
       
   721             EGLint value = attrib_list[i+1];
       
   722             switch( attrib_list[i] )
       
   723                 {
       
   724                 case EGL_WIDTH:
       
   725                     {
       
   726                     if( value < 0 )
       
   727                         {
       
   728                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_PARAMETER );
       
   729                         }
       
   730                     width = value;
       
   731                     break;
       
   732                     }
       
   733 
       
   734                 case EGL_HEIGHT:
       
   735                     {
       
   736                     if( value < 0 )
       
   737                         {
       
   738                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_PARAMETER );
       
   739                         }
       
   740                     height = value;
       
   741                     break;
       
   742                     }
       
   743 
       
   744                 case EGL_LARGEST_PBUFFER:
       
   745                     {
       
   746                     largestPbuffer = value;
       
   747                     break;
       
   748                     }
       
   749 
       
   750                 case EGL_TEXTURE_FORMAT:
       
   751                     {
       
   752                     if( !(renderableType & EGL_OPENGL_ES_BIT) &&
       
   753                         !(renderableType & EGL_OPENGL_ES2_BIT) ||
       
   754                         (value != EGL_TEXTURE_RGB &&
       
   755                          value != EGL_TEXTURE_RGBA &&
       
   756                          value != EGL_NO_TEXTURE) )
       
   757                         {
       
   758                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
   759                         }
       
   760                     textureFormat = value;
       
   761                     break;
       
   762                     }
       
   763 
       
   764                 case EGL_TEXTURE_TARGET:
       
   765                     {
       
   766                     if( !(renderableType & EGL_OPENGL_ES_BIT) &&
       
   767                         !(renderableType & EGL_OPENGL_ES2_BIT) ||
       
   768                         (value != EGL_TEXTURE_2D &&
       
   769                          value != EGL_NO_TEXTURE) )
       
   770                         {
       
   771                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
   772                         }
       
   773                     textureTarget = value;
       
   774                     break;
       
   775                     }
       
   776 
       
   777                 case EGL_MIPMAP_TEXTURE:
       
   778                     {
       
   779                     if( !(renderableType & EGL_OPENGL_ES_BIT) ||
       
   780                         !(renderableType & EGL_OPENGL_ES2_BIT) )
       
   781                         {
       
   782                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
   783                         }
       
   784                     mipmapTexture = value;
       
   785                     break;
       
   786                     }
       
   787 
       
   788                 case EGL_VG_COLORSPACE:
       
   789                     {
       
   790                     if( !(renderableType & EGL_OPENVG_BIT) ||
       
   791                         (value != EGL_VG_COLORSPACE_sRGB &&
       
   792                          value != EGL_VG_COLORSPACE_LINEAR) )
       
   793                         {
       
   794                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
   795                         }
       
   796                     colorSpace = value;
       
   797                     break;
       
   798                     }
       
   799 
       
   800                 case EGL_VG_ALPHA_FORMAT:
       
   801                     {
       
   802                     if( !(renderableType & EGL_OPENVG_BIT) ||
       
   803                         (value != EGL_VG_ALPHA_FORMAT_PRE &&
       
   804                          value != EGL_VG_ALPHA_FORMAT_NONPRE) )
       
   805                         {
       
   806                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
   807                         }
       
   808                     alphaFormat = value;
       
   809                     break;
       
   810                     }
       
   811 
       
   812                 default:
       
   813                     EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
   814                 }
       
   815             }
       
   816         }
       
   817 
       
   818     if( (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE) ||
       
   819         (textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) )
       
   820         {
       
   821         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_MATCH );
       
   822         }
       
   823 
       
   824     CEGLPbufferSurface* surface = EGLI_NEW CEGLPbufferSurface( colorSpace, alphaFormat,
       
   825         EGL_BACK_BUFFER, config, largestPbuffer, textureFormat, textureTarget, mipmapTexture );
       
   826     // \note AddSurface() will destroy the object if it fails to take ownership
       
   827     surface = (CEGLPbufferSurface*)display->AddSurface( surface );
       
   828     if( !surface )
       
   829         {
       
   830         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
   831         }
       
   832     if( !(surface->Resize(width, height)) )
       
   833         {
       
   834         display->RemoveSurface( surface );
       
   835         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
   836         }
       
   837     // \todo refactor all this surface creation stuff
       
   838     if( (renderableType & EGL_OPENVG_BIT) && (state->SupportedApis() & EGL_OPENVG_BIT) )
       
   839         {
       
   840         // \todo Delay surface creation until needed.
       
   841         // \todo largest Pbuffer
       
   842         if( !(state->VGInterface()->CreateSurface( surface->Descriptor(), surface->VGBuffers(), NULL )) )
       
   843             {
       
   844             // \note RemoveSurface() will destroy the object
       
   845             display->RemoveSurface( surface );
       
   846             EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
   847             }
       
   848         }
       
   849 
       
   850     if( renderableType & EGL_OPENGL_ES_BIT && (state->SupportedApis() & EGL_OPENGL_ES_BIT) )
       
   851         {
       
   852         struct EGLINativePbufferContainer* nativePbuffer = CEGLOs::CreateNativePbuffer( display->NativeType(),
       
   853             *config, width, height, largestPbuffer, textureFormat, textureTarget );
       
   854         if( !nativePbuffer )
       
   855             {
       
   856             if( surface->VGClientSurface() )
       
   857                 {
       
   858                 state->VGInterface()->ReleaseSurface( surface->VGClientSurface() );
       
   859                 }
       
   860             // \note RemoveSurface() will destroy the object
       
   861             display->RemoveSurface( surface );
       
   862             EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
   863             }
       
   864         surface->SetNativePbufferContainer( nativePbuffer );
       
   865         }
       
   866 
       
   867     if( renderableType & EGL_OPENGL_ES2_BIT && (state->SupportedApis() & EGL_OPENGL_ES2_BIT) )
       
   868         {
       
   869         struct EGLINativePbufferContainer* nativePbuffer = CEGLOs::CreateNativePbuffer( display->NativeType(),
       
   870             *config, width, height, largestPbuffer, textureFormat, textureTarget );
       
   871         if( !nativePbuffer )
       
   872             {
       
   873             if( surface->VGClientSurface() )
       
   874                 {
       
   875                 state->VGInterface()->ReleaseSurface( surface->VGClientSurface() );
       
   876                 }
       
   877             // \note RemoveSurface() will destroy the object
       
   878             display->RemoveSurface( surface );
       
   879             EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
   880             }
       
   881         surface->SetNativePbufferContainer( nativePbuffer );
       
   882         }
       
   883 
       
   884     surface->AddRef();
       
   885 
       
   886     EGLI_LEAVE_RET( (EGLSurface)surface, EGL_SUCCESS );
       
   887     }
       
   888 
       
   889 EGLAPI EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
       
   890 				  EGLNativePixmapType pixmap,
       
   891 				  const EGLint *attrib_list)
       
   892     {
       
   893     EGLI_ENTER_RET( EGL_NO_SURFACE );
       
   894     // eglCreatePixmapSurface – EGL_BAD_MATCH raised (as no pixmap-supporting configs)
       
   895     EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_MATCH );
       
   896     }
       
   897 
       
   898 EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surfaceId)
       
   899     {
       
   900     EGLI_ENTER_RET( EGL_FALSE );
       
   901     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
   902     CEGLSurface* surface = display->GetSurface( surfaceId );
       
   903     if( !surface )
       
   904         {
       
   905         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
   906         }
       
   907 
       
   908     // \note EGLI_ENTER_RET macro will fail if thread allocation didn't succeed
       
   909     CEGLThread* thread = getThread();
       
   910 
       
   911     surface->Lock();
       
   912     //TODO: client apis
       
   913     if( surface->RemoveRef() )
       
   914         {
       
   915         if( surface->VGClientSurface() )
       
   916             {
       
   917             if( !(state->VGInterface()->ReleaseSurface(surface->VGClientSurface())) )
       
   918                 {
       
   919                 // need to add reference because surface is still alive
       
   920                 surface->AddRef();
       
   921                 surface->Unlock();
       
   922                 // \todo error code?
       
   923                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ACCESS );
       
   924                 }
       
   925             }
       
   926         // \note RemoveSurface() will destroy the object
       
   927         display->RemoveSurface( surface );
       
   928         surface = NULL;
       
   929         }
       
   930     else
       
   931         {
       
   932         surface->Terminate();
       
   933         }
       
   934     if( surface ) surface->Unlock();
       
   935     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
   936     }
       
   937 
       
   938 EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surfaceId,
       
   939 				  EGLint attribute, EGLint *value)
       
   940     {
       
   941     EGLI_ENTER_RET( EGL_FALSE );
       
   942     if( !value )
       
   943         {
       
   944         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_PARAMETER );
       
   945         }
       
   946     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
   947     
       
   948     CEGLSurface* surface = display->GetSurface( surfaceId );
       
   949     if( !surface )
       
   950         {
       
   951         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
   952         }
       
   953     surface->Lock();
       
   954     EGLint ret = EGL_BAD_ATTRIBUTE;
       
   955     switch( attribute )
       
   956         {
       
   957         case EGL_VG_ALPHA_FORMAT:
       
   958             {
       
   959             ret = surface->AlphaFormat();
       
   960             break;
       
   961             }
       
   962         case EGL_VG_COLORSPACE:
       
   963             {
       
   964             ret = surface->ColorSpace();
       
   965             break;
       
   966             }
       
   967         case EGL_CONFIG_ID:
       
   968             {
       
   969             ret = surface->Config()->Id();
       
   970             break;
       
   971             }
       
   972         case EGL_HEIGHT:
       
   973             {
       
   974             ret = surface->Height();
       
   975             break;
       
   976             }
       
   977         case EGL_WIDTH:
       
   978             {
       
   979             ret = surface->Width();
       
   980             break;
       
   981             }
       
   982         case EGL_HORIZONTAL_RESOLUTION:
       
   983             {
       
   984             if( surface->Type() == CEGLSurface::WINDOW_SURFACE )
       
   985                 {
       
   986                 //TODO
       
   987                 EGLI_ASSERT( false );
       
   988                 }
       
   989             else
       
   990                 {
       
   991                 ret = EGL_UNKNOWN;
       
   992                 }
       
   993             break;
       
   994             }
       
   995         case EGL_VERTICAL_RESOLUTION:
       
   996             {
       
   997             if( surface->Type() == CEGLSurface::WINDOW_SURFACE )
       
   998                 {
       
   999                 //TODO
       
  1000                 EGLI_ASSERT( false );
       
  1001                 }
       
  1002             else
       
  1003                 {
       
  1004                 ret = EGL_UNKNOWN;
       
  1005                 }
       
  1006             break;
       
  1007             }
       
  1008         case EGL_PIXEL_ASPECT_RATIO:
       
  1009             {
       
  1010             if( surface->Type() == CEGLSurface::WINDOW_SURFACE )
       
  1011                 {
       
  1012                 //TODO
       
  1013                 EGLI_ASSERT( false );
       
  1014                 }
       
  1015             else
       
  1016                 {
       
  1017                 ret = EGL_UNKNOWN;
       
  1018                 }
       
  1019             break;
       
  1020             }
       
  1021         case EGL_LARGEST_PBUFFER:
       
  1022             {
       
  1023             if( surface->Type() == CEGLSurface::PBUFFER_SURFACE )
       
  1024                 {
       
  1025                 ret = ((CEGLPbufferSurface*)surface)->IsLargestPbuffer();
       
  1026                 }            
       
  1027             break;
       
  1028             }
       
  1029         case EGL_MIPMAP_TEXTURE:
       
  1030             {
       
  1031             if( surface->Type() == CEGLSurface::PBUFFER_SURFACE )
       
  1032                 {
       
  1033 				ret = ((CEGLPbufferSurface*)surface)->MipmapTexture();
       
  1034                 }
       
  1035             break;
       
  1036             }
       
  1037         case EGL_MIPMAP_LEVEL:
       
  1038             {
       
  1039             if( surface->Type() == CEGLSurface::PBUFFER_SURFACE )
       
  1040                 {
       
  1041                 ret = surface->MipmapLevel();
       
  1042                 }
       
  1043             break;
       
  1044             }
       
  1045         case EGL_MULTISAMPLE_RESOLVE:
       
  1046             {
       
  1047             ret = surface->MultisampleResolve();
       
  1048             break;
       
  1049             }
       
  1050         case EGL_RENDER_BUFFER:
       
  1051             {
       
  1052             ret = surface->RenderBuffer();
       
  1053             break;
       
  1054             }
       
  1055         case EGL_SWAP_BEHAVIOR:
       
  1056             {
       
  1057             ret = surface->SwapBehavior();
       
  1058             break;
       
  1059             }
       
  1060         case EGL_TEXTURE_FORMAT:
       
  1061             {
       
  1062             if( surface->Type() == CEGLSurface::PBUFFER_SURFACE )
       
  1063                 {
       
  1064 				ret = ((CEGLPbufferSurface*)surface)->TextureFormat();
       
  1065                 }
       
  1066             break;
       
  1067             }
       
  1068         case EGL_TEXTURE_TARGET:
       
  1069             {
       
  1070             if( surface->Type() == CEGLSurface::PBUFFER_SURFACE )
       
  1071                 {
       
  1072                 ret = ((CEGLPbufferSurface*)surface)->TextureTarget();
       
  1073                 }
       
  1074             break;
       
  1075             }
       
  1076         default:
       
  1077             {
       
  1078             surface->Unlock();
       
  1079             EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ATTRIBUTE );
       
  1080             }
       
  1081         }
       
  1082     *value = ret;
       
  1083     surface->Unlock();
       
  1084     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  1085     }
       
  1086 
       
  1087 
       
  1088 EGLAPI EGLBoolean EGLAPIENTRY eglBindAPI(EGLenum api)
       
  1089     {    
       
  1090     CEGLThread* thread = getThread();
       
  1091     EGLI_ASSERT( thread != NULL );
       
  1092     
       
  1093     if( thread && thread->IsSupportedApi( api ) )
       
  1094         {
       
  1095         thread->SetApi( api );
       
  1096         thread->SetError( EGL_SUCCESS );
       
  1097         return EGL_TRUE;        
       
  1098         }
       
  1099     else if( thread )
       
  1100         {
       
  1101         thread->SetError( EGL_BAD_PARAMETER );
       
  1102         }
       
  1103     return EGL_FALSE;
       
  1104     }
       
  1105 
       
  1106 EGLAPI EGLenum EGLAPIENTRY eglQueryAPI(void)
       
  1107     {    
       
  1108     CEGLThread* thread = getThread();
       
  1109     EGLI_ASSERT( thread != NULL );
       
  1110     
       
  1111     EGLenum api = EGL_NONE;
       
  1112     if( thread )
       
  1113         {
       
  1114         api = thread->CurrentApi();
       
  1115         thread->SetError( EGL_SUCCESS );
       
  1116         }
       
  1117     return api;
       
  1118     }
       
  1119 
       
  1120 EGLAPI EGLBoolean EGLAPIENTRY eglWaitClient(void)
       
  1121     {
       
  1122     EGLI_ENTER_RET( EGL_FALSE );    
       
  1123     // Macro above fails if thread is not available.
       
  1124     CEGLThread* thread = getThread();
       
  1125 
       
  1126     switch( thread->CurrentApi() )
       
  1127         {
       
  1128         case EGL_OPENVG_API:
       
  1129             {
       
  1130             if( !(thread->CurrentVGSurface()) )
       
  1131                 {
       
  1132                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_CURRENT_SURFACE );
       
  1133                 }
       
  1134             if( !(thread->CurrentVGContext()) )
       
  1135                 {
       
  1136                 EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  1137                 }
       
  1138             if( !(state->VGInterface()) )
       
  1139                 {
       
  1140                 // \todo error code?
       
  1141                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ACCESS );
       
  1142                 }
       
  1143             state->VGInterface()->Finish();
       
  1144             break;
       
  1145             }
       
  1146         case EGL_OPENGL_ES_API:
       
  1147             {
       
  1148             CEGLSurface* read = NULL;
       
  1149             CEGLSurface* draw = NULL;
       
  1150             thread->CurrentGLESSurfaces( &read, &draw );
       
  1151             if( !read || !draw )
       
  1152                 {
       
  1153                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_CURRENT_SURFACE );
       
  1154                 }
       
  1155             if( !(thread->CurrentGLESContext()) )
       
  1156                 {
       
  1157                 EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  1158                 }
       
  1159 			state->GLESInterface( thread->CurrentGLESContext()->ClientVersion() )->Finish();
       
  1160             break;
       
  1161             }
       
  1162         }
       
  1163     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  1164     }
       
  1165 
       
  1166 EGLAPI EGLBoolean EGLAPIENTRY eglReleaseThread(void)
       
  1167     {
       
  1168 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
  1169 #if defined(_WIN32)
       
  1170     EGLI_ASSERT( g_tlsIndex != TLS_OUT_OF_INDEXES );
       
  1171     if( TlsGetValue( g_tlsIndex ) == NULL )
       
  1172         {
       
  1173         // Already released or first call => success
       
  1174         return EGL_TRUE;
       
  1175         }
       
  1176 #else // Linux
       
  1177     // \todo
       
  1178     EGLI_ASSERT( false );
       
  1179 #endif
       
  1180 #else
       
  1181     EGLI_ENTER_RET( EGL_FALSE );
       
  1182 #endif //EGLI_USE_PLATSIM_EXTENSIONS
       
  1183 
       
  1184     CEGLThread* thread = getThread();
       
  1185     EGLenum api = thread->CurrentApi();
       
  1186     if( thread->CurrentVGContext() )
       
  1187         {
       
  1188         const CEGLDisplay* display = thread->CurrentVGContext()->Display();
       
  1189         EGLI_ASSERT( display );
       
  1190         thread->SetApi( EGL_OPENVG_API );
       
  1191         eglMakeCurrent( (EGLDisplay)display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
       
  1192         }
       
  1193     if( thread->CurrentGLESContext() )
       
  1194         {
       
  1195         const CEGLDisplay* display = thread->CurrentGLESContext()->Display();
       
  1196         EGLI_ASSERT( display );
       
  1197         thread->SetApi( EGL_OPENGL_ES_API );
       
  1198         eglMakeCurrent( (EGLDisplay)display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
       
  1199         }
       
  1200     thread->SetApi( api );
       
  1201 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
  1202     process->RemoveThread( thread->Id() );
       
  1203     if( process->ThreadCount() == 0 )
       
  1204         {
       
  1205         // All threads destroyed from process => it's not a process any more
       
  1206         state->RemoveProcess( process->Id() );
       
  1207         process = NULL;
       
  1208         }
       
  1209 #else
       
  1210     releaseState();
       
  1211 #endif
       
  1212     return EGL_TRUE;
       
  1213     }
       
  1214 
       
  1215 EGLAPI EGLSurface EGLAPIENTRY eglCreatePbufferFromClientBuffer(
       
  1216 	      EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer,
       
  1217 	      EGLConfig configId, const EGLint *attrib_list)
       
  1218     {
       
  1219     // \todo combine with eglCreatePbufferSurface()
       
  1220     EGLI_ENTER_RET( EGL_NO_SURFACE );
       
  1221     EGLI_GET_DISPLAY_RET( dpy, EGL_NO_SURFACE );
       
  1222     
       
  1223     // EGLI_ENTER_RET macro above will fail if thread is not available
       
  1224     CEGLThread* thread = getThread();
       
  1225     switch( buftype )
       
  1226         {
       
  1227         case EGL_OPENVG_IMAGE:
       
  1228             {
       
  1229             if( !(thread->CurrentVGContext()) )
       
  1230                 {
       
  1231                 EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ACCESS );
       
  1232                 }
       
  1233             break;
       
  1234             }
       
  1235 
       
  1236         default:
       
  1237             EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_PARAMETER );
       
  1238         }
       
  1239 
       
  1240     CEGLConfig* config = state->GetConfig( configId );
       
  1241     if( !config )
       
  1242         {
       
  1243         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_CONFIG );
       
  1244         }
       
  1245     
       
  1246     if( !(state->VGInterface()) )
       
  1247         {
       
  1248         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
  1249         }
       
  1250 
       
  1251     CColorDescriptor colorDescriptor;
       
  1252     int width = 0;
       
  1253     int height = 0;
       
  1254     if( !(state->VGInterface()->IsValidImage(buffer, &colorDescriptor, &width, &height)) )
       
  1255         {
       
  1256         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_PARAMETER );
       
  1257         }
       
  1258     if( display->FindSurfaceByClientBuffer( buffer ) != NULL ||
       
  1259         state->VGInterface()->IsImageInUse( buffer ) )
       
  1260         {
       
  1261         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ACCESS );
       
  1262         }
       
  1263     if( !(colorDescriptor.MatchBitDepth(*(config->GetDescriptor()))) )
       
  1264         {
       
  1265         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_MATCH );
       
  1266         }
       
  1267     
       
  1268     EGLint textureFormat = EGL_NO_TEXTURE;
       
  1269     EGLint textureTarget = EGL_NO_TEXTURE;
       
  1270     EGLint mipmapTexture = EGL_FALSE;
       
  1271     EGLint largestPbuffer = EGL_FALSE;
       
  1272     EGLint colorSpace = colorDescriptor.isNonlinear() ? EGL_VG_COLORSPACE_sRGB : EGL_VG_COLORSPACE_LINEAR;
       
  1273     EGLint alphaFormat = colorDescriptor.isPremultiplied() ? EGL_VG_ALPHA_FORMAT_PRE : EGL_VG_ALPHA_FORMAT_NONPRE;
       
  1274     
       
  1275     EGLint renderableType = config->GetAttribute( EGL_RENDERABLE_TYPE );
       
  1276     if( attrib_list && attrib_list[0] != EGL_NONE )
       
  1277         {
       
  1278         for( int i=0; attrib_list[i] != EGL_NONE; i+=2 )
       
  1279             {
       
  1280             EGLint value = attrib_list[i+1];
       
  1281             switch( attrib_list[i] )
       
  1282                 {
       
  1283                 case EGL_TEXTURE_FORMAT:
       
  1284                     {
       
  1285                     if( !(renderableType & EGL_OPENGL_ES_BIT) &&
       
  1286                         !(renderableType & EGL_OPENGL_ES2_BIT) ||
       
  1287                         (value != EGL_TEXTURE_RGB &&
       
  1288                          value != EGL_TEXTURE_RGBA &&
       
  1289                          value != EGL_NO_TEXTURE) )
       
  1290                         {
       
  1291                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
  1292                         }
       
  1293                     textureFormat = value;
       
  1294                     break;
       
  1295                     }
       
  1296 
       
  1297                 case EGL_TEXTURE_TARGET:
       
  1298                     {
       
  1299                     if( !(renderableType & EGL_OPENGL_ES_BIT) &&
       
  1300                         !(renderableType & EGL_OPENGL_ES2_BIT) ||
       
  1301                         (value != EGL_TEXTURE_2D &&
       
  1302                          value != EGL_NO_TEXTURE) )
       
  1303                         {
       
  1304                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
  1305                         }
       
  1306                     textureTarget = value;
       
  1307                     break;
       
  1308                     }
       
  1309 
       
  1310                 case EGL_MIPMAP_TEXTURE:
       
  1311                     {
       
  1312                     if( !(renderableType & EGL_OPENGL_ES_BIT) ||
       
  1313                         !(renderableType & EGL_OPENGL_ES2_BIT) )
       
  1314                         {
       
  1315                         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
  1316                         }
       
  1317                     mipmapTexture = value;
       
  1318                     break;
       
  1319                     }
       
  1320 
       
  1321                 default:
       
  1322                     EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ATTRIBUTE );
       
  1323                 }
       
  1324             }
       
  1325         }
       
  1326 
       
  1327     if( (textureFormat == EGL_NO_TEXTURE && textureTarget != EGL_NO_TEXTURE) ||
       
  1328         (textureFormat != EGL_NO_TEXTURE && textureTarget == EGL_NO_TEXTURE) )
       
  1329         {
       
  1330         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_MATCH );
       
  1331         }
       
  1332 
       
  1333     CEGLPbufferSurface* surface = EGLI_NEW CEGLPbufferSurface( colorSpace, alphaFormat,
       
  1334         EGL_BACK_BUFFER, config, largestPbuffer, textureFormat, textureTarget, mipmapTexture, buffer );
       
  1335     if( !surface )
       
  1336         {
       
  1337         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
  1338         }
       
  1339     // \note AddSurface() will destroy the object if it fails to take ownership
       
  1340     surface = (CEGLPbufferSurface*)display->AddSurface( surface );
       
  1341     if( !surface )
       
  1342         {
       
  1343         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
  1344         }
       
  1345     if( !(surface->Resize(width, height)) )
       
  1346         {
       
  1347         display->RemoveSurface( surface );
       
  1348         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
  1349         }
       
  1350     
       
  1351     if( !(state->VGInterface()->CreateSurface(surface->Descriptor(), surface->VGBuffers(), buffer)) )
       
  1352         {
       
  1353         // \note RemoveSurface() will destroy the object
       
  1354         display->RemoveSurface( surface );
       
  1355         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_ALLOC );
       
  1356         }
       
  1357     surface->AddRef();
       
  1358     
       
  1359     EGLI_LEAVE_RET( surface, EGL_SUCCESS );
       
  1360     }
       
  1361 
       
  1362 EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surfaceId,
       
  1363 			    EGLint attribute, EGLint value)
       
  1364     {
       
  1365     EGLI_ENTER_RET( EGL_FALSE );
       
  1366     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
  1367     CEGLSurface* surface = display->GetSurface( surfaceId );
       
  1368     if( !surface )
       
  1369         {
       
  1370         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  1371         }
       
  1372     surface->Lock();
       
  1373     switch( attribute )
       
  1374         {
       
  1375         case EGL_MIPMAP_LEVEL:
       
  1376             {
       
  1377             if( !(surface->Config()->GetAttribute( EGL_RENDERABLE_TYPE ) & EGL_OPENGL_ES_BIT ))
       
  1378                 {
       
  1379                 surface->Unlock();
       
  1380                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_PARAMETER );
       
  1381                 }
       
  1382             break;
       
  1383             }
       
  1384         case EGL_MULTISAMPLE_RESOLVE:
       
  1385             {
       
  1386 			bool hasBoxBit = !!(surface->Config()->GetAttribute( EGL_SURFACE_TYPE ) & EGL_MULTISAMPLE_RESOLVE_BOX_BIT );
       
  1387             if( value != EGL_MULTISAMPLE_RESOLVE_BOX ||
       
  1388                 value != EGL_MULTISAMPLE_RESOLVE_DEFAULT )
       
  1389                 {
       
  1390                 surface->Unlock();
       
  1391                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ATTRIBUTE );
       
  1392                 } 
       
  1393             else if( value == EGL_MULTISAMPLE_RESOLVE_BOX && !hasBoxBit )
       
  1394                 {
       
  1395                 surface->Unlock();
       
  1396                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_MATCH );
       
  1397                 }
       
  1398             break;
       
  1399             }
       
  1400         case EGL_SWAP_BEHAVIOR:
       
  1401             {
       
  1402 			bool hasPreservedBit = !!(surface->Config()->GetAttribute( EGL_SURFACE_TYPE ) & EGL_SWAP_BEHAVIOR_PRESERVED_BIT );
       
  1403             if( value != EGL_BUFFER_PRESERVED ||
       
  1404                 value != EGL_BUFFER_DESTROYED )
       
  1405                 {
       
  1406                 surface->Unlock();
       
  1407                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ATTRIBUTE );
       
  1408                 }
       
  1409             else if( value == EGL_BUFFER_PRESERVED && !hasPreservedBit )
       
  1410                 {
       
  1411                 surface->Unlock();
       
  1412                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_MATCH );
       
  1413                 }
       
  1414             break;
       
  1415             }
       
  1416         default:
       
  1417             {
       
  1418             surface->Unlock();
       
  1419             EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ATTRIBUTE );
       
  1420             }
       
  1421 
       
  1422         }
       
  1423     surface->SetAttribute( attribute, value );
       
  1424     surface->Unlock();
       
  1425     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  1426     }
       
  1427 
       
  1428 EGLAPI EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surfaceId, EGLint buffer)
       
  1429     {
       
  1430     EGLI_ENTER_RET( EGL_FALSE );
       
  1431     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
  1432 
       
  1433     // EGLI_ENTER_RET macro above will fail if thread is not available
       
  1434     CEGLThread* thread = getThread();
       
  1435 
       
  1436     CEGLSurface* surface = display->GetSurface( surfaceId );
       
  1437     if( !surface )
       
  1438         {
       
  1439         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  1440         }
       
  1441 
       
  1442     if( buffer != EGL_BACK_BUFFER )
       
  1443         {
       
  1444         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_PARAMETER );
       
  1445         }
       
  1446 
       
  1447 	if( thread->CurrentGLESContext() == NULL)
       
  1448 		{
       
  1449 		EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  1450 		}
       
  1451 
       
  1452 	if( surface->IsLocked() )
       
  1453 		{
       
  1454 		EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ACCESS );
       
  1455 		}
       
  1456 	surface->Lock();
       
  1457 
       
  1458 	CEGLSurface* glesReadSurface;
       
  1459 	thread->CurrentGLESSurfaces( &glesReadSurface, NULL );
       
  1460 	state->SyncSurface( EGL_OPENVG_API, 0, surface, glesReadSurface );
       
  1461 
       
  1462     EGLint renderableType = surface->Config()->GetAttribute( EGL_RENDERABLE_TYPE );
       
  1463 
       
  1464     if( (!(renderableType & EGL_OPENGL_ES_BIT) && !(renderableType & EGL_OPENGL_ES2_BIT)) ||
       
  1465         surface->Type() != CEGLSurface::PBUFFER_SURFACE ||
       
  1466         (surface->Config()->GetAttribute( EGL_BIND_TO_TEXTURE_RGB ) == EGL_FALSE &&
       
  1467          surface->Config()->GetAttribute( EGL_BIND_TO_TEXTURE_RGBA ) == EGL_FALSE ) )
       
  1468         {
       
  1469         surface->Unlock();
       
  1470         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  1471         }
       
  1472     if( ((CEGLPbufferSurface*)surface)->TextureFormat() == EGL_NO_TEXTURE )
       
  1473         {
       
  1474         surface->Unlock();
       
  1475         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_MATCH );
       
  1476         }
       
  1477 	bool mipmapTexture = !!((CEGLPbufferSurface*)surface)->MipmapTexture();
       
  1478 	IEGLtoGLESInterface* iFace = state->GLESInterface( thread->CurrentGLESContext()->ClientVersion() );
       
  1479 	if( surface->BoundContext() == thread->CurrentGLESContext() )
       
  1480 		{
       
  1481 		iFace->Flush();
       
  1482 		}
       
  1483 	else
       
  1484 		{
       
  1485 		// \todo Wait for all issued client API commands drawing to the surface to complete.
       
  1486 		}
       
  1487 	int level = surface->Attribute( EGL_MIPMAP_LEVEL );
       
  1488 	int textureName = iFace->BindTexImage( surface, level, mipmapTexture, surface->Descriptor(), surface->VGColorBuffer());
       
  1489 	EGLITextureBinding& binding = surface->TextureBinding();
       
  1490 	binding.name = textureName;
       
  1491 	binding.level = level;
       
  1492 	binding.clientVersion = thread->CurrentGLESContext()->ClientVersion();
       
  1493 	binding.context = eglGetCurrentContext();
       
  1494     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  1495     }
       
  1496 
       
  1497 EGLAPI EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surfaceId, EGLint buffer)
       
  1498     {
       
  1499     EGLI_ENTER_RET( EGL_FALSE );
       
  1500     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
  1501 
       
  1502 	// EGLI_ENTER_RET macro above will fail if thread is not available
       
  1503     CEGLThread* thread = getThread();
       
  1504 
       
  1505     if( buffer != EGL_BACK_BUFFER )
       
  1506         {
       
  1507         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_PARAMETER );
       
  1508         }
       
  1509     CEGLSurface* surface = display->GetSurface( surfaceId );
       
  1510     // \todo errors etc.
       
  1511     if( !surface || (surface && surface->Type() != CEGLSurface::PBUFFER_SURFACE) )
       
  1512         {
       
  1513         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  1514         }
       
  1515     if( ((CEGLPbufferSurface*)surface)->TextureFormat() == EGL_NO_TEXTURE )
       
  1516         {
       
  1517         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_MATCH );
       
  1518         }
       
  1519 
       
  1520 	EGLITextureBinding& binding = surface->TextureBinding();
       
  1521 
       
  1522 	if( display->GetContext( binding.context ))
       
  1523 		{
       
  1524 		EGLenum origAPI = eglQueryAPI();
       
  1525 		EGLSurface origReadSurface, origDrawSurface;
       
  1526 		EGLContext origContext;
       
  1527 		bool switchAPI = origAPI == EGL_OPENGL_ES_API;
       
  1528 		bool switchContext = binding.context != thread->CurrentGLESContext();
       
  1529 		if( switchAPI )
       
  1530 			{
       
  1531 			eglBindAPI( EGL_OPENGL_ES_API );
       
  1532 			}
       
  1533 		if( switchContext )
       
  1534 			{
       
  1535 			// Switch to the context where the texture lives.
       
  1536 			origReadSurface = eglGetCurrentSurface(EGL_READ);
       
  1537 			origDrawSurface = eglGetCurrentSurface(EGL_DRAW);
       
  1538 			origContext = eglGetCurrentContext();
       
  1539 			eglMakeCurrent( display, surfaceId, surfaceId, binding.context );
       
  1540 			}
       
  1541 		state->GLESInterface(binding.clientVersion)->ReleaseTexImage( binding.name, binding.level );
       
  1542 		if( switchContext )
       
  1543 			{
       
  1544 			// Switch back to the original context.
       
  1545 			eglMakeCurrent( display, origDrawSurface, origReadSurface, origContext );
       
  1546 			}
       
  1547 		if( switchAPI )
       
  1548 			{
       
  1549 			eglBindAPI( origAPI );
       
  1550 			}
       
  1551 		}
       
  1552 	else
       
  1553 		{
       
  1554 		// The context has been destroyed. Ignore the call.
       
  1555 		}
       
  1556 	binding.name = 0;
       
  1557 	surface->Unlock();
       
  1558 
       
  1559     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  1560     }
       
  1561 
       
  1562 EGLAPI EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval)
       
  1563     {
       
  1564     EGLI_ENTER_RET( EGL_FALSE );
       
  1565     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
  1566     CEGLThread* thread = process->CurrentThread();
       
  1567     EGLI_ASSERT( thread != NULL );
       
  1568     
       
  1569     if( !(thread->CurrentVGContext()) )
       
  1570         {
       
  1571         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_CONTEXT );
       
  1572         }
       
  1573     if( !(thread->CurrentVGSurface()) )
       
  1574         {
       
  1575         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  1576         }
       
  1577     // eglSwapInterval – hardcode EGL_MAX_SWAP_INTERVAL and EGL_MIN_SWAP_INTERVAL to 1, so nothing here
       
  1578     if( thread->CurrentVGSurface()->Type() == CEGLSurface::WINDOW_SURFACE )
       
  1579         {
       
  1580         ((CEGLWindowSurface*)thread->CurrentVGSurface())->SetSwapInterval( /*interval*/ 1 );
       
  1581         }
       
  1582 
       
  1583     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  1584     }
       
  1585 
       
  1586 EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig configId,
       
  1587 			    EGLContext share_context,
       
  1588 			    const EGLint *attrib_list)
       
  1589     {
       
  1590     EGLI_ENTER_RET( EGL_NO_CONTEXT );
       
  1591     EGLI_GET_DISPLAY_RET( dpy, EGL_NO_CONTEXT );
       
  1592 
       
  1593     CEGLConfig* config = state->GetConfig( configId );
       
  1594     if( !config )
       
  1595         {
       
  1596         EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_CONFIG );
       
  1597         }
       
  1598 
       
  1599     CEGLThread* thread = process->CurrentThread();
       
  1600     EGLI_ASSERT( thread != NULL );
       
  1601 
       
  1602     EGLenum currentApi = thread->CurrentApi();
       
  1603     if( currentApi == EGL_NONE )
       
  1604         {
       
  1605         EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_MATCH );
       
  1606         }
       
  1607     
       
  1608     CEGLContext* shareContext = NULL;
       
  1609     if( share_context != EGL_NO_CONTEXT )
       
  1610         {
       
  1611         shareContext = display->GetContext( share_context );
       
  1612         if( !shareContext || (shareContext && process->Id() != shareContext->ProcessId()) )
       
  1613             {
       
  1614             EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_MATCH );
       
  1615             }
       
  1616         if( currentApi != shareContext->ClientApi() )
       
  1617             {
       
  1618             EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_CONTEXT );
       
  1619             }
       
  1620         }
       
  1621     
       
  1622     EGLint renderableType = config->GetAttribute( EGL_RENDERABLE_TYPE );
       
  1623     EGLint clientVersion = 1;
       
  1624     if( attrib_list && attrib_list[0] != EGL_NONE )
       
  1625         {
       
  1626         switch( attrib_list[0] )
       
  1627             {
       
  1628             case EGL_CONTEXT_CLIENT_VERSION:
       
  1629                 {
       
  1630                 if( currentApi != EGL_OPENGL_ES_API )
       
  1631                     {
       
  1632                     EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_ATTRIBUTE );
       
  1633                     }
       
  1634                 if( attrib_list[1] == 1 ) //GLES 1.1
       
  1635                     {
       
  1636                     if( !(renderableType & EGL_OPENGL_ES_BIT) )
       
  1637                         {
       
  1638                         EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_CONFIG );
       
  1639                         }
       
  1640                     clientVersion = 1;
       
  1641                     }
       
  1642                 else if( attrib_list[1] == 2 ) //GLES 2.0
       
  1643                     {
       
  1644                     if( !(renderableType & EGL_OPENGL_ES2_BIT) )
       
  1645                         {
       
  1646                         EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_CONFIG );
       
  1647                         }
       
  1648                     clientVersion = 2;
       
  1649                     }
       
  1650                 else
       
  1651                     {
       
  1652                     EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_ATTRIBUTE );
       
  1653                     }
       
  1654                 break;
       
  1655                 }
       
  1656 
       
  1657             default:
       
  1658                 {
       
  1659                 EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_ATTRIBUTE );
       
  1660                 break;
       
  1661                 }
       
  1662             }
       
  1663         }
       
  1664     
       
  1665     void* clientContext = NULL;
       
  1666     CEGLContext* context = NULL;
       
  1667     switch( currentApi )
       
  1668         {
       
  1669         case EGL_OPENVG_API:
       
  1670             {
       
  1671             EGLI_ASSERT( state->VGInterface() != NULL );
       
  1672             clientContext = state->VGInterface()->CreateContext( 
       
  1673                 shareContext != NULL ? shareContext->ClientContext() : shareContext );
       
  1674             if( clientContext )
       
  1675                 {
       
  1676                 context = EGLI_NEW CEGLContext( process->Id(), display, config, currentApi, clientVersion, clientContext );
       
  1677                 // \note AddContext() will destroy the object if it fails to take ownership
       
  1678                 context = display->AddContext( context );
       
  1679                 if( !context )
       
  1680                     {
       
  1681                     state->VGInterface()->ReleaseContext( clientContext );
       
  1682                     EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_ALLOC );
       
  1683                     }
       
  1684                 }
       
  1685             break;
       
  1686             }
       
  1687 
       
  1688         case EGL_OPENGL_ES_API:
       
  1689             {
       
  1690 			EGLINativeContextType nativeShareContext = shareContext != NULL ? shareContext->NativeContext() : NULL;
       
  1691 			EGLINativeContextType nativeContext = CEGLOs::CreateNativeContext( *config, display->NativeType(), nativeShareContext );
       
  1692             if( !nativeContext )
       
  1693                 {
       
  1694                 EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_ALLOC );
       
  1695                 }
       
  1696 
       
  1697 			IEGLtoGLESInterface* iFace = state->GLESInterface( clientVersion );
       
  1698 			EGLI_ASSERT( iFace != NULL );
       
  1699 			clientContext = state->GLESInterface( clientVersion )->CreateContext( nativeContext );
       
  1700 			if( clientContext )
       
  1701 		        {
       
  1702                 context = EGLI_NEW CEGLContext( process->Id(), display, config, currentApi, clientVersion, clientContext );
       
  1703                 if( context )
       
  1704                     // \note AddContext() will destroy the object if it fails to take ownership
       
  1705 		            context = display->AddContext( context );
       
  1706 		        if( !context )
       
  1707 			        {
       
  1708 			        iFace->ReleaseContext( clientContext );
       
  1709 					CEGLOs::DestroyNativeContext( nativeContext );
       
  1710                     EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_ALLOC );
       
  1711 			        }
       
  1712                 context->SetNativeContext( nativeContext );
       
  1713 		        }
       
  1714 	        else
       
  1715 		        {
       
  1716 				CEGLOs::DestroyNativeContext( nativeContext );
       
  1717                 EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_ALLOC );
       
  1718 				}
       
  1719 			break;
       
  1720 			}
       
  1721 
       
  1722         case EGL_NONE:
       
  1723             {
       
  1724             EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_MATCH );
       
  1725             break;
       
  1726             }
       
  1727         }
       
  1728     
       
  1729     if( context )
       
  1730         {
       
  1731         context->AddRef();
       
  1732         }
       
  1733     else
       
  1734         {
       
  1735         EGLI_LEAVE_RET( EGL_NO_CONTEXT, EGL_BAD_ALLOC );
       
  1736         }
       
  1737 
       
  1738     EGLI_LEAVE_RET( (EGLContext)context, EGL_SUCCESS );
       
  1739     }
       
  1740 
       
  1741 EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
       
  1742     {
       
  1743     EGLI_ENTER_RET( EGL_FALSE );
       
  1744     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
  1745 
       
  1746     CEGLThread* thread = process->CurrentThread();
       
  1747     EGLI_ASSERT( thread != NULL );
       
  1748 
       
  1749     CEGLContext* context = display->GetContext( ctx );
       
  1750     if( !context )
       
  1751         {
       
  1752         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_CONTEXT );
       
  1753         }
       
  1754 
       
  1755     EGLenum clientApi = context->ClientApi();
       
  1756     switch( clientApi )
       
  1757         {
       
  1758         case EGL_OPENVG_API:
       
  1759             {
       
  1760             if( context->RemoveRef() )
       
  1761                 {
       
  1762                 state->VGInterface()->ReleaseContext(context->ClientContext());
       
  1763                 // \note RemoveContext() will destroy the object
       
  1764                 display->RemoveContext( context );
       
  1765                 }
       
  1766             else
       
  1767                 {
       
  1768                 context->Terminate();
       
  1769                 }
       
  1770             break;
       
  1771             }
       
  1772 
       
  1773         case EGL_OPENGL_ES_API:
       
  1774             {
       
  1775             if( context->RemoveRef() )
       
  1776                 {
       
  1777 				if( !(state->GLESInterface( context->ClientVersion() )->ReleaseContext( context->ClientContext() )) )
       
  1778 					{
       
  1779 					// \todo Handle errors!
       
  1780                     EGLI_ASSERT( false );
       
  1781 					}
       
  1782                 if( context->NativeContext() && !(CEGLOs::DestroyNativeContext(context->NativeContext())) )
       
  1783                     {
       
  1784                     // \todo Handle errors!
       
  1785                     EGLI_ASSERT( false );
       
  1786                     }
       
  1787                 // \note RemoveContext() will destroy the object
       
  1788                 display->RemoveContext( context );
       
  1789                 }
       
  1790             else
       
  1791                 {
       
  1792                 context->Terminate();
       
  1793                 }
       
  1794             break;
       
  1795             }
       
  1796         }
       
  1797 
       
  1798     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  1799     }
       
  1800 
       
  1801 EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw,
       
  1802 			  EGLSurface read, EGLContext ctx)
       
  1803     {
       
  1804     EGLI_ENTER_RET( EGL_FALSE );
       
  1805     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
  1806 
       
  1807     CEGLThread* thread = process->CurrentThread();
       
  1808     EGLI_ASSERT( thread );
       
  1809     
       
  1810     bool releaseCurrent = ( draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE && ctx == EGL_NO_CONTEXT );
       
  1811     
       
  1812     if( (ctx == EGL_NO_CONTEXT && draw != EGL_NO_SURFACE && read != EGL_NO_SURFACE) ||
       
  1813         ((draw == EGL_NO_SURFACE || read == EGL_NO_SURFACE) && ctx != EGL_NO_CONTEXT) )
       
  1814         {
       
  1815         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_MATCH );
       
  1816         }
       
  1817     
       
  1818     CEGLContext* context = display->GetContext( ctx );
       
  1819     if( (!releaseCurrent && !context ) || (context && context->ProcessId() != process->Id()) )
       
  1820         {
       
  1821         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_CONTEXT );
       
  1822         }
       
  1823 
       
  1824     EGLenum currentApi = thread->CurrentApi();
       
  1825     CEGLContext* currentContext = NULL;
       
  1826     CEGLSurface* currentDrawSurface = NULL;
       
  1827     CEGLSurface* currentReadSurface = NULL;
       
  1828     CEGLSurface* drawSurface = NULL;
       
  1829     CEGLSurface* readSurface = NULL;
       
  1830 
       
  1831     if( !releaseCurrent )
       
  1832         {    
       
  1833         if( context && context->ClientApi() == EGL_OPENVG_API && ( draw != read ) )
       
  1834             {
       
  1835             EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_MATCH );
       
  1836             }
       
  1837         drawSurface = display->GetSurface( draw );
       
  1838         readSurface = display->GetSurface( read );
       
  1839         if( !drawSurface || !readSurface )
       
  1840             {
       
  1841             EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  1842             }
       
  1843 
       
  1844         if( !(context->Config()->IsCompatible( *(drawSurface->Config()), context->ClientApi())) ||
       
  1845             !(context->Config()->IsCompatible( *(readSurface->Config()), context->ClientApi())) )
       
  1846             {
       
  1847             EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_MATCH );
       
  1848             }
       
  1849 
       
  1850         if( (context->Thread() && context->Thread() != thread) ||
       
  1851             (drawSurface->BoundContext() && drawSurface->BoundContext()->Thread() != thread) ||
       
  1852             (readSurface->BoundContext() && readSurface->BoundContext()->Thread() != thread) )
       
  1853             {
       
  1854             EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ACCESS );
       
  1855             }
       
  1856 
       
  1857         if( drawSurface->Type() == CEGLSurface::WINDOW_SURFACE &&
       
  1858             !(CEGLOs::IsValidNativeWindow(((CEGLWindowSurface*)drawSurface)->NativeType())) )
       
  1859             {
       
  1860             EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_NATIVE_WINDOW );
       
  1861             }
       
  1862         if( readSurface != drawSurface && readSurface->Type() == CEGLSurface::WINDOW_SURFACE &&
       
  1863             !(CEGLOs::IsValidNativeWindow(((CEGLWindowSurface*)readSurface)->NativeType())) )
       
  1864             {
       
  1865             EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_NATIVE_WINDOW );
       
  1866             }
       
  1867 
       
  1868         // TODO: If binding ctx would exceed the number of current contexts of that client
       
  1869         //       API type supported by the implementation, an EGL_BAD_ACCESS error is
       
  1870         //       generated.
       
  1871 
       
  1872         // TODO: If either draw or read are pbuffers created with eglCreatePbufferFromClientBuffer,
       
  1873         //       and the underlying bound client API buffers are in use by the
       
  1874         //       client API that created them, an EGL_BAD_ACCESS error is generated        
       
  1875 
       
  1876         // TODO: If draw and read cannot fit into graphics memory simultaneously, an EGL_BAD_MATCH error is generated.
       
  1877 
       
  1878         // TODO: If the previous context of the calling thread has unflushed commands, and
       
  1879         //       the previous surface is no longer valid, an EGL_BAD_CURRENT_SURFACE
       
  1880         //       error is generated.
       
  1881 
       
  1882         // TODO: If the ancillary buffers for draw and read cannot be allocated, an EGL_BAD_ALLOC error is generated.
       
  1883 
       
  1884         // TODO: If a power management event has occurred, an EGL_CONTEXT_LOST error is generated.
       
  1885         
       
  1886         // TODO: flush context
       
  1887         switch( context->ClientApi() )
       
  1888             {
       
  1889             case EGL_OPENVG_API:
       
  1890                 {
       
  1891                 state->VGInterface()->Flush();
       
  1892                 currentContext = thread->SwitchVGContext( context );
       
  1893                 currentDrawSurface = thread->SwitchVGSurface( drawSurface );
       
  1894                 drawSurface->BindToContext( context );
       
  1895                 if( !(state->VGInterface()->SetCurrentSurface(context->ClientContext(), drawSurface->VGClientSurface())) )
       
  1896                     {
       
  1897                     // Restore previous context/surface
       
  1898                     thread->SwitchVGContext( currentContext );
       
  1899                     thread->SwitchVGSurface( currentDrawSurface );
       
  1900                     // \todo error code?
       
  1901                     EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ACCESS );
       
  1902                     }
       
  1903                 // \todo track changes through locking
       
  1904                 drawSurface->SetVGDirty( true );
       
  1905                 break;
       
  1906                 }
       
  1907 
       
  1908             case EGL_OPENGL_ES_API:
       
  1909                 {
       
  1910 				if( thread->CurrentGLESContext() )
       
  1911 					{
       
  1912 					state->GLESInterface(context->ClientVersion())->Flush();
       
  1913 					}
       
  1914                 currentContext = thread->SwitchGLESContext( context );
       
  1915                 thread->SwitchGLESSurfaces( drawSurface, readSurface, currentReadSurface, currentDrawSurface );
       
  1916 				drawSurface->BindToContext( context );
       
  1917                 if( drawSurface != readSurface )
       
  1918                     {
       
  1919                     readSurface->BindToContext( context );
       
  1920                     }
       
  1921 				EGLINativeContextType nativeContext = (EGLINativeContextType)state->GLESInterface(context->ClientVersion())->GetNativeContext( context->ClientContext() );
       
  1922                 if( !(context->NativeGLFunctions()) )
       
  1923                     {
       
  1924                     EGLINativeGLFunctions* nativeFuncs = EGLI_NEW EGLINativeGLFunctions;
       
  1925                     if( !nativeFuncs )
       
  1926                         {
       
  1927                         // Restore previous context/surface
       
  1928                         thread->SwitchGLESContext( currentContext );
       
  1929                         thread->SwitchGLESSurfaces( currentReadSurface, currentDrawSurface, readSurface, drawSurface );
       
  1930                         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ALLOC );
       
  1931                         }
       
  1932                     memset( nativeFuncs, 0, sizeof(EGLINativeGLFunctions) );
       
  1933                     if( !(CEGLOs::InitializeNativeGLFunctions(nativeFuncs, display->NativeType(), nativeContext)) )
       
  1934                         {
       
  1935                         // Restore previous context/surface
       
  1936                         thread->SwitchGLESContext( currentContext );
       
  1937                         thread->SwitchGLESSurfaces( currentReadSurface, currentDrawSurface, readSurface, drawSurface );
       
  1938                         delete nativeFuncs;
       
  1939                         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ALLOC );
       
  1940                         }
       
  1941                     context->SetNativeGLFucntions( nativeFuncs );
       
  1942                     }
       
  1943                 EGLINativeDisplayType drawDC = NULL;
       
  1944                 EGLINativeDisplayType readDC = NULL;
       
  1945                 if( drawSurface->Type() == CEGLSurface::PBUFFER_SURFACE ) 
       
  1946                     {
       
  1947                     drawDC = ((CEGLPbufferSurface*)drawSurface)->NativeDisplay();
       
  1948                     }
       
  1949                 else if( drawSurface->Type() == CEGLSurface::WINDOW_SURFACE )
       
  1950                     {
       
  1951                     drawDC = ((CEGLWindowSurface*)drawSurface)->OsContext()->glesDisplay;
       
  1952                     }
       
  1953 
       
  1954                 if( readSurface == drawSurface )
       
  1955                     {
       
  1956                     readDC = drawDC;
       
  1957                     }
       
  1958                 else if( readSurface->Type() == CEGLSurface::PBUFFER_SURFACE )
       
  1959                     {
       
  1960                     readDC = ((CEGLPbufferSurface*)readSurface)->NativeDisplay();
       
  1961                     }
       
  1962                 else if( readSurface->Type() == CEGLSurface::WINDOW_SURFACE )
       
  1963                     {
       
  1964                     readDC = ((CEGLWindowSurface*)readSurface)->OsContext()->glesDisplay;
       
  1965                     }
       
  1966 
       
  1967                 if( !(CEGLOs::MakeNativeContextCurrent(context->NativeGLFunctions(), drawDC, readDC, context->NativeContext())) )
       
  1968                     {
       
  1969                     // Restore previous context/surface. CEGLOs::MakeNativeContextCurrent() will restore previous
       
  1970                     // native context/surface on failure
       
  1971                     thread->SwitchGLESContext( currentContext );
       
  1972                     thread->SwitchGLESSurfaces( currentReadSurface, currentDrawSurface, readSurface, drawSurface );
       
  1973                     // \todo error code?
       
  1974                     EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ACCESS );
       
  1975                     }
       
  1976                 break;
       
  1977                 }
       
  1978 
       
  1979             default:
       
  1980                 {
       
  1981                 EGLI_ASSERT( false );
       
  1982                 break;
       
  1983                 }
       
  1984             }        
       
  1985         }
       
  1986     else
       
  1987         {
       
  1988         switch( currentApi )
       
  1989             {
       
  1990             case EGL_OPENVG_API:
       
  1991                 {
       
  1992                 state->VGInterface()->Flush();
       
  1993 				if( thread->CurrentGLESContext() )
       
  1994 					{
       
  1995 					// Sync surface before releasing the VG context because there
       
  1996 					// might not be a VG context if GLES locks the surface later.
       
  1997 					CEGLSurface* glesReadSurface;
       
  1998 					thread->CurrentGLESSurfaces( &glesReadSurface, NULL );
       
  1999 					state->SyncSurface( EGL_OPENGL_API, thread->CurrentGLESContext()->ClientVersion(), thread->CurrentVGSurface(), glesReadSurface );
       
  2000 					}
       
  2001                 currentContext = thread->SwitchVGContext( NULL );
       
  2002                 currentDrawSurface = thread->SwitchVGSurface( NULL );
       
  2003                 break;
       
  2004                 }
       
  2005 
       
  2006             case EGL_OPENGL_ES_API:
       
  2007                 {
       
  2008 				if( thread->CurrentGLESContext() )
       
  2009 					{
       
  2010 					state->GLESInterface(thread->CurrentGLESContext()->ClientVersion())->Flush();
       
  2011 					}
       
  2012 				if( thread->CurrentVGContext() )
       
  2013 					{
       
  2014 					// Sync surface before releasing the GLES context because there
       
  2015 					// might not be a GLES context if VG locks the surface later.
       
  2016 					CEGLSurface* glesReadSurface;
       
  2017 					CEGLSurface* glesDrawSurface;
       
  2018 					thread->CurrentGLESSurfaces( &glesReadSurface, &glesDrawSurface );
       
  2019 					state->SyncSurface( EGL_OPENVG_API, 0, glesReadSurface, glesReadSurface );
       
  2020 					if( glesDrawSurface != glesReadSurface )
       
  2021 						{
       
  2022 						state->SyncSurface( EGL_OPENVG_API, 0, glesDrawSurface, NULL );
       
  2023 						}
       
  2024 					}
       
  2025                 currentContext = thread->SwitchGLESContext( NULL );
       
  2026                 thread->SwitchGLESSurfaces( NULL, NULL, currentReadSurface, currentDrawSurface );
       
  2027                 break;
       
  2028                 }
       
  2029             }
       
  2030         }
       
  2031 
       
  2032     if( currentDrawSurface && currentDrawSurface != drawSurface )
       
  2033         {
       
  2034         currentDrawSurface->BindToContext( NULL );
       
  2035         if( currentDrawSurface->RemoveRef() )
       
  2036             {
       
  2037             if( currentDrawSurface->VGClientSurface() )
       
  2038                 {
       
  2039                 if( !(state->VGInterface()->ReleaseSurface(currentDrawSurface->VGClientSurface())) )
       
  2040                     {
       
  2041                     // \todo error code?
       
  2042                     EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ACCESS );
       
  2043                     }
       
  2044                 }
       
  2045             if( currentDrawSurface->Type() == CEGLSurface::PBUFFER_SURFACE )
       
  2046                 {
       
  2047                 //((CEGLPbufferSurface*)currentDrawSurface)->SetNativePbufferContainer( NULL );
       
  2048                 //EGLI_ASSERT( false );
       
  2049                 }
       
  2050             // \note RemoveSurface() will destroy the object
       
  2051             display->RemoveSurface( currentDrawSurface );
       
  2052             }
       
  2053         if( currentReadSurface == currentDrawSurface )
       
  2054             {
       
  2055             currentReadSurface = NULL;
       
  2056             }
       
  2057         currentDrawSurface = NULL;
       
  2058         }
       
  2059 
       
  2060     if( currentReadSurface && currentReadSurface != readSurface )
       
  2061         {
       
  2062         currentReadSurface->BindToContext( NULL );
       
  2063         if( currentReadSurface->RemoveRef() )
       
  2064             {
       
  2065             if( currentReadSurface->VGClientSurface() )
       
  2066                 {
       
  2067                 if( !(state->VGInterface()->ReleaseSurface(currentReadSurface->VGClientSurface())) )
       
  2068                     {
       
  2069                     // \todo error code?
       
  2070                     EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ACCESS );
       
  2071                     }
       
  2072                 }
       
  2073             if( currentReadSurface->Type() == CEGLSurface::PBUFFER_SURFACE )
       
  2074                 {
       
  2075                 // \todo 
       
  2076                 ((CEGLPbufferSurface*)currentReadSurface)->SetNativePbufferContainer( NULL );
       
  2077                 }
       
  2078             // \note RemoveSurface() will destroy the object
       
  2079             display->RemoveSurface( currentReadSurface );
       
  2080             }
       
  2081         }
       
  2082 
       
  2083     if( currentContext && currentContext != context )
       
  2084         {
       
  2085         currentContext->SetThread( NULL );
       
  2086         if( currentContext->RemoveRef() )
       
  2087             {
       
  2088             if( currentContext->ClientContext() )
       
  2089                 {
       
  2090                 if( currentContext->ClientApi() == EGL_OPENVG_API )
       
  2091                     {
       
  2092 					bool success = state->VGInterface()->ReleaseContext( currentContext->ClientContext() );
       
  2093                     EGLI_ASSERT( success );
       
  2094                     }
       
  2095                 if( currentContext->ClientApi() == EGL_OPENGL_ES_API )
       
  2096                     {
       
  2097 					bool success = state->GLESInterface(currentContext->ClientVersion())->ReleaseContext(currentContext->ClientContext());
       
  2098                     EGLI_ASSERT( success );
       
  2099                     }
       
  2100                 }
       
  2101             if( currentContext->NativeContext() )
       
  2102                 {
       
  2103                 if( !(CEGLOs::DestroyNativeContext(currentContext->NativeContext())) )
       
  2104                     {
       
  2105                     // \todo Handle errors!
       
  2106                     EGLI_ASSERT( false );
       
  2107                     }
       
  2108                 }
       
  2109             // \note RemoveContext() will destroy the object
       
  2110             display->RemoveContext( currentContext );
       
  2111             currentContext = NULL;
       
  2112             }
       
  2113         }
       
  2114     if( context && currentContext != context ) 
       
  2115         {
       
  2116         context->AddRef();
       
  2117         }
       
  2118     if( drawSurface && currentDrawSurface != drawSurface ) 
       
  2119         {
       
  2120         drawSurface->AddRef();
       
  2121         }
       
  2122     if( readSurface && readSurface != drawSurface && readSurface != currentReadSurface )
       
  2123         {
       
  2124         readSurface->AddRef();
       
  2125         }
       
  2126     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  2127     }
       
  2128 
       
  2129 
       
  2130 EGLAPI EGLContext EGLAPIENTRY eglGetCurrentContext(void)
       
  2131     {
       
  2132     EGLI_ENTER_RET( EGL_NO_CONTEXT );
       
  2133     CEGLThread* thread = process->CurrentThread();
       
  2134     EGLI_ASSERT( thread != NULL );
       
  2135     EGLContext ret = EGL_NO_CONTEXT;
       
  2136     switch( thread->CurrentApi() )
       
  2137         {
       
  2138         case EGL_OPENVG_API:
       
  2139             {
       
  2140             if( thread->CurrentVGContext() )
       
  2141                 {
       
  2142                 ret = thread->CurrentVGContext();
       
  2143                 }
       
  2144             break;
       
  2145             }
       
  2146         case EGL_OPENGL_ES_API:
       
  2147             {
       
  2148             if( thread->CurrentGLESContext() )
       
  2149                 {
       
  2150                 ret = thread->CurrentGLESContext();
       
  2151                 }
       
  2152             break;
       
  2153             }
       
  2154         }
       
  2155     EGLI_LEAVE_RET( ret, EGL_SUCCESS );
       
  2156     }
       
  2157 
       
  2158 EGLAPI EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw)
       
  2159     {    
       
  2160     EGLI_ENTER_RET( EGL_NO_SURFACE );
       
  2161     if( readdraw != EGL_READ && readdraw != EGL_DRAW )
       
  2162         {
       
  2163         EGLI_LEAVE_RET( EGL_NO_SURFACE, EGL_BAD_PARAMETER );
       
  2164         }
       
  2165 
       
  2166     CEGLThread* thread = process->CurrentThread();
       
  2167     EGLI_ASSERT( thread != NULL );
       
  2168 
       
  2169     EGLSurface ret = EGL_NO_SURFACE;
       
  2170     EGLenum currentApi = thread->CurrentApi();
       
  2171     switch( currentApi )
       
  2172         {
       
  2173         case EGL_OPENVG_API:
       
  2174             {
       
  2175             CEGLContext* context = thread->CurrentVGContext();
       
  2176             if( context )
       
  2177                 {
       
  2178                 ret = thread->CurrentVGSurface();
       
  2179                 }
       
  2180             break;
       
  2181             }
       
  2182 
       
  2183         case EGL_OPENGL_ES_API:
       
  2184             {
       
  2185             CEGLSurface* read = NULL;
       
  2186             CEGLSurface* draw = NULL;
       
  2187             thread->CurrentGLESSurfaces( &read, &draw );
       
  2188             switch( readdraw )
       
  2189                 {
       
  2190                 case EGL_READ:
       
  2191                     {
       
  2192                     ret = (EGLSurface)read;
       
  2193                     break;
       
  2194                     }
       
  2195 
       
  2196                 case EGL_DRAW:
       
  2197                     {
       
  2198                     ret = (EGLSurface)draw;
       
  2199                     break;
       
  2200                     }
       
  2201                 }
       
  2202             break;
       
  2203             }
       
  2204 
       
  2205         default:
       
  2206             {
       
  2207             EGLI_ASSERT( false );
       
  2208             }
       
  2209         }
       
  2210     EGLI_LEAVE_RET( ret, EGL_SUCCESS );
       
  2211     }
       
  2212 
       
  2213 EGLAPI EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void)
       
  2214     {
       
  2215     EGLI_ENTER_RET( EGL_NO_DISPLAY );
       
  2216     CEGLThread* thread = process->CurrentThread();
       
  2217     EGLI_ASSERT( thread );
       
  2218     EGLenum currentApi = thread->CurrentApi();
       
  2219     EGLDisplay ret = EGL_NO_DISPLAY;
       
  2220     switch( currentApi )
       
  2221         {
       
  2222         case EGL_OPENVG_API:
       
  2223             {
       
  2224             if( thread->CurrentVGContext() )
       
  2225                 {
       
  2226                 ret = (EGLDisplay)thread->CurrentVGContext()->Display();
       
  2227                 }
       
  2228             break;
       
  2229             }
       
  2230         case EGL_OPENGL_ES_API:
       
  2231             {
       
  2232             if( thread->CurrentGLESContext() )
       
  2233                 {
       
  2234                 ret = (EGLDisplay)thread->CurrentGLESContext()->Display();
       
  2235                 }
       
  2236             break;
       
  2237             }
       
  2238 
       
  2239         default:
       
  2240             EGLI_ASSERT( false );
       
  2241         }
       
  2242     EGLI_LEAVE_RET( ret, EGL_SUCCESS );
       
  2243     }
       
  2244 
       
  2245 EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx,
       
  2246 			   EGLint attribute, EGLint *value)
       
  2247     {
       
  2248     EGLI_ENTER_RET( EGL_FALSE );
       
  2249     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE )
       
  2250     if( !value )
       
  2251         {
       
  2252         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_PARAMETER );
       
  2253         }
       
  2254     CEGLContext* context = display->GetContext( ctx );
       
  2255     if( !context )
       
  2256         {
       
  2257         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_CONTEXT );
       
  2258         }
       
  2259     switch( attribute )
       
  2260         {
       
  2261         case EGL_CONFIG_ID:
       
  2262             {
       
  2263             *value = ((CEGLConfig*)context->Config())->GetAttribute( EGL_CONFIG_ID );
       
  2264             break;
       
  2265             }
       
  2266 
       
  2267         case EGL_CONTEXT_CLIENT_TYPE:
       
  2268             {
       
  2269             *value = context->ClientApi();
       
  2270             break;
       
  2271             }
       
  2272 
       
  2273         case EGL_CONTEXT_CLIENT_VERSION:
       
  2274             {
       
  2275             *value = context->ClientVersion();
       
  2276             break;
       
  2277             }
       
  2278 
       
  2279         case EGL_RENDER_BUFFER:
       
  2280             {
       
  2281             CEGLSurface* surface = NULL;
       
  2282             CEGLThread* thread = process->CurrentThread();
       
  2283             EGLI_ASSERT( thread != NULL );
       
  2284             if( thread->CurrentVGContext() == context )
       
  2285                 {
       
  2286                 surface = thread->CurrentVGSurface();
       
  2287                 }
       
  2288             else if( thread->CurrentGLESContext() == context )
       
  2289                 {
       
  2290                 thread->CurrentGLESSurfaces( NULL, &surface );
       
  2291                 }
       
  2292             else
       
  2293                 {
       
  2294                 surface = process->FindBoundSurface( context, false );
       
  2295                 }
       
  2296             if( surface )
       
  2297                 {
       
  2298                 *value = surface->RenderBuffer();
       
  2299                 }
       
  2300             else 
       
  2301                 {
       
  2302                 *value = EGL_NONE;
       
  2303                 }
       
  2304             break;
       
  2305             }
       
  2306 
       
  2307         default:
       
  2308             {
       
  2309             EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ATTRIBUTE );
       
  2310             }
       
  2311         }
       
  2312     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  2313     }
       
  2314 
       
  2315 
       
  2316 EGLAPI EGLBoolean EGLAPIENTRY eglWaitGL(void)
       
  2317     {
       
  2318     EGLI_ENTER_RET( EGL_FALSE );
       
  2319     // EGLI_ENTER_RET macro above will fail if thread is not available
       
  2320     CEGLThread* thread = getThread();
       
  2321     EGLBoolean ret = EGL_TRUE;
       
  2322     EGLenum api = eglQueryAPI();
       
  2323     if( eglBindAPI( EGL_OPENGL_ES_API ) )
       
  2324         {
       
  2325         ret = eglWaitClient();
       
  2326         if( thread->IsSupportedApi(api) )
       
  2327             {
       
  2328             eglBindAPI( api );
       
  2329             }
       
  2330         }    
       
  2331     EGLI_LEAVE_RET( ret, thread->Error() );
       
  2332     }
       
  2333 
       
  2334 EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine)
       
  2335     {
       
  2336     EGLI_ENTER_RET( EGL_FALSE );
       
  2337     // eglWaitNative – no-op, as no such thing as native rendering to pbuffers
       
  2338     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  2339     }
       
  2340 
       
  2341 EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surfaceId)
       
  2342     {
       
  2343     // \todo eglSwapBuffers – all surfaces are single-buffered pbuffers, so this just needs to do a flush in the current client API
       
  2344     EGLI_ENTER_RET( EGL_FALSE );
       
  2345     EGLI_GET_DISPLAY_RET( dpy, EGL_FALSE );
       
  2346 
       
  2347     // EGLI_ENTER_RET macro above will fail if thread is not available
       
  2348     CEGLThread* thread = getThread();
       
  2349 
       
  2350     CEGLSurface* surface = display->GetSurface( surfaceId );
       
  2351     if( !surface )
       
  2352         {
       
  2353         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  2354         }
       
  2355     EGLenum currentApi = thread->CurrentApi();
       
  2356     switch( currentApi )
       
  2357         {
       
  2358         case EGL_OPENVG_API:
       
  2359             {
       
  2360             if( thread->CurrentVGContext() != surface->BoundContext() )
       
  2361                 {
       
  2362                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  2363                 }
       
  2364             break;
       
  2365             }
       
  2366         case EGL_OPENGL_ES_API:
       
  2367             {
       
  2368             if( thread->CurrentGLESContext() != surface->BoundContext() )
       
  2369                 {
       
  2370                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  2371                 }
       
  2372             // \todo other GLES stuff?
       
  2373             }
       
  2374         }
       
  2375     if( surface->Type() != CEGLSurface::WINDOW_SURFACE || surface->RenderBuffer() == EGL_SINGLE_BUFFER )
       
  2376         {
       
  2377         EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  2378         }
       
  2379 
       
  2380     if( !(CEGLOs::IsValidNativeWindow(((CEGLWindowSurface*)surface)->NativeType())) )
       
  2381         {
       
  2382         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_NATIVE_WINDOW ); 
       
  2383         }
       
  2384 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
  2385     int w, h;
       
  2386     if( !(CEGLOs::GetNativeWindowSize(((CEGLWindowSurface*)surface)->NativeType(), w, h)) )
       
  2387         {
       
  2388         // \todo Error code?
       
  2389         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_SURFACE );
       
  2390         }
       
  2391 #else
       
  2392     int w = surface->Width();
       
  2393     int h = surface->Height();
       
  2394 #endif
       
  2395     if( surface->Width() != w || surface->Height() != h )
       
  2396         {
       
  2397         if( !(surface->Resize(w, h)) )
       
  2398             {
       
  2399             EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ALLOC );
       
  2400             }
       
  2401         if( w <= 0 || h <= 0 )
       
  2402             {
       
  2403             // invisible window => do nothing
       
  2404             EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  2405             }
       
  2406         if( surface->VGClientSurface() && state->VGInterface() )
       
  2407             {
       
  2408             if( !(state->VGInterface()->ResizeSurface(thread->CurrentVGContext()->ClientContext(),
       
  2409                 surface->VGClientSurface(), w, h, surface->VGBuffers())) )
       
  2410                 {
       
  2411                 EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ALLOC );
       
  2412                 }
       
  2413             }
       
  2414         }
       
  2415 
       
  2416     EGLint stride = surface->Stride();
       
  2417     void* buf = ((CEGLWindowSurface*)surface)->CurrentBuffer();
       
  2418 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
  2419     buf = (void*)((char*)buf + ((surface->Height() - 1) * stride));
       
  2420 #else
       
  2421     switch( currentApi )
       
  2422         {
       
  2423         case EGL_OPENVG_API:
       
  2424             {
       
  2425             state->VGInterface()->CopyBuffers( buf, surface->Stride(), surface->VGClientSurface() );
       
  2426             break;
       
  2427             }
       
  2428         case EGL_OPENGL_ES_API:
       
  2429             {
       
  2430 			if( surface->BoundContext() && !(state->GLESInterface(surface->BoundContext()->ClientVersion())) )
       
  2431 				{
       
  2432 				// \todo error code?
       
  2433 				EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_ACCESS );
       
  2434 				}
       
  2435             }
       
  2436         }
       
  2437 #endif
       
  2438     CEGLOs::BlitToOSWindow( currentApi, display, ((CEGLWindowSurface*)surface)->OsContext(), buf, surface->Width(), surface->Height(), stride );
       
  2439     EGLI_LEAVE_RET( EGL_TRUE, EGL_SUCCESS );
       
  2440     }
       
  2441 
       
  2442 EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface,
       
  2443 			  EGLNativePixmapType target)
       
  2444     {
       
  2445     EGLI_ENTER_RET( EGL_FALSE );
       
  2446     // eglCopyBuffers always raises EGL_BAD_NATIVE_PIXMAP error (as no native pixmaps supported)
       
  2447     EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_NATIVE_PIXMAP );
       
  2448     }
       
  2449 
       
  2450 /* Now, define eglGetProcAddress using the generic function ptr. type */
       
  2451 EGLAPI __eglMustCastToProperFunctionPointerType EGLAPIENTRY
       
  2452        eglGetProcAddress(const char *procname)
       
  2453     {
       
  2454     EGLI_ENTER_RET( NULL );
       
  2455     // \todo EGL
       
  2456     __eglMustCastToProperFunctionPointerType ret = NULL;
       
  2457     if( strncmp( procname, "vg", 2 ) == 0 )
       
  2458         {
       
  2459         ret = state->VGInterface()->GetVGProcAddress( procname );
       
  2460         }
       
  2461     else if( strncmp( procname, "egl", 3 ) == 0 )
       
  2462         {
       
  2463         ret = (__eglMustCastToProperFunctionPointerType)CEGLExtension::eglGetProcAddress( procname );
       
  2464         }
       
  2465     else if( strncmp( procname, "gl", 2 ) == 0 )
       
  2466         {
       
  2467         ret = state->GLESInterface(2)->GetGLProcAddress( procname );
       
  2468 		if( ret == NULL )
       
  2469 			{
       
  2470 			// Not found in GLES2, try GLES1.
       
  2471 			ret = state->GLESInterface(1)->GetGLProcAddress( procname );
       
  2472 			}
       
  2473         }
       
  2474     else
       
  2475         {
       
  2476         // return just NULL pointer...
       
  2477         }
       
  2478     EGLI_LEAVE_RET( ret, EGL_SUCCESS );
       
  2479     }
       
  2480 
       
  2481 #if defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
  2482 // non-standard platsim functions
       
  2483 EGLAPI void EGLAPIENTRY eglPlatsimSetProcessInformation( EGLint processId, EGLint threadId )
       
  2484     {
       
  2485     EGLI_ENTER_RET(EGLI_NO_RET);
       
  2486     if( process && process->Id() != processId )
       
  2487         {
       
  2488         process = state->GetProcess( processId );
       
  2489         }
       
  2490     if( !process )
       
  2491         {
       
  2492         process = state->AddProcess( processId, true );
       
  2493         EGLI_ASSERT( process != NULL );
       
  2494         CEGLThread* thread = process->AddThread( threadId, true, state->SupportedApis() );
       
  2495         EGLI_ASSERT( thread != NULL );
       
  2496         }
       
  2497     else if( !(process->HasThread( threadId )) )
       
  2498         {
       
  2499         CEGLThread* thread = process->AddThread( threadId, true, state->SupportedApis() );
       
  2500         EGLI_ASSERT( thread != NULL );
       
  2501         }
       
  2502     else
       
  2503         {
       
  2504         state->SetCurrentProcessThread( processId, threadId );
       
  2505         } 
       
  2506     EGLI_LEAVE_RET( EGLI_NO_RET, EGL_SUCCESS );
       
  2507     }
       
  2508 
       
  2509 EGLAPI EGLint EGLAPIENTRY eglPlatsimGetError()
       
  2510     {
       
  2511     //TODO
       
  2512     EGLI_ENTER_RET( EGL_SUCCESS );
       
  2513     EGLI_ASSERT( process != NULL );
       
  2514     CEGLThread* thread = process->CurrentThread();
       
  2515     EGLI_ASSERT( thread != NULL );
       
  2516     EGLint err = thread->Error();
       
  2517     EGLI_LEAVE_RET( err, err );
       
  2518     }
       
  2519 
       
  2520 // This is called after eglCreateWindowSurface()
       
  2521 EGLAPI void EGLAPIENTRY eglPlatsimSetSurfaceParams(
       
  2522     EGLDisplay displayId, EGLSurface surfaceId, EGLint width, EGLint height,
       
  2523     EGLint stride, void* buffer0, void *buffer1)
       
  2524     {
       
  2525     EGLI_ENTER_RET( EGLI_NO_RET );
       
  2526     CEGLDisplay* display = state->GetDisplay( displayId );
       
  2527     if( !display || (display && !(display->IsInitialized())) )
       
  2528         {
       
  2529         EGLI_LEAVE_RET( EGLI_NO_RET, EGL_NOT_INITIALIZED );
       
  2530         }
       
  2531     EGLI_ASSERT( display->ProcessId() == process->Id() );
       
  2532 
       
  2533     CEGLSurface* surface = display->GetSurface( surfaceId );
       
  2534     if( !surface )
       
  2535         {
       
  2536         EGLI_LEAVE_RET( EGLI_NO_RET, EGL_BAD_SURFACE );
       
  2537         }
       
  2538 
       
  2539     EGLI_ASSERT( surface->Type() == CEGLSurface::WINDOW_SURFACE );
       
  2540     if( !(surface->Resize(width, height)) )
       
  2541         {
       
  2542         EGLI_LEAVE_RET( EGLI_NO_RET, EGL_BAD_ALLOC );
       
  2543         }
       
  2544     ((CEGLWindowSurface*)surface)->SetStride( stride );
       
  2545     ((CEGLWindowSurface*)surface)->SetWindowBuffers( buffer0, buffer1 );
       
  2546     
       
  2547     CEGLThread* thread = process->CurrentThread();
       
  2548     EGLI_ASSERT( thread != NULL );
       
  2549     //TODO: resizing
       
  2550     switch( thread->CurrentApi() )
       
  2551         {
       
  2552         case EGL_OPENVG_API:
       
  2553             {
       
  2554             if( !(surface->VGColorBuffer()) )
       
  2555                 {
       
  2556                 EGLI_ASSERT( state->VGInterface() != NULL );
       
  2557                 SurfaceDescriptor* surfaceDesc = surface->Descriptor();                
       
  2558 				bool success = state->VGInterface()->CreateSurface( surfaceDesc, surface->VGBuffers(), NULL );
       
  2559                 EGLI_ASSERT( success );
       
  2560                 }
       
  2561             break;
       
  2562             }
       
  2563         case EGL_OPENGL_ES_API:
       
  2564             {
       
  2565             //TODO: GLES not implemented
       
  2566             //EGLI_ASSERT( false );
       
  2567             break;
       
  2568             }
       
  2569         default:
       
  2570             {
       
  2571             EGLI_ASSERT( false );
       
  2572             }
       
  2573         }
       
  2574     
       
  2575     //TODO: what else? 
       
  2576     EGLI_LEAVE_RET( EGLI_NO_RET, EGL_SUCCESS );
       
  2577     }
       
  2578 
       
  2579 EGLAPI EGLNativePixmapType EGLAPIENTRY eglPlatsimGetPixmapSurfaceBitmap( EGLDisplay display, EGLSurface surface)
       
  2580     {
       
  2581     //TODO
       
  2582     return NULL;
       
  2583     }
       
  2584 #endif
       
  2585 
       
  2586 #if defined(_WIN32)
       
  2587 
       
  2588 BOOL WINAPI DllMain( HINSTANCE hinstDLL,
       
  2589                      DWORD fdwReason,
       
  2590                      LPVOID lpvReserved )
       
  2591     {
       
  2592 #if !defined(EGLI_USE_PLATSIM_EXTENSIONS)
       
  2593     switch( fdwReason )
       
  2594         {
       
  2595         case DLL_PROCESS_ATTACH:
       
  2596             {
       
  2597             g_tlsIndex = TlsAlloc();
       
  2598             if( g_tlsIndex == TLS_OUT_OF_INDEXES )
       
  2599                 return FALSE;
       
  2600             if( !g_lockInitialized )
       
  2601                 {
       
  2602                 CEGLOs::InitializeLock( &g_eglLock );
       
  2603                 g_lockInitialized = true;
       
  2604                 }
       
  2605             break;
       
  2606             }
       
  2607 	    case DLL_THREAD_ATTACH:
       
  2608             {
       
  2609             break;
       
  2610             }
       
  2611 
       
  2612 	    case DLL_THREAD_DETACH:
       
  2613             {
       
  2614             break;
       
  2615             }
       
  2616 	    case DLL_PROCESS_DETACH:
       
  2617             {
       
  2618             if( g_eglState )
       
  2619                 {
       
  2620                 EGLI_ASSERT( g_eglState->RefCount() == 0 );
       
  2621                 delete g_eglState;
       
  2622                 g_eglState = NULL;
       
  2623                 }
       
  2624              if( g_lockInitialized )
       
  2625                 {
       
  2626                 CEGLOs::DestroyLock( &g_eglLock );
       
  2627                 g_lockInitialized = false;
       
  2628                 }
       
  2629             if( g_tlsIndex != TLS_OUT_OF_INDEXES )
       
  2630                 {
       
  2631                 TlsFree( g_tlsIndex );
       
  2632                 }
       
  2633             break;
       
  2634             }
       
  2635         }
       
  2636 #else
       
  2637 switch( fdwReason )
       
  2638         {
       
  2639         case DLL_PROCESS_ATTACH:
       
  2640 	    case DLL_THREAD_ATTACH:
       
  2641 	    case DLL_THREAD_DETACH:
       
  2642             {
       
  2643             break;
       
  2644             }
       
  2645 	    case DLL_PROCESS_DETACH:
       
  2646             {
       
  2647             EGLI_ASSERT( g_eglState == NULL );
       
  2648             break;
       
  2649             }
       
  2650         }
       
  2651 #endif // EGLI_USE_PLATSIM_EXTENSIONS
       
  2652 
       
  2653     return TRUE;
       
  2654     }
       
  2655 
       
  2656 #endif // _WIN32
       
  2657 
       
  2658 #ifdef __cplusplus
       
  2659 }
       
  2660 #endif