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

Side by Side Diff: ui/gl/gl_fence.cc

Issue 331293003: Add common GLFence::IsSupported() check (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gl/gl_fence.h" 5 #include "ui/gl/gl_fence.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "ui/gl/gl_bindings.h" 8 #include "ui/gl/gl_bindings.h"
9 #include "ui/gl/gl_context.h" 9 #include "ui/gl/gl_context.h"
10 #include "ui/gl/gl_gl_api_implementation.h"
10 #include "ui/gl/gl_version_info.h" 11 #include "ui/gl/gl_version_info.h"
11 12
13 namespace gfx {
14
12 namespace { 15 namespace {
13 16
14 class GLFenceNVFence: public gfx::GLFence { 17 class GLFenceNVFence: public GLFence {
15 public: 18 public:
16 GLFenceNVFence(bool flush) { 19 GLFenceNVFence(bool flush) {
17 // What if either of these GL calls fails? TestFenceNV will return true. 20 // What if either of these GL calls fails? TestFenceNV will return true.
18 // See spec: 21 // See spec:
19 // http://www.opengl.org/registry/specs/NV/fence.txt 22 // http://www.opengl.org/registry/specs/NV/fence.txt
20 // 23 //
21 // What should happen if TestFenceNV is called for a name before SetFenceNV 24 // What should happen if TestFenceNV is called for a name before SetFenceNV
22 // is called? 25 // is called?
23 // We generate an INVALID_OPERATION error, and return TRUE. 26 // We generate an INVALID_OPERATION error, and return TRUE.
24 // This follows the semantics for texture object names before 27 // This follows the semantics for texture object names before
25 // they are bound, in that they acquire their state upon binding. 28 // they are bound, in that they acquire their state upon binding.
26 // We will arbitrarily return TRUE for consistency. 29 // We will arbitrarily return TRUE for consistency.
27 glGenFencesNV(1, &fence_); 30 glGenFencesNV(1, &fence_);
28 glSetFenceNV(fence_, GL_ALL_COMPLETED_NV); 31 glSetFenceNV(fence_, GL_ALL_COMPLETED_NV);
29 if (flush) { 32 if (flush) {
30 glFlush(); 33 glFlush();
31 } else { 34 } else {
32 flush_event_ = gfx::GLContext::GetCurrent()->SignalFlush(); 35 flush_event_ = GLContext::GetCurrent()->SignalFlush();
33 } 36 }
34 } 37 }
35 38
36 virtual bool HasCompleted() OVERRIDE { 39 virtual bool HasCompleted() OVERRIDE {
37 return !!glTestFenceNV(fence_); 40 return !!glTestFenceNV(fence_);
38 } 41 }
39 42
40 virtual void ClientWait() OVERRIDE { 43 virtual void ClientWait() OVERRIDE {
41 if (!flush_event_ || flush_event_->IsSignaled()) { 44 if (!flush_event_ || flush_event_->IsSignaled()) {
42 glFinishFenceNV(fence_); 45 glFinishFenceNV(fence_);
43 } else { 46 } else {
44 LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping..."; 47 LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
45 } 48 }
46 } 49 }
47 50
48 virtual void ServerWait() OVERRIDE { 51 virtual void ServerWait() OVERRIDE {
49 ClientWait(); 52 ClientWait();
50 } 53 }
51 54
52 private: 55 private:
53 virtual ~GLFenceNVFence() { 56 virtual ~GLFenceNVFence() {
54 glDeleteFencesNV(1, &fence_); 57 glDeleteFencesNV(1, &fence_);
55 } 58 }
56 59
57 GLuint fence_; 60 GLuint fence_;
58 scoped_refptr<gfx::GLContext::FlushEvent> flush_event_; 61 scoped_refptr<GLContext::FlushEvent> flush_event_;
59 }; 62 };
60 63
61 class GLFenceARBSync: public gfx::GLFence { 64 class GLFenceARBSync: public GLFence {
62 public: 65 public:
63 GLFenceARBSync(bool flush) { 66 GLFenceARBSync(bool flush) {
64 sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); 67 sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
65 if (flush) { 68 if (flush) {
66 glFlush(); 69 glFlush();
67 } else { 70 } else {
68 flush_event_ = gfx::GLContext::GetCurrent()->SignalFlush(); 71 flush_event_ = GLContext::GetCurrent()->SignalFlush();
69 } 72 }
70 } 73 }
71 74
72 virtual bool HasCompleted() OVERRIDE { 75 virtual bool HasCompleted() OVERRIDE {
73 // Handle the case where FenceSync failed. 76 // Handle the case where FenceSync failed.
74 if (!sync_) 77 if (!sync_)
75 return true; 78 return true;
76 79
77 // We could potentially use glGetSynciv here, but it doesn't work 80 // We could potentially use glGetSynciv here, but it doesn't work
78 // on OSX 10.7 (always says the fence is not signaled yet). 81 // on OSX 10.7 (always says the fence is not signaled yet).
(...skipping 16 matching lines...) Expand all
95 LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping..."; 98 LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
96 } 99 }
97 } 100 }
98 101
99 private: 102 private:
100 virtual ~GLFenceARBSync() { 103 virtual ~GLFenceARBSync() {
101 glDeleteSync(sync_); 104 glDeleteSync(sync_);
102 } 105 }
103 106
104 GLsync sync_; 107 GLsync sync_;
105 scoped_refptr<gfx::GLContext::FlushEvent> flush_event_; 108 scoped_refptr<GLContext::FlushEvent> flush_event_;
106 }; 109 };
107 110
108 #if !defined(OS_MACOSX) 111 #if !defined(OS_MACOSX)
109 class EGLFenceSync : public gfx::GLFence { 112 class EGLFenceSync : public GLFence {
110 public: 113 public:
111 EGLFenceSync(bool flush) { 114 EGLFenceSync(bool flush) {
112 display_ = eglGetCurrentDisplay(); 115 display_ = eglGetCurrentDisplay();
113 sync_ = eglCreateSyncKHR(display_, EGL_SYNC_FENCE_KHR, NULL); 116 sync_ = eglCreateSyncKHR(display_, EGL_SYNC_FENCE_KHR, NULL);
114 if (flush) { 117 if (flush) {
115 glFlush(); 118 glFlush();
116 } else { 119 } else {
117 flush_event_ = gfx::GLContext::GetCurrent()->SignalFlush(); 120 flush_event_ = GLContext::GetCurrent()->SignalFlush();
118 } 121 }
119 } 122 }
120 123
121 virtual bool HasCompleted() OVERRIDE { 124 virtual bool HasCompleted() OVERRIDE {
122 EGLint value = 0; 125 EGLint value = 0;
123 eglGetSyncAttribKHR(display_, sync_, EGL_SYNC_STATUS_KHR, &value); 126 eglGetSyncAttribKHR(display_, sync_, EGL_SYNC_STATUS_KHR, &value);
124 DCHECK(value == EGL_SIGNALED_KHR || value == EGL_UNSIGNALED_KHR); 127 DCHECK(value == EGL_SIGNALED_KHR || value == EGL_UNSIGNALED_KHR);
125 return !value || value == EGL_SIGNALED_KHR; 128 return !value || value == EGL_SIGNALED_KHR;
126 } 129 }
127 130
(...skipping 17 matching lines...) Expand all
145 } 148 }
146 149
147 150
148 private: 151 private:
149 virtual ~EGLFenceSync() { 152 virtual ~EGLFenceSync() {
150 eglDestroySyncKHR(display_, sync_); 153 eglDestroySyncKHR(display_, sync_);
151 } 154 }
152 155
153 EGLSyncKHR sync_; 156 EGLSyncKHR sync_;
154 EGLDisplay display_; 157 EGLDisplay display_;
155 scoped_refptr<gfx::GLContext::FlushEvent> flush_event_; 158 scoped_refptr<GLContext::FlushEvent> flush_event_;
156 }; 159 };
157 #endif // !OS_MACOSX 160 #endif // !OS_MACOSX
158 161
159 // static 162 // static
160 gfx::GLFence* CreateFence(bool flush) { 163 GLFence* CreateFence(bool flush) {
161 DCHECK(gfx::GLContext::GetCurrent()) 164 DCHECK(GLContext::GetCurrent())
162 << "Trying to create fence with no context"; 165 << "Trying to create fence with no context";
163 166
167 scoped_ptr<GLFence> fence;
164 // Prefer ARB_sync which supports server-side wait. 168 // Prefer ARB_sync which supports server-side wait.
165 if (gfx::g_driver_gl.ext.b_GL_ARB_sync || 169 if (g_driver_gl.ext.b_GL_ARB_sync ||
166 gfx::GLContext::GetCurrent()->GetVersionInfo()->is_es3) 170 GetGLVersionInfo()->is_es3) {
167 return new GLFenceARBSync(flush); 171 fence.reset(new GLFenceARBSync(flush));
168 #if !defined(OS_MACOSX) 172 #if !defined(OS_MACOSX)
169 if (gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) 173 } else if (g_driver_egl.ext.b_EGL_KHR_fence_sync) {
170 return new EGLFenceSync(flush); 174 fence.reset(new EGLFenceSync(flush));
171 #endif 175 #endif
172 if (gfx::g_driver_gl.ext.b_GL_NV_fence) 176 } else if (g_driver_gl.ext.b_GL_NV_fence) {
173 return new GLFenceNVFence(flush); 177 fence.reset(new GLFenceNVFence(flush));
174 return NULL; 178 }
179
180 DCHECK(!!fence.get() == GLFence::IsSupported());
reveman 2014/06/17 00:50:05 DCHECK_EQ?
181 return fence.release();
175 } 182 }
176 183
177 } // namespace 184 } // namespace
178 185
179 namespace gfx {
180
181 GLFence::GLFence() { 186 GLFence::GLFence() {
182 } 187 }
183 188
184 GLFence::~GLFence() { 189 GLFence::~GLFence() {
185 } 190 }
186 191
192 bool GLFence::IsSupported() {
193 DCHECK(GetGLVersionInfo());
194 return g_driver_gl.ext.b_GL_ARB_sync || GetGLVersionInfo()->is_es3 ||
195 #if !defined(OS_MACOSX)
196 g_driver_egl.ext.b_EGL_KHR_fence_sync ||
197 #endif
198 g_driver_gl.ext.b_GL_NV_fence;
199 }
200
187 GLFence* GLFence::Create() { 201 GLFence* GLFence::Create() {
188 return CreateFence(true); 202 return CreateFence(true);
189 } 203 }
190 204
191 GLFence* GLFence::CreateWithoutFlush() { 205 GLFence* GLFence::CreateWithoutFlush() {
192 return CreateFence(false); 206 return CreateFence(false);
193 } 207 }
194 208
195 } // namespace gfx 209 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698