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