Revert 233039 "Blink roll 161254:161319"
[chromium-blink-merge.git] / ui / gl / gl_fence.cc
blob9b85300fabdbc10e7ecf27685930a7b55f1a2408
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"
11 namespace {
13 class GLFenceNVFence: public gfx::GLFence {
14 public:
15 GLFenceNVFence() {
16 // What if either of these GL calls fails? TestFenceNV will return true.
17 // See spec:
18 // http://www.opengl.org/registry/specs/NV/fence.txt
20 // What should happen if TestFenceNV is called for a name before SetFenceNV
21 // is called?
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);
28 glFlush();
31 virtual bool HasCompleted() OVERRIDE {
32 return !!glTestFenceNV(fence_);
35 virtual void ClientWait() OVERRIDE {
36 glFinishFenceNV(fence_);
39 private:
40 virtual ~GLFenceNVFence() {
41 glDeleteFencesNV(1, &fence_);
44 GLuint fence_;
47 class GLFenceARBSync: public gfx::GLFence {
48 public:
49 GLFenceARBSync() {
50 sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
51 glFlush();
54 virtual bool HasCompleted() OVERRIDE {
55 // Handle the case where FenceSync failed.
56 if (!sync_)
57 return true;
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);
69 private:
70 virtual ~GLFenceARBSync() {
71 glDeleteSync(sync_);
74 GLsync sync_;
77 #if !defined(OS_MACOSX)
78 class EGLFenceSync : public gfx::GLFence {
79 public:
80 EGLFenceSync() {
81 display_ = eglGetCurrentDisplay();
82 sync_ = eglCreateSyncKHR(display_, EGL_SYNC_FENCE_KHR, NULL);
83 glFlush();
86 virtual bool HasCompleted() OVERRIDE {
87 EGLint value = 0;
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 {
94 EGLint flags = 0;
95 EGLTimeKHR time = EGL_FOREVER_KHR;
96 eglClientWaitSyncKHR(display_, sync_, flags, time);
99 private:
100 virtual ~EGLFenceSync() {
101 eglDestroySyncKHR(display_, sync_);
104 EGLSyncKHR sync_;
105 EGLDisplay display_;
107 #endif // !OS_MACOSX
109 } // namespace
111 namespace gfx {
113 GLFence::GLFence() {
116 GLFence::~GLFence() {
119 // static
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();
124 #endif
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();
129 return NULL;
132 } // namespace gfx