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)) {
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user