// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ui/gl/gl_fence_arb.h" #include "base/strings/stringprintf.h" #include "ui/gl/gl_bindings.h" namespace gfx { namespace { std::string GetGLErrors() { // Clears and logs all current gl errors. std::string accumulated_errors; GLenum error; while ((error = glGetError()) != GL_NO_ERROR) { accumulated_errors += base::StringPrintf("0x%x ", error); } return accumulated_errors; } } // namespace GLFenceARB::GLFenceARB() { sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); DCHECK_EQ(GL_TRUE, glIsSync(sync_)); glFlush(); } bool GLFenceARB::HasCompleted() { // Handle the case where FenceSync failed. if (!sync_) return true; DCHECK_EQ(GL_TRUE, glIsSync(sync_)); // We could potentially use glGetSynciv here, but it doesn't work // on OSX 10.7 (always says the fence is not signaled yet). // glClientWaitSync works better, so let's use that instead. GLenum result = glClientWaitSync(sync_, 0, 0); if (result == GL_WAIT_FAILED) { LOG(FATAL) << "Failed to wait for GLFence. error code:" << GetGLErrors(); } return result != GL_TIMEOUT_EXPIRED; } void GLFenceARB::ClientWait() { DCHECK_EQ(GL_TRUE, glIsSync(sync_)); GLenum result = glClientWaitSync(sync_, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); DCHECK_NE(static_cast(GL_TIMEOUT_EXPIRED), result); if (result == GL_WAIT_FAILED) { LOG(FATAL) << "Failed to wait for GLFence. error code:" << GetGLErrors(); } } void GLFenceARB::ServerWait() { DCHECK_EQ(GL_TRUE, glIsSync(sync_)); glWaitSync(sync_, 0, GL_TIMEOUT_IGNORED); } GLFenceARB::~GLFenceARB() { DCHECK_EQ(GL_TRUE, glIsSync(sync_)); glDeleteSync(sync_); } } // namespace gfx