Opengl translator: fix EGL Windows specific issues
Fixed management of DC's, use one DC for each egl config as before
but use the correct one every time and not the last one used during
createContext call.
Filter out GENERIC pixel formats which might not be supported by
accelerated hardware.
Prevent calling to ChoosePixelFormat at every create{window/pbuffer}
call, instead use the exact config specified by the caller. We
need to call at least once to wglChoosePixelFormat in order to let
the driver initialize, we do it during eglInitialize time just before
querying the native pixel formats.
Change-Id: Id00addaed9cb0369c41311d2bcd3ce8c7ea6408c
This commit is contained in:
committed by
Guy Zadickario
parent
a62aa2c009
commit
44fd37338e
@@ -35,18 +35,16 @@ public:
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
DEFAULT_DISPLAY = 0
|
DEFAULT_DISPLAY = 0
|
||||||
};
|
};
|
||||||
WinDisplay():m_current(DEFAULT_DISPLAY){};
|
WinDisplay(){};
|
||||||
DisplayInfo& getInfo(int configurationIndex){ return m_map[configurationIndex];}
|
DisplayInfo& getInfo(int configurationIndex){ return m_map[configurationIndex];}
|
||||||
HDC getCurrentDC(){return m_map[m_current].dc;}
|
HDC getDC(int configId){return m_map[configId].dc;}
|
||||||
void setDefault(const DisplayInfo& info){m_map[DEFAULT_DISPLAY] = info; m_current = DEFAULT_DISPLAY;}
|
void setInfo(int configurationIndex,const DisplayInfo& info);
|
||||||
void setCurrent(int configurationIndex,const DisplayInfo& info);
|
bool isPixelFormatSet(int cfgId){ return m_map[cfgId].isPixelFormatSet;}
|
||||||
bool isCurrentPixelFormatSet(){ return m_map[m_current].isPixelFormatSet;}
|
void pixelFormatWasSet(int cfgId){m_map[cfgId].isPixelFormatSet = true;}
|
||||||
void currentPixelFormatWasSet(){m_map[m_current].isPixelFormatSet = true;}
|
bool infoExists(int configurationIndex);
|
||||||
bool needToSetCurrent(int configurationIndex);
|
|
||||||
void releaseAll();
|
void releaseAll();
|
||||||
private:
|
private:
|
||||||
std::map<int,DisplayInfo> m_map;
|
std::map<int,DisplayInfo> m_map;
|
||||||
int m_current;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void WinDisplay::releaseAll(){
|
void WinDisplay::releaseAll(){
|
||||||
@@ -56,13 +54,12 @@ void WinDisplay::releaseAll(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WinDisplay::needToSetCurrent(int configurationIndex){
|
bool WinDisplay::infoExists(int configurationIndex){
|
||||||
return m_map.find(configurationIndex) == m_map.end();
|
return m_map.find(configurationIndex) == m_map.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WinDisplay::setCurrent(int configurationIndex,const DisplayInfo& info){
|
void WinDisplay::setInfo(int configurationIndex,const DisplayInfo& info){
|
||||||
m_map[configurationIndex] = info;
|
m_map[configurationIndex] = info;
|
||||||
m_current = configurationIndex;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WglExtProcs{
|
struct WglExtProcs{
|
||||||
@@ -198,11 +195,23 @@ EGLNativeDisplayType getDefaultDisplay() {
|
|||||||
|
|
||||||
HWND hwnd = createDummyWindow();
|
HWND hwnd = createDummyWindow();
|
||||||
HDC hdc = GetDC(hwnd);
|
HDC hdc = GetDC(hwnd);
|
||||||
dpy->setDefault(DisplayInfo(hdc,hwnd));
|
dpy->setInfo(WinDisplay::DEFAULT_DISPLAY,DisplayInfo(hdc,hwnd));
|
||||||
return static_cast<EGLNativeDisplayType>(dpy);
|
return static_cast<EGLNativeDisplayType>(dpy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static HDC getDummyDC(EGLNativeDisplayType display,int cfgId){
|
||||||
|
|
||||||
|
HDC dpy = NULL;
|
||||||
|
if(display->infoExists(cfgId)){
|
||||||
|
HWND hwnd = createDummyWindow();
|
||||||
|
dpy = GetDC(hwnd);
|
||||||
|
display->setInfo(cfgId,DisplayInfo(dpy,hwnd));
|
||||||
|
} else {
|
||||||
|
dpy = display->getDC(cfgId);
|
||||||
|
}
|
||||||
|
return dpy;
|
||||||
|
}
|
||||||
void initPtrToWglFunctions(){
|
void initPtrToWglFunctions(){
|
||||||
|
|
||||||
HWND hwnd = createDummyWindow();
|
HWND hwnd = createDummyWindow();
|
||||||
@@ -250,11 +259,11 @@ void initPtrToWglFunctions(){
|
|||||||
ctx = wglCreateContext(dpy);
|
ctx = wglCreateContext(dpy);
|
||||||
if(!ctx){
|
if(!ctx){
|
||||||
err = GetLastError();
|
err = GetLastError();
|
||||||
printf("error while creating dummy context %d\n",err);
|
fprintf(stderr,"error while creating dummy context %d\n",err);
|
||||||
}
|
}
|
||||||
if(!wglMakeCurrent(dpy,ctx)){
|
if(!wglMakeCurrent(dpy,ctx)){
|
||||||
err = GetLastError();
|
err = GetLastError();
|
||||||
printf("error while making dummy context current %d\n",err);
|
fprintf(stderr,"error while making dummy context current %d\n",err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!s_wglExtProcs){
|
if(!s_wglExtProcs){
|
||||||
@@ -280,6 +289,17 @@ bool releaseDisplay(EGLNativeDisplayType dpy) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static bool initPixelFormat(HDC dc){
|
||||||
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
|
unsigned int numpf;
|
||||||
|
int iPixelFormat;
|
||||||
|
|
||||||
|
if(s_wglExtProcs->wglChoosePixelFormatARB) {
|
||||||
|
return s_wglExtProcs->wglChoosePixelFormatARB(dc,NULL, NULL, 1, &iPixelFormat, &numpf);
|
||||||
|
} else {
|
||||||
|
return ChoosePixelFormat(dc,&pfd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
EglConfig* pixelFormatToConfig(EGLNativeDisplayType display,int renderableType,EGLNativePixelFormatType* frmt,int index){
|
EglConfig* pixelFormatToConfig(EGLNativeDisplayType display,int renderableType,EGLNativePixelFormatType* frmt,int index){
|
||||||
|
|
||||||
@@ -290,10 +310,11 @@ EglConfig* pixelFormatToConfig(EGLNativeDisplayType display,int renderableType,E
|
|||||||
EGLint pMaxWidth,pMaxHeight,pMaxPixels;
|
EGLint pMaxWidth,pMaxHeight,pMaxPixels;
|
||||||
EGLint configId,level;
|
EGLint configId,level;
|
||||||
EGLint window,bitmap,pbuffer,transparent;
|
EGLint window,bitmap,pbuffer,transparent;
|
||||||
HDC dpy = display->getCurrentDC();
|
HDC dpy = getDummyDC(display,WinDisplay::DEFAULT_DISPLAY);
|
||||||
|
|
||||||
if(frmt->iPixelType != PFD_TYPE_RGBA) return NULL; // other formats are not supported yet
|
if(frmt->iPixelType != PFD_TYPE_RGBA) return NULL; // other formats are not supported yet
|
||||||
if(!((frmt->dwFlags & PFD_SUPPORT_OPENGL) && (frmt->dwFlags & PFD_DOUBLEBUFFER))) return NULL; //pixel format does not supports opengl or double buffer
|
if(!((frmt->dwFlags & PFD_SUPPORT_OPENGL) && (frmt->dwFlags & PFD_DOUBLEBUFFER))) return NULL; //pixel format does not supports opengl or double buffer
|
||||||
|
if( 0 != (frmt->dwFlags & (PFD_GENERIC_FORMAT | PFD_NEED_PALETTE )) ) return NULL; //discard generic pixel formats as well as pallete pixel formats
|
||||||
|
|
||||||
int attribs [] = {
|
int attribs [] = {
|
||||||
WGL_DRAW_TO_WINDOW_ARB,
|
WGL_DRAW_TO_WINDOW_ARB,
|
||||||
@@ -315,6 +336,7 @@ EglConfig* pixelFormatToConfig(EGLNativeDisplayType display,int renderableType,E
|
|||||||
if(bitmap) supportedSurfaces |= EGL_PIXMAP_BIT;
|
if(bitmap) supportedSurfaces |= EGL_PIXMAP_BIT;
|
||||||
if(pbuffer) supportedSurfaces |= EGL_PBUFFER_BIT;
|
if(pbuffer) supportedSurfaces |= EGL_PBUFFER_BIT;
|
||||||
|
|
||||||
|
|
||||||
if(!supportedSurfaces) return NULL;
|
if(!supportedSurfaces) return NULL;
|
||||||
|
|
||||||
//default values
|
//default values
|
||||||
@@ -352,8 +374,14 @@ EglConfig* pixelFormatToConfig(EGLNativeDisplayType display,int renderableType,E
|
|||||||
void queryConfigs(EGLNativeDisplayType display,int renderableType,ConfigsList& listOut) {
|
void queryConfigs(EGLNativeDisplayType display,int renderableType,ConfigsList& listOut) {
|
||||||
PIXELFORMATDESCRIPTOR pfd;
|
PIXELFORMATDESCRIPTOR pfd;
|
||||||
int iPixelFormat = 1;
|
int iPixelFormat = 1;
|
||||||
HDC dpy = display->getCurrentDC();
|
HDC dpy = getDummyDC(display,WinDisplay::DEFAULT_DISPLAY);
|
||||||
|
|
||||||
|
//
|
||||||
|
// We need to call wglChoosePixelFormat at least once,
|
||||||
|
// seems that the driver needs to initialize itself.
|
||||||
|
// do it here during initialization.
|
||||||
|
//
|
||||||
|
initPixelFormat(dpy);
|
||||||
|
|
||||||
//quering num of formats
|
//quering num of formats
|
||||||
int nFormats = DescribePixelFormat(dpy, iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR), &pfd);
|
int nFormats = DescribePixelFormat(dpy, iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR), &pfd);
|
||||||
@@ -364,7 +392,6 @@ void queryConfigs(EGLNativeDisplayType display,int renderableType,ConfigsList& l
|
|||||||
EglConfig* pConfig = pixelFormatToConfig(display,renderableType,&pfd,iPixelFormat);
|
EglConfig* pConfig = pixelFormatToConfig(display,renderableType,&pfd,iPixelFormat);
|
||||||
if(pConfig) listOut.push_back(pConfig);
|
if(pConfig) listOut.push_back(pConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool validNativeWin(EGLNativeDisplayType dpy,EGLNativeWindowType win) {
|
bool validNativeWin(EGLNativeDisplayType dpy,EGLNativeWindowType win) {
|
||||||
@@ -380,49 +407,13 @@ bool validNativePixmap(EGLNativeDisplayType dpy,EGLNativeSurfaceType pix) {
|
|||||||
return GetObject(pix->getBmap(), sizeof(BITMAP), (LPSTR)&bm);
|
return GetObject(pix->getBmap(), sizeof(BITMAP), (LPSTR)&bm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool setPixelFormat(HDC dc,EglConfig* cfg) {
|
|
||||||
EGLint red,green,blue,alpha,depth,stencil;
|
|
||||||
bool gotAttribs = cfg->getConfAttrib(EGL_RED_SIZE,&red) &&
|
|
||||||
cfg->getConfAttrib(EGL_GREEN_SIZE,&green) &&
|
|
||||||
cfg->getConfAttrib(EGL_BLUE_SIZE,&blue) &&
|
|
||||||
cfg->getConfAttrib(EGL_ALPHA_SIZE,&alpha) &&
|
|
||||||
cfg->getConfAttrib(EGL_DEPTH_SIZE,&depth) &&
|
|
||||||
cfg->getConfAttrib(EGL_STENCIL_SIZE,&stencil) ;
|
|
||||||
|
|
||||||
if(!gotAttribs) return false;
|
|
||||||
int wglPixelFormatAttribs[] = {
|
|
||||||
WGL_SUPPORT_OPENGL_ARB ,TRUE,
|
|
||||||
WGL_DRAW_TO_PBUFFER_ARB ,TRUE,
|
|
||||||
WGL_DRAW_TO_WINDOW_ARB ,TRUE,
|
|
||||||
WGL_COLOR_BITS_ARB ,red+green+blue,
|
|
||||||
WGL_RED_BITS_ARB ,red,
|
|
||||||
WGL_GREEN_BITS_ARB ,green,
|
|
||||||
WGL_BLUE_BITS_ARB ,blue,
|
|
||||||
WGL_ALPHA_BITS_ARB ,alpha,
|
|
||||||
WGL_STENCIL_BITS_ARB ,stencil,
|
|
||||||
WGL_DEPTH_BITS_ARB ,depth,
|
|
||||||
WGL_DOUBLE_BUFFER_ARB ,TRUE,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
int iPixelFormat;
|
|
||||||
unsigned int numpf;
|
|
||||||
if(!s_wglExtProcs->wglChoosePixelFormatARB || !s_wglExtProcs->wglChoosePixelFormatARB(dc,wglPixelFormatAttribs, NULL, 1, &iPixelFormat, &numpf)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
EGLNativePixelFormatType frmt = cfg->nativeConfig();
|
|
||||||
//int iPixelFormat = ChoosePixelFormat(dc,&frmt);
|
|
||||||
if(!iPixelFormat) return false;
|
|
||||||
return SetPixelFormat(dc,iPixelFormat,&frmt);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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) {
|
||||||
RECT r;
|
RECT r;
|
||||||
if(!GetClientRect(win,&r)) return false;
|
if(!GetClientRect(win,&r)) return false;
|
||||||
*width = r.right - r.left;
|
*width = r.right - r.left;
|
||||||
*height = r.bottom - r.top;
|
*height = r.bottom - r.top;
|
||||||
HDC dc = GetDC(win);
|
HDC dc = GetDC(win);
|
||||||
bool ret = setPixelFormat(dc,cfg);
|
bool ret = SetPixelFormat(dc,cfg->nativeId(),&cfg->nativeConfig());
|
||||||
DeleteDC(dc);
|
DeleteDC(dc);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -440,39 +431,8 @@ bool checkPixmapPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativePixmapType pi
|
|||||||
|
|
||||||
EGLNativeSurfaceType createPbufferSurface(EGLNativeDisplayType display,EglConfig* cfg,EglPbufferSurface* pbSurface) {
|
EGLNativeSurfaceType createPbufferSurface(EGLNativeDisplayType display,EglConfig* cfg,EglPbufferSurface* pbSurface) {
|
||||||
|
|
||||||
//converting configuration into WGL pixel Format
|
|
||||||
EGLint red,green,blue,alpha,depth,stencil;
|
|
||||||
bool gotAttribs = cfg->getConfAttrib(EGL_RED_SIZE,&red) &&
|
|
||||||
cfg->getConfAttrib(EGL_GREEN_SIZE,&green) &&
|
|
||||||
cfg->getConfAttrib(EGL_BLUE_SIZE,&blue) &&
|
|
||||||
cfg->getConfAttrib(EGL_ALPHA_SIZE,&alpha) &&
|
|
||||||
cfg->getConfAttrib(EGL_DEPTH_SIZE,&depth) &&
|
|
||||||
cfg->getConfAttrib(EGL_STENCIL_SIZE,&stencil) ;
|
|
||||||
|
|
||||||
if(!gotAttribs) return false;
|
|
||||||
int wglPixelFormatAttribs[] = {
|
|
||||||
WGL_SUPPORT_OPENGL_ARB ,TRUE,
|
|
||||||
WGL_DRAW_TO_PBUFFER_ARB ,TRUE,
|
|
||||||
WGL_BIND_TO_TEXTURE_RGBA_ARB ,TRUE,
|
|
||||||
WGL_COLOR_BITS_ARB ,red+green+blue,
|
|
||||||
WGL_RED_BITS_ARB ,red,
|
|
||||||
WGL_GREEN_BITS_ARB ,green,
|
|
||||||
WGL_BLUE_BITS_ARB ,blue,
|
|
||||||
WGL_ALPHA_BITS_ARB ,alpha,
|
|
||||||
WGL_STENCIL_BITS_ARB ,stencil,
|
|
||||||
WGL_DEPTH_BITS_ARB ,depth,
|
|
||||||
WGL_DOUBLE_BUFFER_ARB ,TRUE,
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
HDC dpy = display->getCurrentDC();
|
|
||||||
int pixfmt;
|
|
||||||
unsigned int numpf;
|
|
||||||
if(!s_wglExtProcs->wglChoosePixelFormatARB || !s_wglExtProcs->wglChoosePixelFormatARB(dpy,wglPixelFormatAttribs, NULL, 1, &pixfmt, &numpf)) {
|
|
||||||
DWORD err = GetLastError();
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
HDC dpy = getDummyDC(display,cfg->nativeId());
|
||||||
EGLint width,height,largest,texTarget,texFormat;
|
EGLint width,height,largest,texTarget,texFormat;
|
||||||
pbSurface->getDim(&width,&height,&largest);
|
pbSurface->getDim(&width,&height,&largest);
|
||||||
pbSurface->getTexInfo(&texTarget,&texFormat);
|
pbSurface->getTexInfo(&texTarget,&texFormat);
|
||||||
@@ -496,7 +456,7 @@ EGLNativeSurfaceType createPbufferSurface(EGLNativeDisplayType display,EglConfig
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
if(!s_wglExtProcs->wglCreatePbufferARB) return NULL;
|
if(!s_wglExtProcs->wglCreatePbufferARB) return NULL;
|
||||||
EGLNativePbufferType pb = s_wglExtProcs->wglCreatePbufferARB(dpy,pixfmt,width,height,pbAttribs);
|
EGLNativePbufferType pb = s_wglExtProcs->wglCreatePbufferARB(dpy,cfg->nativeId(),width,height,pbAttribs);
|
||||||
if(!pb) {
|
if(!pb) {
|
||||||
DWORD err = GetLastError();
|
DWORD err = GetLastError();
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -505,7 +465,6 @@ EGLNativeSurfaceType createPbufferSurface(EGLNativeDisplayType display,EglConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool releasePbuffer(EGLNativeDisplayType display,EGLNativeSurfaceType pb) {
|
bool releasePbuffer(EGLNativeDisplayType display,EGLNativeSurfaceType pb) {
|
||||||
HDC dis = display->getCurrentDC();
|
|
||||||
if(!s_wglExtProcs->wglReleasePbufferDCARB || !s_wglExtProcs->wglDestroyPbufferARB) return false;
|
if(!s_wglExtProcs->wglReleasePbufferDCARB || !s_wglExtProcs->wglDestroyPbufferARB) return false;
|
||||||
if(!s_wglExtProcs->wglReleasePbufferDCARB(pb->getPbuffer(),pb->getDC()) || !s_wglExtProcs->wglDestroyPbufferARB(pb->getPbuffer())){
|
if(!s_wglExtProcs->wglReleasePbufferDCARB(pb->getPbuffer(),pb->getDC()) || !s_wglExtProcs->wglDestroyPbufferARB(pb->getPbuffer())){
|
||||||
DWORD err = GetLastError();
|
DWORD err = GetLastError();
|
||||||
@@ -517,18 +476,13 @@ bool releasePbuffer(EGLNativeDisplayType display,EGLNativeSurfaceType pb) {
|
|||||||
EGLNativeContextType createContext(EGLNativeDisplayType display,EglConfig* cfg,EGLNativeContextType sharedContext) {
|
EGLNativeContextType createContext(EGLNativeDisplayType display,EglConfig* cfg,EGLNativeContextType sharedContext) {
|
||||||
|
|
||||||
EGLNativeContextType ctx = NULL;
|
EGLNativeContextType ctx = NULL;
|
||||||
HDC dpy = NULL;
|
HDC dpy = getDummyDC(display,cfg->nativeId());
|
||||||
if(display->needToSetCurrent(cfg->id())){
|
|
||||||
HWND hwnd = createDummyWindow();
|
|
||||||
dpy = GetDC(hwnd);
|
|
||||||
display->setCurrent(cfg->id(),DisplayInfo(dpy,hwnd));
|
|
||||||
} else {
|
|
||||||
dpy = display->getCurrentDC();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!display->isCurrentPixelFormatSet()){
|
if(!display->isPixelFormatSet(cfg->nativeId())){
|
||||||
if(!setPixelFormat(dpy,cfg)) return NULL;
|
if(!SetPixelFormat(dpy,cfg->nativeId(),&cfg->nativeConfig())){
|
||||||
display->currentPixelFormatWasSet();
|
return NULL;
|
||||||
|
}
|
||||||
|
display->pixelFormatWasSet(cfg->nativeId());
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = wglCreateContext(dpy);
|
ctx = wglCreateContext(dpy);
|
||||||
@@ -562,11 +516,9 @@ bool makeCurrent(EGLNativeDisplayType display,EglSurface* read,EglSurface* draw,
|
|||||||
bool ret = wglMakeCurrent(hdcDraw,ctx);
|
bool ret = wglMakeCurrent(hdcDraw,ctx);
|
||||||
return ret;
|
return ret;
|
||||||
} else if (!s_wglExtProcs->wglMakeContextCurrentARB ) {
|
} else if (!s_wglExtProcs->wglMakeContextCurrentARB ) {
|
||||||
printf("OS :1-:make current failed %d\n",GetLastError());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
retVal = s_wglExtProcs->wglMakeContextCurrentARB(hdcDraw,hdcRead,ctx);
|
retVal = s_wglExtProcs->wglMakeContextCurrentARB(hdcDraw,hdcRead,ctx);
|
||||||
printf("OS ::2-make current failed %d\n",GetLastError());
|
|
||||||
|
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user