adding error handling for Xerrors on EGl linux implementation (EglLinuxApi.cpp)
Change-Id: Ib8535e2c25c7de67c8d7830a644643b52742ceaa
This commit is contained in:
@@ -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<EGLNativeWindowType>(newReadPtr->native()))) {
|
||||
if(newReadPtr->type() == EglSurface::WINDOW && !EglOS::validNativeWin(nativeDisplay,reinterpret_cast<EGLNativeWindowType>(nativeRead))) {
|
||||
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);
|
||||
}
|
||||
|
||||
//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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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<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);
|
||||
}
|
||||
|
||||
@@ -815,27 +818,29 @@ EGLAPI EGLBoolean EGLAPIENTRY eglWaitNative(EGLint engine) {
|
||||
}
|
||||
ThreadInfo* thread = getThreadInfo();
|
||||
EglContext* currCtx = static_cast<EglContext*>(thread->eglContext);
|
||||
EglDisplay* dpy = static_cast<EglDisplay*>(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<EGLNativeWindowType>(read->native()))) {
|
||||
!EglOS::validNativeWin(nativeDisplay,reinterpret_cast<EGLNativeWindowType>(read->native()))) {
|
||||
RETURN_ERROR(EGL_FALSE,EGL_BAD_SURFACE);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
if(draw) {
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -15,9 +15,48 @@
|
||||
*/
|
||||
#include "EglOsApi.h"
|
||||
#include <string.h>
|
||||
#include <X11/Xlib.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) \
|
||||
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) {
|
||||
|
||||
Reference in New Issue
Block a user