/* * Copyright (C) 2013 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ANDROID_HWUI_FENCE_H #define ANDROID_HWUI_FENCE_H #include #include namespace android { namespace uirenderer { /** * Creating a Fence instance inserts a new sync fence in the OpenGL * commands stream. The caller can then wait for the fence to be signaled * by calling the wait method. */ class Fence { public: enum { /** * Default timeout in nano-seconds for wait() */ kDefaultTimeout = 1000000000 }; /** * Inserts a new sync fence in the OpenGL commands stream. */ Fence() { mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); if (mDisplay != EGL_NO_DISPLAY) { mFence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL); } else { mFence = EGL_NO_SYNC_KHR; } } /** * Destroys the fence. Any caller waiting on the fence will be * signaled immediately. */ ~Fence() { if (mFence != EGL_NO_SYNC_KHR) { eglDestroySyncKHR(mDisplay, mFence); } } /** * Blocks the calling thread until this fence is signaled, or until * nanoseconds have passed. * * Returns true if waiting for the fence was successful, false if * a timeout or an error occurred. */ bool wait(EGLTimeKHR timeout = kDefaultTimeout) { EGLint waitStatus = eglClientWaitSyncKHR(mDisplay, mFence, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, timeout); if (waitStatus == EGL_FALSE) { ALOGW("Failed to wait for the fence %#x", eglGetError()); } return waitStatus == EGL_CONDITION_SATISFIED_KHR; } private: EGLDisplay mDisplay; EGLSyncKHR mFence; }; // class Fence /** * An AutoFence creates a Fence instance and waits for the fence * to be signaled when the AutoFence is destroyed. This is useful * to automatically wait for a series of OpenGL commands to be * executed. For example: * * void drawAndWait() { * glDrawElements(); * AutoFence fence; * } */ class AutoFence { public: AutoFence(EGLTimeKHR timeout = Fence::kDefaultTimeout): mTimeout(timeout) { } ~AutoFence() { mFence.wait(mTimeout); } private: EGLTimeKHR mTimeout; Fence mFence; }; // class AutoFence }; // namespace uirenderer }; // namespace android #endif // ANDROID_HWUI_FENCE_H