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"
13 class GLFenceNVFence
: public gfx::GLFence
{
16 // What if either of these GL calls fails? TestFenceNV will return true.
18 // http://www.opengl.org/registry/specs/NV/fence.txt
20 // What should happen if TestFenceNV is called for a name before SetFenceNV
22 // We generate an INVALID_OPERATION error, and return TRUE.
23 // This follows the semantics for texture object names before
24 // they are bound, in that they acquire their state upon binding.
25 // We will arbitrarily return TRUE for consistency.
26 glGenFencesNV(1, &fence_
);
27 glSetFenceNV(fence_
, GL_ALL_COMPLETED_NV
);
31 virtual bool HasCompleted() OVERRIDE
{
32 return !!glTestFenceNV(fence_
);
35 virtual void ClientWait() OVERRIDE
{
36 glFinishFenceNV(fence_
);
40 virtual ~GLFenceNVFence() {
41 glDeleteFencesNV(1, &fence_
);
47 class GLFenceARBSync
: public gfx::GLFence
{
50 sync_
= glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE
, 0);
54 virtual bool HasCompleted() OVERRIDE
{
55 // Handle the case where FenceSync failed.
59 // We could potentially use glGetSynciv here, but it doesn't work
60 // on OSX 10.7 (always says the fence is not signaled yet).
61 // glClientWaitSync works better, so let's use that instead.
62 return glClientWaitSync(sync_
, 0, 0) != GL_TIMEOUT_EXPIRED
;
65 virtual void ClientWait() OVERRIDE
{
66 glClientWaitSync(sync_
, GL_SYNC_FLUSH_COMMANDS_BIT
, GL_TIMEOUT_IGNORED
);
70 virtual ~GLFenceARBSync() {
77 #if !defined(OS_MACOSX)
78 class EGLFenceSync
: public gfx::GLFence
{
81 display_
= eglGetCurrentDisplay();
82 sync_
= eglCreateSyncKHR(display_
, EGL_SYNC_FENCE_KHR
, NULL
);
86 virtual bool HasCompleted() OVERRIDE
{
88 eglGetSyncAttribKHR(display_
, sync_
, EGL_SYNC_STATUS_KHR
, &value
);
89 DCHECK(value
== EGL_SIGNALED_KHR
|| value
== EGL_UNSIGNALED_KHR
);
90 return !value
|| value
== EGL_SIGNALED_KHR
;
93 virtual void ClientWait() OVERRIDE
{
95 EGLTimeKHR time
= EGL_FOREVER_KHR
;
96 eglClientWaitSyncKHR(display_
, sync_
, flags
, time
);
100 virtual ~EGLFenceSync() {
101 eglDestroySyncKHR(display_
, sync_
);
116 GLFence::~GLFence() {
120 GLFence
* GLFence::Create() {
121 #if !defined(OS_MACOSX)
122 if (gfx::g_driver_egl
.ext
.b_EGL_KHR_fence_sync
)
123 return new EGLFenceSync();
125 if (gfx::g_driver_gl
.ext
.b_GL_NV_fence
)
126 return new GLFenceNVFence();
127 if (gfx::g_driver_gl
.ext
.b_GL_ARB_sync
)
128 return new GLFenceARBSync();