EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { VALIDATE_DISPLAY(dpy,EGL_FALSE); if (!s_display.initialize(&s_eglIface)) { return EGL_FALSE; } if (major!=NULL) *major = s_display.getVersionMajor(); if (minor!=NULL) *minor = s_display.getVersionMinor(); return EGL_TRUE; }
EGLAPI EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay display, EGLConfig *configs, EGLint config_size, EGLint *num_config) { VALIDATE_DISPLAY(display); if(!num_config) { RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER); } if(configs == NULL) { *num_config = dpy->nConfigs(); } else { *num_config = dpy->getConfigs(configs,config_size); } return EGL_TRUE; }
EGLAPI const char * EGLAPIENTRY eglQueryString(EGLDisplay display, EGLint name) { VALIDATE_DISPLAY(display); static const char* vendor = "Google"; static const char* version = "1.4"; static const char* extensions = "EGL_KHR_image_base EGL_KHR_gl_texture_2D_image"; if(!EglValidate::stringName(name)) { RETURN_ERROR(NULL,EGL_BAD_PARAMETER); } switch(name) { case EGL_VENDOR: return vendor; case EGL_VERSION: return version; case EGL_EXTENSIONS: return extensions; } return NULL; }
EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay display, EGLSurface surface) { VALIDATE_DISPLAY(display); VALIDATE_SURFACE(surface,Srfc); ThreadInfo* thread = getThreadInfo(); ContextPtr currentCtx = thread->eglContext; //if surface not window return if(Srfc->type() != EglSurface::WINDOW){ RETURN_ERROR(EGL_TRUE,EGL_SUCCESS); } if(!currentCtx.Ptr() || !currentCtx->usingSurface(Srfc) || !dpy->nativeType()->isValidNativeWin(Srfc.Ptr()->native())) { RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); } dpy->nativeType()->swapBuffers(Srfc->native()); return EGL_TRUE; }
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyImageKHR(EGLDisplay display, EGLImageKHR image) { VALIDATE_DISPLAY(display); return dpy->destroyImageKHR(image) ? EGL_TRUE:EGL_FALSE; }
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context) { VALIDATE_DISPLAY(display); bool releaseContext = EglValidate::releaseContext(context, read, draw); if(!releaseContext && EglValidate::badContextMatch(context, read, draw)) { RETURN_ERROR(EGL_FALSE, EGL_BAD_MATCH); } ThreadInfo* thread = getThreadInfo(); ContextPtr prevCtx = thread->eglContext; if(releaseContext) { //releasing current context if(prevCtx.Ptr()) { g_eglInfo->getIface(prevCtx->version())->flush(); if(!dpy->nativeType()->makeCurrent(NULL,NULL,NULL)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ACCESS); } thread->updateInfo(ContextPtr(NULL),dpy,NULL,ShareGroupPtr(NULL),dpy->getManager(prevCtx->version())); } } else { //assining new context VALIDATE_CONTEXT(context); VALIDATE_SURFACE(draw,newDrawSrfc); VALIDATE_SURFACE(read,newReadSrfc); EglSurface* newDrawPtr = newDrawSrfc.Ptr(); EglSurface* newReadPtr = newReadSrfc.Ptr(); ContextPtr newCtx = ctx; if (newCtx.Ptr() && prevCtx.Ptr()) { if (newCtx.Ptr() == prevCtx.Ptr()) { if (newDrawPtr == prevCtx->draw().Ptr() && newReadPtr == prevCtx->read().Ptr()) { // nothing to do return EGL_TRUE; } } else { // Make sure previous context is detached from surfaces releaseContext = true; } } //surfaces compatibility check if(!((*ctx->getConfig()).compatibleWith((*newDrawPtr->getConfig()))) || !((*ctx->getConfig()).compatibleWith((*newReadPtr->getConfig())))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_MATCH); } EglOS::Display* nativeDisplay = dpy->nativeType(); EglOS::Surface* nativeRead = newReadPtr->native(); EglOS::Surface* nativeDraw = newDrawPtr->native(); //checking native window validity if(newReadPtr->type() == EglSurface::WINDOW && !nativeDisplay->isValidNativeWin(nativeRead)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW); } if(newDrawPtr->type() == EglSurface::WINDOW && !nativeDisplay->isValidNativeWin(nativeDraw)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW); } if(prevCtx.Ptr()) { g_eglInfo->getIface(prevCtx->version())->flush(); } if (!dpy->nativeType()->makeCurrent( newReadPtr->native(), newDrawPtr->native(), newCtx->nativeType())) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ACCESS); } //TODO: handle the following errors // EGL_BAD_CURRENT_SURFACE , EGL_CONTEXT_LOST , EGL_BAD_ACCESS thread->updateInfo(newCtx,dpy,newCtx->getGlesContext(),newCtx->getShareGroup(),dpy->getManager(newCtx->version())); newCtx->setSurfaces(newReadSrfc,newDrawSrfc); g_eglInfo->getIface(newCtx->version())->initContext(newCtx->getGlesContext(),newCtx->getShareGroup()); // Initialize the GLES extension function table used in // eglGetProcAddress for the context's GLES version if not // yet initialized. We initialize it here to make sure we call the // GLES getProcAddress after when a context is bound. g_eglInfo->initClientExtFuncTable(newCtx->version()); } // release previous context surface binding if(prevCtx.Ptr() && releaseContext) { prevCtx->setSurfaces(SurfacePtr(NULL),SurfacePtr(NULL)); } return EGL_TRUE; }
EGLAPI EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay display, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) { VALIDATE_DISPLAY(display); if(!num_config) { RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER); } //selection defaults // NOTE: Some variables below are commented out to reduce compiler warnings. // TODO(digit): Look if these variables are really needed or not, and if so // fix the code to do it properly. EGLint surface_type = EGL_WINDOW_BIT; EGLint renderable_type = EGL_OPENGL_ES_BIT; //EGLBoolean bind_to_tex_rgb = EGL_DONT_CARE; //EGLBoolean bind_to_tex_rgba = EGL_DONT_CARE; EGLenum caveat = EGL_DONT_CARE; EGLint config_id = EGL_DONT_CARE; EGLBoolean native_renderable = EGL_DONT_CARE; EGLint native_visual_type = EGL_DONT_CARE; //EGLint max_swap_interval = EGL_DONT_CARE; //EGLint min_swap_interval = EGL_DONT_CARE; EGLint trans_red_val = EGL_DONT_CARE; EGLint trans_green_val = EGL_DONT_CARE; EGLint trans_blue_val = EGL_DONT_CARE; EGLenum transparent_type = EGL_NONE; //EGLint buffer_size = 0; EGLint red_size = 0; EGLint green_size = 0; EGLint blue_size = 0; EGLint alpha_size = 0; EGLint depth_size = 0; EGLint frame_buffer_level = 0; //EGLint sample_buffers_num = 0; EGLint samples_per_pixel = 0; EGLint stencil_size = 0; if(!EglValidate::noAttribs(attrib_list)) { //there are attribs int i = 0 ; bool hasConfigId = false; while(attrib_list[i] != EGL_NONE && !hasConfigId) { switch(attrib_list[i]) { case EGL_MAX_PBUFFER_WIDTH: case EGL_MAX_PBUFFER_HEIGHT: case EGL_MAX_PBUFFER_PIXELS: case EGL_NATIVE_VISUAL_ID: break; //we dont care from those selection crateria case EGL_LEVEL: if(attrib_list[i+1] == EGL_DONT_CARE) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } frame_buffer_level = attrib_list[i+1]; break; case EGL_BUFFER_SIZE: if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } //buffer_size = attrib_list[i+1]; break; case EGL_RED_SIZE: if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } red_size = attrib_list[i+1]; break; case EGL_GREEN_SIZE: if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } green_size = attrib_list[i+1]; break; case EGL_BLUE_SIZE: if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } blue_size = attrib_list[i+1]; break; case EGL_ALPHA_SIZE: if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } alpha_size = attrib_list[i+1]; break; case EGL_BIND_TO_TEXTURE_RGB: //bind_to_tex_rgb = attrib_list[i+1]; break; case EGL_BIND_TO_TEXTURE_RGBA: //bind_to_tex_rgba = attrib_list[i+1]; break; case EGL_CONFIG_CAVEAT: if(attrib_list[i+1] != EGL_NONE && attrib_list[i+1] != EGL_SLOW_CONFIG && attrib_list[i+1] != EGL_NON_CONFORMANT_CONFIG) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } caveat = attrib_list[i+1]; break; case EGL_CONFIG_ID: if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } config_id = attrib_list[i+1]; hasConfigId = true; break; case EGL_DEPTH_SIZE: if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } depth_size = attrib_list[i+1]; break; case EGL_MAX_SWAP_INTERVAL: if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } //max_swap_interval = attrib_list[i+1]; break; case EGL_MIN_SWAP_INTERVAL: if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } //min_swap_interval = attrib_list[i+1]; break; case EGL_NATIVE_RENDERABLE: native_renderable = attrib_list[i+1]; break; case EGL_RENDERABLE_TYPE: renderable_type = attrib_list[i+1]; break; case EGL_NATIVE_VISUAL_TYPE: native_visual_type = attrib_list[i+1]; break; if(attrib_list[i+1] < 0 || attrib_list[i+1] > 1 ) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } case EGL_SAMPLE_BUFFERS: //sample_buffers_num = attrib_list[i+1]; break; if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } case EGL_SAMPLES: if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } samples_per_pixel = attrib_list[i+1]; break; case EGL_STENCIL_SIZE: if(attrib_list[i+1] < 0) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } stencil_size = attrib_list[i+1]; break; case EGL_SURFACE_TYPE: surface_type = attrib_list[i+1]; break; case EGL_TRANSPARENT_TYPE: if(attrib_list[i+1] != EGL_NONE && attrib_list[i+1] != EGL_TRANSPARENT_RGB ) { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } transparent_type = attrib_list[i+1]; break; case EGL_TRANSPARENT_RED_VALUE: trans_red_val = attrib_list[i+1]; break; case EGL_TRANSPARENT_GREEN_VALUE: trans_green_val = attrib_list[i+1]; break; case EGL_TRANSPARENT_BLUE_VALUE: trans_blue_val = attrib_list[i+1]; break; default: RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } i+=2; } if(hasConfigId) { EglConfig* pConfig = dpy->getConfig(config_id); if(pConfig) { if(configs) { configs[0] = static_cast<EGLConfig>(pConfig); } *num_config = 1; return EGL_TRUE; } else { RETURN_ERROR(EGL_FALSE,EGL_BAD_ATTRIBUTE); } } } EglConfig dummy(red_size,green_size,blue_size,alpha_size,caveat,config_id,depth_size, frame_buffer_level,0,0,0,native_renderable,renderable_type,0,native_visual_type, samples_per_pixel,stencil_size,surface_type,transparent_type, trans_red_val,trans_green_val,trans_blue_val,NULL); *num_config = dpy->chooseConfigs(dummy,configs,config_size); return EGL_TRUE; }
EGLAPI EGLBoolean EGLAPIENTRY eglTerminate(EGLDisplay display) { VALIDATE_DISPLAY(display); dpy->terminate(); return EGL_TRUE; }