• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetD3DEGLDisplay(void * nativeDisplay)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 
SkANGLEGLContext()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 
~SkANGLEGLContext()112 SkANGLEGLContext::~SkANGLEGLContext() {
113     this->destroyGLContext();
114 }
115 
destroyGLContext()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 
makeCurrent() const136 void SkANGLEGLContext::makeCurrent() const {
137     if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
138         SkDebugf("Could not set the context.\n");
139     }
140 }
141 
swapBuffers() const142 void SkANGLEGLContext::swapBuffers() const {
143     if (!eglSwapBuffers(fDisplay, fSurface)) {
144         SkDebugf("Could not complete eglSwapBuffers.\n");
145     }
146 }
147