Fence.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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. #define LOG_TAG "Fence"
  17. #define ATRACE_TAG ATRACE_TAG_GRAPHICS
  18. //#define LOG_NDEBUG 0
  19. // We would eliminate the non-conforming zero-length array, but we can't since
  20. // this is effectively included from the Linux kernel
  21. #pragma clang diagnostic push
  22. #pragma clang diagnostic ignored "-Wzero-length-array"
  23. #include <sync/sync.h>
  24. #pragma clang diagnostic pop
  25. #include <ui/Fence.h>
  26. #include <unistd.h>
  27. #include <utils/Log.h>
  28. #include <utils/Trace.h>
  29. namespace android {
  30. const sp<Fence> Fence::NO_FENCE = sp<Fence>(new Fence);
  31. Fence::Fence() :
  32. mFenceFd(-1) {
  33. }
  34. Fence::Fence(int fenceFd) :
  35. mFenceFd(fenceFd) {
  36. }
  37. Fence::~Fence() {
  38. if (mFenceFd != -1) {
  39. close(mFenceFd);
  40. }
  41. }
  42. status_t Fence::wait(int timeout) {
  43. ATRACE_CALL();
  44. if (mFenceFd == -1) {
  45. return NO_ERROR;
  46. }
  47. int err = sync_wait(mFenceFd, timeout);
  48. return err < 0 ? -errno : status_t(NO_ERROR);
  49. }
  50. status_t Fence::waitForever(const char* logname) {
  51. ATRACE_CALL();
  52. if (mFenceFd == -1) {
  53. return NO_ERROR;
  54. }
  55. int warningTimeout = 3000;
  56. int err = sync_wait(mFenceFd, warningTimeout);
  57. if (err < 0 && errno == ETIME) {
  58. ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd,
  59. warningTimeout);
  60. err = sync_wait(mFenceFd, TIMEOUT_NEVER);
  61. }
  62. return err < 0 ? -errno : status_t(NO_ERROR);
  63. }
  64. sp<Fence> Fence::merge(const String8& name, const sp<Fence>& f1,
  65. const sp<Fence>& f2) {
  66. ATRACE_CALL();
  67. int result;
  68. // Merge the two fences. In the case where one of the fences is not a
  69. // valid fence (e.g. NO_FENCE) we merge the one valid fence with itself so
  70. // that a new fence with the given name is created.
  71. if (f1->isValid() && f2->isValid()) {
  72. result = sync_merge(name.string(), f1->mFenceFd, f2->mFenceFd);
  73. } else if (f1->isValid()) {
  74. result = sync_merge(name.string(), f1->mFenceFd, f1->mFenceFd);
  75. } else if (f2->isValid()) {
  76. result = sync_merge(name.string(), f2->mFenceFd, f2->mFenceFd);
  77. } else {
  78. return NO_FENCE;
  79. }
  80. if (result == -1) {
  81. status_t err = -errno;
  82. ALOGE("merge: sync_merge(\"%s\", %d, %d) returned an error: %s (%d)",
  83. name.string(), f1->mFenceFd, f2->mFenceFd,
  84. strerror(-err), err);
  85. return NO_FENCE;
  86. }
  87. return sp<Fence>(new Fence(result));
  88. }
  89. int Fence::dup() const {
  90. return ::dup(mFenceFd);
  91. }
  92. nsecs_t Fence::getSignalTime() const {
  93. if (mFenceFd == -1) {
  94. return -1;
  95. }
  96. struct sync_fence_info_data* finfo = sync_fence_info(mFenceFd);
  97. if (finfo == NULL) {
  98. ALOGE("sync_fence_info returned NULL for fd %d", mFenceFd);
  99. return -1;
  100. }
  101. if (finfo->status != 1) {
  102. sync_fence_info_free(finfo);
  103. return INT64_MAX;
  104. }
  105. struct sync_pt_info* pinfo = NULL;
  106. uint64_t timestamp = 0;
  107. while ((pinfo = sync_pt_info(finfo, pinfo)) != NULL) {
  108. if (pinfo->timestamp_ns > timestamp) {
  109. timestamp = pinfo->timestamp_ns;
  110. }
  111. }
  112. sync_fence_info_free(finfo);
  113. return nsecs_t(timestamp);
  114. }
  115. size_t Fence::getFlattenedSize() const {
  116. return 4;
  117. }
  118. size_t Fence::getFdCount() const {
  119. return isValid() ? 1 : 0;
  120. }
  121. status_t Fence::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const {
  122. if (size < getFlattenedSize() || count < getFdCount()) {
  123. return NO_MEMORY;
  124. }
  125. // Cast to uint32_t since the size of a size_t can vary between 32- and
  126. // 64-bit processes
  127. FlattenableUtils::write(buffer, size, static_cast<uint32_t>(getFdCount()));
  128. if (isValid()) {
  129. *fds++ = mFenceFd;
  130. count--;
  131. }
  132. return NO_ERROR;
  133. }
  134. status_t Fence::unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count) {
  135. if (mFenceFd != -1) {
  136. // Don't unflatten if we already have a valid fd.
  137. return INVALID_OPERATION;
  138. }
  139. if (size < getFlattenedSize()) {
  140. return NO_MEMORY;
  141. }
  142. uint32_t numFds;
  143. FlattenableUtils::read(buffer, size, numFds);
  144. if (numFds > 1) {
  145. return BAD_VALUE;
  146. }
  147. if (count < numFds) {
  148. return NO_MEMORY;
  149. }
  150. if (numFds) {
  151. mFenceFd = *fds++;
  152. count--;
  153. }
  154. return NO_ERROR;
  155. }
  156. } // namespace android