EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) { VALIDATE_DISPLAY_INIT(dpy, NULL); VALIDATE_CONFIG(config, EGL_FALSE); if (win == 0) { setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); } EGLint surfaceType; if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE; if (!(surfaceType & EGL_WINDOW_BIT)) { setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); } if (static_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) { setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } egl_surface_t* surface = egl_window_surface_t::create( &s_display, config, surfaceType, static_cast<ANativeWindow*>(win)); if (!surface) { setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE); } return surface; }
EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface eglSurface, EGLint buffer) { VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); if (eglSurface == EGL_NO_SURFACE) { setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); } if (buffer != EGL_BACK_BUFFER) { setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); } egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) ); if (surface->getTextureFormat() == EGL_NO_TEXTURE) { setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); } if (!(surface->getSurfaceType() & EGL_PBUFFER_BIT)) { setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); } //It's now safe to cast to pbuffer surface egl_pbuffer_surface_t* pbSurface = (egl_pbuffer_surface_t*)surface; DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); rcEnc->rcBindTexture(rcEnc, pbSurface->getRcColorBuffer()); return GL_TRUE; }
EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) { VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE); EGLContext_t * context = static_cast<EGLContext_t*>(ctx); EGLBoolean ret = EGL_TRUE; switch (attribute) { case EGL_CONFIG_ID: ret = s_display.getConfigAttrib(context->config, EGL_CONFIG_ID, value); break; case EGL_CONTEXT_CLIENT_TYPE: *value = EGL_OPENGL_ES_API; break; case EGL_CONTEXT_CLIENT_VERSION: *value = context->version; break; case EGL_RENDER_BUFFER: if (!context->draw) *value = EGL_NONE; else *value = EGL_BACK_BUFFER; //single buffer not supported break; default: ALOGE("eglQueryContext %x EGL_BAD_ATTRIBUTE", attribute); setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE); break; } return ret; }
EGLBoolean eglTerminate(EGLDisplay dpy) { VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); s_display.terminate(); return EGL_TRUE; }
EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) { return 0; VALIDATE_DISPLAY_INIT(dpy, NULL); VALIDATE_CONFIG(config, EGL_FALSE); if (win == 0) { setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); } //eglDisplay *s_display = (eglDisplay *)dpy; EGLint surfaceType = EGL_WINDOW_BIT; //LOGE("s_display->getConfigAttrib: %p", s_display->getConfigAttrib); //LOGE("s_display->m_attribs: %d", s_display->m_attribs); //LOGE("s_display->m_configs: %d", s_display->m_configs); //LOGE("s_display->m_numConfigAttribs: %d", s_display->m_numConfigAttribs); /*if (s_display->getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) { return EGL_FALSE; }*/ if (!(surfaceType & EGL_WINDOW_BIT)) { setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); } if (static_cast<ANativeWindow*>(win)->common.magic != ANDROID_NATIVE_WINDOW_MAGIC) { setErrorReturn(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } egl_surface_t* surface = egl_window_surface_t::create(dpy, config, surfaceType, static_cast<ANativeWindow*>(win)); if (!surface) { setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE); } return surface; }
EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) { VALIDATE_DISPLAY_INIT(dpy, EGL_NO_IMAGE_KHR); if (ctx != EGL_NO_CONTEXT) { setErrorReturn(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); } if (target != EGL_NATIVE_BUFFER_ANDROID) { setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); } android_native_buffer_t* native_buffer = (android_native_buffer_t*)buffer; if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); if (native_buffer->common.version != sizeof(android_native_buffer_t)) setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); switch (native_buffer->format) { case HAL_PIXEL_FORMAT_RGBA_8888: case HAL_PIXEL_FORMAT_RGBX_8888: case HAL_PIXEL_FORMAT_RGB_888: case HAL_PIXEL_FORMAT_RGB_565: case HAL_PIXEL_FORMAT_BGRA_8888: case HAL_PIXEL_FORMAT_RGBA_5551: case HAL_PIXEL_FORMAT_RGBA_4444: break; default: setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_IMAGE_KHR); } native_buffer->common.incRef(&native_buffer->common); return (EGLImageKHR)native_buffer; }
EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { VALIDATE_DISPLAY_INIT(dpy, NULL); VALIDATE_CONFIG(config, EGL_FALSE); EGLint surfaceType; if (s_display.getConfigAttrib(config, EGL_SURFACE_TYPE, &surfaceType) == EGL_FALSE) return EGL_FALSE; if (!(surfaceType & EGL_PBUFFER_BIT)) { setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); } int32_t w = 0; int32_t h = 0; EGLint texFormat = EGL_NO_TEXTURE; EGLint texTarget = EGL_NO_TEXTURE; while (attrib_list[0]) { switch (attrib_list[0]) { case EGL_WIDTH: w = attrib_list[1]; break; case EGL_HEIGHT: h = attrib_list[1]; break; case EGL_TEXTURE_FORMAT: texFormat = attrib_list[1]; break; case EGL_TEXTURE_TARGET: texTarget = attrib_list[1]; break; default: break; }; attrib_list+=2; } if (((texFormat == EGL_NO_TEXTURE)&&(texTarget != EGL_NO_TEXTURE)) || ((texFormat != EGL_NO_TEXTURE)&&(texTarget == EGL_NO_TEXTURE))) { setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); } // TODO: check EGL_TEXTURE_FORMAT - need to support eglBindTexImage GLenum pixelFormat; if (s_display.getConfigGLPixelFormat(config, &pixelFormat) == EGL_FALSE) setErrorReturn(EGL_BAD_MATCH, EGL_NO_SURFACE); egl_surface_t* surface = egl_pbuffer_surface_t::create(dpy, config, surfaceType, w, h, pixelFormat); if (!surface) { setErrorReturn(EGL_BAD_ALLOC, EGL_NO_SURFACE); } //setup attributes surface->setTextureFormat(texFormat); surface->setTextureTarget(texTarget); return surface; }
EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface eglSurface) { VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); egl_surface_t* surface(static_cast<egl_surface_t*>(eglSurface)); delete surface; return EGL_TRUE; }
EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) { VALIDATE_DISPLAY_INIT(dpy, NULL); VALIDATE_CONFIG(config, EGL_FALSE); if (s_display.getConfigAttrib(config, attribute, value)) { return EGL_TRUE; } else { RETURN_ERROR(EGL_FALSE, EGL_BAD_ATTRIBUTE); } }
EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img) { VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); android_native_buffer_t* native_buffer = (android_native_buffer_t*)img; if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); if (native_buffer->common.version != sizeof(android_native_buffer_t)) setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); native_buffer->common.decRef(&native_buffer->common); return EGL_TRUE; }
EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); VALIDATE_CONTEXT_RETURN(ctx, EGL_FALSE); EGLContext_t * context = static_cast<EGLContext_t*>(ctx); /*if (getEGLThreadInfo()->currentContext == context) { eglMakeCurrent(dpy, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); } if (context->rcContext) { DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); rcEnc->rcDestroyContext(rcEnc, context->rcContext); context->rcContext = 0; } delete context;*/ return EGL_TRUE; }
EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface eglSurface) { VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); if (eglSurface == EGL_NO_SURFACE) setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); egl_surface_t* d = static_cast<egl_surface_t*>(eglSurface); if (d->dpy != dpy) setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE); // post the surface d->swapBuffers(); hostCon->flush(); return EGL_TRUE; }
EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) { VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); int attribs_size = 0; if (attrib_list) { const EGLint * attrib_p = attrib_list; while (attrib_p[0] != EGL_NONE) { attribs_size += 2; attrib_p += 2; } attribs_size++; //for the terminating EGL_NONE } DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); *num_config = rcEnc->rcChooseConfig(rcEnc, (EGLint*)attrib_list, attribs_size * sizeof(EGLint), (uint32_t*)configs, config_size); return EGL_TRUE; }
EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) { VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); EGLContext_t* ctx = getEGLThreadInfo()->currentContext; if (!ctx) { setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE); } if (!ctx->draw) { setErrorReturn(EGL_BAD_SURFACE, EGL_FALSE); } egl_surface_t* draw(static_cast<egl_surface_t*>(ctx->draw)); draw->setSwapInterval(interval); rcEnc->rcFBSetSwapInterval(rcEnc, interval); //TODO: implement on the host return EGL_TRUE; }
EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) { VALIDATE_DISPLAY_INIT(dpy, NULL); if(!num_config) { RETURN_ERROR(EGL_FALSE,EGL_BAD_PARAMETER); } GLint numConfigs = s_display.getNumConfigs(); if (!configs) { *num_config = numConfigs; return EGL_TRUE; } int i=0; for (i=0 ; i<numConfigs && i<config_size ; i++) { *configs++ = (EGLConfig)i; } *num_config = i; return EGL_TRUE; }
EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface eglSurface, EGLint attribute, EGLint *value) { VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); egl_surface_t* surface( static_cast<egl_surface_t*>(eglSurface) ); EGLBoolean ret = EGL_TRUE; switch (attribute) { case EGL_CONFIG_ID: ret = s_display.getConfigAttrib(surface->config, EGL_CONFIG_ID, value); break; case EGL_WIDTH: *value = surface->getWidth(); break; case EGL_HEIGHT: *value = surface->getHeight(); break; case EGL_TEXTURE_FORMAT: *value = surface->getTextureFormat(); break; case EGL_TEXTURE_TARGET: *value = surface->getTextureTarget(); break; case EGL_SWAP_BEHAVIOR: *value = surface->getSwapBehavior(); break; case EGL_LARGEST_PBUFFER: // not modified for a window or pixmap surface // and we ignore it when creating a PBuffer surface (default is EGL_FALSE) if (surface->getSurfaceType() & EGL_PBUFFER_BIT) *value = EGL_FALSE; break; //TODO: complete other attributes default: ALOGE("eglQuerySurface %x EGL_BAD_ATTRIBUTE", attribute); ret = setErrorFunc(EGL_BAD_ATTRIBUTE, EGL_FALSE); break; } return ret; }
EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) { VALIDATE_DISPLAY_INIT(dpy, EGL_NO_CONTEXT); VALIDATE_CONFIG(config, EGL_NO_CONTEXT); EGLint version = 1; //default while (attrib_list && attrib_list[0]) { if (attrib_list[0] == EGL_CONTEXT_CLIENT_VERSION) version = attrib_list[1]; attrib_list+=2; } uint32_t rcShareCtx = 0; EGLContext_t * shareCtx = NULL; if (share_context) { shareCtx = static_cast<EGLContext_t*>(share_context); rcShareCtx = shareCtx->rcContext; if (shareCtx->dpy != dpy) setErrorReturn(EGL_BAD_MATCH, EGL_NO_CONTEXT); } DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_NO_CONTEXT); uint32_t rcContext = rcEnc->rcCreateContext(rcEnc, (uint32_t)config, rcShareCtx, version); if (!rcContext) { ALOGE("rcCreateContext returned 0"); setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT); } EGLContext_t * context = new EGLContext_t(dpy, config, shareCtx); if (!context) setErrorReturn(EGL_BAD_ALLOC, EGL_NO_CONTEXT); context->version = version; context->rcContext = rcContext; return context; }
EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); VALIDATE_SURFACE_RETURN(draw, EGL_FALSE); VALIDATE_SURFACE_RETURN(read, EGL_FALSE); if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT)) setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT)) setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); EGLContext_t * context = static_cast<EGLContext_t*>(ctx); uint32_t ctxHandle = (context) ? context->rcContext : 0; egl_surface_t * drawSurf = static_cast<egl_surface_t *>(draw); uint32_t drawHandle = (drawSurf) ? drawSurf->getRcSurface() : 0; egl_surface_t * readSurf = static_cast<egl_surface_t *>(read); uint32_t readHandle = (readSurf) ? readSurf->getRcSurface() : 0; // // Nothing to do if no binding change has made // EGLThreadInfo *tInfo = getEGLThreadInfo(); if (tInfo->currentContext == context && (context == NULL || (context && context->draw == draw && context->read == read))) { return EGL_TRUE; } if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) { //context is current to another thread setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE); } DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); if (rcEnc->rcMakeCurrent(rcEnc, ctxHandle, drawHandle, readHandle) == EGL_FALSE) { ALOGE("rcMakeCurrent returned EGL_FALSE"); setErrorReturn(EGL_BAD_CONTEXT, EGL_FALSE); } //Now make the local bind if (context) { context->draw = draw; context->read = read; context->flags |= EGLContext_t::IS_CURRENT; //set the client state if (context->version == 2) { hostCon->gl2Encoder()->setClientState(context->getClientState()); hostCon->gl2Encoder()->setSharedGroup(context->getSharedGroup()); } else { hostCon->glEncoder()->setClientState(context->getClientState()); hostCon->glEncoder()->setSharedGroup(context->getSharedGroup()); } } else { //release ClientState & SharedGroup if (tInfo->currentContext->version == 2) { hostCon->gl2Encoder()->setClientState(NULL); hostCon->gl2Encoder()->setSharedGroup(GLSharedGroupPtr(NULL)); } else { hostCon->glEncoder()->setClientState(NULL); hostCon->glEncoder()->setSharedGroup(GLSharedGroupPtr(NULL)); } } if (tInfo->currentContext) tInfo->currentContext->flags &= ~EGLContext_t::IS_CURRENT; //Now make current tInfo->currentContext = context; //Check maybe we need to init the encoder, if it's first eglMakeCurrent if (tInfo->currentContext) { if (tInfo->currentContext->version == 2) { if (!hostCon->gl2Encoder()->isInitialized()) { s_display.gles2_iface()->init(); hostCon->gl2Encoder()->setInitialized(); ClientAPIExts::initClientFuncs(s_display.gles2_iface(), 1); } } else { if (!hostCon->glEncoder()->isInitialized()) { s_display.gles_iface()->init(); hostCon->glEncoder()->setInitialized(); ClientAPIExts::initClientFuncs(s_display.gles_iface(), 0); } } } return EGL_TRUE; }
const char* eglQueryString(EGLDisplay dpy, EGLint name) { VALIDATE_DISPLAY_INIT(dpy, NULL); return s_display.queryString(name); }