OLD | NEW |
| (Empty) |
1 | |
2 /* | |
3 * Copyright 2011 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 #include "gl/SkNativeGLContext.h" | |
9 | |
10 SkNativeGLContext::AutoContextRestore::AutoContextRestore() { | |
11 fOldEGLContext = eglGetCurrentContext(); | |
12 fOldDisplay = eglGetCurrentDisplay(); | |
13 fOldSurface = eglGetCurrentSurface(EGL_DRAW); | |
14 | |
15 } | |
16 | |
17 SkNativeGLContext::AutoContextRestore::~AutoContextRestore() { | |
18 if (fOldDisplay) { | |
19 eglMakeCurrent(fOldDisplay, fOldSurface, fOldSurface, fOldEGLContext); | |
20 } | |
21 } | |
22 | |
23 /////////////////////////////////////////////////////////////////////////////// | |
24 | |
25 SkNativeGLContext::SkNativeGLContext() | |
26 : fContext(EGL_NO_CONTEXT) | |
27 , fDisplay(EGL_NO_DISPLAY) | |
28 , fSurface(EGL_NO_SURFACE) { | |
29 } | |
30 | |
31 SkNativeGLContext::~SkNativeGLContext() { | |
32 this->destroyGLContext(); | |
33 } | |
34 | |
35 void SkNativeGLContext::destroyGLContext() { | |
36 if (fDisplay) { | |
37 eglMakeCurrent(fDisplay, 0, 0, 0); | |
38 | |
39 if (fContext) { | |
40 eglDestroyContext(fDisplay, fContext); | |
41 fContext = EGL_NO_CONTEXT; | |
42 } | |
43 | |
44 if (fSurface) { | |
45 eglDestroySurface(fDisplay, fSurface); | |
46 fSurface = EGL_NO_SURFACE; | |
47 } | |
48 | |
49 //TODO should we close the display? | |
50 fDisplay = EGL_NO_DISPLAY; | |
51 } | |
52 } | |
53 | |
54 const GrGLInterface* SkNativeGLContext::createGLContext(GrGLStandard forcedGpuAP
I) { | |
55 static const EGLint kEGLContextAttribsForOpenGL[] = { | |
56 EGL_NONE | |
57 }; | |
58 | |
59 static const EGLint kEGLContextAttribsForOpenGLES[] = { | |
60 EGL_CONTEXT_CLIENT_VERSION, 2, | |
61 EGL_NONE | |
62 }; | |
63 | |
64 static const struct { | |
65 const EGLint* fContextAttribs; | |
66 EGLenum fAPI; | |
67 EGLint fRenderableTypeBit; | |
68 GrGLStandard fStandard; | |
69 } kAPIs[] = { | |
70 { // OpenGL | |
71 kEGLContextAttribsForOpenGL, | |
72 EGL_OPENGL_API, | |
73 EGL_OPENGL_BIT, | |
74 kGL_GrGLStandard | |
75 }, | |
76 { // OpenGL ES. This seems to work for both ES2 and 3 (when available)
. | |
77 kEGLContextAttribsForOpenGLES, | |
78 EGL_OPENGL_ES_API, | |
79 EGL_OPENGL_ES2_BIT, | |
80 kGLES_GrGLStandard | |
81 }, | |
82 }; | |
83 | |
84 size_t apiLimit = SK_ARRAY_COUNT(kAPIs); | |
85 size_t api = 0; | |
86 if (forcedGpuAPI == kGL_GrGLStandard) { | |
87 apiLimit = 1; | |
88 } else if (forcedGpuAPI == kGLES_GrGLStandard) { | |
89 api = 1; | |
90 } | |
91 SkASSERT(forcedGpuAPI == kNone_GrGLStandard || kAPIs[api].fStandard == force
dGpuAPI); | |
92 | |
93 const GrGLInterface* interface = NULL; | |
94 | |
95 for (; NULL == interface && api < apiLimit; ++api) { | |
96 fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
97 | |
98 EGLint majorVersion; | |
99 EGLint minorVersion; | |
100 eglInitialize(fDisplay, &majorVersion, &minorVersion); | |
101 | |
102 #if 0 | |
103 SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR)); | |
104 SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS)); | |
105 SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION)); | |
106 SkDebugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS)); | |
107 #endif | |
108 | |
109 if (!eglBindAPI(kAPIs[api].fAPI)) { | |
110 continue; | |
111 } | |
112 | |
113 EGLint numConfigs; | |
114 const EGLint configAttribs[] = { | |
115 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, | |
116 EGL_RENDERABLE_TYPE, kAPIs[api].fRenderableTypeBit, | |
117 EGL_RED_SIZE, 8, | |
118 EGL_GREEN_SIZE, 8, | |
119 EGL_BLUE_SIZE, 8, | |
120 EGL_ALPHA_SIZE, 8, | |
121 EGL_NONE | |
122 }; | |
123 | |
124 EGLConfig surfaceConfig; | |
125 if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numCon
figs)) { | |
126 SkDebugf("eglChooseConfig failed. EGL Error: 0x%08x\n", eglGetError(
)); | |
127 continue; | |
128 } | |
129 | |
130 fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, kAPIs[api].fC
ontextAttribs); | |
131 if (EGL_NO_CONTEXT == fContext) { | |
132 SkDebugf("eglCreateContext failed. EGL Error: 0x%08x\n", eglGetErro
r()); | |
133 continue; | |
134 } | |
135 | |
136 static const EGLint kSurfaceAttribs[] = { | |
137 EGL_WIDTH, 1, | |
138 EGL_HEIGHT, 1, | |
139 EGL_NONE | |
140 }; | |
141 | |
142 fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, kSurfaceAttr
ibs); | |
143 if (EGL_NO_SURFACE == fSurface) { | |
144 SkDebugf("eglCreatePbufferSurface failed. EGL Error: 0x%08x\n", eglG
etError()); | |
145 this->destroyGLContext(); | |
146 continue; | |
147 } | |
148 | |
149 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | |
150 SkDebugf("eglMakeCurrent failed. EGL Error: 0x%08x\n", eglGetError(
)); | |
151 this->destroyGLContext(); | |
152 continue; | |
153 } | |
154 | |
155 interface = GrGLCreateNativeInterface(); | |
156 if (NULL == interface) { | |
157 SkDebugf("Failed to create gl interface.\n"); | |
158 this->destroyGLContext(); | |
159 continue; | |
160 } | |
161 | |
162 if (!interface->validate()) { | |
163 interface->unref(); | |
164 interface = NULL; | |
165 this->destroyGLContext(); | |
166 } | |
167 } | |
168 | |
169 return interface; | |
170 } | |
171 | |
172 void SkNativeGLContext::makeCurrent() const { | |
173 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | |
174 SkDebugf("Could not set the context.\n"); | |
175 } | |
176 } | |
177 | |
178 void SkNativeGLContext::swapBuffers() const { | |
179 if (!eglSwapBuffers(fDisplay, fSurface)) { | |
180 SkDebugf("Could not complete eglSwapBuffers.\n"); | |
181 } | |
182 } | |
OLD | NEW |