diff options
Diffstat (limited to 'emulator/opengl/system/egl/egl.cpp')
-rw-r--r-- | emulator/opengl/system/egl/egl.cpp | 1254 |
1 files changed, 0 insertions, 1254 deletions
diff --git a/emulator/opengl/system/egl/egl.cpp b/emulator/opengl/system/egl/egl.cpp deleted file mode 100644 index ee195ac..0000000 --- a/emulator/opengl/system/egl/egl.cpp +++ /dev/null @@ -1,1254 +0,0 @@ -/* -* Copyright (C) 2011 The Android Open Source Project -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -#include "HostConnection.h" -#include "ThreadInfo.h" -#include "eglDisplay.h" -#include "egl_ftable.h" -#include <cutils/log.h> -#include "gralloc_cb.h" -#include "GLClientState.h" -#include "GLSharedGroup.h" -#include "eglContext.h" -#include "ClientAPIExts.h" - -#include "GLEncoder.h" -#ifdef WITH_GLES2 -#include "GL2Encoder.h" -#endif - -#include <system/window.h> - -template<typename T> -static T setErrorFunc(GLint error, T returnValue) { - getEGLThreadInfo()->eglError = error; - return returnValue; -} - -const char * eglStrError(EGLint err) -{ - switch (err){ - case EGL_SUCCESS: return "EGL_SUCCESS"; - case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; - case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; - case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; - case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; - case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; - case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; - case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; - case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; - case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; - case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; - case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; - case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; - case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; - case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; - default: return "UNKNOWN"; - } -} - -#define LOG_EGL_ERRORS 1 - -#ifdef LOG_EGL_ERRORS - -#define setErrorReturn(error, retVal) \ - { \ - ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, error, eglStrError(error)); \ - return setErrorFunc(error, retVal); \ - } - -#define RETURN_ERROR(ret,err) \ - ALOGE("tid %d: %s(%d): error 0x%x (%s)", gettid(), __FUNCTION__, __LINE__, err, eglStrError(err)); \ - getEGLThreadInfo()->eglError = err; \ - return ret; - -#else //!LOG_EGL_ERRORS - -#define setErrorReturn(error, retVal) return setErrorFunc(error, retVal); - -#define RETURN_ERROR(ret,err) \ - getEGLThreadInfo()->eglError = err; \ - return ret; - -#endif //LOG_EGL_ERRORS - -#define VALIDATE_CONFIG(cfg,ret) \ - if(((int)cfg<0)||((int)cfg>s_display.getNumConfigs())) { \ - RETURN_ERROR(ret,EGL_BAD_CONFIG); \ - } - -#define VALIDATE_DISPLAY(dpy,ret) \ - if ((dpy) != (EGLDisplay)&s_display) { \ - RETURN_ERROR(ret, EGL_BAD_DISPLAY); \ - } - -#define VALIDATE_DISPLAY_INIT(dpy,ret) \ - VALIDATE_DISPLAY(dpy, ret) \ - if (!s_display.initialized()) { \ - RETURN_ERROR(ret, EGL_NOT_INITIALIZED); \ - } - -#define DEFINE_HOST_CONNECTION \ - HostConnection *hostCon = HostConnection::get(); \ - renderControl_encoder_context_t *rcEnc = (hostCon ? hostCon->rcEncoder() : NULL) - -#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \ - HostConnection *hostCon = HostConnection::get(); \ - if (!hostCon) { \ - ALOGE("egl: Failed to get host connection\n"); \ - return ret; \ - } \ - renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \ - if (!rcEnc) { \ - ALOGE("egl: Failed to get renderControl encoder context\n"); \ - return ret; \ - } - -#define VALIDATE_CONTEXT_RETURN(context,ret) \ - if (!context) { \ - RETURN_ERROR(ret,EGL_BAD_CONTEXT); \ - } - -#define VALIDATE_SURFACE_RETURN(surface, ret) \ - if (surface != EGL_NO_SURFACE) { \ - egl_surface_t* s( static_cast<egl_surface_t*>(surface) ); \ - if (s->dpy != (EGLDisplay)&s_display) \ - setErrorReturn(EGL_BAD_DISPLAY, EGL_FALSE); \ - } - - -EGLContext_t::EGLContext_t(EGLDisplay dpy, EGLConfig config, EGLContext_t* shareCtx) : - dpy(dpy), - config(config), - read(EGL_NO_SURFACE), - draw(EGL_NO_SURFACE), - shareCtx(shareCtx), - rcContext(0), - versionString(NULL), - vendorString(NULL), - rendererString(NULL), - extensionString(NULL) -{ - flags = 0; - version = 1; - clientState = new GLClientState(); - if (shareCtx) - sharedGroup = shareCtx->getSharedGroup(); - else - sharedGroup = GLSharedGroupPtr(new GLSharedGroup()); -}; - -EGLContext_t::~EGLContext_t() -{ - delete clientState; - delete [] versionString; - delete [] vendorString; - delete [] rendererString; - delete [] extensionString; -} - -// ---------------------------------------------------------------------------- -//egl_surface_t - -//we don't need to handle depth since it's handled when window created on the host - -struct egl_surface_t { - - EGLDisplay dpy; - EGLConfig config; - - - egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType); - virtual ~egl_surface_t(); - - virtual void setSwapInterval(int interval) = 0; - virtual EGLBoolean swapBuffers() = 0; - - EGLint getSwapBehavior() const; - uint32_t getRcSurface() { return rcSurface; } - EGLint getSurfaceType() { return surfaceType; } - - EGLint getWidth(){ return width; } - EGLint getHeight(){ return height; } - void setTextureFormat(EGLint _texFormat) { texFormat = _texFormat; } - EGLint getTextureFormat() { return texFormat; } - void setTextureTarget(EGLint _texTarget) { texTarget = _texTarget; } - EGLint getTextureTarget() { return texTarget; } - -private: - // - //Surface attributes - // - EGLint width; - EGLint height; - EGLint texFormat; - EGLint texTarget; - -protected: - void setWidth(EGLint w) { width = w; } - void setHeight(EGLint h) { height = h; } - - EGLint surfaceType; - uint32_t rcSurface; //handle to surface created via remote control -}; - -egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType) - : dpy(dpy), config(config), surfaceType(surfaceType), rcSurface(0) -{ - width = 0; - height = 0; - texFormat = EGL_NO_TEXTURE; - texTarget = EGL_NO_TEXTURE; -} - -EGLint egl_surface_t::getSwapBehavior() const { - return EGL_BUFFER_PRESERVED; -} - -egl_surface_t::~egl_surface_t() -{ -} - -// ---------------------------------------------------------------------------- -// egl_window_surface_t - -struct egl_window_surface_t : public egl_surface_t { - static egl_window_surface_t* create( - EGLDisplay dpy, EGLConfig config, EGLint surfType, - ANativeWindow* window); - - virtual ~egl_window_surface_t(); - - virtual void setSwapInterval(int interval); - virtual EGLBoolean swapBuffers(); - -private: - egl_window_surface_t( - EGLDisplay dpy, EGLConfig config, EGLint surfType, - ANativeWindow* window); - EGLBoolean init(); - - ANativeWindow* nativeWindow; - android_native_buffer_t* buffer; -}; - -egl_window_surface_t::egl_window_surface_t ( - EGLDisplay dpy, EGLConfig config, EGLint surfType, - ANativeWindow* window) -: egl_surface_t(dpy, config, surfType), - nativeWindow(window), - buffer(NULL) -{ - // keep a reference on the window - nativeWindow->common.incRef(&nativeWindow->common); - EGLint w,h; - nativeWindow->query(nativeWindow, NATIVE_WINDOW_WIDTH, &w); - setWidth(w); - nativeWindow->query(nativeWindow, NATIVE_WINDOW_HEIGHT, &h); - setHeight(h); -} - -EGLBoolean egl_window_surface_t::init() -{ - if (nativeWindow->dequeueBuffer(nativeWindow, &buffer) != NO_ERROR) { - setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE); - } - nativeWindow->lockBuffer(nativeWindow, buffer); - - DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); - rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, - getWidth(), getHeight()); - if (!rcSurface) { - ALOGE("rcCreateWindowSurface returned 0"); - return EGL_FALSE; - } - rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, - ((cb_handle_t*)(buffer->handle))->hostHandle); - - return EGL_TRUE; -} - -egl_window_surface_t* egl_window_surface_t::create( - EGLDisplay dpy, EGLConfig config, EGLint surfType, - ANativeWindow* window) -{ - egl_window_surface_t* wnd = new egl_window_surface_t( - dpy, config, surfType, window); - if (wnd && !wnd->init()) { - delete wnd; - wnd = NULL; - } - return wnd; -} - -egl_window_surface_t::~egl_window_surface_t() { - DEFINE_HOST_CONNECTION; - if (rcSurface && rcEnc) { - rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface); - } - if (buffer) { - nativeWindow->cancelBuffer(nativeWindow, buffer); - } - nativeWindow->common.decRef(&nativeWindow->common); -} - -void egl_window_surface_t::setSwapInterval(int interval) -{ - nativeWindow->setSwapInterval(nativeWindow, interval); -} - -EGLBoolean egl_window_surface_t::swapBuffers() -{ - DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); - - rcEnc->rcFlushWindowColorBuffer(rcEnc, rcSurface); - - nativeWindow->queueBuffer(nativeWindow, buffer); - if (nativeWindow->dequeueBuffer(nativeWindow, &buffer)) { - buffer = NULL; - setErrorReturn(EGL_BAD_ALLOC, EGL_FALSE); - } - nativeWindow->lockBuffer(nativeWindow, buffer); - - rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, - ((cb_handle_t *)(buffer->handle))->hostHandle); - - return EGL_TRUE; -} - -// ---------------------------------------------------------------------------- -//egl_pbuffer_surface_t - -struct egl_pbuffer_surface_t : public egl_surface_t { - static egl_pbuffer_surface_t* create(EGLDisplay dpy, EGLConfig config, - EGLint surfType, int32_t w, int32_t h, GLenum pixelFormat); - - virtual ~egl_pbuffer_surface_t(); - - virtual void setSwapInterval(int interval) {} - virtual EGLBoolean swapBuffers() { return EGL_TRUE; } - - uint32_t getRcColorBuffer() { return rcColorBuffer; } - -private: - egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfType, - int32_t w, int32_t h); - EGLBoolean init(GLenum format); - - uint32_t rcColorBuffer; -}; - -egl_pbuffer_surface_t::egl_pbuffer_surface_t(EGLDisplay dpy, EGLConfig config, - EGLint surfType, int32_t w, int32_t h) -: egl_surface_t(dpy, config, surfType), - rcColorBuffer(0) -{ - setWidth(w); - setHeight(h); -} - -egl_pbuffer_surface_t::~egl_pbuffer_surface_t() -{ - DEFINE_HOST_CONNECTION; - if (rcEnc) { - if (rcColorBuffer) rcEnc->rcCloseColorBuffer(rcEnc, rcColorBuffer); - if (rcSurface) rcEnc->rcDestroyWindowSurface(rcEnc, rcSurface); - } -} - -EGLBoolean egl_pbuffer_surface_t::init(GLenum pixelFormat) -{ - DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); - - rcSurface = rcEnc->rcCreateWindowSurface(rcEnc, (uint32_t)config, - getWidth(), getHeight()); - if (!rcSurface) { - ALOGE("rcCreateWindowSurface returned 0"); - return EGL_FALSE; - } - - rcColorBuffer = rcEnc->rcCreateColorBuffer(rcEnc, getWidth(), getHeight(), - pixelFormat); - if (!rcColorBuffer) { - ALOGE("rcCreateColorBuffer returned 0"); - return EGL_FALSE; - } - - rcEnc->rcSetWindowColorBuffer(rcEnc, rcSurface, rcColorBuffer); - - return EGL_TRUE; -} - -egl_pbuffer_surface_t* egl_pbuffer_surface_t::create(EGLDisplay dpy, - EGLConfig config, EGLint surfType, int32_t w, int32_t h, - GLenum pixelFormat) -{ - egl_pbuffer_surface_t* pb = new egl_pbuffer_surface_t(dpy, config, surfType, - w, h); - if (pb && !pb->init(pixelFormat)) { - delete pb; - pb = NULL; - } - return pb; -} - -static const char *getGLString(int glEnum) -{ - EGLThreadInfo *tInfo = getEGLThreadInfo(); - if (!tInfo || !tInfo->currentContext) { - return NULL; - } - - const char** strPtr = NULL; - -#define GL_VENDOR 0x1F00 -#define GL_RENDERER 0x1F01 -#define GL_VERSION 0x1F02 -#define GL_EXTENSIONS 0x1F03 - - switch(glEnum) { - case GL_VERSION: - strPtr = &tInfo->currentContext->versionString; - break; - case GL_VENDOR: - strPtr = &tInfo->currentContext->vendorString; - break; - case GL_RENDERER: - strPtr = &tInfo->currentContext->rendererString; - break; - case GL_EXTENSIONS: - strPtr = &tInfo->currentContext->extensionString; - break; - } - - if (!strPtr) { - return NULL; - } - - if (*strPtr != NULL) { - // - // string is already cached - // - return *strPtr; - } - - // - // first query of that string - need to query host - // - DEFINE_AND_VALIDATE_HOST_CONNECTION(NULL); - char *hostStr = NULL; - int n = rcEnc->rcGetGLString(rcEnc, glEnum, NULL, 0); - if (n < 0) { - hostStr = new char[-n+1]; - n = rcEnc->rcGetGLString(rcEnc, glEnum, hostStr, -n); - if (n <= 0) { - delete [] hostStr; - hostStr = NULL; - } - } - - // - // keep the string in the context and return its value - // - *strPtr = hostStr; - return hostStr; -} - -// ---------------------------------------------------------------------------- - -// The one and only supported display object. -static eglDisplay s_display; - -static EGLClient_eglInterface s_eglIface = { - getThreadInfo: getEGLThreadInfo, - getGLString: getGLString -}; - -#define DBG_FUNC DBG("%s\n", __FUNCTION__) -EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) -{ - // - // we support only EGL_DEFAULT_DISPLAY. - // - if (display_id != EGL_DEFAULT_DISPLAY) { - return EGL_NO_DISPLAY; - } - - return (EGLDisplay)&s_display; -} - -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; -} - -EGLBoolean eglTerminate(EGLDisplay dpy) -{ - VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); - - s_display.terminate(); - return EGL_TRUE; -} - -EGLint eglGetError() -{ - EGLint error = getEGLThreadInfo()->eglError; - getEGLThreadInfo()->eglError = EGL_SUCCESS; - return error; -} - -__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) -{ - // search in EGL function table - for (int i=0; i<egl_num_funcs; i++) { - if (!strcmp(egl_funcs_by_name[i].name, procname)) { - return (__eglMustCastToProperFunctionPointerType)egl_funcs_by_name[i].proc; - } - } - - // - // Make sure display is initialized before searching in client APIs - // - if (!s_display.initialized()) { - if (!s_display.initialize(&s_eglIface)) { - return NULL; - } - } - - // look in gles client api's extensions table - return (__eglMustCastToProperFunctionPointerType)ClientAPIExts::getProcAddress(procname); - - // Fail - function not found. - return NULL; -} - -const char* eglQueryString(EGLDisplay dpy, EGLint name) -{ - VALIDATE_DISPLAY_INIT(dpy, NULL); - - return s_display.queryString(name); -} - -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 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 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); - } -} - -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; -} - -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; -} - -EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) -{ - //XXX: Pixmap not supported. The host cannot render to a pixmap resource - // located on host. In order to support Pixmaps we should either punt - // to s/w rendering -or- let the host render to a buffer that will be - // copied back to guest at some sync point. None of those methods not - // implemented and pixmaps are not used with OpenGL anyway ... - return EGL_NO_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 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; -} - -EGLBoolean eglBindAPI(EGLenum api) -{ - if (api != EGL_OPENGL_ES_API) - setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); - return EGL_TRUE; -} - -EGLenum eglQueryAPI() -{ - return EGL_OPENGL_ES_API; -} - -EGLBoolean eglWaitClient() -{ - return eglWaitGL(); -} - -EGLBoolean eglReleaseThread() -{ - EGLThreadInfo *tInfo = getEGLThreadInfo(); - if (tInfo && tInfo->currentContext) { - return eglMakeCurrent(&s_display, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); - } - return EGL_TRUE; -} - -EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) -{ - //TODO - ALOGW("%s not implemented", __FUNCTION__); - return 0; -} - -EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) -{ - //TODO - ALOGW("%s not implemented", __FUNCTION__); - return 0; -} - -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 eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) -{ - //TODO - ALOGW("%s not implemented", __FUNCTION__); - return 0; -} - -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; -} - -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 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 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; -} - -EGLContext eglGetCurrentContext() -{ - return getEGLThreadInfo()->currentContext; -} - -EGLSurface eglGetCurrentSurface(EGLint readdraw) -{ - EGLContext_t * context = getEGLThreadInfo()->currentContext; - if (!context) - return EGL_NO_SURFACE; //not an error - - switch (readdraw) { - case EGL_READ: - return context->read; - case EGL_DRAW: - return context->draw; - default: - setErrorReturn(EGL_BAD_PARAMETER, EGL_NO_SURFACE); - } -} - -EGLDisplay eglGetCurrentDisplay() -{ - EGLContext_t * context = getEGLThreadInfo()->currentContext; - if (!context) - return EGL_NO_DISPLAY; //not an error - - return context->dpy; -} - -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 eglWaitGL() -{ - EGLThreadInfo *tInfo = getEGLThreadInfo(); - if (!tInfo || !tInfo->currentContext) { - return EGL_FALSE; - } - - if (tInfo->currentContext->version == 2) { - s_display.gles2_iface()->finish(); - } - else { - s_display.gles_iface()->finish(); - } - - return EGL_TRUE; -} - -EGLBoolean eglWaitNative(EGLint engine) -{ - 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 eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) -{ - //TODO :later - return 0; -} - -EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list) -{ - //TODO later - return 0; -} - -EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface) -{ - //TODO later - return 0; -} - -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; -} - -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; -} - -#define FENCE_SYNC_HANDLE (EGLSyncKHR)0xFE4CE - -EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, - const EGLint *attrib_list) -{ - // TODO: This implementation could be faster. We should require the host EGL - // to support KHR_fence_sync, or at least pipe the fence command to the host - // and wait for it (probably involving a glFinish on the host) in - // eglClientWaitSyncKHR. - - VALIDATE_DISPLAY(dpy, EGL_NO_SYNC_KHR); - - if (type != EGL_SYNC_FENCE_KHR || - (attrib_list != NULL && attrib_list[0] != EGL_NONE)) { - setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_NO_SYNC_KHR); - } - - EGLThreadInfo *tInfo = getEGLThreadInfo(); - if (!tInfo || !tInfo->currentContext) { - setErrorReturn(EGL_BAD_MATCH, EGL_NO_SYNC_KHR); - } - - if (tInfo->currentContext->version == 2) { - s_display.gles2_iface()->finish(); - } else { - s_display.gles_iface()->finish(); - } - - return FENCE_SYNC_HANDLE; -} - -EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) -{ - if (sync != FENCE_SYNC_HANDLE) { - setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); - } - - return EGL_TRUE; -} - -EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, - EGLTimeKHR timeout) -{ - if (sync != FENCE_SYNC_HANDLE) { - setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); - } - - return EGL_CONDITION_SATISFIED_KHR; -} - -EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, - EGLint attribute, EGLint *value) -{ - if (sync != FENCE_SYNC_HANDLE) { - setErrorReturn(EGL_BAD_PARAMETER, EGL_FALSE); - } - - switch (attribute) { - case EGL_SYNC_TYPE_KHR: - *value = EGL_SYNC_FENCE_KHR; - return EGL_TRUE; - case EGL_SYNC_STATUS_KHR: - *value = EGL_SIGNALED_KHR; - return EGL_TRUE; - case EGL_SYNC_CONDITION_KHR: - *value = EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR; - return EGL_TRUE; - default: - setErrorReturn(EGL_BAD_ATTRIBUTE, EGL_FALSE); - } -} |