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
getDefaultDisplay()24 EGLNativeDisplayType getDefaultDisplay() {return 0;}
25
releaseDisplay(EGLNativeDisplayType dpy)26 bool releaseDisplay(EGLNativeDisplayType dpy) {
27 return true;
28 }
29
pixelFormatToConfig(int index,int renderableType,EGLNativePixelFormatType * frmt)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
initNativeConfigs()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
queryConfigs(EGLNativeDisplayType dpy,int renderableType,ConfigsList & listOut)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
validNativeDisplay(EGLNativeInternalDisplayType dpy)114 bool validNativeDisplay(EGLNativeInternalDisplayType dpy) {
115 return true;
116 }
117
validNativeWin(EGLNativeDisplayType dpy,EGLNativeWindowType win)118 bool validNativeWin(EGLNativeDisplayType dpy, EGLNativeWindowType win) {
119 unsigned int width,height;
120 return nsGetWinDims(win,&width,&height);
121 }
122
validNativeWin(EGLNativeDisplayType dpy,EGLNativeSurfaceType win)123 bool validNativeWin(EGLNativeDisplayType dpy, EGLNativeSurfaceType win) {
124 return validNativeWin(dpy,(EGLNativeWindowType)win);
125 }
126
127 //no support for pixmap in mac
validNativePixmap(EGLNativeDisplayType dpy,EGLNativeSurfaceType pix)128 bool validNativePixmap(EGLNativeDisplayType dpy, EGLNativeSurfaceType pix) {
129
130 return true;
131 }
132
checkWindowPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativeWindowType win,EglConfig * cfg,unsigned int * width,unsigned int * height)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
checkPixmapPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativePixmapType pix,EglConfig * cfg,unsigned int * width,unsigned int * height)146 bool checkPixmapPixelFormatMatch(EGLNativeDisplayType dpy,EGLNativePixmapType pix,EglConfig* cfg,unsigned int* width,unsigned int* height) {
147 return false;
148 }
149
createPbufferSurface(EGLNativeDisplayType dpy,EglConfig * cfg,EglPbufferSurface * srfc)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
releasePbuffer(EGLNativeDisplayType dis,EGLNativeSurfaceType pb)169 bool releasePbuffer(EGLNativeDisplayType dis,EGLNativeSurfaceType pb) {
170 nsDestroyPBuffer(pb);
171 return true;
172 }
173
createContext(EGLNativeDisplayType dpy,EglConfig * cfg,EGLNativeContextType sharedContext)174 EGLNativeContextType createContext(EGLNativeDisplayType dpy,EglConfig* cfg,EGLNativeContextType sharedContext) {
175 return nsCreateContext(cfg->nativeConfig(),sharedContext);
176 }
177
destroyContext(EGLNativeDisplayType dpy,EGLNativeContextType ctx)178 bool destroyContext(EGLNativeDisplayType dpy,EGLNativeContextType ctx) {
179 nsDestroyContext(ctx);
180 return true;
181 }
182
makeCurrent(EGLNativeDisplayType dpy,EglSurface * read,EglSurface * draw,EGLNativeContextType ctx)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
swapBuffers(EGLNativeDisplayType dpy,EGLNativeSurfaceType srfc)216 void swapBuffers(EGLNativeDisplayType dpy,EGLNativeSurfaceType srfc){
217 nsSwapBuffers();
218 }
219
waitNative()220 void waitNative(){}
221
swapInterval(EGLNativeDisplayType dpy,EGLNativeSurfaceType win,int interval)222 void swapInterval(EGLNativeDisplayType dpy,EGLNativeSurfaceType win,int interval){
223 nsSwapInterval(&interval);
224 }
225
createWindowSurface(EGLNativeWindowType wnd)226 EGLNativeSurfaceType createWindowSurface(EGLNativeWindowType wnd){
227 return (EGLNativeSurfaceType)wnd;
228 }
229
createPixmapSurface(EGLNativePixmapType pix)230 EGLNativeSurfaceType createPixmapSurface(EGLNativePixmapType pix){
231 return (EGLNativeSurfaceType)pix;
232 }
233
destroySurface(EGLNativeSurfaceType srfc)234 void destroySurface(EGLNativeSurfaceType srfc){
235 }
236
getInternalDisplay(EGLNativeDisplayType dpy)237 EGLNativeInternalDisplayType getInternalDisplay(EGLNativeDisplayType dpy){
238 return (EGLNativeInternalDisplayType)dpy;
239 }
240
deleteDisplay(EGLNativeInternalDisplayType idpy)241 void deleteDisplay(EGLNativeInternalDisplayType idpy){
242 }
243
244 };
245