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 321df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennisconst sp<Fence> Fence::NO_FENCE = sp<Fence>(new 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 57ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopianstatus_t Fence::waitForever(const char* logname) { 58ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall ATRACE_CALL(); 59ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall if (mFenceFd == -1) { 60ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall return NO_ERROR; 61ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall } 62ea74d3b78d607cde17790a7bb83e6f68ffd34cfdMathias Agopian unsigned int warningTimeout = 3000; 63ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall int err = sync_wait(mFenceFd, warningTimeout); 64b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian if (err < 0 && errno == ETIME) { 65ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd, 66ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall warningTimeout); 67ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall err = sync_wait(mFenceFd, TIMEOUT_NEVER); 68ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall } 69b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian return err < 0 ? -errno : status_t(NO_ERROR); 70ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall} 71ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall 72f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1, 73f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis const sp<Fence>& f2) { 74f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis ATRACE_CALL(); 751df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis int result; 761df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis // Merge the two fences. In the case where one of the fences is not a 771df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis // valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so 781df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis // that a new fence with the given name is created. 791df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (f1->isValid() && f2->isValid()) { 801df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd); 811df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } else if (f1->isValid()) { 821df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis result = sync_merge(name.string(), f1->mFenceFd, f1->mFenceFd); 831df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } else if (f2->isValid()) { 841df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis result = sync_merge(name.string(), f2->mFenceFd, f2->mFenceFd); 851df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } else { 861df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis return NO_FENCE; 871df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } 88f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (result == -1) { 89d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian status_t err = -errno; 90d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)", 91d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian name.string(), f1->mFenceFd, f2->mFenceFd, 92d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian strerror(-err), err); 93ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall return NO_FENCE; 94f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 95f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return sp<Fence>(new Fence(result)); 96f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 97f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 98f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hallint Fence::dup() const { 99f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall return ::dup(mFenceFd); 100f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall} 101f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall 10282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennisnsecs_t Fence::getSignalTime() const { 10382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (mFenceFd == -1) { 10482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis return -1; 10582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 10682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 10782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd); 10882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (finfo == NULL) { 10982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd); 11082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis return -1; 11182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 11282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (finfo->status != 1) { 1137c36cd231542990e0ef8240fcc8dfd35a9e4b38bJesse Hall sync_fence_info_free(finfo); 11482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis return INT64_MAX; 11582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 11682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 11782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis struct sync_pt_info* pinfo = NULL; 11882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis uint64_t timestamp = 0; 11982dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) { 12082dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis if (pinfo->timestamp_ns > timestamp) { 12182dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis timestamp = pinfo->timestamp_ns; 12282dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 12382dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis } 12482dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis sync_fence_info_free(finfo); 12582dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 12682dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis return nsecs_t(timestamp); 12782dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis} 12882dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6addJamie Gennis 129f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFlattenedSize() const { 130e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return 1; 131f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 132f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 133f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFdCount() const { 1341df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis return isValid() ? 1 : 0; 135f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 136f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 137e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatus_t Fence::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const { 138e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (size < getFlattenedSize() || count < getFdCount()) { 139e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return NO_MEMORY; 140f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 141e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian FlattenableUtils::write(buffer, size, getFdCount()); 1421df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis if (isValid()) { 143e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian *fds++ = mFenceFd; 144e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian count--; 1451df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } 146f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return NO_ERROR; 147f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 148f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 149e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopianstatus_t Fence::unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count) { 150f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis if (mFenceFd != -1) { 151f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis // Don't unflatten if we already have a valid fd. 152f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return INVALID_OPERATION; 153f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis } 154f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 155e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (size < 1) { 156e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return NO_MEMORY; 157e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian } 158e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 159e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian size_t numFds; 160e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian FlattenableUtils::read(buffer, size, numFds); 161e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 162e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (numFds > 1) { 163e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return BAD_VALUE; 164e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian } 165e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 166e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (count < numFds) { 167e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian return NO_MEMORY; 168e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian } 169e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian 170e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian if (numFds) { 171e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian mFenceFd = *fds++; 172e142428a9c8b9d2380032cd4d7b55ee440fe8770Mathias Agopian count--; 1731df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis } 1741df8c345854155cbbcb9f80de9d12d66ea70ac08Jamie Gennis 175f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis return NO_ERROR; 176f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} 177f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis 178f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} // namespace android 179