Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / ui / gl / gl_fence.cc
blobdef030b5defcdc6b0c64838aa4bb7798a5f9e12e
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
3 // found in the LICENSE file.
5 #include "ui/gl/gl_fence.h"
7 #include "base/compiler_specific.h"
8 #include "ui/gl/gl_bindings.h"
9 #include "ui/gl/gl_context.h"
10 #include "ui/gl/gl_version_info.h"
12 namespace {
14 class GLFenceNVFence: public gfx::GLFence {
15 public:
16 GLFenceNVFence(bool flush) {
17 // What if either of these GL calls fails? TestFenceNV will return true.
18 // See spec:
19 // http://www.opengl.org/registry/specs/NV/fence.txt
21 // What should happen if TestFenceNV is called for a name before SetFenceNV
22 // is called?
23 // We generate an INVALID_OPERATION error, and return TRUE.
24 // This follows the semantics for texture object names before
25 // they are bound, in that they acquire their state upon binding.
26 // We will arbitrarily return TRUE for consistency.
27 glGenFencesNV(1, &fence_);
28 glSetFenceNV(fence_, GL_ALL_COMPLETED_NV);
29 if (flush) {
30 glFlush();
31 } else {
32 flush_event_ = gfx::GLContext::GetCurrent()->SignalFlush();
36 virtual bool HasCompleted() OVERRIDE {
37 return !!glTestFenceNV(fence_);
40 virtual void ClientWait() OVERRIDE {
41 if (!flush_event_ || flush_event_->IsSignaled()) {
42 glFinishFenceNV(fence_);
43 } else {
44 LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
48 virtual void ServerWait() OVERRIDE {
49 ClientWait();
52 private:
53 virtual ~GLFenceNVFence() {
54 glDeleteFencesNV(1, &fence_);
57 GLuint fence_;
58 scoped_refptr<gfx::GLContext::FlushEvent> flush_event_;
61 class GLFenceARBSync: public gfx::GLFence {
62 public:
63 GLFenceARBSync(bool flush) {
64 sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
65 if (flush) {
66 glFlush();
67 } else {
68 flush_event_ = gfx::GLContext::GetCurrent()->SignalFlush();
72 virtual bool HasCompleted() OVERRIDE {
73 // Handle the case where FenceSync failed.
74 if (!sync_)
75 return true;
77 // We could potentially use glGetSynciv here, but it doesn't work
78 // on OSX 10.7 (always says the fence is not signaled yet).
79 // glClientWaitSync works better, so let's use that instead.
80 return glClientWaitSync(sync_, 0, 0) != GL_TIMEOUT_EXPIRED;
83 virtual void ClientWait() OVERRIDE {
84 if (!flush_event_ || flush_event_->IsSignaled()) {
85 glClientWaitSync(sync_, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
86 } else {
87 LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
91 virtual void ServerWait() OVERRIDE {
92 if (!flush_event_ || flush_event_->IsSignaled()) {
93 glWaitSync(sync_, 0, GL_TIMEOUT_IGNORED);
94 } else {
95 LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
99 private:
100 virtual ~GLFenceARBSync() {
101 glDeleteSync(sync_);
104 GLsync sync_;
105 scoped_refptr<gfx::GLContext::FlushEvent> flush_event_;
108 #if !defined(OS_MACOSX)
109 class EGLFenceSync : public gfx::GLFence {
110 public:
111 EGLFenceSync(bool flush) {
112 display_ = eglGetCurrentDisplay();
113 sync_ = eglCreateSyncKHR(display_, EGL_SYNC_FENCE_KHR, NULL);
114 if (flush) {
115 glFlush();
116 } else {
117 flush_event_ = gfx::GLContext::GetCurrent()->SignalFlush();
121 virtual bool HasCompleted() OVERRIDE {
122 EGLint value = 0;
123 eglGetSyncAttribKHR(display_, sync_, EGL_SYNC_STATUS_KHR, &value);
124 DCHECK(value == EGL_SIGNALED_KHR || value == EGL_UNSIGNALED_KHR);
125 return !value || value == EGL_SIGNALED_KHR;
128 virtual void ClientWait() OVERRIDE {
129 if (!flush_event_ || flush_event_->IsSignaled()) {
130 EGLint flags = 0;
131 EGLTimeKHR time = EGL_FOREVER_KHR;
132 eglClientWaitSyncKHR(display_, sync_, flags, time);
133 } else {
134 LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
138 virtual void ServerWait() OVERRIDE {
139 if (!flush_event_ || flush_event_->IsSignaled()) {
140 EGLint flags = 0;
141 eglWaitSyncKHR(display_, sync_, flags);
142 } else {
143 LOG(ERROR) << "Trying to wait for uncommitted fence. Skipping...";
148 private:
149 virtual ~EGLFenceSync() {
150 eglDestroySyncKHR(display_, sync_);
153 EGLSyncKHR sync_;
154 EGLDisplay display_;
155 scoped_refptr<gfx::GLContext::FlushEvent> flush_event_;
157 #endif // !OS_MACOSX
159 // static
160 gfx::GLFence* CreateFence(bool flush) {
161 DCHECK(gfx::GLContext::GetCurrent())
162 << "Trying to create fence with no context";
164 #if !defined(OS_MACOSX)
165 if (gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync)
166 return new EGLFenceSync(flush);
167 #endif
168 // Prefer ARB_sync which supports server-side wait.
169 if (gfx::g_driver_gl.ext.b_GL_ARB_sync ||
170 gfx::GLContext::GetCurrent()->GetVersionInfo()->is_es3)
171 return new GLFenceARBSync(flush);
172 if (gfx::g_driver_gl.ext.b_GL_NV_fence)
173 return new GLFenceNVFence(flush);
174 return NULL;
177 } // namespace
179 namespace gfx {
181 GLFence::GLFence() {
184 GLFence::~GLFence() {
187 GLFence* GLFence::Create() {
188 return CreateFence(true);
191 GLFence* GLFence::CreateWithoutFlush() {
192 return CreateFence(false);
195 } // namespace gfx