Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/gpu/gl/egl/SkCreatePlatformGLContext_egl.cpp

Issue 1194783003: Implement SkGLContext swapBuffers with fence syncs (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: windows build Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/gl/debug/SkDebugGLContext.cpp ('k') | src/gpu/gl/glx/SkCreatePlatformGLContext_glx.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
12 #define EGL_EGLEXT_PROTOTYPES
11 #include <EGL/egl.h> 13 #include <EGL/egl.h>
14 #include <EGL/eglext.h>
12 15
13 namespace { 16 namespace {
14 17
18 // TODO: Share this class with ANGLE if/when it gets support for EGL_KHR_fence_s ync.
19 class SkEGLFenceSync : public SkGpuFenceSync {
20 public:
21 static SkEGLFenceSync* CreateIfSupported(EGLDisplay);
22
23 SkPlatformGpuFence SK_WARN_UNUSED_RESULT insertFence() const override;
24 bool flushAndWaitFence(SkPlatformGpuFence fence) const override;
25 void deleteFence(SkPlatformGpuFence fence) const override;
26
27 private:
28 SkEGLFenceSync(EGLDisplay display) : fDisplay(display) {}
29
30 EGLDisplay fDisplay;
31
32 typedef SkGpuFenceSync INHERITED;
33 };
34
15 class EGLGLContext : public SkGLContext { 35 class EGLGLContext : public SkGLContext {
16 public: 36 public:
17 EGLGLContext(GrGLStandard forcedGpuAPI); 37 EGLGLContext(GrGLStandard forcedGpuAPI);
18 ~EGLGLContext() override; 38 ~EGLGLContext() override;
19 void makeCurrent() const override;
20 void swapBuffers() const override;
21 39
22 private: 40 private:
23 void destroyGLContext(); 41 void destroyGLContext();
24 42
43 void onPlatformMakeCurrent() const override;
44 void onPlatformSwapBuffers() const override;
45 GrGLFuncPtr onPlatformGetProcAddress(const char*) const override;
46
25 EGLContext fContext; 47 EGLContext fContext;
26 EGLDisplay fDisplay; 48 EGLDisplay fDisplay;
27 EGLSurface fSurface; 49 EGLSurface fSurface;
28 }; 50 };
29 51
30 EGLGLContext::EGLGLContext(GrGLStandard forcedGpuAPI) 52 EGLGLContext::EGLGLContext(GrGLStandard forcedGpuAPI)
31 : fContext(EGL_NO_CONTEXT) 53 : fContext(EGL_NO_CONTEXT)
32 , fDisplay(EGL_NO_DISPLAY) 54 , fDisplay(EGL_NO_DISPLAY)
33 , fSurface(EGL_NO_SURFACE) { 55 , fSurface(EGL_NO_SURFACE) {
34 static const EGLint kEGLContextAttribsForOpenGL[] = { 56 static const EGLint kEGLContextAttribsForOpenGL[] = {
(...skipping 27 matching lines...) Expand all
62 84
63 size_t apiLimit = SK_ARRAY_COUNT(kAPIs); 85 size_t apiLimit = SK_ARRAY_COUNT(kAPIs);
64 size_t api = 0; 86 size_t api = 0;
65 if (forcedGpuAPI == kGL_GrGLStandard) { 87 if (forcedGpuAPI == kGL_GrGLStandard) {
66 apiLimit = 1; 88 apiLimit = 1;
67 } else if (forcedGpuAPI == kGLES_GrGLStandard) { 89 } else if (forcedGpuAPI == kGLES_GrGLStandard) {
68 api = 1; 90 api = 1;
69 } 91 }
70 SkASSERT(forcedGpuAPI == kNone_GrGLStandard || kAPIs[api].fStandard == force dGpuAPI); 92 SkASSERT(forcedGpuAPI == kNone_GrGLStandard || kAPIs[api].fStandard == force dGpuAPI);
71 93
72 for (; NULL == fGL.get() && api < apiLimit; ++api) { 94 SkAutoTUnref<const GrGLInterface> gl;
95
96 for (; NULL == gl.get() && api < apiLimit; ++api) {
73 fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 97 fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
74 98
75 EGLint majorVersion; 99 EGLint majorVersion;
76 EGLint minorVersion; 100 EGLint minorVersion;
77 eglInitialize(fDisplay, &majorVersion, &minorVersion); 101 eglInitialize(fDisplay, &majorVersion, &minorVersion);
78 102
79 #if 0 103 #if 0
80 SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR)); 104 SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR));
81 SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS)); 105 SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS));
82 SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION)); 106 SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 this->destroyGLContext(); 151 this->destroyGLContext();
128 continue; 152 continue;
129 } 153 }
130 154
131 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { 155 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
132 SkDebugf("eglMakeCurrent failed. EGL Error: 0x%08x\n", eglGetError( )); 156 SkDebugf("eglMakeCurrent failed. EGL Error: 0x%08x\n", eglGetError( ));
133 this->destroyGLContext(); 157 this->destroyGLContext();
134 continue; 158 continue;
135 } 159 }
136 160
137 fGL.reset(GrGLCreateNativeInterface()); 161 gl.reset(GrGLCreateNativeInterface());
138 if (NULL == fGL.get()) { 162 if (NULL == gl.get()) {
139 SkDebugf("Failed to create gl interface.\n"); 163 SkDebugf("Failed to create gl interface.\n");
140 this->destroyGLContext(); 164 this->destroyGLContext();
141 continue; 165 continue;
142 } 166 }
143 167
144 if (!fGL->validate()) { 168 if (!gl->validate()) {
145 SkDebugf("Failed to validate gl interface.\n"); 169 SkDebugf("Failed to validate gl interface.\n");
146 this->destroyGLContext(); 170 this->destroyGLContext();
147 continue; 171 continue;
148 } 172 }
173
174 this->init(gl.detach(), SkEGLFenceSync::CreateIfSupported(fDisplay));
175 break;
149 } 176 }
150 } 177 }
151 178
152 EGLGLContext::~EGLGLContext() { 179 EGLGLContext::~EGLGLContext() {
180 this->teardown();
153 this->destroyGLContext(); 181 this->destroyGLContext();
154 } 182 }
155 183
156 void EGLGLContext::destroyGLContext() { 184 void EGLGLContext::destroyGLContext() {
157 fGL.reset(NULL);
158 if (fDisplay) { 185 if (fDisplay) {
159 eglMakeCurrent(fDisplay, 0, 0, 0); 186 eglMakeCurrent(fDisplay, 0, 0, 0);
160 187
161 if (fContext) { 188 if (fContext) {
162 eglDestroyContext(fDisplay, fContext); 189 eglDestroyContext(fDisplay, fContext);
163 fContext = EGL_NO_CONTEXT; 190 fContext = EGL_NO_CONTEXT;
164 } 191 }
165 192
166 if (fSurface) { 193 if (fSurface) {
167 eglDestroySurface(fDisplay, fSurface); 194 eglDestroySurface(fDisplay, fSurface);
168 fSurface = EGL_NO_SURFACE; 195 fSurface = EGL_NO_SURFACE;
169 } 196 }
170 197
171 //TODO should we close the display? 198 //TODO should we close the display?
172 fDisplay = EGL_NO_DISPLAY; 199 fDisplay = EGL_NO_DISPLAY;
173 } 200 }
174 } 201 }
175 202
176 203
177 void EGLGLContext::makeCurrent() const { 204 void EGLGLContext::onPlatformMakeCurrent() const {
178 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { 205 if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) {
179 SkDebugf("Could not set the context.\n"); 206 SkDebugf("Could not set the context.\n");
180 } 207 }
181 } 208 }
182 209
183 void EGLGLContext::swapBuffers() const { 210 void EGLGLContext::onPlatformSwapBuffers() const {
184 if (!eglSwapBuffers(fDisplay, fSurface)) { 211 if (!eglSwapBuffers(fDisplay, fSurface)) {
185 SkDebugf("Could not complete eglSwapBuffers.\n"); 212 SkDebugf("Could not complete eglSwapBuffers.\n");
186 } 213 }
187 } 214 }
188 215
216 GrGLFuncPtr EGLGLContext::onPlatformGetProcAddress(const char* procName) const {
217 return eglGetProcAddress(procName);
218 }
219
220 static bool supports_egl_extension(EGLDisplay display, const char* extension) {
221 int extensionLength = strlen(extension);
222 const char* extensionsStr = eglQueryString(display, EGL_EXTENSIONS);
223 while (const char* match = strstr(extensionsStr, extension)) {
224 // Ensure the string we found is its own extension, not a substring of a larger extension
225 // (e.g. GL_ARB_occlusion_query / GL_ARB_occlusion_query2).
226 if ((match == extensionsStr || match[-1] == ' ') &&
227 (match[extensionLength] == ' ' || match[extensionLength] == '\0')) {
228 return true;
229 }
230 extensionsStr = match + extensionLength;
231 }
232 return false;
233 }
234
235 SkEGLFenceSync* SkEGLFenceSync::CreateIfSupported(EGLDisplay display) {
236 if (!display || !supports_egl_extension(display, "EGL_KHR_fence_sync")) {
237 return NULL;
238 }
239 return SkNEW_ARGS(SkEGLFenceSync, (display));
240 }
241
242 SkPlatformGpuFence SkEGLFenceSync::insertFence() const {
243 return eglCreateSyncKHR(fDisplay, EGL_SYNC_FENCE_KHR, NULL);
244 }
245
246 bool SkEGLFenceSync::flushAndWaitFence(SkPlatformGpuFence platformFence) const {
247 EGLSyncKHR eglsync = static_cast<EGLSyncKHR>(platformFence);
248 return EGL_CONDITION_SATISFIED_KHR == eglClientWaitSyncKHR(fDisplay,
249 eglsync,
250 EGL_SYNC_FLUSH_CO MMANDS_BIT_KHR,
251 EGL_FOREVER_KHR);
252 }
253
254 void SkEGLFenceSync::deleteFence(SkPlatformGpuFence platformFence) const {
255 EGLSyncKHR eglsync = static_cast<EGLSyncKHR>(platformFence);
256 eglDestroySyncKHR(fDisplay, eglsync);
257 }
258
189 } // anonymous namespace 259 } // anonymous namespace
190 260
191 SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI) { 261 SkGLContext* SkCreatePlatformGLContext(GrGLStandard forcedGpuAPI) {
192 EGLGLContext* ctx = SkNEW_ARGS(EGLGLContext, (forcedGpuAPI)); 262 EGLGLContext* ctx = SkNEW_ARGS(EGLGLContext, (forcedGpuAPI));
193 if (!ctx->isValid()) { 263 if (!ctx->isValid()) {
194 SkDELETE(ctx); 264 SkDELETE(ctx);
195 return NULL; 265 return NULL;
196 } 266 }
197 return ctx; 267 return ctx;
198 } 268 }
199 269
OLDNEW
« no previous file with comments | « src/gpu/gl/debug/SkDebugGLContext.cpp ('k') | src/gpu/gl/glx/SkCreatePlatformGLContext_glx.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698