diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp b/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp index d019e180b..18671cfcf 100644 --- a/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp +++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglImp.cpp @@ -418,7 +418,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay display, EGLConf if(!(cfg->surfaceType() & EGL_WINDOW_BIT)) { RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_MATCH); } - if(!EglOS::validNativeWin(win)) { + if(!EglOS::validNativeWin(dpy->nativeType(),win)) { RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_NATIVE_WINDOW); } if(!EglValidate::noAttribs(attrib_list)) { @@ -669,19 +669,22 @@ EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay display, EGLSurface draw RETURN_ERROR(EGL_FALSE,EGL_BAD_MATCH); } + EGLNativeDisplayType nativeDisplay = dpy->nativeType(); + void* nativeRead = newReadPtr->native(); + void* nativeDraw = newDrawPtr->native(); //checking native window validity - if(newReadPtr->type() == EglSurface::WINDOW && !EglOS::validNativeWin(reinterpret_cast(newReadPtr->native()))) { + if(newReadPtr->type() == EglSurface::WINDOW && !EglOS::validNativeWin(nativeDisplay,reinterpret_cast(nativeRead))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW); } - if(newDrawPtr->type() == EglSurface::WINDOW && !EglOS::validNativeWin(reinterpret_cast(newDrawPtr->native()))) { + if(newDrawPtr->type() == EglSurface::WINDOW && !EglOS::validNativeWin(nativeDisplay,reinterpret_cast(nativeDraw))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW); } //checking native pixmap validity - if(newReadPtr->type() == EglSurface::PIXMAP && !EglOS::validNativePixmap(reinterpret_cast(newReadPtr->native()))) { + if(newReadPtr->type() == EglSurface::PIXMAP && !EglOS::validNativePixmap(nativeDisplay,reinterpret_cast(nativeRead))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP); } - if(newDrawPtr->type() == EglSurface::PIXMAP && !EglOS::validNativePixmap(reinterpret_cast(newDrawPtr->native()))) { + if(newDrawPtr->type() == EglSurface::PIXMAP && !EglOS::validNativePixmap(nativeDisplay,reinterpret_cast(nativeDraw))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP); } if(prevCtx) { @@ -750,7 +753,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay display, EGLSurface surf RETURN_ERROR(EGL_TRUE,EGL_SUCCESS); } - if(!currentCtx || !currentCtx->usingSurface(Srfc) || !EglOS::validNativeWin(reinterpret_cast(Srfc.Ptr()->native()))) { + if(!currentCtx || !currentCtx->usingSurface(Srfc) || !EglOS::validNativeWin(dpy->nativeType(),reinterpret_cast(Srfc.Ptr()->native()))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); } @@ -815,27 +818,29 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine) { } ThreadInfo* thread = getThreadInfo(); EglContext* currCtx = static_cast(thread->eglContext); + EglDisplay* dpy = static_cast(thread->eglDisplay); if(currCtx) { - EglSurface* read = currCtx->read().Ptr(); - EglSurface* draw = currCtx->read().Ptr(); + SurfacePtr read = currCtx->read(); + SurfacePtr draw = currCtx->draw(); + EGLNativeDisplayType nativeDisplay = dpy->nativeType(); if(read) { if(read->type() == EglSurface::WINDOW && - !EglOS::validNativeWin(reinterpret_cast(read->native()))) { + !EglOS::validNativeWin(nativeDisplay,reinterpret_cast(read->native()))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); } if(read->type() == EglSurface::PIXMAP && - !EglOS::validNativePixmap(reinterpret_cast(read->native()))) { + !EglOS::validNativePixmap(nativeDisplay,reinterpret_cast(read->native()))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); } } if(draw) { if(draw->type() == EglSurface::WINDOW && - !EglOS::validNativeWin(reinterpret_cast(draw->native()))) { + !EglOS::validNativeWin(nativeDisplay,reinterpret_cast(draw->native()))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); } if(draw->type() == EglSurface::PIXMAP && - !EglOS::validNativePixmap(reinterpret_cast(draw->native()))) { + !EglOS::validNativePixmap(nativeDisplay,reinterpret_cast(draw->native()))) { RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); } } @@ -909,7 +914,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay display, EGLSurface surf EGLNativePixmapType target) { VALIDATE_DISPLAY(display); VALIDATE_SURFACE(surface,srfc); - if(!EglOS::validNativePixmap(target)) { + if(!EglOS::validNativePixmap(dpy->nativeType(),target)) { RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP); } diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglOsApi.h b/tools/emulator/opengl/host/libs/Translator/EGL/EglOsApi.h index f72dfd633..97841820d 100644 --- a/tools/emulator/opengl/host/libs/Translator/EGL/EglOsApi.h +++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglOsApi.h @@ -36,8 +36,8 @@ namespace EglOS{ bool releasePbuffer(EGLNativeDisplayType dis,EGLNativePbufferType pb); bool destroyContext(EGLNativeDisplayType dpy,EGLNativeContextType ctx); bool releaseDisplay(EGLNativeDisplayType dpy); - bool validNativeWin(EGLNativeWindowType win); - bool validNativePixmap(EGLNativePixmapType pix); + bool validNativeWin(EGLNativeDisplayType dpy,EGLNativeWindowType win); + bool validNativePixmap(EGLNativeDisplayType dpy,EGLNativePixmapType pix); bool checkWindowPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativeWindowType win,EglConfig* cfg,unsigned int* width,unsigned int* height); bool checkPixmapPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativePixmapType pix,EglConfig* cfg,unsigned int* width,unsigned int* height); bool makeCurrent(EGLNativeDisplayType dpy,EglSurface* read,EglSurface* draw,EGLNativeContextType); diff --git a/tools/emulator/opengl/host/libs/Translator/EGL/EglX11Api.cpp b/tools/emulator/opengl/host/libs/Translator/EGL/EglX11Api.cpp index 2f57f3a8c..a161ae10d 100644 --- a/tools/emulator/opengl/host/libs/Translator/EGL/EglX11Api.cpp +++ b/tools/emulator/opengl/host/libs/Translator/EGL/EglX11Api.cpp @@ -15,9 +15,48 @@ */ #include "EglOsApi.h" #include +#include #include +#include +class ErrorHandler{ +public: +ErrorHandler(EGLNativeDisplayType dpy); +~ErrorHandler(); +int getLastError(){ return s_lastErrorCode;}; + +private: +static int s_lastErrorCode; +int (*m_oldErrorHandler) (Display *, XErrorEvent *); +static android::Mutex s_lock; +static int errorHandlerProc(EGLNativeDisplayType dpy,XErrorEvent* event); + +}; + + +int ErrorHandler::s_lastErrorCode = 0; +android::Mutex ErrorHandler::s_lock; + +ErrorHandler::ErrorHandler(EGLNativeDisplayType dpy){ + s_lock.lock(); + XSync(dpy,False); + s_lastErrorCode = 0; + m_oldErrorHandler = XSetErrorHandler(errorHandlerProc); +} + +ErrorHandler::~ErrorHandler(){ + XSetErrorHandler(m_oldErrorHandler); + s_lastErrorCode = 0; + s_lock.unlock(); +} + +int ErrorHandler::errorHandlerProc(EGLNativeDisplayType dpy,XErrorEvent* event){ + android::Mutex::Autolock mutex(s_lock); + s_lastErrorCode = event->error_code; + return 0; +} + #define IS_SUCCESS(a) \ if(a != Success) return false; @@ -109,14 +148,22 @@ void queryConfigs(EGLNativeDisplayType dpy,ConfigsList& listOut) { XFree(frmtList); } -bool validNativeWin(EGLNativeWindowType win) { - //TODO: use XGetgeometry to check validity - return true; +bool validNativeWin(EGLNativeDisplayType dpy,EGLNativeWindowType win) { + Window root; + int tmp; + unsigned int utmp; + ErrorHandler handler(dpy); + if(!XGetGeometry(dpy,win,&root,&tmp,&tmp,&utmp,&utmp,&utmp,&utmp)) return false; + return handler.getLastError() == 0; } -bool validNativePixmap(EGLNativePixmapType pix) { - //TODO: use XGetgeometry to check validity - return true; +bool validNativePixmap(EGLNativeDisplayType dpy,EGLNativePixmapType pix) { + Window root; + int tmp; + unsigned int utmp; + ErrorHandler handler(dpy); + if(!XGetGeometry(dpy,pix,&root,&tmp,&tmp,&utmp,&utmp,&utmp,&utmp)) return false; + return handler.getLastError() == 0; } bool checkWindowPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativeWindowType win,EglConfig* cfg,unsigned int* width,unsigned int* height) { @@ -164,7 +211,9 @@ bool releasePbuffer(EGLNativeDisplayType dis,EGLNativePbufferType pb) { } EGLNativeContextType createContext(EGLNativeDisplayType dpy,EglConfig* cfg,EGLNativeContextType sharedContext) { - return glXCreateNewContext(dpy,cfg->nativeConfig(),GLX_RGBA_TYPE,sharedContext,true); + ErrorHandler handler(dpy); + EGLNativeContextType retVal = glXCreateNewContext(dpy,cfg->nativeConfig(),GLX_RGBA_TYPE,sharedContext,true); + return handler.getLastError() == 0 ? retVal : NULL; } bool destroyContext(EGLNativeDisplayType dpy,EGLNativeContextType ctx) { @@ -188,8 +237,9 @@ GLXDrawable convertSurface(EglSurface* srfc) { bool makeCurrent(EGLNativeDisplayType dpy,EglSurface* read,EglSurface* draw,EGLNativeContextType ctx){ - -return glXMakeContextCurrent(dpy,convertSurface(draw),convertSurface(read),ctx); + ErrorHandler handler(dpy); + bool retval = glXMakeContextCurrent(dpy,convertSurface(draw),convertSurface(read),ctx); + return (handler.getLastError() == 0) && retval; } void swapBuffers(EGLNativeDisplayType dpy,EGLNativeWindowType win) {