Fence.cpp revision 82dbc7429f5f9f2b303b31dc5b9f2bfd1bbe6add
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#define LOG_TAG "Fence" 18#define ATRACE_TAG ATRACE_TAG_GRAPHICS 19//#define LOG_NDEBUG 0 20 21 // This is needed for stdint.h to define INT64_MAX in C++ 22 #define __STDC_LIMIT_MACROS 23 24#include <sync/sync.h> 25#include <ui/Fence.h> 26#include <unistd.h> 27#include <utils/Log.h> 28#include <utils/Trace.h> 29 30namespace android { 31 32const sp<Fence> Fence::NO_FENCE = sp<Fence>(); 33 34Fence::Fence() : 35 mFenceFd(-1) { 36} 37 38Fence::Fence(int fenceFd) : 39 mFenceFd(fenceFd) { 40} 41 42Fence::~Fence() { 43 if (mFenceFd != -1) { 44 close(mFenceFd); 45 } 46} 47 48status_t Fence::wait(unsigned int timeout) { 49 ATRACE_CALL(); 50 if (mFenceFd == -1) { 51 return NO_ERROR; 52 } 53 int err = sync_wait(mFenceFd, timeout); 54 return err < 0 ? -errno : status_t(NO_ERROR); 55} 56 57status_t Fence::waitForever(unsigned int warningTimeout, const char* logname) { 58 ATRACE_CALL(); 59 if (mFenceFd == -1) { 60 return NO_ERROR; 61 } 62 int err = sync_wait(mFenceFd, warningTimeout); 63 if (err < 0 && errno == ETIME) { 64 ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd, 65 warningTimeout); 66 err = sync_wait(mFenceFd, TIMEOUT_NEVER); 67 } 68 return err < 0 ? -errno : status_t(NO_ERROR); 69} 70 71sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1, 72 const sp<Fence>& f2) { 73 ATRACE_CALL(); 74 int result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd); 75 if (result == -1) { 76 status_t err = -errno; 77 ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)", 78 name.string(), f1->mFenceFd, f2->mFenceFd, 79 strerror(-err), err); 80 return NO_FENCE; 81 } 82 return sp<Fence>(new Fence(result)); 83} 84 85int Fence::dup() const { 86 if (mFenceFd == -1) { 87 return -1; 88 } 89 return ::dup(mFenceFd); 90} 91 92nsecs_t Fence::getSignalTime() const { 93 if (mFenceFd == -1) { 94 return -1; 95 } 96 97 struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd); 98 if (finfo == NULL) { 99 ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd); 100 return -1; 101 } 102 if (finfo->status != 1) { 103 return INT64_MAX; 104 } 105 106 struct sync_pt_info* pinfo = NULL; 107 uint64_t timestamp = 0; 108 while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) { 109 if (pinfo->timestamp_ns > timestamp) { 110 timestamp = pinfo->timestamp_ns; 111 } 112 } 113 sync_fence_info_free(finfo); 114 115 return nsecs_t(timestamp); 116} 117 118size_t Fence::getFlattenedSize() const { 119 return 0; 120} 121 122size_t Fence::getFdCount() const { 123 return 1; 124} 125 126status_t Fence::flatten(void* buffer, size_t size, int fds[], 127 size_t count) const { 128 if (size != 0 || count != 1) { 129 return BAD_VALUE; 130 } 131 132 fds[0] = mFenceFd; 133 return NO_ERROR; 134} 135 136status_t Fence::unflatten(void const* buffer, size_t size, int fds[], 137 size_t count) { 138 if (size != 0 || count != 1) { 139 return BAD_VALUE; 140 } 141 if (mFenceFd != -1) { 142 // Don't unflatten if we already have a valid fd. 143 return INVALID_OPERATION; 144 } 145 146 mFenceFd = fds[0]; 147 return NO_ERROR; 148} 149 150} // namespace android 151