mirror of
https://github.com/darlinghq/darling-cocotron.git
synced 2024-10-07 09:33:28 +00:00
Port Cocotron to the new EGL-based OpenGL.framework
See darlinghq/darling#365 TODO: * Get rid of the few remaining glX calls * Port CALayerContext
This commit is contained in:
parent
452ec7a16f
commit
50a571eb4b
@ -14,6 +14,9 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \
|
||||
|
||||
find_package(X11 REQUIRED)
|
||||
find_package(Freetype REQUIRED)
|
||||
|
||||
# We do not link to host's libGL (directly),
|
||||
# but we still need to include its headers
|
||||
find_package(OpenGL REQUIRED)
|
||||
|
||||
find_package(PkgConfig REQUIRED)
|
||||
@ -297,7 +300,7 @@ set(AppKit_sources
|
||||
X11.subproj/X11SubWindow.m
|
||||
X11.subproj/KTFont_FT.m
|
||||
# O2Font_FT.m is built in Onyx2D
|
||||
# CGLContext.m is built in OpenGL
|
||||
# CGLContext.m no longer used
|
||||
# X11.subproj/NSOpenGLDrawable_X11.m
|
||||
# X11.subproj/O2Context_cairo.m
|
||||
X11.subproj/X11Display.m
|
||||
@ -391,14 +394,12 @@ add_framework(AppKit
|
||||
Onyx2D
|
||||
CoreText
|
||||
CoreData
|
||||
OpenGL
|
||||
QuartzCore
|
||||
CoreGraphics
|
||||
# native libraries
|
||||
FreeType
|
||||
fontconfig
|
||||
X11
|
||||
GL
|
||||
jpeg png tiff
|
||||
CIRCULAR_DEPENDENCIES
|
||||
OpenGL
|
||||
QuartzCore
|
||||
CoreGraphics
|
||||
)
|
||||
|
@ -64,9 +64,14 @@ static inline void _clearCurrentContext(){
|
||||
if(_currentContext()==self)
|
||||
_clearCurrentContext();
|
||||
[_pixelFormat release];
|
||||
|
||||
if (_cglWindow != NULL) {
|
||||
CGLDestroyWindow(_cglWindow);
|
||||
}
|
||||
[_subwindow release];
|
||||
_view=nil;
|
||||
|
||||
|
||||
|
||||
|
||||
CGLReleaseContext(_glContext);
|
||||
[super dealloc];
|
||||
}
|
||||
@ -107,57 +112,47 @@ static inline void _clearCurrentContext(){
|
||||
|
||||
if([_view window]!=nil)
|
||||
rect=[_view convertRect:rect toView:nil];
|
||||
|
||||
GLint size[2]={
|
||||
rect.size.width,
|
||||
rect.size.height };
|
||||
GLint origin[2]={
|
||||
rect.origin.x,
|
||||
rect.origin.y };
|
||||
GLint hidden[1]= {
|
||||
[_view isHidden] ? 1 : 0
|
||||
};
|
||||
|
||||
CGLSetParameter(_glContext,kCGLCPSurfaceBackingSize,size);
|
||||
CGLSetParameter(_glContext,kCGLCPSurfaceBackingOrigin,origin);
|
||||
CGLSetParameter(_glContext,kCGLCPSurfaceHidden,hidden);
|
||||
if (_subwindow == nil) {
|
||||
_subwindow = [[[_view window] _createSubWindowWithFrame: rect] retain];
|
||||
_cglWindow = CGLGetWindow([_subwindow nativeWindow]);
|
||||
} else {
|
||||
[_subwindow setFrame: rect];
|
||||
}
|
||||
|
||||
if ([_view isHidden]) {
|
||||
[_subwindow hide];
|
||||
} else {
|
||||
[_subwindow show];
|
||||
}
|
||||
}
|
||||
|
||||
-(void)setView:(NSView *)view {
|
||||
if(_view!=view)
|
||||
_hasPrepared=NO;
|
||||
|
||||
_view=view;
|
||||
|
||||
CGLLockContext(_glContext);
|
||||
|
||||
GLint num[1]={[[_view window] windowNumber]};
|
||||
|
||||
CGLSetParameter(_glContext,kCGLCPSurfaceWindowNumber,num);
|
||||
|
||||
[self update];
|
||||
if (_view == view) return;
|
||||
|
||||
CGLUnlockContext(_glContext);
|
||||
_hasPrepared = NO;
|
||||
_view = view;
|
||||
|
||||
if (_cglWindow != NULL) {
|
||||
CGLDestroyWindow(_cglWindow);
|
||||
_cglWindow = NULL;
|
||||
}
|
||||
[_subwindow release];
|
||||
_subwindow = nil;
|
||||
|
||||
[self updateViewParameters];
|
||||
}
|
||||
|
||||
-(void)makeCurrentContext {
|
||||
CGLError error;
|
||||
|
||||
if((error=CGLSetCurrentContext(_glContext))!=kCGLNoError)
|
||||
NSLog(@"CGLSetCurrentContext failed with %d in %s %d",error,__FILE__,__LINE__);
|
||||
|
||||
_setCurrentContext(self);
|
||||
|
||||
#if 0
|
||||
/*
|
||||
We need to reload the view values when becoming current because it may
|
||||
have moved windows since the last make current
|
||||
*/
|
||||
// Possible this shouldnt be done here, especially on a non-main thread
|
||||
|
||||
// Don't do this here due to threading reason. Figure out where to do this when moving windows, view _setWindow ?
|
||||
[self updateViewParameters];
|
||||
#endif
|
||||
[self performSelectorOnMainThread: @selector(updateViewParameters)
|
||||
withObject: nil
|
||||
waitUntilDone: YES];
|
||||
|
||||
if((error=CGLContextMakeCurrentAndAttachToWindow(_glContext, _cglWindow))!=kCGLNoError)
|
||||
NSLog(@"CGLSetCurrentContext failed with %d in %s %d",error,__FILE__,__LINE__);
|
||||
|
||||
_setCurrentContext(self);
|
||||
|
||||
if(!_hasPrepared){
|
||||
_hasPrepared=YES;
|
||||
|
@ -26,6 +26,9 @@
|
||||
#import <AppKit/NSFontManager.h>
|
||||
#import <AppKit/NSFontTypeface.h>
|
||||
#import <AppKit/NSWindow.h>
|
||||
|
||||
#import <OpenGL/CGLInternal.h>
|
||||
|
||||
#import <fcntl.h>
|
||||
#import <fontconfig/fontconfig.h>
|
||||
#import <X11/Xutil.h>
|
||||
@ -94,6 +97,8 @@ static void socketCallback(
|
||||
};
|
||||
_cfSocket = CFSocketCreateWithNative(kCFAllocatorDefault, _fileDescriptor, kCFSocketReadCallBack, socketCallback, &context);
|
||||
_source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, _cfSocket, 0);
|
||||
|
||||
CGLRegisterNativeDisplay(_display);
|
||||
#endif
|
||||
|
||||
_windowsByID=[NSMutableDictionary new];
|
||||
|
@ -17,35 +17,7 @@
|
||||
_parent = parent;
|
||||
frame = [self convertFrame: frame];
|
||||
|
||||
X11Display *x11Display = (X11Display *) [NSDisplay currentDisplay];
|
||||
_display = x11Display.display;
|
||||
|
||||
/*
|
||||
static const GLint attrs[] = {
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
GLX_RED_SIZE, 4,
|
||||
GLX_GREEN_SIZE, 4,
|
||||
GLX_BLUE_SIZE, 4,
|
||||
GLX_DEPTH_SIZE, 4,
|
||||
None
|
||||
};
|
||||
int screen = DefaultScreen(_display);
|
||||
// TODO: get rid of glX here
|
||||
XVisualInfo *visualInfo = glXChooseVisual(display, screen, attrs);
|
||||
|
||||
Colormap cmap = XCreateColormap(
|
||||
_display,
|
||||
RootWindow(_display, visualInfo->screen),
|
||||
visualInfo->visual,
|
||||
AllocNone
|
||||
);
|
||||
|
||||
XSetWindowAttributes xattr = {0};
|
||||
xattr.colormap = cmap;
|
||||
xattr.border_pixel = 0;
|
||||
xattr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;
|
||||
*/
|
||||
_display = [(X11Display *) [NSDisplay currentDisplay] display];
|
||||
|
||||
_window = XCreateSimpleWindow(
|
||||
_display, [parent windowHandle],
|
||||
|
@ -10,7 +10,7 @@
|
||||
#import <Onyx2D/O2Geometry.h>
|
||||
#import <X11/Xlib.h>
|
||||
#import <GL/glx.h>
|
||||
#import <OpenGL/OpenGL.h>
|
||||
#import <OpenGL/CGLInternal.h>
|
||||
|
||||
@class O2Context_cairo, X11Display, CAWindowOpenGLContext;
|
||||
|
||||
@ -20,6 +20,7 @@
|
||||
XVisualInfo *_visualInfo;
|
||||
Window _window;
|
||||
CGLContextObj _cglContext;
|
||||
CGLWindowRef _cglWindow;
|
||||
CAWindowOpenGLContext *_caContext;
|
||||
|
||||
id _delegate;
|
||||
|
@ -64,7 +64,7 @@ void CGNativeBorderFrameWidthsForStyle(unsigned styleMask,CGFloat *top,CGFloat *
|
||||
_frame=[self transformFrame:frame];
|
||||
if(isPanel && styleMask&NSDocModalWindowMask)
|
||||
styleMask=NSBorderlessWindowMask;
|
||||
|
||||
// TODO: get rid of these glX calls
|
||||
GLint att[] = {
|
||||
GLX_RGBA,
|
||||
GLX_DOUBLEBUFFER,
|
||||
@ -108,6 +108,8 @@ void CGNativeBorderFrameWidthsForStyle(unsigned styleMask,CGFloat *top,CGFloat *
|
||||
XSetWMProtocols(_display, _window, &atm , 1);
|
||||
|
||||
XSetWindowBackgroundPixmap(_display, _window, None);
|
||||
|
||||
_cglWindow = CGLGetWindow(_window);
|
||||
|
||||
[(X11Display*)[NSDisplay currentDisplay] setWindow:self forID:_window];
|
||||
|
||||
@ -119,7 +121,6 @@ void CGNativeBorderFrameWidthsForStyle(unsigned styleMask,CGFloat *top,CGFloat *
|
||||
|
||||
-(void)dealloc {
|
||||
[self invalidate];
|
||||
[_context release];
|
||||
[_deviceDictionary release];
|
||||
[super dealloc];
|
||||
}
|
||||
@ -168,10 +169,26 @@ void CGNativeBorderFrameWidthsForStyle(unsigned styleMask,CGFloat *top,CGFloat *
|
||||
return _delegate;
|
||||
}
|
||||
|
||||
-(void)invalidate {
|
||||
_delegate=nil;
|
||||
[_context release];
|
||||
_context=nil;
|
||||
-(void) invalidate {
|
||||
// This is essentially dealloc; we release our contexts
|
||||
// and windows, but unlike dealloc, this method can be called
|
||||
// several times, so set everything to nil/NULL/0.
|
||||
_delegate = nil;
|
||||
|
||||
[_context release];
|
||||
_context = nil;
|
||||
|
||||
[_caContext release];
|
||||
_caContext = nil;
|
||||
|
||||
if (_cglContext != NULL) {
|
||||
CGLReleaseContext(_cglContext);
|
||||
_cglContext = NULL;
|
||||
}
|
||||
if (_cglWindow != NULL) {
|
||||
CGLDestroyWindow(_cglWindow);
|
||||
_cglWindow = NULL;
|
||||
}
|
||||
|
||||
if(_window) {
|
||||
[(X11Display*)[NSDisplay currentDisplay] setWindow:nil forID:_window];
|
||||
@ -301,37 +318,37 @@ void CGNativeBorderFrameWidthsForStyle(unsigned styleMask,CGFloat *top,CGFloat *
|
||||
return NO;
|
||||
}
|
||||
|
||||
CGL_EXPORT CGLError CGLCreateContextForWindow(CGLPixelFormatObj pixelFormat,CGLContextObj share,CGLContextObj *resultp,Display *display,XVisualInfo *visualInfo,Window window);
|
||||
|
||||
-(void)createCGLContextObjIfNeeded {
|
||||
if(_cglContext==NULL){
|
||||
-(void) createCGLContextObjIfNeeded {
|
||||
if (_cglContext==NULL) {
|
||||
CGLError error;
|
||||
|
||||
if((error=CGLCreateContextForWindow(NULL,NULL,&_cglContext,_display,_visualInfo,_window))!=kCGLNoError)
|
||||
NSLog(@"glXCreateContext failed at %s %d with error %d",__FILE__,__LINE__,error);
|
||||
|
||||
if ((error = CGLCreateContext(NULL, NULL, &_cglContext)) != kCGLNoError)
|
||||
NSLog(@"CGLCreateContext failed at %s %d with error %d", __FILE__ , __LINE__, error);
|
||||
if ((error = CGLContextMakeCurrentAndAttachToWindow(_cglContext, _cglWindow)) != kCGLNoError)
|
||||
NSLog(@"CGLContextMakeCurrentAndAttachToWindow failed with error %d", error);
|
||||
}
|
||||
if(_cglContext!=NULL && _caContext==NULL){
|
||||
_caContext=[[CAWindowOpenGLContext alloc] initWithCGLContext:_cglContext];
|
||||
if (_cglContext != nil && _caContext == nil){
|
||||
_caContext = [[CAWindowOpenGLContext alloc] initWithCGLContext:_cglContext];
|
||||
NSLog(@"Create _caContext %p %@", _caContext, _caContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
-(void)openGLFlushBuffer {
|
||||
-(void) openGLFlushBuffer {
|
||||
CGLError error;
|
||||
|
||||
|
||||
[self createCGLContextObjIfNeeded];
|
||||
if(_caContext==NULL)
|
||||
if (_caContext == nil)
|
||||
return;
|
||||
|
||||
O2Surface *surface = [_context surface];
|
||||
size_t width=O2ImageGetWidth(surface);
|
||||
size_t height=O2ImageGetHeight(surface);
|
||||
size_t width = O2ImageGetWidth(surface);
|
||||
size_t height = O2ImageGetHeight(surface);
|
||||
|
||||
[_caContext prepareViewportWidth: width height: height];
|
||||
[_caContext renderSurface: surface];
|
||||
|
||||
[_caContext prepareViewportWidth:width height:height];
|
||||
[_caContext renderSurface:surface];
|
||||
|
||||
glFlush();
|
||||
glXSwapBuffers(_display,_window);
|
||||
CGLSwapBuffers(_cglWindow);
|
||||
}
|
||||
|
||||
-(void)flushBuffer {
|
||||
|
@ -7,7 +7,9 @@ The above copyright notice and this permission notice shall be included in all c
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <CoreGraphics/CGSubWindow.h>
|
||||
#import <OpenGL/gl.h>
|
||||
#import <OpenGL/CGLInternal.h>
|
||||
|
||||
@class NSOpenGLPixelFormat, NSOpenGLPixelBuffer, NSView;
|
||||
|
||||
@ -25,7 +27,8 @@ typedef enum {
|
||||
NSOpenGLPixelFormat *_pixelFormat;
|
||||
NSView *_view;
|
||||
void *_glContext;
|
||||
id __remove;
|
||||
CGSubWindow *_subwindow;
|
||||
CGLWindowRef _cglWindow;
|
||||
BOOL _hasPrepared;
|
||||
}
|
||||
|
||||
|
@ -46,7 +46,7 @@
|
||||
|
||||
// 0's are silently ignored per spec.
|
||||
if(_numberOfBuffers>0 && _bufferObjects!=NULL) // nVidia driver will crash if bufferObjects is NULL, does not conform to spec.
|
||||
CGLDeleteBuffers(_numberOfBuffers,_bufferObjects);
|
||||
glDeleteBuffers(_numberOfBuffers,_bufferObjects);
|
||||
|
||||
if(_bufferObjects!=NULL)
|
||||
free(_bufferObjects);
|
||||
@ -91,9 +91,9 @@
|
||||
}
|
||||
else {
|
||||
_readPixels[i]=NULL;
|
||||
CGLBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, _bufferObjects[i]);
|
||||
CGLBufferData(GL_PIXEL_PACK_BUFFER_ARB, _width*_rowsPerBuffer*4, NULL,GL_STREAM_READ);
|
||||
CGLBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, _bufferObjects[i]);
|
||||
glBufferData(GL_PIXEL_PACK_BUFFER_ARB, _width*_rowsPerBuffer*4, NULL,GL_STREAM_READ);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER_ARB, 0);
|
||||
}
|
||||
|
||||
row+=_rowsPerBuffer;
|
||||
@ -177,7 +177,7 @@ static inline uint32_t premultiplyPixel(uint32_t value){
|
||||
if(_bufferObjects[i]==0)
|
||||
glReadPixels(0,row,_width,rowCount,PIXEL_FORMAT, GL_UNSIGNED_BYTE,_readPixels[i]);
|
||||
else {
|
||||
CGLBindBuffer(GL_PIXEL_PACK_BUFFER,_bufferObjects[i]);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER,_bufferObjects[i]);
|
||||
unbind=YES;
|
||||
|
||||
glReadPixels(0,row,_width,rowCount,PIXEL_FORMAT, GL_UNSIGNED_BYTE, 0);
|
||||
@ -191,7 +191,7 @@ static inline uint32_t premultiplyPixel(uint32_t value){
|
||||
}
|
||||
|
||||
if(unbind)
|
||||
CGLBindBuffer(GL_PIXEL_PACK_BUFFER,0);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER,0);
|
||||
|
||||
row=0;
|
||||
unbind=NO;
|
||||
@ -205,8 +205,8 @@ static inline uint32_t premultiplyPixel(uint32_t value){
|
||||
inputRow=_readPixels[i];
|
||||
else {
|
||||
unbind=YES;
|
||||
CGLBindBuffer(GL_PIXEL_PACK_BUFFER,_bufferObjects[i]);
|
||||
inputRow=(GLubyte*)CGLMapBuffer(GL_PIXEL_PACK_BUFFER,GL_READ_ONLY);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER,_bufferObjects[i]);
|
||||
inputRow=(GLubyte*)glMapBuffer(GL_PIXEL_PACK_BUFFER,GL_READ_ONLY);
|
||||
}
|
||||
|
||||
if(_isOpaque){
|
||||
@ -243,18 +243,18 @@ static inline uint32_t premultiplyPixel(uint32_t value){
|
||||
}
|
||||
|
||||
if(_bufferObjects[i]!=0){
|
||||
CGLUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
glUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
}
|
||||
|
||||
row+=rowCount;
|
||||
}
|
||||
|
||||
if(unbind)
|
||||
CGLBindBuffer(GL_PIXEL_PACK_BUFFER,0);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER,0);
|
||||
|
||||
#if 0
|
||||
if(_usePixelBuffer){
|
||||
CGLBindBuffer(GL_PIXEL_PACK_BUFFER,0);
|
||||
glBindBuffer(GL_PIXEL_PACK_BUFFER,0);
|
||||
if(inputBytes!=NULL){
|
||||
CGLUnmapBuffer(GL_PIXEL_PACK_BUFFER);
|
||||
}
|
||||
|
@ -87,8 +87,5 @@ add_framework(CoreGraphics
|
||||
CoreFoundation
|
||||
Foundation
|
||||
Onyx2D
|
||||
GL
|
||||
CIRCULAR_DEPENDENCIES
|
||||
AppKit
|
||||
OpenGL
|
||||
)
|
||||
|
@ -32,11 +32,12 @@
|
||||
GLint backingOrigin[2]={rect.origin.x,rect.origin.y};
|
||||
GLint backingSize[2]={width,height};
|
||||
|
||||
CGLSetParameter(_glContext,kCGLCPSurfaceBackingOrigin,backingOrigin);
|
||||
CGLSetParameter(_glContext,kCGLCPSurfaceBackingSize,backingSize);
|
||||
// FIXME: convert to CGSubWindow
|
||||
//CGLSetParameter(_glContext,kCGLCPSurfaceBackingOrigin,backingOrigin);
|
||||
//CGLSetParameter(_glContext,kCGLCPSurfaceBackingSize,backingSize);
|
||||
|
||||
GLint opacity=0;
|
||||
CGLSetParameter(_glContext,kCGLCPSurfaceOpacity,&opacity);
|
||||
//CGLSetParameter(_glContext,kCGLCPSurfaceOpacity,&opacity);
|
||||
|
||||
_renderer=[[CARenderer rendererWithCGLContext:_glContext options:nil] retain];
|
||||
|
||||
@ -58,8 +59,8 @@
|
||||
GLint backingOrigin[2]={rect.origin.x,rect.origin.y};
|
||||
GLint backingSize[2]={width,height};
|
||||
|
||||
CGLSetParameter(_glContext,kCGLCPSurfaceBackingOrigin,backingOrigin);
|
||||
CGLSetParameter(_glContext,kCGLCPSurfaceBackingSize,backingSize);
|
||||
// CGLSetParameter(_glContext,kCGLCPSurfaceBackingOrigin,backingOrigin);
|
||||
// CGLSetParameter(_glContext,kCGLCPSurfaceBackingSize,backingSize);
|
||||
}
|
||||
|
||||
-(void)setLayer:(CALayer *)layer {
|
||||
|
@ -77,9 +77,6 @@ add_framework(QuartzCore
|
||||
CoreFoundation
|
||||
Foundation
|
||||
Onyx2D
|
||||
# native libraries
|
||||
GL
|
||||
CIRCULAR_DEPENDENCIES
|
||||
OpenGL
|
||||
CoreGraphics
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user