Fence.cpp revision 7c36cd231542990e0ef8240fcc8dfd35a9e4b38b
1f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis/* 2f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Copyright (C) 2012 The Android Open Source Project 3f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * 4f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Licensed under the Apache License, Version 2.0 (the "License"); 5f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * you may not use this file except in compliance with the License. 6f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * You may obtain a copy of the License at 7f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * 8f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * http://www.apache.org/licenses/LICENSE-2.0 9f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * 10f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * Unless required by applicable law or agreed to in writing, software 11f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * distributed under the License is distributed on an "AS IS" BASIS, 12f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * See the License for the specific language governing permissions and 14f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis * limitations under the License. 15f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis */ 16f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 17f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#define LOG_TAG "Fence" 18f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#define ATRACE_TAG ATRACE_TAG_GRAPHICS 19f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis//#define LOG_NDEBUG 0 20f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 2182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis // This is needed for stdint.h to define INT64_MAX in C++ 2282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis #define __STDC_LIMIT_MACROS 2382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 24f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <sync/sync.h> 25f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <ui/Fence.h> 26f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <unistd.h> 27f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <utils/Log.h> 28f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <utils/Trace.h> 29f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 30f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisnamespace android { 31f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 32ef19414bd8b77a26f5751f3845be79025a8263feJesse Hallconst sp<Fence> Fence::NO_FENCE = sp<Fence>(); 33ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall 34f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::Fence() : 35f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis mFenceFd(-1) { 36f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 37f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 38f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::Fence(int fenceFd) : 39f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis mFenceFd(fenceFd) { 40f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 41f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 42f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::~Fence() { 43f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (mFenceFd != -1) { 44f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis close(mFenceFd); 45f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 46f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 47f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 48b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopianstatus_t Fence::wait(unsigned int timeout) { 49f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis ATRACE_CALL(); 50f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (mFenceFd == -1) { 51f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return NO_ERROR; 52f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 53b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian int err = sync_wait(mFenceFd, timeout); 54b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian return err < 0 ? -errno : status_t(NO_ERROR); 55f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 56f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 57b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopianstatus_t Fence::waitForever(unsigned int warningTimeout, const char* logname) { 58ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall ATRACE_CALL(); 59ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall if (mFenceFd == -1) { 60ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall return NO_ERROR; 61ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall } 62ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall int err = sync_wait(mFenceFd, warningTimeout); 63b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian if (err < 0 && errno == ETIME) { 64ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd, 65ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall warningTimeout); 66ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall err = sync_wait(mFenceFd, TIMEOUT_NEVER); 67ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall } 68b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian return err < 0 ? -errno : status_t(NO_ERROR); 69ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall} 70ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall 71f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1, 72f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis const sp<Fence>& f2) { 73f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis ATRACE_CALL(); 74f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis int result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd); 75f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (result == -1) { 76d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian status_t err = -errno; 77d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)", 78d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian name.string(), f1->mFenceFd, f2->mFenceFd, 79d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian strerror(-err), err); 80ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall return NO_FENCE; 81f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 82f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return sp<Fence>(new Fence(result)); 83f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 84f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 85f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hallint Fence::dup() const { 86c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall if (mFenceFd == -1) { 87c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall return -1; 88c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall } 89f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall return ::dup(mFenceFd); 90f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall} 91f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall 9282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisnsecs_t Fence::getSignalTime() const { 9382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (mFenceFd == -1) { 9482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis return -1; 9582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 9682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 9782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd); 9882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (finfo == NULL) { 9982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd); 10082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis return -1; 10182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 10282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (finfo->status != 1) { 1037c36cd231542990e0ef8240fcc8dfd35a9e4b38bJesse Hall sync_fence_info_free(finfo); 10482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis return INT64_MAX; 10582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 10682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 10782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis struct sync_pt_info* pinfo = NULL; 10882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis uint64_t timestamp = 0; 10982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) { 11082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (pinfo->timestamp_ns > timestamp) { 11182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis timestamp = pinfo->timestamp_ns; 11282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 11382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 11482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis sync_fence_info_free(finfo); 11582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 11682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis return nsecs_t(timestamp); 11782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis} 11882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 119f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFlattenedSize() const { 120f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return 0; 121f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 122f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 123f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFdCount() const { 124f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return 1; 125f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 126f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 127f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisstatus_t Fence::flatten(void* buffer, size_t size, int fds[], 128f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis size_t count) const { 129f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (size != 0 || count != 1) { 130f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return BAD_VALUE; 131f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 132f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 133f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis fds[0] = mFenceFd; 134f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return NO_ERROR; 135f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 136f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 137f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisstatus_t Fence::unflatten(void const* buffer, size_t size, int fds[], 138f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis size_t count) { 139f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (size != 0 || count != 1) { 140f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return BAD_VALUE; 141f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 142f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (mFenceFd != -1) { 143f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // Don't unflatten if we already have a valid fd. 144f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return INVALID_OPERATION; 145f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 146f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 147f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis mFenceFd = fds[0]; 148f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return NO_ERROR; 149f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 150f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 151f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} // namespace android 152