ConsumerBase.cpp 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /*
  2. * Copyright (C) 2010 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. #include <inttypes.h>
  17. #define LOG_TAG "ConsumerBase"
  18. #define ATRACE_TAG ATRACE_TAG_GRAPHICS
  19. //#define LOG_NDEBUG 0
  20. #define EGL_EGLEXT_PROTOTYPES
  21. #include <EGL/egl.h>
  22. #include <EGL/eglext.h>
  23. #include <hardware/hardware.h>
  24. #include <gui/BufferItem.h>
  25. #include <gui/IGraphicBufferAlloc.h>
  26. #include <gui/ISurfaceComposer.h>
  27. #include <gui/SurfaceComposerClient.h>
  28. #include <gui/ConsumerBase.h>
  29. #include <private/gui/ComposerService.h>
  30. #include <utils/Log.h>
  31. #include <utils/String8.h>
  32. #include <utils/Trace.h>
  33. // Macros for including the ConsumerBase name in log messages
  34. #define CB_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
  35. //#define CB_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
  36. //#define CB_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
  37. //#define CB_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
  38. #define CB_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
  39. namespace android {
  40. // Get an ID that's unique within this process.
  41. static int32_t createProcessUniqueId() {
  42. static volatile int32_t globalCounter = 0;
  43. return android_atomic_inc(&globalCounter);
  44. }
  45. ConsumerBase::ConsumerBase(const sp<IGraphicBufferConsumer>& bufferQueue, bool controlledByApp) :
  46. mAbandoned(false),
  47. mConsumer(bufferQueue) {
  48. // Choose a name using the PID and a process-unique ID.
  49. mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
  50. // Note that we can't create an sp<...>(this) in a ctor that will not keep a
  51. // reference once the ctor ends, as that would cause the refcount of 'this'
  52. // dropping to 0 at the end of the ctor. Since all we need is a wp<...>
  53. // that's what we create.
  54. wp<ConsumerListener> listener = static_cast<ConsumerListener*>(this);
  55. sp<IConsumerListener> proxy = new BufferQueue::ProxyConsumerListener(listener);
  56. status_t err = mConsumer->consumerConnect(proxy, controlledByApp);
  57. if (err != NO_ERROR) {
  58. CB_LOGE("ConsumerBase: error connecting to BufferQueue: %s (%d)",
  59. strerror(-err), err);
  60. } else {
  61. mConsumer->setConsumerName(mName);
  62. }
  63. }
  64. ConsumerBase::~ConsumerBase() {
  65. CB_LOGV("~ConsumerBase");
  66. Mutex::Autolock lock(mMutex);
  67. // Verify that abandon() has been called before we get here. This should
  68. // be done by ConsumerBase::onLastStrongRef(), but it's possible for a
  69. // derived class to override that method and not call
  70. // ConsumerBase::onLastStrongRef().
  71. LOG_ALWAYS_FATAL_IF(!mAbandoned, "[%s] ~ConsumerBase was called, but the "
  72. "consumer is not abandoned!", mName.string());
  73. }
  74. void ConsumerBase::onLastStrongRef(const void* id __attribute__((unused))) {
  75. abandon();
  76. }
  77. void ConsumerBase::freeBufferLocked(int slotIndex) {
  78. CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
  79. mSlots[slotIndex].mGraphicBuffer = 0;
  80. mSlots[slotIndex].mFence = Fence::NO_FENCE;
  81. mSlots[slotIndex].mFrameNumber = 0;
  82. }
  83. void ConsumerBase::onFrameAvailable(const BufferItem& item) {
  84. CB_LOGV("onFrameAvailable");
  85. sp<FrameAvailableListener> listener;
  86. { // scope for the lock
  87. Mutex::Autolock lock(mMutex);
  88. listener = mFrameAvailableListener.promote();
  89. }
  90. if (listener != NULL) {
  91. CB_LOGV("actually calling onFrameAvailable");
  92. listener->onFrameAvailable(item);
  93. }
  94. }
  95. void ConsumerBase::onFrameReplaced(const BufferItem &item) {
  96. CB_LOGV("onFrameReplaced");
  97. sp<FrameAvailableListener> listener;
  98. {
  99. Mutex::Autolock lock(mMutex);
  100. listener = mFrameAvailableListener.promote();
  101. }
  102. if (listener != NULL) {
  103. CB_LOGV("actually calling onFrameReplaced");
  104. listener->onFrameReplaced(item);
  105. }
  106. }
  107. void ConsumerBase::onBuffersReleased() {
  108. Mutex::Autolock lock(mMutex);
  109. CB_LOGV("onBuffersReleased");
  110. if (mAbandoned) {
  111. // Nothing to do if we're already abandoned.
  112. return;
  113. }
  114. uint64_t mask = 0;
  115. mConsumer->getReleasedBuffers(&mask);
  116. for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
  117. if (mask & (1ULL << i)) {
  118. freeBufferLocked(i);
  119. }
  120. }
  121. }
  122. void ConsumerBase::onSidebandStreamChanged() {
  123. }
  124. void ConsumerBase::abandon() {
  125. CB_LOGV("abandon");
  126. Mutex::Autolock lock(mMutex);
  127. if (!mAbandoned) {
  128. abandonLocked();
  129. mAbandoned = true;
  130. }
  131. }
  132. void ConsumerBase::abandonLocked() {
  133. CB_LOGV("abandonLocked");
  134. for (int i =0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) {
  135. freeBufferLocked(i);
  136. }
  137. // disconnect from the BufferQueue
  138. mConsumer->consumerDisconnect();
  139. mConsumer.clear();
  140. }
  141. bool ConsumerBase::isAbandoned() {
  142. Mutex::Autolock _l(mMutex);
  143. return mAbandoned;
  144. }
  145. void ConsumerBase::setFrameAvailableListener(
  146. const wp<FrameAvailableListener>& listener) {
  147. CB_LOGV("setFrameAvailableListener");
  148. Mutex::Autolock lock(mMutex);
  149. mFrameAvailableListener = listener;
  150. }
  151. status_t ConsumerBase::detachBuffer(int slot) {
  152. CB_LOGV("detachBuffer");
  153. Mutex::Autolock lock(mMutex);
  154. status_t result = mConsumer->detachBuffer(slot);
  155. if (result != NO_ERROR) {
  156. CB_LOGE("Failed to detach buffer: %d", result);
  157. return result;
  158. }
  159. freeBufferLocked(slot);
  160. return result;
  161. }
  162. status_t ConsumerBase::setDefaultBufferSize(uint32_t width, uint32_t height) {
  163. Mutex::Autolock _l(mMutex);
  164. return mConsumer->setDefaultBufferSize(width, height);
  165. }
  166. status_t ConsumerBase::setDefaultBufferFormat(PixelFormat defaultFormat) {
  167. Mutex::Autolock _l(mMutex);
  168. return mConsumer->setDefaultBufferFormat(defaultFormat);
  169. }
  170. status_t ConsumerBase::setDefaultBufferDataSpace(
  171. android_dataspace defaultDataSpace) {
  172. Mutex::Autolock _l(mMutex);
  173. return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
  174. }
  175. void ConsumerBase::dump(String8& result) const {
  176. dump(result, "");
  177. }
  178. void ConsumerBase::dump(String8& result, const char* prefix) const {
  179. Mutex::Autolock _l(mMutex);
  180. dumpLocked(result, prefix);
  181. }
  182. void ConsumerBase::dumpLocked(String8& result, const char* prefix) const {
  183. result.appendFormat("%smAbandoned=%d\n", prefix, int(mAbandoned));
  184. if (!mAbandoned) {
  185. mConsumer->dump(result, prefix);
  186. }
  187. }
  188. status_t ConsumerBase::acquireBufferLocked(BufferItem *item,
  189. nsecs_t presentWhen, uint64_t maxFrameNumber) {
  190. status_t err = mConsumer->acquireBuffer(item, presentWhen, maxFrameNumber);
  191. if (err != NO_ERROR) {
  192. return err;
  193. }
  194. if (item->mGraphicBuffer != NULL) {
  195. mSlots[item->mBuf].mGraphicBuffer = item->mGraphicBuffer;
  196. }
  197. mSlots[item->mBuf].mFrameNumber = item->mFrameNumber;
  198. mSlots[item->mBuf].mFence = item->mFence;
  199. CB_LOGV("acquireBufferLocked: -> slot=%d/%" PRIu64,
  200. item->mBuf, item->mFrameNumber);
  201. return OK;
  202. }
  203. status_t ConsumerBase::addReleaseFence(int slot,
  204. const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence) {
  205. Mutex::Autolock lock(mMutex);
  206. return addReleaseFenceLocked(slot, graphicBuffer, fence);
  207. }
  208. status_t ConsumerBase::addReleaseFenceLocked(int slot,
  209. const sp<GraphicBuffer> graphicBuffer, const sp<Fence>& fence) {
  210. CB_LOGV("addReleaseFenceLocked: slot=%d", slot);
  211. // If consumer no longer tracks this graphicBuffer, we can safely
  212. // drop this fence, as it will never be received by the producer.
  213. if (!stillTracking(slot, graphicBuffer)) {
  214. return OK;
  215. }
  216. if (!mSlots[slot].mFence.get()) {
  217. mSlots[slot].mFence = fence;
  218. } else {
  219. sp<Fence> mergedFence = Fence::merge(
  220. String8::format("%.28s:%d", mName.string(), slot),
  221. mSlots[slot].mFence, fence);
  222. if (!mergedFence.get()) {
  223. CB_LOGE("failed to merge release fences");
  224. // synchronization is broken, the best we can do is hope fences
  225. // signal in order so the new fence will act like a union
  226. mSlots[slot].mFence = fence;
  227. return BAD_VALUE;
  228. }
  229. mSlots[slot].mFence = mergedFence;
  230. }
  231. return OK;
  232. }
  233. status_t ConsumerBase::releaseBufferLocked(
  234. int slot, const sp<GraphicBuffer> graphicBuffer,
  235. EGLDisplay display, EGLSyncKHR eglFence) {
  236. // If consumer no longer tracks this graphicBuffer (we received a new
  237. // buffer on the same slot), the buffer producer is definitely no longer
  238. // tracking it.
  239. if (!stillTracking(slot, graphicBuffer)) {
  240. return OK;
  241. }
  242. CB_LOGV("releaseBufferLocked: slot=%d/%" PRIu64,
  243. slot, mSlots[slot].mFrameNumber);
  244. status_t err = mConsumer->releaseBuffer(slot, mSlots[slot].mFrameNumber,
  245. display, eglFence, mSlots[slot].mFence);
  246. if (err == IGraphicBufferConsumer::STALE_BUFFER_SLOT) {
  247. freeBufferLocked(slot);
  248. }
  249. mSlots[slot].mFence = Fence::NO_FENCE;
  250. return err;
  251. }
  252. bool ConsumerBase::stillTracking(int slot,
  253. const sp<GraphicBuffer> graphicBuffer) {
  254. if (slot < 0 || slot >= BufferQueue::NUM_BUFFER_SLOTS) {
  255. return false;
  256. }
  257. return (mSlots[slot].mGraphicBuffer != NULL &&
  258. mSlots[slot].mGraphicBuffer->handle == graphicBuffer->handle);
  259. }
  260. } // namespace android