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 "EglOsApi.h"
     17 #include "MacNative.h"
     18 #define MAX_PBUFFER_MIPMAP_LEVEL 1
     19 
     20 namespace EglOS {
     21 
     22 static std::list<EGLNativePixelFormatType> s_nativeConfigs;
     23 
     24 EGLNativeDisplayType getDefaultDisplay() {return 0;}
     25 
     26 bool releaseDisplay(EGLNativeDisplayType dpy) {
     27     return true;
     28 }
     29 
     30 static EglConfig* pixelFormatToConfig(int index,int renderableType,EGLNativePixelFormatType* frmt){
     31     if(!frmt) return NULL;
     32 
     33     EGLint  red,green,blue,alpha,depth,stencil;
     34     EGLint  supportedSurfaces,visualType,visualId;
     35     EGLint  transparentType,samples;
     36     EGLint  tRed,tGreen,tBlue;
     37     EGLint  pMaxWidth,pMaxHeight,pMaxPixels;
     38     EGLint  configId,level;
     39     EGLint  window,pbuffer;
     40     EGLint  doubleBuffer,colorSize;
     41 
     42     getPixelFormatAttrib(*frmt,MAC_HAS_DOUBLE_BUFFER,&doubleBuffer);
     43     if(!doubleBuffer) return NULL; //pixel double buffer
     44 
     45     supportedSurfaces = 0;
     46 
     47     getPixelFormatAttrib(*frmt,MAC_DRAW_TO_WINDOW,&window);
     48     getPixelFormatAttrib(*frmt,MAC_DRAW_TO_PBUFFER,&pbuffer);
     49 
     50     if(window)  supportedSurfaces |= EGL_WINDOW_BIT;
     51     if(pbuffer) supportedSurfaces |= EGL_PBUFFER_BIT;
     52 
     53     if(!supportedSurfaces) return NULL;
     54 
     55     //default values
     56     visualId                  = 0;
     57     visualType                = EGL_NONE;
     58     EGLenum caveat            = EGL_NONE;
     59     EGLBoolean renderable     = EGL_FALSE;
     60     pMaxWidth                 = PBUFFER_MAX_WIDTH;
     61     pMaxHeight                = PBUFFER_MAX_HEIGHT;
     62     pMaxPixels                = PBUFFER_MAX_PIXELS;
     63     samples                   = 0;
     64     level                     = 0;
     65     tRed = tGreen = tBlue     = 0;
     66 
     67     transparentType = EGL_NONE;
     68 
     69     getPixelFormatAttrib(*frmt,MAC_SAMPLES_PER_PIXEL,&samples);
     70     getPixelFormatAttrib(*frmt,MAC_COLOR_SIZE,&colorSize);
     71     /* All configs can end up having an alpha channel even if none was requested.
     72      * The default config chooser in GLSurfaceView will therefore not find any
     73      * matching config. Thus, make sure alpha is zero (or at least signalled as
     74      * zero to the calling EGL layer) for the configs where it was intended to
     75      * be zero. */
     76     if (getPixelFormatDefinitionAlpha(index) == 0)
     77         alpha = 0;
     78     else
     79         getPixelFormatAttrib(*frmt,MAC_ALPHA_SIZE,&alpha);
     80     getPixelFormatAttrib(*frmt,MAC_DEPTH_SIZE,&depth);
     81     getPixelFormatAttrib(*frmt,MAC_STENCIL_SIZE,&stencil);
     82 
     83     red = green = blue = (colorSize / 4); //TODO: ask guy if it is OK
     84 
     85     return new EglConfig(red,green,blue,alpha,caveat,(EGLint)index,depth,level,pMaxWidth,pMaxHeight,pMaxPixels,renderable,renderableType,
     86                          visualId,visualType,samples,stencil,supportedSurfaces,transparentType,tRed,tGreen,tBlue,*frmt);
     87 }
     88 
     89 
     90 static void initNativeConfigs(){
     91     int nConfigs = getNumPixelFormats();
     92     if(s_nativeConfigs.empty()){
     93         for(int i=0; i < nConfigs ;i++){
     94              EGLNativePixelFormatType frmt = getPixelFormat(i);
     95              if(frmt){
     96                  s_nativeConfigs.push_back(frmt);
     97              }
     98         }
     99     }
    100 }
    101 
    102 void queryConfigs(EGLNativeDisplayType dpy,int renderableType,ConfigsList& listOut) {
    103     int i = 0 ;
    104     initNativeConfigs();
    105     for(std::list<EGLNativePixelFormatType>::iterator it = s_nativeConfigs.begin(); it != s_nativeConfigs.end();it++){
    106          EGLNativePixelFormatType frmt = *it;
    107          EglConfig* conf = pixelFormatToConfig(i++,renderableType,&frmt);
    108          if(conf){
    109              listOut.push_front(conf);
    110          };
    111     }
    112 }
    113 
    114 bool validNativeDisplay(EGLNativeInternalDisplayType dpy) {
    115     return true;
    116 }
    117 
    118 bool validNativeWin(EGLNativeDisplayType dpy, EGLNativeWindowType win) {
    119     unsigned int width,height;
    120     return nsGetWinDims(win,&width,&height);
    121 }
    122 
    123 bool validNativeWin(EGLNativeDisplayType dpy, EGLNativeSurfaceType win) {
    124     return validNativeWin(dpy,(EGLNativeWindowType)win);
    125 }
    126 
    127 //no support for pixmap in mac
    128 bool validNativePixmap(EGLNativeDisplayType dpy, EGLNativeSurfaceType pix) {
    129 
    130    return true;
    131 }
    132 
    133 bool checkWindowPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativeWindowType win,EglConfig* cfg,unsigned int* width,unsigned int* height) {
    134     int r,g,b;
    135     bool ret = nsGetWinDims(win,width,height);
    136 
    137     cfg->getConfAttrib(EGL_RED_SIZE,&r);
    138     cfg->getConfAttrib(EGL_GREEN_SIZE,&g);
    139     cfg->getConfAttrib(EGL_BLUE_SIZE,&b);
    140     bool match = nsCheckColor(win,r + g + b);
    141 
    142     return ret && match;
    143 }
    144 
    145 //no support for pixmap in mac
    146 bool checkPixmapPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativePixmapType pix,EglConfig* cfg,unsigned int* width,unsigned int* height) {
    147     return false;
    148 }
    149 
    150 EGLNativeSurfaceType createPbufferSurface(EGLNativeDisplayType dpy,EglConfig* cfg,EglPbufferSurface* srfc){
    151     EGLint width,height,hasMipmap,tmp;
    152     EGLint target,format;
    153     GLenum glTexFormat = GL_RGBA, glTexTarget = GL_TEXTURE_2D;
    154     srfc->getDim(&width,&height,&tmp);
    155     srfc->getTexInfo(&format,&target);
    156     switch (format) {
    157     case EGL_TEXTURE_RGB:
    158         glTexFormat = GL_RGB;
    159         break;
    160     case EGL_TEXTURE_RGBA:
    161         glTexFormat = GL_RGBA;
    162         break;
    163     }
    164     srfc->getAttrib(EGL_MIPMAP_TEXTURE,&hasMipmap);
    165     EGLint maxMipmap = hasMipmap ? MAX_PBUFFER_MIPMAP_LEVEL:0;
    166     return (EGLNativeSurfaceType)nsCreatePBuffer(glTexTarget,glTexFormat,maxMipmap,width,height);
    167 }
    168 
    169 bool releasePbuffer(EGLNativeDisplayType dis,EGLNativeSurfaceType pb) {
    170     nsDestroyPBuffer(pb);
    171     return true;
    172 }
    173 
    174 EGLNativeContextType createContext(EGLNativeDisplayType dpy,EglConfig* cfg,EGLNativeContextType sharedContext) {
    175  return nsCreateContext(cfg->nativeConfig(),sharedContext);
    176 }
    177 
    178 bool destroyContext(EGLNativeDisplayType dpy,EGLNativeContextType ctx) {
    179     nsDestroyContext(ctx);
    180     return true;
    181 }
    182 
    183 bool makeCurrent(EGLNativeDisplayType dpy,EglSurface* read,EglSurface* draw,EGLNativeContextType ctx){
    184 
    185     // check for unbind
    186     if (ctx == NULL && read == NULL && draw == NULL) {
    187         nsWindowMakeCurrent(NULL, NULL);
    188         return true;
    189     }
    190     else if (ctx == NULL || read == NULL || draw == NULL) {
    191         // error !
    192         return false;
    193     }
    194 
    195     //dont supporting diffrent read & draw surfaces on Mac
    196     if(read->native() != draw->native()) return false;
    197     switch(draw->type()){
    198     case EglSurface::WINDOW:
    199         nsWindowMakeCurrent(ctx,draw->native());
    200         break;
    201     case EglSurface::PBUFFER:
    202     {
    203         EGLint hasMipmap;
    204         draw->getAttrib(EGL_MIPMAP_TEXTURE,&hasMipmap);
    205         int mipmapLevel = hasMipmap ? MAX_PBUFFER_MIPMAP_LEVEL:0;
    206         nsPBufferMakeCurrent(ctx,draw->native(),mipmapLevel);
    207         break;
    208     }
    209     case EglSurface::PIXMAP: // not supported on Mac
    210     default:
    211         return false;
    212     }
    213     return true;
    214 }
    215 
    216 void swapBuffers(EGLNativeDisplayType dpy,EGLNativeSurfaceType srfc){
    217     nsSwapBuffers();
    218 }
    219 
    220 void waitNative(){}
    221 
    222 void swapInterval(EGLNativeDisplayType dpy,EGLNativeSurfaceType win,int interval){
    223     nsSwapInterval(&interval);
    224 }
    225 
    226 EGLNativeSurfaceType createWindowSurface(EGLNativeWindowType wnd){
    227     return (EGLNativeSurfaceType)wnd;
    228 }
    229 
    230 EGLNativeSurfaceType createPixmapSurface(EGLNativePixmapType pix){
    231     return (EGLNativeSurfaceType)pix;
    232 }
    233 
    234 void destroySurface(EGLNativeSurfaceType srfc){
    235 }
    236 
    237 EGLNativeInternalDisplayType getInternalDisplay(EGLNativeDisplayType dpy){
    238     return (EGLNativeInternalDisplayType)dpy;
    239 }
    240 
    241 void deleteDisplay(EGLNativeInternalDisplayType idpy){
    242 }
    243 
    244 };
    245