hostsupport/hostegl/src/EGLExtension.cpp
branchbug235_bringup_0
changeset 53 c2ef9095503a
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 "EGLExtension.h"
       
    32 #include "EGLState.h"
       
    33 #include "EGLImage.h"
       
    34 #include "EGLContext.h"
       
    35 #include "EGLDisplay.h"
       
    36 #include "eglInternal.h"
       
    37 #include "EGLProcess.h"
       
    38 #include "EGLThread.h"
       
    39 #include "EGLOs.h"
       
    40 #include "ImageTarget.h"
       
    41 
       
    42 #include <string.h>
       
    43 
       
    44 typedef struct
       
    45 	{
       
    46 	const char*      extnName;		// procedure or extension name
       
    47 	ProcPointer      procAddr;      // address
       
    48 	} TExtnInfo;
       
    49 
       
    50 static const TExtnInfo eglProcedures[] =
       
    51     { // list of EGL extension name strings, followed by any EGLI_NEW function names
       
    52         {"eglCreateImageKHR", (ProcPointer)eglCreateImageKHR},
       
    53         {"eglDestroyImageKHR", (ProcPointer)eglDestroyImageKHR}
       
    54     };
       
    55 
       
    56 const EGLint KEglProcCount = sizeof(eglProcedures) / sizeof(TExtnInfo); 
       
    57 
       
    58 CEGLExtension::CEGLExtension()
       
    59     {
       
    60     }
       
    61 
       
    62 CEGLExtension::~CEGLExtension(void)
       
    63     {
       
    64     }
       
    65 
       
    66 ProcPointer CEGLExtension::eglGetProcAddress(const char* aProcname)
       
    67     {
       
    68     EGLint nameLength =  strlen(aProcname);
       
    69 	if ((nameLength > 3) && !strncmp(aProcname, "egl", 3))
       
    70 		{ // EGL extensions - exhaustive search 
       
    71 		for (EGLint idx = 0; idx < KEglProcCount; idx++)
       
    72 			{
       
    73 			if ( strcmp( aProcname, eglProcedures[idx].extnName ) == 0 )
       
    74 				return eglProcedures[idx].procAddr;
       
    75 			}
       
    76 		}	
       
    77 	return NULL;
       
    78     }
       
    79 
       
    80 static EImageTarget mapImageTarget( EGLenum target )
       
    81 	{
       
    82 	switch(target)
       
    83 		{
       
    84 		case EGL_GL_TEXTURE_2D_KHR:
       
    85 			return IMAGE_TARGET_TEXTURE_2D;
       
    86 		case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
       
    87 			return IMAGE_TARGET_TEXTURE_CUBE_MAP_POSITIVE_X;
       
    88         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
       
    89 			return IMAGE_TARGET_TEXTURE_CUBE_MAP_NEGATIVE_X;
       
    90         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
       
    91 			return IMAGE_TARGET_TEXTURE_CUBE_MAP_POSITIVE_Y;
       
    92         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
       
    93 			return IMAGE_TARGET_TEXTURE_CUBE_MAP_NEGATIVE_Y;
       
    94         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
       
    95 			return IMAGE_TARGET_TEXTURE_CUBE_MAP_POSITIVE_Z;
       
    96         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
       
    97 			return IMAGE_TARGET_TEXTURE_CUBE_MAP_NEGATIVE_Z;
       
    98 		case EGL_GL_RENDERBUFFER_KHR:
       
    99 			return IMAGE_TARGET_RENDERBUFFER;
       
   100 		default:
       
   101 			EGLI_ASSERT(false);
       
   102 		}
       
   103 
       
   104 	// Not reached.
       
   105 	return (EImageTarget)-1;
       
   106 	}
       
   107 
       
   108 EGLAPI EGLImageKHR EGLAPIENTRY eglCreateImageKHR( EGLDisplay dpy,
       
   109 												  EGLContext ctx,
       
   110 												  EGLenum target,
       
   111 												  EGLClientBuffer buffer,
       
   112 												  const EGLint *attrib_list )
       
   113     {
       
   114     EGLI_ENTER_RET( EGL_NO_IMAGE_KHR );
       
   115 
       
   116     CEGLImage *image = NULL;
       
   117     CEGLDisplay *display = NULL;
       
   118     CEGLContext *context = NULL;
       
   119 
       
   120     display = state->GetDisplay( dpy );
       
   121     // Check display
       
   122     //<dpy> must be a valid EGLDisplay
       
   123     if( !display )
       
   124        {                   
       
   125        EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_DISPLAY );
       
   126        }
       
   127 
       
   128     context = display->GetContext( ctx ); 
       
   129     // Check context
       
   130     //<ctx> must be a valid OpenVG API context on that display
       
   131     if( !context )
       
   132        {                    
       
   133        EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_CONTEXT );
       
   134        }
       
   135     
       
   136     // Display and context ok, continue...
       
   137     switch( target )
       
   138         {
       
   139         case EGL_NATIVE_PIXMAP_KHR:
       
   140             {
       
   141             // Not supported
       
   142             // 1) set error code to EGL_BAD_PARAMETER
       
   143             // 2) release lock
       
   144             // 3) return no image
       
   145             EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_PARAMETER );
       
   146             break;
       
   147             }
       
   148         case EGL_VG_PARENT_IMAGE_KHR:
       
   149             {            
       
   150             // Context must be client context and api must be openVG
       
   151             if( context->ClientContext() && EGL_OPENVG_API == context->ClientApi() )                    
       
   152                 {                        
       
   153                 EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_CONTEXT );
       
   154                 }
       
   155 
       
   156             //<buffer>
       
   157             //must be a handle of a VGImage object valid in the specified context, cast
       
   158             //into the type EGLClientBuffer
       
   159             //Furthermore, the specified VGImage
       
   160             //<buffer> must not be a child image
       
   161             if ( !state->VGInterface()->IsRootImage( buffer ) )
       
   162                 {
       
   163                 EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_ACCESS );
       
   164                 }
       
   165             
       
   166             // TODO:
       
   167             /*
       
   168             1) We also need to check that VGImage is not bound 
       
   169             to a Pbuffer surface
       
   170             
       
   171             2) VGimage has not been already used to create EGLImage. 
       
   172             
       
   173             3) VGImage itself is not created from EGLImage.            
       
   174             */
       
   175             //state->VGInterface()-
       
   176             // 1)
       
   177             if( EGL_PBUFFER_BIT == context->Config()->GetAttribute( EGL_SURFACE_TYPE ) )
       
   178                 {
       
   179                 // If VGImage is bound to a Pbuffer no EGLImage
       
   180                 EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_ACCESS );
       
   181                 }
       
   182 
       
   183             // Descriptor for pixeldata data values
       
   184             SurfaceDescriptor desc; 
       
   185             // data is actual pixeldata
       
   186             void* data = NULL;
       
   187 
       
   188             //Any values
       
   189             //specified in <attr_list> are ignored.
       
   190      
       
   191             // GetImageData will allocate memory for data
       
   192             // data must be deleted in CEGLImage destructor
       
   193             state->VGInterface()->GetImageData( buffer, desc, data );
       
   194             if ( !data )
       
   195                 {
       
   196                 EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_ACCESS );
       
   197                 }
       
   198 
       
   199             // Create CEGLImage.
       
   200             image = EGLI_NEW CEGLImage( target, buffer, desc, data );
       
   201             
       
   202             // If EGLImage creation fail then return error code.
       
   203             if( !image )
       
   204                 {
       
   205                 EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_ALLOC );
       
   206                 }
       
   207             // Add refcount to VGImage
       
   208             state->VGInterface()->AddRef( buffer );
       
   209             // Add image in array
       
   210             image = display->AddEGLImage( image );
       
   211             break;
       
   212             }   
       
   213 
       
   214         case EGL_GL_TEXTURE_2D_KHR:
       
   215 		case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X_KHR:
       
   216         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_X_KHR:
       
   217         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Y_KHR:
       
   218         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_KHR:
       
   219         case EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z_KHR:
       
   220         case EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_KHR:
       
   221             {
       
   222             // From RFP document
       
   223             // EGL_KHR_gl_image (not required for OpenGL ES 1.1) [R12]
       
   224             /*<ctx> must be a valid OpenGL ES API context on that display.*/
       
   225 			if( context->ClientContext() && (EGL_OPENGL_ES_API != context->ClientApi() || 2 != context->ClientVersion()) )
       
   226                 {                        
       
   227                 EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_CONTEXT );
       
   228                 }
       
   229 
       
   230             
       
   231             // From spec.
       
   232             /*KHR_gl_texture_2D_image requires the presence of an OpenGL ES
       
   233             implementation (1.0 or later and/or 2.0 or later).*/
       
   234             
       
   235             /*Accepted as an attribute in the <attr_list> parameter of
       
   236             eglCreateImageKHR: EGL_GL_TEXTURE_LEVEL_KHR 0x30BC*/
       
   237 
       
   238             //EGL_GL_TEXTURE_LEVEL_KHR  
       
   239 
       
   240             /*If <target> is EGL_GL_TEXTURE_2D_KHR, 
       
   241             <buffer> must be the name of a nonzero, EGL_GL_TEXTURE_2D target texture object, 
       
   242             cast into the type EGLClientBuffer.  
       
   243 
       
   244             <attr_list> should specify the mipmap level
       
   245             which will be used as the EGLImage source (EGL_GL_TEXTURE_LEVEL_KHR); the
       
   246             specified mipmap level must be part of <buffer>.  If not specified, the
       
   247             default value listed in Table bbb will be used, instead.  Additional
       
   248             values specified in <attr_list> are ignored.  The texture must be complete
       
   249             unless the mipmap level to be used is 0, the texture has mipmap level 0
       
   250             specified, and no other mipmap levels are specified. */
       
   251             
       
   252             SurfaceDescriptor surfDesc;
       
   253             EGLint textureLevel = 0;
       
   254             EGLint dataSize;
       
   255 
       
   256             if( attrib_list && attrib_list[0] != EGL_NONE )
       
   257 	            {
       
   258                   for(int i=0; attrib_list[i] != EGL_NONE ; i+=2)
       
   259                     {
       
   260                     if( attrib_list[i] == EGL_GL_TEXTURE_LEVEL_KHR )
       
   261                         {
       
   262                         textureLevel = attrib_list[i+1];
       
   263                         }
       
   264                     }
       
   265 	            }
       
   266 
       
   267 			EImageTarget textureTarget = mapImageTarget(target);
       
   268 
       
   269 			IEGLtoGLES2Interface* iFace = (IEGLtoGLES2Interface*)state->GLESInterface(2);
       
   270 			EStatus status = iFace->GetTextureInfo( context->ClientContext(), textureTarget, buffer, textureLevel, surfDesc );
       
   271 			if ( status != DGLES2_SUCCESS )
       
   272 				{
       
   273 				switch( status )
       
   274 					{
       
   275 					case DGLES2_BAD_PARAMETER:
       
   276 					case DGLES2_BAD_MATCH:
       
   277 						EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_PARAMETER );
       
   278 						break;
       
   279 
       
   280 					default:
       
   281 						EGLI_ASSERT(false);
       
   282 					}
       
   283                 EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_ALLOC );
       
   284                 }
       
   285 			dataSize = surfDesc.m_stride * surfDesc.m_height;
       
   286 			unsigned char* data = new unsigned char [ dataSize ];
       
   287 
       
   288             iFace->GetTextureData( context->ClientContext(), textureTarget, buffer, textureLevel, data );
       
   289             
       
   290             // Create CEGLImage.
       
   291             image = EGLI_NEW CEGLImage( target, buffer, surfDesc, data );
       
   292             
       
   293             // If EGLImage creation fail then return error code.
       
   294             if( !image )
       
   295                 {
       
   296                 EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_ALLOC );
       
   297                 }
       
   298             // Add image in array
       
   299             // That array is in display side.
       
   300             image = display->AddEGLImage( image );
       
   301             break;
       
   302             }
       
   303         case EGL_GL_TEXTURE_3D_KHR:
       
   304             {
       
   305             /*<ctx> must be a valid OpenGL ES API context on that display.*/
       
   306 			//EGL_BAD_PARAMETER 
       
   307             // NOT SUPPORTED 
       
   308             EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_PARAMETER );
       
   309             }
       
   310         case EGL_GL_RENDERBUFFER_KHR:
       
   311             {
       
   312             //EGL_BAD_PARAMETER 
       
   313             // NOT SUPPORTED 
       
   314             EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_PARAMETER );
       
   315             }
       
   316 
       
   317         default:
       
   318             {
       
   319             //EGL_BAD_PARAMETER 
       
   320             EGLI_LEAVE_RET( EGL_NO_IMAGE_KHR, EGL_BAD_PARAMETER );
       
   321             }
       
   322         }
       
   323     EGLI_LEAVE_RET( image, EGL_SUCCESS );
       
   324     }
       
   325 
       
   326 EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR( EGLDisplay dpy,
       
   327 												  EGLImageKHR image)
       
   328     {
       
   329     // TODO:
       
   330     /* Check display
       
   331        Delete image from display array*/ 
       
   332     EGLI_ENTER_RET( EGL_FALSE );
       
   333 
       
   334     CEGLDisplay *display = NULL;
       
   335     CEGLImage *tempImage = NULL;
       
   336 
       
   337     display = state->GetDisplay( dpy );
       
   338     // Check display
       
   339     //<dpy> must be a valid EGLDisplay
       
   340     if( !display )
       
   341        {                   
       
   342        EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_DISPLAY );
       
   343        }
       
   344 
       
   345     tempImage = display->GetImage( image );
       
   346     if( !tempImage )
       
   347         {
       
   348         EGLI_LEAVE_RET( EGL_FALSE, EGL_BAD_PARAMETER );
       
   349         }
       
   350 
       
   351     // Display and image are both ok...
       
   352     // Let siblings know that image is destroyed...
       
   353     // Delete mother of image...
       
   354     // Remove image...
       
   355     //tempImage
       
   356     display->RemoveEGLImage( image );
       
   357 
       
   358     return EGL_TRUE;
       
   359     }
       
   360