• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2* Copyright (C) 2011 The Android Open Source Project
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16#include <stdio.h>
17#include <Cocoa/Cocoa.h>
18#include <OpenGL/OpenGL.h>
19#include "MacPixelFormatsAttribs.h"
20
21//
22// EmuGLContext inherit from NSOpenGLContext
23// and adds binding state for the context to know
24// if it was last bounded to a pbuffer or a window.
25// This is because after the context was bounded to
26// a Pbuffer, before we bind it to a window we must
27// release it form the pbuffer by calling the
28// clearDrawable method. We do not want to call clearDrawable
29// more than really needed since when it is called at a time
30// that a window is bounded to the context it will clear the
31// window content causing flickering effect.
32// Thererfore we call clearDrawable only when we bind the context
33// to a window and it was previously bound to a Pbuffer.
34//
35@interface EmuGLContext : NSOpenGLContext {
36    @private
37        int boundToPbuffer;
38        int boundToWin;
39}
40
41- (id) initWithFormat:(NSOpenGLPixelFormat *)pixelFormat shareContext:(NSOpenGLContext *)share;
42- (void) preBind:(int)forPbuffer;
43@end
44
45@implementation EmuGLContext
46- (id) initWithFormat:(NSOpenGLPixelFormat *)pixelFormat shareContext:(NSOpenGLContext *)share
47{
48    self = [super initWithFormat:pixelFormat shareContext:share];
49    if (self != nil) {
50        boundToPbuffer = 0;
51        boundToWin = 0;
52    }
53    return self;
54}
55
56- (void) preBind:(int)forPbuffer
57{
58    if ((!forPbuffer && boundToPbuffer)) {
59        [self clearDrawable];
60    }
61    boundToPbuffer = forPbuffer;
62    boundToWin = !boundToPbuffer;
63}
64@end
65
66int getNumPixelFormats(){
67    int size;
68    NSOpenGLPixelFormatAttribute** attrib_lists = getPixelFormatsAttributes(&size);
69    return size;
70}
71
72void* getPixelFormat(int i){
73    int size;
74    NSOpenGLPixelFormatAttribute** attrib_lists = getPixelFormatsAttributes(&size);
75    return [[NSOpenGLPixelFormat alloc] initWithAttributes:attrib_lists[i]];
76}
77
78void getPixelFormatAttrib(void* pixelFormat,int attrib,int* val){
79    NSOpenGLPixelFormat *frmt = (NSOpenGLPixelFormat *)pixelFormat;
80    [frmt getValues:val forAttribute:attrib forVirtualScreen:0];
81}
82
83void* nsCreateContext(void* format,void* share){
84    NSOpenGLPixelFormat* frmt = (NSOpenGLPixelFormat*)format;
85    return [[EmuGLContext alloc] initWithFormat:frmt shareContext:share];
86}
87
88void  nsPBufferMakeCurrent(void* context,void* nativePBuffer,int level){
89    EmuGLContext* ctx = (EmuGLContext *)context;
90    NSOpenGLPixelBuffer* pbuff = (NSOpenGLPixelBuffer *)nativePBuffer;
91    if(ctx == nil){
92        [NSOpenGLContext clearCurrentContext];
93    } else {
94        if(pbuff != nil){
95            [ctx preBind:1];
96            [ctx setPixelBuffer:pbuff cubeMapFace:0 mipMapLevel:level currentVirtualScreen:0];
97            [ctx makeCurrentContext];
98        }
99    }
100}
101
102void nsWindowMakeCurrent(void* context,void* nativeWin){
103    EmuGLContext* ctx = (EmuGLContext *)context;
104    NSView* win = (NSView *)nativeWin;
105    if(ctx == nil){
106        [NSOpenGLContext clearCurrentContext];
107    } else if (win != nil) {
108        [ctx preBind:0];
109        [ctx setView: win];
110        [ctx makeCurrentContext];
111    }
112}
113
114void nsSwapBuffers(){
115    NSOpenGLContext* ctx = [NSOpenGLContext currentContext];
116    if(ctx != nil){
117        [ctx flushBuffer];
118    }
119}
120
121void nsSwapInterval(int *interval){
122    NSOpenGLContext* ctx = [NSOpenGLContext currentContext];
123    if( ctx != nil){
124        [ctx setValues:interval forParameter:NSOpenGLCPSwapInterval];
125    }
126}
127
128
129void nsDestroyContext(void* context){
130    EmuGLContext *ctx = (EmuGLContext*)context;
131    if(ctx != nil){
132        [ctx release];
133    }
134}
135
136
137void* nsCreatePBuffer(GLenum target,GLenum format,int maxMip,int width,int height){
138    return [[NSOpenGLPixelBuffer alloc] initWithTextureTarget:target
139                                        textureInternalFormat:format
140                                        textureMaxMipMapLevel:maxMip
141                                        pixelsWide:width pixelsHigh:height];
142
143}
144
145void nsDestroyPBuffer(void* pbuffer){
146    NSOpenGLPixelBuffer *pbuf = (NSOpenGLPixelBuffer*)pbuffer;
147    if(pbuf != nil){
148        [pbuf release];
149    }
150}
151
152bool nsGetWinDims(void* win,unsigned int* width,unsigned int* height){
153    NSView* view = (NSView*)win;
154    if(view != nil){
155        NSRect rect = [view bounds];
156        *width  = rect.size.width;
157        *height = rect.size.height;
158        return true;
159    }
160    return false;
161}
162
163bool  nsCheckColor(void* win,int colorSize){
164    NSView* view = (NSView*)win;
165   if(view != nil){
166       NSWindow* wnd = [view window];
167       if(wnd != nil){
168           NSWindowDepth limit = [wnd depthLimit];
169           NSWindowDepth defaultLimit = [NSWindow defaultDepthLimit];
170
171           int depth = (limit != 0) ? NSBitsPerPixelFromDepth(limit):
172                                      NSBitsPerPixelFromDepth(defaultLimit);
173           return depth >= colorSize;
174
175       }
176   }
177   return false;
178
179}
180