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