SkANGLEGLContext.cpp revision 42380174ca509e78ab932fa8c6dae953e1eaaa5a
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
1142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon#define EGL_PLATFORM_ANGLE_ANGLE                0x3201
1242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon#define EGL_PLATFORM_ANGLE_TYPE_ANGLE           0x3202
1342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon#define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE      0x3206
1442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon#define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE     0x3207
1542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
1642380174ca509e78ab932fa8c6dae953e1eaaa5absalomonEGLDisplay SkANGLEGLContext::GetD3DEGLDisplay(EGLNativeDisplayType nativeDisplay) {
1742380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
1842380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    typedef EGLDisplay (*EGLGetPlatformDisplayEXT)(EGLenum platform,
1942380174ca509e78ab932fa8c6dae953e1eaaa5absalomon                                                   void *native_display,
2042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon                                                   const EGLint *attrib_list);
2142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    EGLGetPlatformDisplayEXT eglGetPlatformDisplayEXT;
2242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    eglGetPlatformDisplayEXT =
2342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        (EGLGetPlatformDisplayEXT) eglGetProcAddress("eglGetPlatformDisplayEXT");
2442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
2542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    if (!eglGetPlatformDisplayEXT) {
2642380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        return eglGetDisplay(nativeDisplay);
2742380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    }
2842380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
2942380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    // Try for an ANGLE D3D11 context, fall back to D3D9.
3042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    EGLint attribs[2][3] = {
3142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        {
3242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon            EGL_PLATFORM_ANGLE_TYPE_ANGLE,
3342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon            EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE,
3442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon            EGL_NONE
3542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        },
3642380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        {
3742380174ca509e78ab932fa8c6dae953e1eaaa5absalomon            EGL_PLATFORM_ANGLE_TYPE_ANGLE,
3842380174ca509e78ab932fa8c6dae953e1eaaa5absalomon            EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE,
3942380174ca509e78ab932fa8c6dae953e1eaaa5absalomon            EGL_NONE
4042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        }
4142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    };
4242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
4342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    EGLDisplay display = EGL_NO_DISPLAY;
4442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    for (int i = 0; i < 2 && display == EGL_NO_DISPLAY; ++i) {
4542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        display = eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE,
4642380174ca509e78ab932fa8c6dae953e1eaaa5absalomon                                            nativeDisplay, attribs[i]);
4742380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    }
4842380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    return display;
4942380174ca509e78ab932fa8c6dae953e1eaaa5absalomon}
5042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
51d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.comSkANGLEGLContext::SkANGLEGLContext()
52d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    : fContext(EGL_NO_CONTEXT)
53d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    , fDisplay(EGL_NO_DISPLAY)
54d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    , fSurface(EGL_NO_SURFACE) {
55d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
56d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    EGLint numConfigs;
57d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    static const EGLint configAttribs[] = {
58d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
59d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
60d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_RED_SIZE, 8,
61d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_GREEN_SIZE, 8,
62d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_BLUE_SIZE, 8,
63d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_ALPHA_SIZE, 8,
64d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_NONE
65d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    };
66d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
6742380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    fDisplay = GetD3DEGLDisplay(EGL_DEFAULT_DISPLAY);
6842380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    if (EGL_NO_DISPLAY == fDisplay) {
6942380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        SkDebugf("Could not create EGL display!");
7042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        return;
7142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    }
7242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
7342380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    EGLint majorVersion;
7442380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    EGLint minorVersion;
7542380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    eglInitialize(fDisplay, &majorVersion, &minorVersion);
7642380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
77d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com    EGLConfig surfaceConfig;
78d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com    eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs);
79d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
80d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    static const EGLint contextAttribs[] = {
81d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_CONTEXT_CLIENT_VERSION, 2,
82d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        EGL_NONE
83d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    };
84d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com    fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, contextAttribs);
85d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
86d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
87d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    static const EGLint surfaceAttribs[] = {
8842380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        EGL_WIDTH, 1,
8942380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        EGL_HEIGHT, 1,
9042380174ca509e78ab932fa8c6dae953e1eaaa5absalomon        EGL_NONE
9142380174ca509e78ab932fa8c6dae953e1eaaa5absalomon    };
9242380174ca509e78ab932fa8c6dae953e1eaaa5absalomon
93d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com    fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, surfaceAttribs);
94d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
95d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com    eglMakeCurrent(fDisplay, fSurface, fSurface, fContext);
96d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
9730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    fGL.reset(GrGLCreateANGLEInterface());
9830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    if (NULL == fGL.get()) {
99d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        SkDebugf("Could not create ANGLE GL interface!\n");
100d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        this->destroyGLContext();
10130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        return;
10230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    }
10330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    if (!fGL->validate()) {
10430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        SkDebugf("Could not validate ANGLE GL interface!\n");
10530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        this->destroyGLContext();
10630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        return;
107d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    }
10830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen}
109d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
11030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunenSkANGLEGLContext::~SkANGLEGLContext() {
11130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    this->destroyGLContext();
11230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen}
11330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen
11430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunenvoid SkANGLEGLContext::destroyGLContext() {
11530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    fGL.reset(NULL);
11630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    if (fDisplay) {
11730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        eglMakeCurrent(fDisplay, 0, 0, 0);
11830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen
11930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        if (fContext) {
12030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen            eglDestroyContext(fDisplay, fContext);
12130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen            fContext = EGL_NO_CONTEXT;
12230bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        }
12330bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen
12430bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        if (fSurface) {
12530bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen            eglDestroySurface(fDisplay, fSurface);
12630bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen            fSurface = EGL_NO_SURFACE;
12730bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        }
12830bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen
12930bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        //TODO should we close the display?
13030bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen        fDisplay = EGL_NO_DISPLAY;
13130bc88ccd524c0372fd2f8f79190ea4b81685bebkkinnunen    }
132d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com}
133d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com
134d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.comvoid SkANGLEGLContext::makeCurrent() const {
135d5c8fe6f344e1b141390c733017656f6fb3f5f63robertphillips@google.com    if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
136d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com        SkDebugf("Could not set the context.\n");
137d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    }
138d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com}
139c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com
140c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.comvoid SkANGLEGLContext::swapBuffers() const {
141c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com    if (!eglSwapBuffers(fDisplay, fSurface)) {
142c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com        SkDebugf("Could not complete eglSwapBuffers.\n");
143c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com    }
144c9542ca3d00878a18a57af80037060d6374d5650djsollen@google.com}
145