1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #include "gl/SkNativeGLContext.h" 9 10 SkNativeGLContext::AutoContextRestore::AutoContextRestore() { 11 fOldEGLContext = eglGetCurrentContext(); 12 fOldDisplay = eglGetCurrentDisplay(); 13 fOldSurface = eglGetCurrentSurface(EGL_DRAW); 14 15 } 16 17 SkNativeGLContext::AutoContextRestore::~AutoContextRestore() { 18 if (NULL != fOldDisplay) { 19 eglMakeCurrent(fOldDisplay, fOldSurface, fOldSurface, fOldEGLContext); 20 } 21 } 22 23 /////////////////////////////////////////////////////////////////////////////// 24 25 SkNativeGLContext::SkNativeGLContext() 26 : fContext(EGL_NO_CONTEXT) 27 , fDisplay(EGL_NO_DISPLAY) 28 , fSurface(EGL_NO_SURFACE) { 29 } 30 31 SkNativeGLContext::~SkNativeGLContext() { 32 this->destroyGLContext(); 33 } 34 35 void SkNativeGLContext::destroyGLContext() { 36 if (fDisplay) { 37 eglMakeCurrent(fDisplay, 0, 0, 0); 38 39 if (fContext) { 40 eglDestroyContext(fDisplay, fContext); 41 fContext = EGL_NO_CONTEXT; 42 } 43 44 if (fSurface) { 45 eglDestroySurface(fDisplay, fSurface); 46 fSurface = EGL_NO_SURFACE; 47 } 48 49 //TODO should we close the display? 50 fDisplay = EGL_NO_DISPLAY; 51 } 52 } 53 54 const GrGLInterface* SkNativeGLContext::createGLContext() { 55 static const EGLint kEGLContextAttribsForOpenGL[] = { 56 EGL_NONE 57 }; 58 59 static const EGLint kEGLContextAttribsForOpenGLES[] = { 60 EGL_CONTEXT_CLIENT_VERSION, 2, 61 EGL_NONE 62 }; 63 64 static const struct { 65 const EGLint* fContextAttribs; 66 EGLenum fAPI; 67 EGLint fRenderableTypeBit; 68 GrGLStandard fStandard; 69 } kAPIs[] = { 70 { // OpenGL 71 kEGLContextAttribsForOpenGL, 72 EGL_OPENGL_API, 73 EGL_OPENGL_BIT, 74 kGL_GrGLStandard 75 }, 76 { // OpenGL ES. This seems to work for both ES2 and 3 (when available). 77 kEGLContextAttribsForOpenGLES, 78 EGL_OPENGL_ES_API, 79 EGL_OPENGL_ES2_BIT, 80 kGLES_GrGLStandard 81 }, 82 }; 83 84 const GrGLInterface* interface = NULL; 85 86 for (size_t api = 0; NULL == interface && api < SK_ARRAY_COUNT(kAPIs); ++api) { 87 fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 88 89 EGLint majorVersion; 90 EGLint minorVersion; 91 eglInitialize(fDisplay, &majorVersion, &minorVersion); 92 93 #if 0 94 SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR)); 95 SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS)); 96 SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION)); 97 SkDebugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS)); 98 #endif 99 100 if (!eglBindAPI(kAPIs[api].fAPI)) { 101 continue; 102 } 103 104 EGLint numConfigs; 105 const EGLint configAttribs[] = { 106 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 107 EGL_RENDERABLE_TYPE, kAPIs[api].fRenderableTypeBit, 108 EGL_RED_SIZE, 8, 109 EGL_GREEN_SIZE, 8, 110 EGL_BLUE_SIZE, 8, 111 EGL_ALPHA_SIZE, 8, 112 EGL_NONE 113 }; 114 115 EGLConfig surfaceConfig; 116 if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) { 117 SkDebugf("eglChooseConfig failed. EGL Error: 0x%08x\n", eglGetError()); 118 continue; 119 } 120 121 fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, kAPIs[api].fContextAttribs); 122 if (EGL_NO_CONTEXT == fContext) { 123 SkDebugf("eglCreateContext failed. EGL Error: 0x%08x\n", eglGetError()); 124 continue; 125 } 126 127 static const EGLint kSurfaceAttribs[] = { 128 EGL_WIDTH, 1, 129 EGL_HEIGHT, 1, 130 EGL_NONE 131 }; 132 133 fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, kSurfaceAttribs); 134 if (EGL_NO_SURFACE == fSurface) { 135 SkDebugf("eglCreatePbufferSurface failed. EGL Error: 0x%08x\n", eglGetError()); 136 this->destroyGLContext(); 137 continue; 138 } 139 140 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { 141 SkDebugf("eglMakeCurrent failed. EGL Error: 0x%08x\n", eglGetError()); 142 this->destroyGLContext(); 143 continue; 144 } 145 146 interface = GrGLCreateNativeInterface(); 147 if (NULL == interface) { 148 SkDebugf("Failed to create gl interface.\n"); 149 this->destroyGLContext(); 150 continue; 151 } 152 153 if (!interface->validate()) { 154 interface->unref(); 155 interface = NULL; 156 this->destroyGLContext(); 157 } 158 } 159 160 return interface; 161 } 162 163 void SkNativeGLContext::makeCurrent() const { 164 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { 165 SkDebugf("Could not set the context.\n"); 166 } 167 } 168 169 void SkNativeGLContext::swapBuffers() const { 170 if (!eglSwapBuffers(fDisplay, fSurface)) { 171 SkDebugf("Could not complete eglSwapBuffers.\n"); 172 } 173 } 174