mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2025-02-07 04:36:27 +00:00
remove use of opengl context for window final surface, force child window option on context
This commit is contained in:
parent
568e8143c2
commit
77beebf4ef
@ -54,6 +54,7 @@ struct _CGLContextObj {
|
||||
int x,y;
|
||||
int w,h;
|
||||
GLint opacity;
|
||||
GLint forceChildWindow;
|
||||
GLint hidden;
|
||||
GLint inParent;
|
||||
CGLPixelSurface *overlay;
|
||||
@ -89,9 +90,23 @@ static LRESULT CALLBACK windowProcedure(HWND handle,UINT message,WPARAM wParam,L
|
||||
if(message==WM_PAINT){
|
||||
Win32Window *parentWindow=GetProp(handle,"Win32Window");
|
||||
|
||||
#if 0
|
||||
ValidateRect(handle, NULL);
|
||||
|
||||
return [parentWindow WM_APP1_wParam:wParam lParam:lParam];
|
||||
#else
|
||||
PAINTSTRUCT paintStruct;
|
||||
RECT updateRECT;
|
||||
GetWindowRect(handle,&updateRECT);
|
||||
InvalidateRect(handle,&updateRECT,FALSE);
|
||||
if(GetUpdateRect(handle,&updateRECT,NO)){
|
||||
BeginPaint(handle,&paintStruct);
|
||||
[parentWindow WM_APP1_wParam:wParam lParam:lParam];
|
||||
EndPaint(handle,&paintStruct);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(message==WM_SETCURSOR){
|
||||
@ -121,12 +136,6 @@ static LRESULT CALLBACK windowProcedure(HWND handle,UINT message,WPARAM wParam,L
|
||||
*/
|
||||
CRITICAL_SECTION requestCriticalSection;
|
||||
|
||||
|
||||
static void createWindowForContext(CGLContextObj context){
|
||||
context->parent=CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_NOACTIVATE,"CGLWindow","",WS_POPUP|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,0,0,10,10,NULL,NULL,GetModuleHandle(NULL),NULL);
|
||||
context->window=CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_NOACTIVATE,"CGLWindow","",WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,0,0,context->w,context->h,context->parent,NULL,GetModuleHandle(NULL),NULL);
|
||||
}
|
||||
|
||||
static void initializeRequest(){
|
||||
InitializeCriticalSection(&requestCriticalSection);
|
||||
}
|
||||
@ -181,22 +190,6 @@ static int reportGLErrorIfNeeded(const char *function,int line){
|
||||
return error;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static BOOL contextHasMakeCurrentReadExtension(CGLContextObj context){
|
||||
const char *extensions=opengl_wglGetExtensionsStringARB(context->windowDC);
|
||||
|
||||
reportGLErrorIfNeeded(__PRETTY_FUNCTION__,__LINE__);
|
||||
|
||||
if(extensions==NULL)
|
||||
return NO;
|
||||
|
||||
if(strstr(extensions,"WGL_ARB_make_current_read")==NULL)
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void _CGLCreateDynamicPbufferBacking(CGLContextObj context);
|
||||
static void _CGLDestroyDynamicPbufferBacking(CGLContextObj context);
|
||||
CGLError _CGLSetCurrentContextFromThreadLocal(int value);
|
||||
@ -322,7 +315,10 @@ static void pfdFromPixelFormat(PIXELFORMATDESCRIPTOR *pfd,CGLPixelFormatObj pixe
|
||||
/* It has to be double buffered regardless of what the application asks for, because we're reading from it, all the pixels must be
|
||||
valid. A single buffer context is problematic in that the driver may not render obscured pixels, all of them since it is off-screen.
|
||||
That isnt a problem with pbuffers but this is the fallback. */
|
||||
|
||||
#ifndef PFD_SUPPORT_COMPOSITION
|
||||
#define PFD_SUPPORT_COMPOSITION 0x00008000
|
||||
#endif
|
||||
|
||||
pfd->dwFlags=PFD_SUPPORT_OPENGL|PFD_DRAW_TO_WINDOW|PFD_DOUBLEBUFFER;
|
||||
pfd->iLayerType=PFD_MAIN_PLANE;
|
||||
pfd->iPixelType=PFD_TYPE_RGBA;
|
||||
@ -372,7 +368,7 @@ return;
|
||||
|
||||
static BOOL contextHasPbufferExtension(CGLContextObj context){
|
||||
const char *extensions=opengl_wglGetExtensionsStringARB(context->windowDC);
|
||||
|
||||
|
||||
// NSLog(@"extensions=%s",extensions);
|
||||
|
||||
reportGLErrorIfNeeded(__PRETTY_FUNCTION__,__LINE__);
|
||||
@ -472,7 +468,10 @@ CGL_EXPORT CGLError CGLCreateContext(CGLPixelFormatObj pixelFormat,CGLContextObj
|
||||
context->w=64;
|
||||
context->h=64;
|
||||
|
||||
createWindowForContext(context);
|
||||
context->forceChildWindow = TRUE;
|
||||
|
||||
context->parent=CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_NOACTIVATE,"CGLWindow","",WS_POPUP|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,0,0,10,10,NULL,NULL,GetModuleHandle(NULL),NULL);
|
||||
context->window=CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_NOACTIVATE,"CGLWindow","",WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,0,0,context->w,context->h,context->parent,NULL,GetModuleHandle(NULL),NULL);
|
||||
|
||||
context->windowDC=GetDC(context->window);
|
||||
|
||||
@ -573,6 +572,9 @@ CGL_EXPORT CGLError CGLUnlockContext(CGLContextObj context) {
|
||||
}
|
||||
|
||||
static BOOL usesChildWindow(CGLContextObj context){
|
||||
if(context->forceChildWindow)
|
||||
return YES;
|
||||
|
||||
Win32Window *parentWindow=[CGWindow windowWithWindowNumber:context->parentWindowNumber];
|
||||
|
||||
if(parentWindow==nil)
|
||||
@ -581,7 +583,7 @@ static BOOL usesChildWindow(CGLContextObj context){
|
||||
if([parentWindow isLayeredWindow])
|
||||
return NO;
|
||||
|
||||
return YES;
|
||||
return NO;
|
||||
}
|
||||
|
||||
static BOOL shouldPutChildInParent(CGLContextObj context) {
|
||||
@ -645,6 +647,13 @@ CGL_EXPORT CGLError CGLSetParameter(CGLContextObj context,CGLContextParameter pa
|
||||
}
|
||||
break;
|
||||
|
||||
case kCGLCPSurfaceIsChildWindow:
|
||||
if(context->forceChildWindow!=value[0]){
|
||||
context->forceChildWindow=value[0];
|
||||
reflectChildWindowState(context,YES);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCGLCPSurfaceBackingOrigin:;
|
||||
BOOL originChanged=(context->x!=value[0] || context->y!=value[1])?YES:NO;
|
||||
|
||||
@ -702,6 +711,10 @@ CGL_EXPORT CGLError CGLGetParameter(CGLContextObj context,CGLContextParameter pa
|
||||
value[1]=context->h;
|
||||
break;
|
||||
|
||||
case kCGLCPSurfaceIsChildWindow:
|
||||
*value=context->forceChildWindow;
|
||||
break;
|
||||
|
||||
case kCGLCPSurfaceBackingOrigin:
|
||||
value[0]=context->x;
|
||||
value[1]=context->y;
|
||||
@ -786,7 +799,8 @@ CGL_EXPORT CGLError CGLCopyPixels(CGLContextObj source,CGLContextObj destination
|
||||
|
||||
CGLError CGLFlushDrawable(CGLContextObj context) {
|
||||
if(usesChildWindow(context)){
|
||||
SwapBuffers(context->windowDC);
|
||||
if(!SwapBuffers(context->windowDC))
|
||||
NSLog(@"SwapBuffers failed, error = %d", GetLastError());
|
||||
}
|
||||
else {
|
||||
Win32Window *parentWindow=[CGWindow windowWithWindowNumber:context->parentWindowNumber];
|
||||
|
@ -43,7 +43,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
int _textureIdCount;
|
||||
GLint *_textureIds;
|
||||
|
||||
CGLContextObj _overlayResult;
|
||||
O2Surface_DIBSection *_overlayResult;
|
||||
NSMutableArray *_overlays;
|
||||
|
||||
int _disableFlushWindow;
|
||||
|
@ -240,7 +240,7 @@ static const char *Win32ClassNameForStyleMask(unsigned styleMask,bool hasShadow)
|
||||
NSZoneFree(NULL,_surfaces);
|
||||
if(_textureIds!=NULL)
|
||||
NSZoneFree(NULL,_textureIds);
|
||||
CGLReleaseContext(_overlayResult);
|
||||
[_overlayResult release];
|
||||
if(_hglrc!=NULL)
|
||||
opengl_wglDeleteContext(_hglrc);
|
||||
|
||||
@ -500,7 +500,64 @@ CGL_EXPORT CGLError CGLCopyPixels(CGLContextObj source,CGLContextObj destination
|
||||
|
||||
if(_surfaceCount==0)
|
||||
return backingSurface;
|
||||
|
||||
#if 1
|
||||
int resultWidth=O2ImageGetWidth(backingSurface);
|
||||
int resultHeight=O2ImageGetHeight(backingSurface);
|
||||
|
||||
if(O2ImageGetWidth(_overlayResult)!=resultWidth || O2ImageGetHeight(_overlayResult)!=resultHeight){
|
||||
[_overlayResult release];
|
||||
_overlayResult=[[O2Surface_DIBSection alloc] initWithWidth:resultWidth height:resultHeight compatibleWithDeviceContext:nil];
|
||||
}
|
||||
|
||||
BLENDFUNCTION blend;
|
||||
|
||||
blend.BlendOp=AC_SRC_OVER;
|
||||
blend.BlendFlags=0;
|
||||
blend.SourceConstantAlpha=255;
|
||||
blend.AlphaFormat=0;
|
||||
|
||||
O2SurfaceLock(_overlayResult);
|
||||
O2SurfaceLock(backingSurface);
|
||||
AlphaBlend([[_overlayResult deviceContext] dc],0,0,resultWidth,resultHeight,[[backingSurface deviceContext] dc],0,0,resultWidth,resultHeight,blend);
|
||||
O2SurfaceUnlock(backingSurface);
|
||||
O2SurfaceUnlock(_overlayResult);
|
||||
|
||||
int i;
|
||||
for(i=0;i<_surfaceCount;i++) {
|
||||
CGLPixelSurface *overlay;
|
||||
GLint sourceOrigin[2];
|
||||
GLint sourceSize[2];
|
||||
GLint sourceOpacity;
|
||||
|
||||
CGLGetParameter(_surfaces[i],kCGLCPOverlayPointer,&overlay);
|
||||
CGLGetParameter(_surfaces[i],kCGLCPSurfaceBackingOrigin,sourceOrigin);
|
||||
CGLGetParameter(_surfaces[i],kCGLCPSurfaceBackingSize,sourceSize);
|
||||
CGLGetParameter(_surfaces[i],kCGLCPSurfaceOpacity,&sourceOpacity);
|
||||
|
||||
O2Surface_DIBSection *srcSurface=(O2Surface_DIBSection *)[overlay validSurface];
|
||||
|
||||
if(srcSurface==nil)
|
||||
return kCGLNoError;
|
||||
|
||||
BLENDFUNCTION blend;
|
||||
|
||||
blend.BlendOp=AC_SRC_OVER;
|
||||
blend.BlendFlags=0;
|
||||
blend.SourceConstantAlpha=255;
|
||||
blend.AlphaFormat=sourceOpacity?0:AC_SRC_ALPHA;
|
||||
|
||||
int y=resultHeight-(sourceOrigin[1]+sourceSize[1]);
|
||||
|
||||
O2SurfaceLock(_overlayResult);
|
||||
O2SurfaceLock(srcSurface);
|
||||
AlphaBlend([[_overlayResult deviceContext] dc],sourceOrigin[0],y,sourceSize[0],sourceSize[1],[[srcSurface deviceContext] dc],0,0,sourceSize[0],sourceSize[1],blend);
|
||||
O2SurfaceUnlock(srcSurface);
|
||||
O2SurfaceUnlock(_overlayResult);
|
||||
}
|
||||
|
||||
return _overlayResult;
|
||||
#else
|
||||
if(_overlayResult==NULL){
|
||||
CGLPixelFormatObj pf;
|
||||
GLint novs;
|
||||
@ -535,6 +592,7 @@ CGL_EXPORT CGLError CGLCopyPixels(CGLContextObj source,CGLContextObj destination
|
||||
CGLGetParameter(_overlayResult,kCGLCPOverlayPointer,&pixelSurface);
|
||||
|
||||
return (O2Surface_DIBSection *)[pixelSurface validSurface];
|
||||
#endif
|
||||
}
|
||||
|
||||
static int reportGLErrorIfNeeded(const char *function,int line){
|
||||
@ -706,7 +764,7 @@ static int reportGLErrorIfNeeded(const char *function,int line){
|
||||
if(!_hasMakeCurrentRead)
|
||||
_hasMakeCurrentRead=(extensions==NULL)?NO:((strstr(extensions,"WGL_EXT_make_current_read")==NULL)?NO:YES);
|
||||
|
||||
_hasSwapHintRect=(extensions==NULL)?NO:((strstr(extensions,"GL_WIN_swap_hint")==NULL)?NO:YES);;
|
||||
_hasSwapHintRect=(extensions==NULL)?NO:((strstr(extensions,"GL_WIN_swap_hint")==NULL)?NO:YES);
|
||||
}
|
||||
|
||||
-(void)openGLFlushBufferOnlyContext:(CGLContextObj)onlyContext {
|
||||
@ -854,7 +912,7 @@ static int reportGLErrorIfNeeded(const char *function,int line){
|
||||
reportGLErrorIfNeeded(__PRETTY_FUNCTION__,__LINE__);
|
||||
}
|
||||
|
||||
opengl_wglBindTexImageARB(CGLGetPBUFFER(pBuffer),WGL_FRONT_LEFT_ARB);
|
||||
opengl_wglBindTexImageARB(CGLGetPBUFFER(pBuffer),WGL_BACK_RIGHT_ARB);
|
||||
reportGLErrorIfNeeded(__PRETTY_FUNCTION__,__LINE__);
|
||||
|
||||
GLint vertices[4*2];
|
||||
@ -959,7 +1017,7 @@ static int reportGLErrorIfNeeded(const char *function,int line){
|
||||
if(_hasRenderTexture) {
|
||||
// This flushes the pipeline, we want to do it last before swap buffer, but not after
|
||||
// swapbuffers as that is a lot slower.
|
||||
opengl_wglReleaseTexImageARB(CGLGetPBUFFER(releasePbuffers[i]),WGL_FRONT_LEFT_ARB);
|
||||
opengl_wglReleaseTexImageARB(CGLGetPBUFFER(releasePbuffers[i]),WGL_BACK_RIGHT_ARB);
|
||||
}
|
||||
|
||||
CGLReleasePBuffer(releasePbuffers[i]);
|
||||
@ -1162,6 +1220,7 @@ static int reportGLErrorIfNeeded(const char *function,int line){
|
||||
|
||||
-(int)WM_APP1_wParam:(WPARAM)wParam lParam:(LPARAM)lParam {
|
||||
[_delegate platformWindow:self needsDisplayInRect:NSZeroRect];
|
||||
return 0;
|
||||
}
|
||||
|
||||
-(int)WM_PAINT_wParam:(WPARAM)wParam lParam:(LPARAM)lParam {
|
||||
|
@ -97,6 +97,8 @@ typedef enum {
|
||||
kCGLCPSurfaceBackingSize=304,
|
||||
|
||||
// internal, do not use
|
||||
kCGLCPSurfaceIsChildWindow=500,
|
||||
|
||||
kCGLCPOverlayPointer=502,
|
||||
|
||||
kCGLCPSurfaceBackingOrigin=503,
|
||||
|
Loading…
x
Reference in New Issue
Block a user