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