/* * 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 "EglOsApi.h" #include "MacNative.h" #define MAX_PBUFFER_MIPMAP_LEVEL 1 namespace EglOS { static std::list<EGLNativePixelFormatType> s_nativeConfigs; EGLNativeDisplayType getDefaultDisplay() {return 0;} bool releaseDisplay(EGLNativeDisplayType dpy) { return true; } static EglConfig* pixelFormatToConfig(int index,int renderableType,EGLNativePixelFormatType* frmt){ if(!frmt) return NULL; EGLint red,green,blue,alpha,depth,stencil; EGLint supportedSurfaces,visualType,visualId; EGLint transparentType,samples; EGLint tRed,tGreen,tBlue; EGLint pMaxWidth,pMaxHeight,pMaxPixels; EGLint configId,level; EGLint window,pbuffer; EGLint doubleBuffer,colorSize; getPixelFormatAttrib(*frmt,MAC_HAS_DOUBLE_BUFFER,&doubleBuffer); if(!doubleBuffer) return NULL; //pixel double buffer supportedSurfaces = 0; getPixelFormatAttrib(*frmt,MAC_DRAW_TO_WINDOW,&window); getPixelFormatAttrib(*frmt,MAC_DRAW_TO_PBUFFER,&pbuffer); if(window) supportedSurfaces |= EGL_WINDOW_BIT; if(pbuffer) supportedSurfaces |= EGL_PBUFFER_BIT; if(!supportedSurfaces) return NULL; //default values visualId = 0; visualType = EGL_NONE; EGLenum caveat = EGL_NONE; EGLBoolean renderable = EGL_FALSE; pMaxWidth = PBUFFER_MAX_WIDTH; pMaxHeight = PBUFFER_MAX_HEIGHT; pMaxPixels = PBUFFER_MAX_PIXELS; samples = 0; level = 0; tRed = tGreen = tBlue = 0; transparentType = EGL_NONE; getPixelFormatAttrib(*frmt,MAC_SAMPLES_PER_PIXEL,&samples); getPixelFormatAttrib(*frmt,MAC_COLOR_SIZE,&colorSize); getPixelFormatAttrib(*frmt,MAC_ALPHA_SIZE,&alpha); getPixelFormatAttrib(*frmt,MAC_DEPTH_SIZE,&depth); getPixelFormatAttrib(*frmt,MAC_STENCIL_SIZE,&stencil); red = green = blue = (colorSize / 4); //TODO: ask guy if it is OK return new EglConfig(red,green,blue,alpha,caveat,(EGLint)index,depth,level,pMaxWidth,pMaxHeight,pMaxPixels,renderable,renderableType, visualId,visualType,samples,stencil,supportedSurfaces,transparentType,tRed,tGreen,tBlue,*frmt); } static void initNativeConfigs(){ int nConfigs = getNumPixelFormats(); if(s_nativeConfigs.empty()){ for(int i=0; i < nConfigs ;i++){ EGLNativePixelFormatType frmt = getPixelFormat(i); if(frmt){ s_nativeConfigs.push_back(frmt); } } } } void queryConfigs(EGLNativeDisplayType dpy,int renderableType,ConfigsList& listOut) { int i = 0 ; initNativeConfigs(); for(std::list<EGLNativePixelFormatType>::iterator it = s_nativeConfigs.begin(); it != s_nativeConfigs.end();it++){ EGLNativePixelFormatType frmt = *it; EglConfig* conf = pixelFormatToConfig(i++,renderableType,&frmt); if(conf){ listOut.push_front(conf); }; } } bool validNativeDisplay(EGLNativeInternalDisplayType dpy) { return true; } bool validNativeWin(EGLNativeDisplayType dpy, EGLNativeWindowType win) { unsigned int width,height; return nsGetWinDims(win,&width,&height); } bool validNativeWin(EGLNativeDisplayType dpy, EGLNativeSurfaceType win) { return validNativeWin(dpy,(EGLNativeWindowType)win); } //no support for pixmap in mac bool validNativePixmap(EGLNativeDisplayType dpy, EGLNativeSurfaceType pix) { return true; } bool checkWindowPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativeWindowType win,EglConfig* cfg,unsigned int* width,unsigned int* height) { int r,g,b; bool ret = nsGetWinDims(win,width,height); cfg->getConfAttrib(EGL_RED_SIZE,&r); cfg->getConfAttrib(EGL_GREEN_SIZE,&g); cfg->getConfAttrib(EGL_BLUE_SIZE,&b); bool match = nsCheckColor(win,r + g + b); return ret && match; } //no support for pixmap in mac bool checkPixmapPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativePixmapType pix,EglConfig* cfg,unsigned int* width,unsigned int* height) { return false; } EGLNativeSurfaceType createPbufferSurface(EGLNativeDisplayType dpy,EglConfig* cfg,EglPbufferSurface* srfc){ EGLint width,height,hasMipmap,tmp; EGLint target,format; srfc->getDim(&width,&height,&tmp); srfc->getTexInfo(&format,&target); srfc->getAttrib(EGL_MIPMAP_TEXTURE,&hasMipmap); EGLint maxMipmap = hasMipmap ? MAX_PBUFFER_MIPMAP_LEVEL:0; return (EGLNativeSurfaceType)nsCreatePBuffer(target,format,maxMipmap,width,height); } bool releasePbuffer(EGLNativeDisplayType dis,EGLNativeSurfaceType pb) { nsDestroyPBuffer(pb); return true; } EGLNativeContextType createContext(EGLNativeDisplayType dpy,EglConfig* cfg,EGLNativeContextType sharedContext) { return nsCreateContext(cfg->nativeConfig(),sharedContext); } bool destroyContext(EGLNativeDisplayType dpy,EGLNativeContextType ctx) { nsDestroyContext(ctx); return true; } bool makeCurrent(EGLNativeDisplayType dpy,EglSurface* read,EglSurface* draw,EGLNativeContextType ctx){ // check for unbind if (ctx == NULL && read == NULL && draw == NULL) { nsWindowMakeCurrent(NULL, NULL); return true; } else if (ctx == NULL || read == NULL || draw == NULL) { // error ! return false; } //dont supporting diffrent read & draw surfaces on Mac if(read->native() != draw->native()) return false; switch(draw->type()){ case EglSurface::WINDOW: nsWindowMakeCurrent(ctx,draw->native()); break; case EglSurface::PBUFFER: { EGLint hasMipmap; draw->getAttrib(EGL_MIPMAP_TEXTURE,&hasMipmap); int mipmapLevel = hasMipmap ? MAX_PBUFFER_MIPMAP_LEVEL:0; nsPBufferMakeCurrent(ctx,draw->native(),mipmapLevel); break; } case EglSurface::PIXMAP: // not supported on Mac default: return false; } return true; } void swapBuffers(EGLNativeDisplayType dpy,EGLNativeSurfaceType srfc){ nsSwapBuffers(); } void waitNative(){} void swapInterval(EGLNativeDisplayType dpy,EGLNativeSurfaceType win,int interval){ nsSwapInterval(&interval); } EGLNativeSurfaceType createWindowSurface(EGLNativeWindowType wnd){ return (EGLNativeSurfaceType)wnd; } EGLNativeSurfaceType createPixmapSurface(EGLNativePixmapType pix){ return (EGLNativeSurfaceType)pix; } void destroySurface(EGLNativeSurfaceType srfc){ } EGLNativeInternalDisplayType getInternalDisplay(EGLNativeDisplayType dpy){ return (EGLNativeInternalDisplayType)dpy; } void deleteDisplay(EGLNativeInternalDisplayType idpy){ } };