1d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 2d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com/* 3d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com * Copyright 2012 Google Inc. 4d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com * 5d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com * Use of this source code is governed by a BSD-style license that can be 6d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com * found in the LICENSE file. 7d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com */ 8d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 9e4545210c950f98d9fa20f51bc1be6c5591534bddjsollen#include "gl/angle/SkANGLEGLContext.h" 10d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 1193276c683d383142dfad31a01c6fdb1c810b6c1fbsalomon#include <EGL/egl.h> 1293276c683d383142dfad31a01c6fdb1c810b6c1fbsalomon 1342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon#define EGL_PLATFORM_ANGLE_ANGLE 0x3201 1442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon#define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3202 1542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3206 1642380174ca509e78ab932fa8c6dae953e1eaaa5absalomon#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3207 1742380174ca509e78ab932fa8c6dae953e1eaaa5absalomon 1893276c683d383142dfad31a01c6fdb1c810b6c1fbsalomonvoid* SkANGLEGLContext::GetD3DEGLDisplay(void* nativeDisplay) { 1942380174ca509e78ab932fa8c6dae953e1eaaa5absalomon 2042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon typedef EGLDisplay (*EGLGetPlatformDisplayEXT)(EGLenum platform, 2142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon void *native_display, 2242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon const EGLint *attrib_list); 2342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGLGetPlatformDisplayEXT eglGetPlatformDisplayEXT; 2442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon eglGetPlatformDisplayEXT = 2542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon (EGLGetPlatformDisplayEXT) eglGetProcAddress("eglGetPlatformDisplayEXT"); 2642380174ca509e78ab932fa8c6dae953e1eaaa5absalomon 2742380174ca509e78ab932fa8c6dae953e1eaaa5absalomon if (!eglGetPlatformDisplayEXT) { 2893276c683d383142dfad31a01c6fdb1c810b6c1fbsalomon return eglGetDisplay(static_cast<EGLNativeDisplayType>(nativeDisplay)); 2942380174ca509e78ab932fa8c6dae953e1eaaa5absalomon } 3042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon 3142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon // Try for an ANGLE D3D11 context, fall back to D3D9. 3242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGLint attribs[2][3] = { 3342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon { 3442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGL_PLATFORM_ANGLE_TYPE_ANGLE, 3542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, 3642380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGL_NONE 3742380174ca509e78ab932fa8c6dae953e1eaaa5absalomon }, 3842380174ca509e78ab932fa8c6dae953e1eaaa5absalomon { 3942380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGL_PLATFORM_ANGLE_TYPE_ANGLE, 4042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, 4142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGL_NONE 4242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon } 4342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon }; 4442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon 4542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGLDisplay display = EGL_NO_DISPLAY; 4642380174ca509e78ab932fa8c6dae953e1eaaa5absalomon for (int i = 0; i < 2 && display == EGL_NO_DISPLAY; ++i) { 4742380174ca509e78ab932fa8c6dae953e1eaaa5absalomon display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, 4842380174ca509e78ab932fa8c6dae953e1eaaa5absalomon nativeDisplay, attribs[i]); 4942380174ca509e78ab932fa8c6dae953e1eaaa5absalomon } 5042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon return display; 5142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon} 5242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon 53d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.comSkANGLEGLContext::SkANGLEGLContext() 54d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com : fContext(EGL_NO_CONTEXT) 55d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com , fDisplay(EGL_NO_DISPLAY) 56d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com , fSurface(EGL_NO_SURFACE) { 57d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 58d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com EGLint numConfigs; 59d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com static const EGLint configAttribs[] = { 60d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 61d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 62d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com EGL_RED_SIZE, 8, 63d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com EGL_GREEN_SIZE, 8, 64d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com EGL_BLUE_SIZE, 8, 65d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com EGL_ALPHA_SIZE, 8, 66d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com EGL_NONE 67d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com }; 68d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 6942380174ca509e78ab932fa8c6dae953e1eaaa5absalomon fDisplay = GetD3DEGLDisplay(EGL_DEFAULT_DISPLAY); 7042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon if (EGL_NO_DISPLAY == fDisplay) { 7142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon SkDebugf("Could not create EGL display!"); 7242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon return; 7342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon } 7442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon 7542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGLint majorVersion; 7642380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGLint minorVersion; 7742380174ca509e78ab932fa8c6dae953e1eaaa5absalomon eglInitialize(fDisplay, &majorVersion, &minorVersion); 7842380174ca509e78ab932fa8c6dae953e1eaaa5absalomon 79d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com EGLConfig surfaceConfig; 80d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs); 81d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 82d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com static const EGLint contextAttribs[] = { 83d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com EGL_CONTEXT_CLIENT_VERSION, 2, 84d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com EGL_NONE 85d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com }; 86d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, contextAttribs); 87d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 88d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 89d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com static const EGLint surfaceAttribs[] = { 9042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGL_WIDTH, 1, 9142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGL_HEIGHT, 1, 9242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon EGL_NONE 9342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon }; 9442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon 95d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs); 96d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 97d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com eglMakeCurrent(fDisplay, fSurface, fSurface, fContext); 98d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 9930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen fGL.reset(GrGLCreateANGLEInterface()); 10030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen if (NULL == fGL.get()) { 101d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com SkDebugf("Could not create ANGLE GL interface!\n"); 102d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com this->destroyGLContext(); 10330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen return; 10430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen } 10530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen if (!fGL->validate()) { 10630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen SkDebugf("Could not validate ANGLE GL interface!\n"); 10730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen this->destroyGLContext(); 10830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen return; 109d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com } 11030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen} 111d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 11230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunenSkANGLEGLContext::~SkANGLEGLContext() { 11330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen this->destroyGLContext(); 11430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen} 11530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 11630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunenvoid SkANGLEGLContext::destroyGLContext() { 11730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen fGL.reset(NULL); 11830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen if (fDisplay) { 11930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen eglMakeCurrent(fDisplay, 0, 0, 0); 12030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 12130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen if (fContext) { 12230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen eglDestroyContext(fDisplay, fContext); 12330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen fContext = EGL_NO_CONTEXT; 12430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen } 12530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 12630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen if (fSurface) { 12730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen eglDestroySurface(fDisplay, fSurface); 12830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen fSurface = EGL_NO_SURFACE; 12930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen } 13030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen 13130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen //TODO should we close the display? 13230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen fDisplay = EGL_NO_DISPLAY; 13330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen } 134d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com} 135d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com 136d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.comvoid SkANGLEGLContext::makeCurrent() const { 137d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { 138d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com SkDebugf("Could not set the context.\n"); 139d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com } 140d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com} 141c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com 142c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.comvoid SkANGLEGLContext::swapBuffers() const { 143c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com if (!eglSwapBuffers(fDisplay, fSurface)) { 144c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com SkDebugf("Could not complete eglSwapBuffers.\n"); 145c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com } 146c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com} 147