adding error handling for Xerrors on EGl linux implementation (EglLinuxApi.cpp)

Change-Id: Ib8535e2c25c7de67c8d7830a644643b52742ceaa
This commit is contained in:
David 'Digit' Turner
2011-05-03 16:42:44 +02:00
parent 892a6306e7
commit 4707d72787
3 changed files with 79 additions and 24 deletions

View File

@@ -418,7 +418,7 @@ EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay display, EGLConf
if(!(cfg->surfaceType() & EGL_WINDOW_BIT)) { if(!(cfg->surfaceType() & EGL_WINDOW_BIT)) {
RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_MATCH); 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); RETURN_ERROR(EGL_NO_SURFACE,EGL_BAD_NATIVE_WINDOW);
} }
if(!EglValidate::noAttribs(attrib_list)) { if(!EglValidate::noAttribs(attrib_list)) {
@@ -669,19 +669,22 @@ EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay display, EGLSurface draw
RETURN_ERROR(EGL_FALSE,EGL_BAD_MATCH); RETURN_ERROR(EGL_FALSE,EGL_BAD_MATCH);
} }
EGLNativeDisplayType nativeDisplay = dpy->nativeType();
void* nativeRead = newReadPtr->native();
void* nativeDraw = newDrawPtr->native();
//checking native window validity //checking native window validity
if(newReadPtr->type() == EglSurface::WINDOW && !EglOS::validNativeWin(reinterpret_cast<EGLNativeWindowType>(newReadPtr->native()))) { if(newReadPtr->type() == EglSurface::WINDOW && !EglOS::validNativeWin(nativeDisplay,reinterpret_cast<EGLNativeWindowType>(nativeRead))) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW); RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW);
} }
if(newDrawPtr->type() == EglSurface::WINDOW && !EglOS::validNativeWin(reinterpret_cast<EGLNativeWindowType>(newDrawPtr->native()))) { if(newDrawPtr->type() == EglSurface::WINDOW && !EglOS::validNativeWin(nativeDisplay,reinterpret_cast<EGLNativeWindowType>(nativeDraw))) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW); RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_WINDOW);
} }
//checking native pixmap validity //checking native pixmap validity
if(newReadPtr->type() == EglSurface::PIXMAP && !EglOS::validNativePixmap(reinterpret_cast<EGLNativePixmapType>(newReadPtr->native()))) { if(newReadPtr->type() == EglSurface::PIXMAP && !EglOS::validNativePixmap(nativeDisplay,reinterpret_cast<EGLNativePixmapType>(nativeRead))) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP); RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP);
} }
if(newDrawPtr->type() == EglSurface::PIXMAP && !EglOS::validNativePixmap(reinterpret_cast<EGLNativePixmapType>(newDrawPtr->native()))) { if(newDrawPtr->type() == EglSurface::PIXMAP && !EglOS::validNativePixmap(nativeDisplay,reinterpret_cast<EGLNativePixmapType>(nativeDraw))) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP); RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP);
} }
if(prevCtx) { if(prevCtx) {
@@ -750,7 +753,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay display, EGLSurface surf
RETURN_ERROR(EGL_TRUE,EGL_SUCCESS); RETURN_ERROR(EGL_TRUE,EGL_SUCCESS);
} }
if(!currentCtx || !currentCtx->usingSurface(Srfc) || !EglOS::validNativeWin(reinterpret_cast<EGLNativeWindowType>(Srfc.Ptr()->native()))) { if(!currentCtx || !currentCtx->usingSurface(Srfc) || !EglOS::validNativeWin(dpy->nativeType(),reinterpret_cast<EGLNativeWindowType>(Srfc.Ptr()->native()))) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
} }
@@ -815,27 +818,29 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine) {
} }
ThreadInfo* thread = getThreadInfo(); ThreadInfo* thread = getThreadInfo();
EglContext* currCtx = static_cast<EglContext*>(thread->eglContext); EglContext* currCtx = static_cast<EglContext*>(thread->eglContext);
EglDisplay* dpy = static_cast<EglDisplay*>(thread->eglDisplay);
if(currCtx) { if(currCtx) {
EglSurface* read = currCtx->read().Ptr(); SurfacePtr read = currCtx->read();
EglSurface* draw = currCtx->read().Ptr(); SurfacePtr draw = currCtx->draw();
EGLNativeDisplayType nativeDisplay = dpy->nativeType();
if(read) { if(read) {
if(read->type() == EglSurface::WINDOW && if(read->type() == EglSurface::WINDOW &&
!EglOS::validNativeWin(reinterpret_cast<EGLNativeWindowType>(read->native()))) { !EglOS::validNativeWin(nativeDisplay,reinterpret_cast<EGLNativeWindowType>(read->native()))) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
} }
if(read->type() == EglSurface::PIXMAP && if(read->type() == EglSurface::PIXMAP &&
!EglOS::validNativePixmap(reinterpret_cast<EGLNativePixmapType>(read->native()))) { !EglOS::validNativePixmap(nativeDisplay,reinterpret_cast<EGLNativePixmapType>(read->native()))) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
} }
} }
if(draw) { if(draw) {
if(draw->type() == EglSurface::WINDOW && if(draw->type() == EglSurface::WINDOW &&
!EglOS::validNativeWin(reinterpret_cast<EGLNativeWindowType>(draw->native()))) { !EglOS::validNativeWin(nativeDisplay,reinterpret_cast<EGLNativeWindowType>(draw->native()))) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
} }
if(draw->type() == EglSurface::PIXMAP && if(draw->type() == EglSurface::PIXMAP &&
!EglOS::validNativePixmap(reinterpret_cast<EGLNativePixmapType>(draw->native()))) { !EglOS::validNativePixmap(nativeDisplay,reinterpret_cast<EGLNativePixmapType>(draw->native()))) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE); RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
} }
} }
@@ -909,7 +914,7 @@ EGLAPI EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay display, EGLSurface surf
EGLNativePixmapType target) { EGLNativePixmapType target) {
VALIDATE_DISPLAY(display); VALIDATE_DISPLAY(display);
VALIDATE_SURFACE(surface,srfc); VALIDATE_SURFACE(surface,srfc);
if(!EglOS::validNativePixmap(target)) { if(!EglOS::validNativePixmap(dpy->nativeType(),target)) {
RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP); RETURN_ERROR(EGL_FALSE,EGL_BAD_NATIVE_PIXMAP);
} }

