207 lines
6.2 KiB
Objective-C
207 lines
6.2 KiB
Objective-C
/*
|
|
* 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 <stdio.h>
|
|
#include <Cocoa/Cocoa.h>
|
|
#include <OpenGL/OpenGL.h>
|
|
#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;
|
|
|
|
}
|