/* * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "MacPixelFormatsAttribs.h" // // EmuGLContext inherit from NSOpenGLContext // and adds binding state for the context to know // if it was last bounded to a pbuffer or a window. // This is because after the context was bounded to // a Pbuffer, before we bind it to a window we must // release it form the pbuffer by calling the // clearDrawable method. We do not want to call clearDrawable // more than really needed since when it is called at a time // that a window is bounded to the context it will clear the // window content causing flickering effect. // Thererfore we call clearDrawable only when we bind the context // to a window and it was previously bound to a Pbuffer. // @interface EmuGLContext : NSOpenGLContext { @private int boundToPbuffer; int boundToWin; } - (id) initWithFormat:(NSOpenGLPixelFormat *)pixelFormat shareContext:(NSOpenGLContext *)share; - (void) preBind:(int)forPbuffer; @end @implementation EmuGLContext - (id) initWithFormat:(NSOpenGLPixelFormat *)pixelFormat shareContext:(NSOpenGLContext *)share { self = [super initWithFormat:pixelFormat shareContext:share]; if (self != nil) { boundToPbuffer = 0; boundToWin = 0; } return self; } - (void) preBind:(int)forPbuffer { if ((!forPbuffer && boundToPbuffer)) { [self clearDrawable]; } boundToPbuffer = forPbuffer; boundToWin = !boundToPbuffer; } @end int getNumPixelFormats(){ int size; NSOpenGLPixelFormatAttribute** attrib_lists = getPixelFormatsAttributes(&size); return size; } void* getPixelFormat(int i){ int size; NSOpenGLPixelFormatAttribute** attrib_lists = getPixelFormatsAttributes(&size); return [[NSOpenGLPixelFormat alloc] initWithAttributes:attrib_lists[i]]; } int getPixelFormatDefinitionAlpha(int i) { int size; NSOpenGLPixelFormatAttribute** attrib_lists = getPixelFormatsAttributes(&size); NSOpenGLPixelFormatAttribute* attribs = attrib_lists[i]; while (*attribs) { switch (*attribs) { // These are the ones that take a value, according to the current // NSOpenGLPixelFormat docs case NSOpenGLPFAAuxBuffers: case NSOpenGLPFAColorSize: case NSOpenGLPFADepthSize: case NSOpenGLPFAStencilSize: case NSOpenGLPFAAccumSize: case NSOpenGLPFARendererID: case NSOpenGLPFAScreenMask: attribs += 2; break; case NSOpenGLPFAAlphaSize: return attribs[1]; break; // All other attributes are boolean attributes that don't take a value default: attribs++; } } return 0; } void getPixelFormatAttrib(void* pixelFormat,int attrib,int* val){ NSOpenGLPixelFormat *frmt = (NSOpenGLPixelFormat *)pixelFormat; [frmt getValues:val forAttribute:attrib forVirtualScreen:0]; } void* nsCreateContext(void* format,void* share){ NSOpenGLPixelFormat* frmt = (NSOpenGLPixelFormat*)format; return [[EmuGLContext alloc] initWithFormat:frmt shareContext:share]; } void nsPBufferMakeCurrent(void* context,void* nativePBuffer,int level){ EmuGLContext* ctx = (EmuGLContext *)context; NSOpenGLPixelBuffer* pbuff = (NSOpenGLPixelBuffer *)nativePBuffer; if(ctx == nil){ [NSOpenGLContext clearCurrentContext]; } else { if(pbuff != nil){ [ctx preBind:1]; [ctx setPixelBuffer:pbuff cubeMapFace:0 mipMapLevel:level currentVirtualScreen:0]; [ctx makeCurrentContext]; } } } void nsWindowMakeCurrent(void* context,void* nativeWin){ EmuGLContext* ctx = (EmuGLContext *)context; NSView* win = (NSView *)nativeWin; if(ctx == nil){ [NSOpenGLContext clearCurrentContext]; } else if (win != nil) { [ctx preBind:0]; [ctx setView: win]; [ctx makeCurrentContext]; } } void nsSwapBuffers(){ NSOpenGLContext* ctx = [NSOpenGLContext currentContext]; if(ctx != nil){ [ctx flushBuffer]; } } void nsSwapInterval(int *interval){ NSOpenGLContext* ctx = [NSOpenGLContext currentContext]; if( ctx != nil){ [ctx setValues:interval forParameter:NSOpenGLCPSwapInterval]; } } void nsDestroyContext(void* context){ EmuGLContext *ctx = (EmuGLContext*)context; if(ctx != nil){ [ctx release]; } } void* nsCreatePBuffer(GLenum target,GLenum format,int maxMip,int width,int height){ return [[NSOpenGLPixelBuffer alloc] initWithTextureTarget:target textureInternalFormat:format textureMaxMipMapLevel:maxMip pixelsWide:width pixelsHigh:height]; } void nsDestroyPBuffer(void* pbuffer){ NSOpenGLPixelBuffer *pbuf = (NSOpenGLPixelBuffer*)pbuffer; if(pbuf != nil){ [pbuf release]; } } bool nsGetWinDims(void* win,unsigned int* width,unsigned int* height){ NSView* view = (NSView*)win; if(view != nil){ NSRect rect = [view bounds]; *width = rect.size.width; *height = rect.size.height; return true; } return false; } bool nsCheckColor(void* win,int colorSize){ NSView* view = (NSView*)win; if(view != nil){ NSWindow* wnd = [view window]; if(wnd != nil){ NSWindowDepth limit = [wnd depthLimit]; NSWindowDepth defaultLimit = [NSWindow defaultDepthLimit]; int depth = (limit != 0) ? NSBitsPerPixelFromDepth(limit): NSBitsPerPixelFromDepth(defaultLimit); return depth >= colorSize; } } return false; }