View File

@@ -36,8 +36,8 @@ namespace EglOS{
bool releasePbuffer(EGLNativeDisplayType dis,EGLNativePbufferType pb); bool releasePbuffer(EGLNativeDisplayType dis,EGLNativePbufferType pb);
bool destroyContext(EGLNativeDisplayType dpy,EGLNativeContextType ctx); bool destroyContext(EGLNativeDisplayType dpy,EGLNativeContextType ctx);
bool releaseDisplay(EGLNativeDisplayType dpy); bool releaseDisplay(EGLNativeDisplayType dpy);
bool validNativeWin(EGLNativeWindowType win); bool validNativeWin(EGLNativeDisplayType dpy,EGLNativeWindowType win);
bool validNativePixmap(EGLNativePixmapType pix); bool validNativePixmap(EGLNativeDisplayType dpy,EGLNativePixmapType pix);
bool checkWindowPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativeWindowType win,EglConfig* cfg,unsigned int* width,unsigned int* height); 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 checkPixmapPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativePixmapType pix,EglConfig* cfg,unsigned int* width,unsigned int* height);
bool makeCurrent(EGLNativeDisplayType dpy,EglSurface* read,EglSurface* draw,EGLNativeContextType); bool makeCurrent(EGLNativeDisplayType dpy,EglSurface* read,EglSurface* draw,EGLNativeContextType);

View File

@@ -15,9 +15,48 @@
*/ */
#include "EglOsApi.h" #include "EglOsApi.h"
#include <string.h> #include <string.h>
#include <X11/Xlib.h>
#include <GL/glx.h> #include <GL/glx.h>
#include <utils/threads.h>
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) \ #define IS_SUCCESS(a) \
if(a != Success) return false; if(a != Success) return false;
@@ -109,14 +148,22 @@ void queryConfigs(EGLNativeDisplayType dpy,ConfigsList& listOut) {
XFree(frmtList); XFree(frmtList);
} }
bool validNativeWin(EGLNativeWindowType win) { bool validNativeWin(EGLNativeDisplayType dpy,EGLNativeWindowType win) {
//TODO: use XGetgeometry to check validity Window root;
return true; 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) { bool validNativePixmap(EGLNativeDisplayType dpy,EGLNativePixmapType pix) {
//TODO: use XGetgeometry to check validity Window root;
return true; 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) { 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) { 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) { bool destroyContext(EGLNativeDisplayType dpy,EGLNativeContextType ctx) {
@@ -188,8 +237,9 @@ GLXDrawable convertSurface(EglSurface* srfc) {
bool makeCurrent(EGLNativeDisplayType dpy,EglSurface* read,EglSurface* draw,EGLNativeContextType ctx){ bool makeCurrent(EGLNativeDisplayType dpy,EglSurface* read,EglSurface* draw,EGLNativeContextType ctx){
ErrorHandler handler(dpy);
return glXMakeContextCurrent(dpy,convertSurface(draw),convertSurface(read),ctx); bool retval = glXMakeContextCurrent(dpy,convertSurface(draw),convertSurface(read),ctx);
return (handler.getLastError() == 0) && retval;
} }
void swapBuffers(EGLNativeDisplayType dpy,EGLNativeWindowType win) { void swapBuffers(EGLNativeDisplayType dpy,EGLNativeWindowType win) {