Home | History | Annotate | Download | only in angle
      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