OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "gl/SkGLContext.h" | 8 #include "gl/SkGLContext.h" |
9 | 9 |
10 #include <GLES2/gl2.h> | 10 #include <GLES2/gl2.h> |
11 #include <EGL/egl.h> | 11 #include <EGL/egl.h> |
12 | 12 |
13 namespace { | 13 namespace { |
14 | 14 |
15 class EGLGLContext : public SkGLContext { | 15 class EGLGLContext : public SkGLContext { |
16 public: | 16 public: |
17 EGLGLContext(); | 17 EGLGLContext(GrGLStandard forcedGpuAPI); |
18 | 18 virtual ~EGLGLContext() SK_OVERRIDE; |
19 virtual ~EGLGLContext(); | |
20 | |
21 virtual void makeCurrent() const SK_OVERRIDE; | 19 virtual void makeCurrent() const SK_OVERRIDE; |
22 virtual void swapBuffers() const SK_OVERRIDE; | 20 virtual void swapBuffers() const SK_OVERRIDE; |
23 protected: | |
24 virtual const GrGLInterface* createGLContext(GrGLStandard forcedGpuAPI) SK_O
VERRIDE; | |
25 virtual void destroyGLContext() SK_OVERRIDE; | |
26 | 21 |
27 private: | 22 private: |
| 23 void destroyGLContext(); |
| 24 |
28 EGLContext fContext; | 25 EGLContext fContext; |
29 EGLDisplay fDisplay; | 26 EGLDisplay fDisplay; |
30 EGLSurface fSurface; | 27 EGLSurface fSurface; |
31 }; | 28 }; |
32 | 29 |
33 EGLGLContext::EGLGLContext() | 30 EGLGLContext::EGLGLContext(GrGLStandard forcedGpuAPI) |
34 : fContext(EGL_NO_CONTEXT) | 31 : fContext(EGL_NO_CONTEXT) |
35 , fDisplay(EGL_NO_DISPLAY) | 32 , fDisplay(EGL_NO_DISPLAY) |
36 , fSurface(EGL_NO_SURFACE) { | 33 , fSurface(EGL_NO_SURFACE) { |
37 } | |
38 | |
39 EGLGLContext::~EGLGLContext() { | |
40 this->destroyGLContext(); | |
41 } | |
42 | |
43 void EGLGLContext::destroyGLContext() { | |
44 if (fDisplay) { | |
45 eglMakeCurrent(fDisplay, 0, 0, 0); | |
46 | |
47 if (fContext) { | |
48 eglDestroyContext(fDisplay, fContext); | |
49 fContext = EGL_NO_CONTEXT; | |
50 } | |
51 | |
52 if (fSurface) { | |
53 eglDestroySurface(fDisplay, fSurface); | |
54 fSurface = EGL_NO_SURFACE; | |
55 } | |
56 | |
57 //TODO should we close the display? | |
58 fDisplay = EGL_NO_DISPLAY; | |
59 } | |
60 } | |
61 | |
62 const GrGLInterface* EGLGLContext::createGLContext(GrGLStandard forcedGpuAPI) { | |
63 static const EGLint kEGLContextAttribsForOpenGL[] = { | 34 static const EGLint kEGLContextAttribsForOpenGL[] = { |
64 EGL_NONE | 35 EGL_NONE |
65 }; | 36 }; |
66 | 37 |
67 static const EGLint kEGLContextAttribsForOpenGLES[] = { | 38 static const EGLint kEGLContextAttribsForOpenGLES[] = { |
68 EGL_CONTEXT_CLIENT_VERSION, 2, | 39 EGL_CONTEXT_CLIENT_VERSION, 2, |
69 EGL_NONE | 40 EGL_NONE |
70 }; | 41 }; |
71 | 42 |
72 static const struct { | 43 static const struct { |
(...skipping 18 matching lines...) Expand all Loading... |
91 | 62 |
92 size_t apiLimit = SK_ARRAY_COUNT(kAPIs); | 63 size_t apiLimit = SK_ARRAY_COUNT(kAPIs); |
93 size_t api = 0; | 64 size_t api = 0; |
94 if (forcedGpuAPI == kGL_GrGLStandard) { | 65 if (forcedGpuAPI == kGL_GrGLStandard) { |
95 apiLimit = 1; | 66 apiLimit = 1; |
96 } else if (forcedGpuAPI == kGLES_GrGLStandard) { | 67 } else if (forcedGpuAPI == kGLES_GrGLStandard) { |
97 api = 1; | 68 api = 1; |
98 } | 69 } |
99 SkASSERT(forcedGpuAPI == kNone_GrGLStandard || kAPIs[api].fStandard == force
dGpuAPI); | 70 SkASSERT(forcedGpuAPI == kNone_GrGLStandard || kAPIs[api].fStandard == force
dGpuAPI); |
100 | 71 |
101 const GrGLInterface* interface = NULL; | 72 for (; NULL == fGL.get() && api < apiLimit; ++api) { |
102 | |
103 for (; NULL == interface && api < apiLimit; ++api) { | |
104 fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); | 73 fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); |
105 | 74 |
106 EGLint majorVersion; | 75 EGLint majorVersion; |
107 EGLint minorVersion; | 76 EGLint minorVersion; |
108 eglInitialize(fDisplay, &majorVersion, &minorVersion); | 77 eglInitialize(fDisplay, &majorVersion, &minorVersion); |
109 | 78 |
110 #if 0 | 79 #if 0 |
111 SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR)); | 80 SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR)); |
112 SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS)); | 81 SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS)); |
113 SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION)); | 82 SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 this->destroyGLContext(); | 122 this->destroyGLContext(); |
154 continue; | 123 continue; |
155 } | 124 } |
156 | 125 |
157 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | 126 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { |
158 SkDebugf("eglMakeCurrent failed. EGL Error: 0x%08x\n", eglGetError(
)); | 127 SkDebugf("eglMakeCurrent failed. EGL Error: 0x%08x\n", eglGetError(
)); |
159 this->destroyGLContext(); | 128 this->destroyGLContext(); |
160 continue; | 129 continue; |
161 } | 130 } |
162 | 131 |
163 interface = GrGLCreateNativeInterface(); | 132 fGL.reset(GrGLCreateNativeInterface()); |
164 if (NULL == interface) { | 133 if (NULL == fGL.get()) { |
165 SkDebugf("Failed to create gl interface.\n"); | 134 SkDebugf("Failed to create gl interface.\n"); |
166 this->destroyGLContext(); | 135 this->destroyGLContext(); |
167 continue; | 136 continue; |
168 } | 137 } |
169 | 138 |
170 if (!interface->validate()) { | 139 if (!fGL->validate()) { |
171 interface->unref(); | 140 SkDebugf("Failed to validate gl interface.\n"); |
172 interface = NULL; | |
173 this->destroyGLContext(); | 141 this->destroyGLContext(); |
| 142 continue; |
174 } | 143 } |
175 } | 144 } |
| 145 } |
176 | 146 |
177 return interface; | 147 EGLGLContext::~EGLGLContext() { |
| 148 this->destroyGLContext(); |
178 } | 149 } |
179 | 150 |
| 151 void EGLGLContext::destroyGLContext() { |
| 152 fGL.reset(NULL); |
| 153 if (fDisplay) { |
| 154 eglMakeCurrent(fDisplay, 0, 0, 0); |
| 155 |
| 156 if (fContext) { |
| 157 eglDestroyContext(fDisplay, fContext); |
| 158 fContext = EGL_NO_CONTEXT; |
| 159 } |
| 160 |
| 161 if (fSurface) { |
| 162 eglDestroySurface(fDisplay, fSurface); |
| 163 fSurface = EGL_NO_SURFACE; |
| 164 } |
| 165 |
| 166 //TODO should we close the display? |
| 167 fDisplay = EGL_NO_DISPLAY; |
| 168 } |
| 169 } |
| 170 |
| 171 |
180 void EGLGLContext::makeCurrent() const { | 172 void EGLGLContext::makeCurrent() const { |
181 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { | 173 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { |
182 SkDebugf("Could not set the context.\n"); | 174 SkDebugf("Could not set the context.\n"); |
183 } | 175 } |
184 } | 176 } |
185 | 177 |
186 void EGLGLContext::swapBuffers() const { | 178 void EGLGLContext::swapBuffers() const { |
187 if (!eglSwapBuffers(fDisplay, fSurface)) { | 179 if (!eglSwapBuffers(fDisplay, fSurface)) { |
188 SkDebugf("Could not complete eglSwapBuffers.\n"); | 180 SkDebugf("Could not complete eglSwapBuffers.\n"); |
189 } | 181 } |
190 } | 182 } |
191 | 183 |
192 } // anonymous namespace | 184 } // anonymous namespace |
193 | 185 |
194 SkGLContext* SkCreatePlatformGLContext() { | 186 SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI) { |
195 return SkNEW(EGLGLContext); | 187 EGLGLContext* ctx = SkNEW_ARGS(EGLGLContext, (forcedGpuAPI)); |
| 188 if (!ctx->isValid()) { |
| 189 SkDELETE(ctx); |
| 190 return NULL; |
| 191 } |
| 192 return ctx; |
196 } | 193 } |
197 | 194 |
OLD | NEW |