1 2 /* 3 * Copyright 2012 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 9 #include "gl/angle/SkANGLEGLContext.h" 10 11 #include <EGL/egl.h> 12 13 #define EGL_PLATFORM_ANGLE_ANGLE 0x3201 14 #define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202 15 #define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3206 16 #define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207 17 18 void* SkANGLEGLContext::GetD3DEGLDisplay(void* nativeDisplay) { 19 20 typedef EGLDisplay (*EGLGetPlatformDisplayEXT)(EGLenum platform, 21 void *native_display, 22 const EGLint *attrib_list); 23 EGLGetPlatformDisplayEXT eglGetPlatformDisplayEXT; 24 eglGetPlatformDisplayEXT = 25 (EGLGetPlatformDisplayEXT) eglGetProcAddress("eglGetPlatformDisplayEXT"); 26 27 if (!eglGetPlatformDisplayEXT) { 28 return eglGetDisplay(static_cast<EGLNativeDisplayType>(nativeDisplay)); 29 } 30 31 // Try for an ANGLE D3D11 context, fall back to D3D9. 32 EGLint attribs[2][3] = { 33 { 34 EGL_PLATFORM_ANGLE_TYPE_ANGLE, 35 EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 36 EGL_NONE 37 }, 38 { 39 EGL_PLATFORM_ANGLE_TYPE_ANGLE, 40 EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, 41 EGL_NONE 42 } 43 }; 44 45 EGLDisplay display = EGL_NO_DISPLAY; 46 for (int i = 0; i < 2 && display == EGL_NO_DISPLAY; ++i) { 47 display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, 48 nativeDisplay, attribs[i]); 49 } 50 return display; 51 } 52 53 SkANGLEGLContext::SkANGLEGLContext() 54 : fContext(EGL_NO_CONTEXT) 55 , fDisplay(EGL_NO_DISPLAY) 56 , fSurface(EGL_NO_SURFACE) { 57 58 EGLint numConfigs; 59 static const EGLint configAttribs[] = { 60 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 61 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 62 EGL_RED_SIZE, 8, 63 EGL_GREEN_SIZE, 8, 64 EGL_BLUE_SIZE, 8, 65 EGL_ALPHA_SIZE, 8, 66 EGL_NONE 67 }; 68 69 fDisplay = GetD3DEGLDisplay(EGL_DEFAULT_DISPLAY); 70 if (EGL_NO_DISPLAY == fDisplay) { 71 SkDebugf("Could not create EGL display!"); 72 return; 73 } 74 75 EGLint majorVersion; 76 EGLint minorVersion; 77 eglInitialize(fDisplay, &majorVersion, &minorVersion); 78 79 EGLConfig surfaceConfig; 80 eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs); 81 82 static const EGLint contextAttribs[] = { 83 EGL_CONTEXT_CLIENT_VERSION, 2, 84 EGL_NONE 85 }; 86 fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, contextAttribs); 87 88 89 static const EGLint surfaceAttribs[] = { 90 EGL_WIDTH, 1, 91 EGL_HEIGHT, 1, 92 EGL_NONE 93 }; 94 95 fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs); 96 97 eglMakeCurrent(fDisplay, fSurface, fSurface, fContext); 98 99 fGL.reset(GrGLCreateANGLEInterface()); 100 if (NULL == fGL.get()) { 101 SkDebugf("Could not create ANGLE GL interface!\n"); 102 this->destroyGLContext(); 103 return; 104 } 105 if (!fGL->validate()) { 106 SkDebugf("Could not validate ANGLE GL interface!\n"); 107 this->destroyGLContext(); 108 return; 109 } 110 } 111 112 SkANGLEGLContext::~SkANGLEGLContext() { 113 this->destroyGLContext(); 114 } 115 116 void SkANGLEGLContext::destroyGLContext() { 117 fGL.reset(NULL); 118 if (fDisplay) { 119 eglMakeCurrent(fDisplay, 0, 0, 0); 120 121 if (fContext) { 122 eglDestroyContext(fDisplay, fContext); 123 fContext = EGL_NO_CONTEXT; 124 } 125 126 if (fSurface) { 127 eglDestroySurface(fDisplay, fSurface); 128 fSurface = EGL_NO_SURFACE; 129 } 130 131 //TODO should we close the display? 132 fDisplay = EGL_NO_DISPLAY; 133 } 134 } 135 136 void SkANGLEGLContext::makeCurrent() const { 137 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { 138 SkDebugf("Could not set the context.\n"); 139 } 140 } 141 142 void SkANGLEGLContext::swapBuffers() const { 143 if (!eglSwapBuffers(fDisplay, fSurface)) { 144 SkDebugf("Could not complete eglSwapBuffers.\n"); 145 } 146 } 147