1405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy/* 2405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * Copyright (C) 2013 The Android Open Source Project 3405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * 4405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * you may not use this file except in compliance with the License. 6405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * You may obtain a copy of the License at 7405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * 8405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * http://www.apache.org/licenses/LICENSE-2.0 9405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * 10405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * Unless required by applicable law or agreed to in writing, software 11405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * See the License for the specific language governing permissions and 14405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * limitations under the License. 15405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy */ 16405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 17405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy#ifndef ANDROID_HWUI_FENCE_H 18405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy#define ANDROID_HWUI_FENCE_H 19405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 20405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy#include <EGL/egl.h> 21405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy#include <EGL/eglext.h> 22405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 23405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guynamespace android { 24405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guynamespace uirenderer { 25405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 26405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy/** 27405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * Creating a Fence instance inserts a new sync fence in the OpenGL 28405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * commands stream. The caller can then wait for the fence to be signaled 29405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * by calling the wait method. 30405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy */ 31405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guyclass Fence { 32405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guypublic: 33405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy enum { 34405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy /** 35405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * Default timeout in nano-seconds for wait() 36405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy */ 37405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy kDefaultTimeout = 1000000000 38405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy }; 39405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 40405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy /** 41405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * Inserts a new sync fence in the OpenGL commands stream. 42405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy */ 43405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy Fence() { 44405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy mDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 45405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy if (mDisplay != EGL_NO_DISPLAY) { 46405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy mFence = eglCreateSyncKHR(mDisplay, EGL_SYNC_FENCE_KHR, NULL); 47405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy } else { 48405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy mFence = EGL_NO_SYNC_KHR; 49405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy } 50405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy } 51405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 52405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy /** 53405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * Destroys the fence. Any caller waiting on the fence will be 54405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * signaled immediately. 55405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy */ 56405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy ~Fence() { 57405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy if (mFence != EGL_NO_SYNC_KHR) { 58405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy eglDestroySyncKHR(mDisplay, mFence); 59405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy } 60405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy } 61405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 62405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy /** 63405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * Blocks the calling thread until this fence is signaled, or until 64405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * <timeout> nanoseconds have passed. 65405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * 66405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * Returns true if waiting for the fence was successful, false if 67405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * a timeout or an error occurred. 68405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy */ 69405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy bool wait(EGLTimeKHR timeout = kDefaultTimeout) { 70405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy EGLint waitStatus = eglClientWaitSyncKHR(mDisplay, mFence, 71405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, timeout); 72405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy if (waitStatus == EGL_FALSE) { 73405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy ALOGW("Failed to wait for the fence %#x", eglGetError()); 74405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy } 75405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy return waitStatus == EGL_CONDITION_SATISFIED_KHR; 76405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy } 77405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 78405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guyprivate: 79405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy EGLDisplay mDisplay; 80405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy EGLSyncKHR mFence; 81405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 82405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy}; // class Fence 83405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 84405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy/** 85405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * An AutoFence creates a Fence instance and waits for the fence 86405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * to be signaled when the AutoFence is destroyed. This is useful 87405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * to automatically wait for a series of OpenGL commands to be 88405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * executed. For example: 89405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * 90405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * void drawAndWait() { 91405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * glDrawElements(); 92405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * AutoFence fence; 93405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy * } 94405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy */ 95405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guyclass AutoFence { 96405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guypublic: 97405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy AutoFence(EGLTimeKHR timeout = Fence::kDefaultTimeout): mTimeout(timeout) { 98405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy } 99405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 100405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy ~AutoFence() { 101405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy mFence.wait(mTimeout); 102405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy } 103405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 104405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guyprivate: 105405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy EGLTimeKHR mTimeout; 106405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy Fence mFence; 107405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 108405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy}; // class AutoFence 109405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 110405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy}; // namespace uirenderer 111405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy}; // namespace android 112405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy 113405436021da156fbe3c5d4de48bdefa564cf7fc0Romain Guy#endif // ANDROID_HWUI_FENCE_H 114