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
21f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <sync/sync.h>
22f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <ui/Fence.h>
23f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <unistd.h>
24f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <utils/Log.h>
25f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis#include <utils/Trace.h>
26f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
27f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisnamespace android {
28f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
29ef19414bd8b77a26f5751f3845be79025a8263feJesse Hallconst sp<Fence> Fence::NO_FENCE = sp<Fence>();
30ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall
31f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::Fence() :
32f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    mFenceFd(-1) {
33f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
34f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
35f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::Fence(int fenceFd) :
36f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    mFenceFd(fenceFd) {
37f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
38f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
39f25e183a70bd631f75dce51e85b7d568472a0cdbJamie GennisFence::~Fence() {
40f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    if (mFenceFd != -1) {
41f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        close(mFenceFd);
42f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    }
43f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
44f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
45b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopianstatus_t Fence::wait(unsigned int timeout) {
46f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    ATRACE_CALL();
47f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    if (mFenceFd == -1) {
48f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        return NO_ERROR;
49f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    }
50b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian    int err = sync_wait(mFenceFd, timeout);
51b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian    return err < 0 ? -errno : status_t(NO_ERROR);
52f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
53f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
54b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopianstatus_t Fence::waitForever(unsigned int warningTimeout, const char* logname) {
55ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall    ATRACE_CALL();
56ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall    if (mFenceFd == -1) {
57ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall        return NO_ERROR;
58ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall    }
59ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall    int err = sync_wait(mFenceFd, warningTimeout);
60b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian    if (err < 0 && errno == ETIME) {
61ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall        ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd,
62ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall                warningTimeout);
63ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall        err = sync_wait(mFenceFd, TIMEOUT_NEVER);
64ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall    }
65b5c9dcdf3bdab1862047060b8e18c9d1831db8bbMathias Agopian    return err < 0 ? -errno : status_t(NO_ERROR);
66ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall}
67ba607d53c6a94ea8c4c12571980c4ad159af308bJesse Hall
68f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
69f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        const sp<Fence>& f2) {
70f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    ATRACE_CALL();
71f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    int result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd);
72f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    if (result == -1) {
73d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian        status_t err = -errno;
74d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian        ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)",
75d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian                name.string(), f1->mFenceFd, f2->mFenceFd,
76d83d67b5d5e98b7f0bdf54b68f6ea28fa4905a33Mathias Agopian                strerror(-err), err);
77ef19414bd8b77a26f5751f3845be79025a8263feJesse Hall        return NO_FENCE;
78f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    }
79f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    return sp<Fence>(new Fence(result));
80f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
81f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
82f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hallint Fence::dup() const {
83c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall    if (mFenceFd == -1) {
84c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall        return -1;
85c777b0b3b9b0ea5d8e378fccde6935765e28e329Jesse Hall    }
86f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall    return ::dup(mFenceFd);
87f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall}
88f9783af225aa3b41ec0af36f90941a714269abb7Jesse Hall
89f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFlattenedSize() const {
90f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    return 0;
91f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
92f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
93f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennissize_t Fence::getFdCount() const {
94f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    return 1;
95f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
96f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
97f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisstatus_t Fence::flatten(void* buffer, size_t size, int fds[],
98f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        size_t count) const {
99f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    if (size != 0 || count != 1) {
100f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        return BAD_VALUE;
101f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    }
102f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
103f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    fds[0] = mFenceFd;
104f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    return NO_ERROR;
105f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
106f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
107f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennisstatus_t Fence::unflatten(void const* buffer, size_t size, int fds[],
108f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        size_t count) {
109f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    if (size != 0 || count != 1) {
110f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        return BAD_VALUE;
111f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    }
112f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    if (mFenceFd != -1) {
113f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        // Don't unflatten if we already have a valid fd.
114f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis        return INVALID_OPERATION;
115f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    }
116f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
117f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    mFenceFd = fds[0];
118f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis    return NO_ERROR;
119f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis}
120f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis
121f25e183a70bd631f75dce51e85b7d568472a0cdbJamie Gennis} // namespace android
122