Home | History | Annotate | Download | only in EGL
      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 
     66 int getNumPixelFormats(){
     67     int size;
     68     NSOpenGLPixelFormatAttribute** attrib_lists = getPixelFormatsAttributes(&size);
     69     return size;
     70 }
     71 
     72 void* getPixelFormat(int i){
     73     int size;
     74     NSOpenGLPixelFormatAttribute** attrib_lists = getPixelFormatsAttributes(&size);
     75     return [[NSOpenGLPixelFormat alloc] initWithAttributes:attrib_lists[i]];
     76 }
     77 
     78 int getPixelFormatDefinitionAlpha(int i) {
     79     int size;
     80     NSOpenGLPixelFormatAttribute** attrib_lists = getPixelFormatsAttributes(&size);
     81     NSOpenGLPixelFormatAttribute* attribs = attrib_lists[i];
     82     while (*attribs) {
     83         switch (*attribs) {
     84         // These are the ones that take a value, according to the current
     85         // NSOpenGLPixelFormat docs
     86         case NSOpenGLPFAAuxBuffers:
     87         case NSOpenGLPFAColorSize:
     88         case NSOpenGLPFADepthSize:
     89         case NSOpenGLPFAStencilSize:
     90         case NSOpenGLPFAAccumSize:
     91         case NSOpenGLPFARendererID:
     92         case NSOpenGLPFAScreenMask:
     93             attribs += 2;
     94             break;
     95         case NSOpenGLPFAAlphaSize:
     96             return attribs[1];
     97             break;
     98         // All other attributes are boolean attributes that don't take a value
     99         default:
    100             attribs++;
    101         }
    102     }
    103     return 0;
    104 }
    105 
    106 void getPixelFormatAttrib(void* pixelFormat,int attrib,int* val){
    107     NSOpenGLPixelFormat *frmt = (NSOpenGLPixelFormat *)pixelFormat;
    108     [frmt getValues:val forAttribute:attrib forVirtualScreen:0];
    109 }
    110 
    111 void* nsCreateContext(void* format,void* share){
    112     NSOpenGLPixelFormat* frmt = (NSOpenGLPixelFormat*)format;
    113     return [[EmuGLContext alloc] initWithFormat:frmt shareContext:share];
    114 }
    115 
    116 void  nsPBufferMakeCurrent(void* context,void* nativePBuffer,int level){
    117     EmuGLContext* ctx = (EmuGLContext *)context;
    118     NSOpenGLPixelBuffer* pbuff = (NSOpenGLPixelBuffer *)nativePBuffer;
    119     if(ctx == nil){
    120         [NSOpenGLContext clearCurrentContext];
    121     } else {
    122         if(pbuff != nil){
    123             [ctx preBind:1];
    124             [ctx setPixelBuffer:pbuff cubeMapFace:0 mipMapLevel:level currentVirtualScreen:0];
    125             [ctx makeCurrentContext];
    126         }
    127     }
    128 }
    129 
    130 void nsWindowMakeCurrent(void* context,void* nativeWin){
    131     EmuGLContext* ctx = (EmuGLContext *)context;
    132     NSView* win = (NSView *)nativeWin;
    133     if(ctx == nil){
    134         [NSOpenGLContext clearCurrentContext];
    135     } else if (win != nil) {
    136         [ctx preBind:0];
    137         [ctx setView: win];
    138         [ctx makeCurrentContext];
    139     }
    140 }
    141 
    142 void nsSwapBuffers(){
    143     NSOpenGLContext* ctx = [NSOpenGLContext currentContext];
    144     if(ctx != nil){
    145         [ctx flushBuffer];
    146     }
    147 }
    148 
    149 void nsSwapInterval(int *interval){
    150     NSOpenGLContext* ctx = [NSOpenGLContext currentContext];
    151     if( ctx != nil){
    152         [ctx setValues:interval forParameter:NSOpenGLCPSwapInterval];
    153     }
    154 }
    155 
    156 
    157 void nsDestroyContext(void* context){
    158     EmuGLContext *ctx = (EmuGLContext*)context;
    159     if(ctx != nil){
    160         [ctx release];
    161     }
    162 }
    163 
    164 
    165 void* nsCreatePBuffer(GLenum target,GLenum format,int maxMip,int width,int height){
    166     return [[NSOpenGLPixelBuffer alloc] initWithTextureTarget:target
    167                                         textureInternalFormat:format
    168                                         textureMaxMipMapLevel:maxMip
    169                                         pixelsWide:width pixelsHigh:height];
    170 
    171 }
    172 
    173 void nsDestroyPBuffer(void* pbuffer){
    174     NSOpenGLPixelBuffer *pbuf = (NSOpenGLPixelBuffer*)pbuffer;
    175     if(pbuf != nil){
    176         [pbuf release];
    177     }
    178 }
    179 
    180 bool nsGetWinDims(void* win,unsigned int* width,unsigned int* height){
    181     NSView* view = (NSView*)win;
    182     if(view != nil){
    183         NSRect rect = [view bounds];
    184         *width  = rect.size.width;
    185         *height = rect.size.height;
    186         return true;
    187     }
    188     return false;
    189 }
    190 
    191 bool  nsCheckColor(void* win,int colorSize){
    192     NSView* view = (NSView*)win;
    193    if(view != nil){
    194        NSWindow* wnd = [view window];
    195        if(wnd != nil){
    196            NSWindowDepth limit = [wnd depthLimit];
    197            NSWindowDepth defaultLimit = [NSWindow defaultDepthLimit];
    198 
    199            int depth = (limit != 0) ? NSBitsPerPixelFromDepth(limit):
    200                                       NSBitsPerPixelFromDepth(defaultLimit);
    201            return depth >= colorSize;
    202 
    203        }
    204    }
    205    return false;
    206 
    207 }
    208