BufferQueueCore.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. /*
  2. * Copyright 2014 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 "BufferQueueCore"
  17. #define ATRACE_TAG ATRACE_TAG_GRAPHICS
  18. //#define LOG_NDEBUG 0
  19. #define EGL_EGLEXT_PROTOTYPES
  20. #if DEBUG_ONLY_CODE
  21. #define VALIDATE_CONSISTENCY() do { validateConsistencyLocked(); } while (0)
  22. #else
  23. #define VALIDATE_CONSISTENCY()
  24. #endif
  25. #include <inttypes.h>
  26. #include <cutils/properties.h>
  27. #include <cutils/atomic.h>
  28. #include <gui/BufferItem.h>
  29. #include <gui/BufferQueueCore.h>
  30. #include <gui/IConsumerListener.h>
  31. #include <gui/IProducerListener.h>
  32. #include <gui/ISurfaceComposer.h>
  33. #include <private/gui/ComposerService.h>
  34. #include <system/window.h>
  35. namespace android {
  36. static String8 getUniqueName() {
  37. static volatile int32_t counter = 0;
  38. return String8::format("unnamed-%d-%d", getpid(),
  39. android_atomic_inc(&counter));
  40. }
  41. static uint64_t getUniqueId() {
  42. static std::atomic<uint32_t> counter{0};
  43. static uint64_t id = static_cast<uint64_t>(getpid()) << 32;
  44. return id | counter++;
  45. }
  46. BufferQueueCore::BufferQueueCore() :
  47. mMutex(),
  48. mIsAbandoned(false),
  49. mConsumerControlledByApp(false),
  50. mConsumerName(getUniqueName()),
  51. mConsumerListener(),
  52. mConsumerUsageBits(0),
  53. mConsumerIsProtected(false),
  54. mConnectedApi(NO_CONNECTED_API),
  55. mLinkedToDeath(),
  56. mConnectedProducerListener(),
  57. mBufferReleasedCbEnabled(false),
  58. mSlots(),
  59. mQueue(),
  60. mFreeSlots(),
  61. mFreeBuffers(),
  62. mUnusedSlots(),
  63. mActiveBuffers(),
  64. mDequeueCondition(),
  65. mDequeueBufferCannotBlock(false),
  66. mQueueBufferCanDrop(false),
  67. mLegacyBufferDrop(true),
  68. mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
  69. mDefaultWidth(1),
  70. mDefaultHeight(1),
  71. mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),
  72. mMaxBufferCount(BufferQueueDefs::NUM_BUFFER_SLOTS),
  73. mMaxAcquiredBufferCount(1),
  74. mMaxDequeuedBufferCount(1),
  75. mBufferHasBeenQueued(false),
  76. mFrameCounter(0),
  77. mTransformHint(0),
  78. mIsAllocating(false),
  79. mIsAllocatingCondition(),
  80. mAllowAllocation(true),
  81. mBufferAge(0),
  82. mGenerationNumber(0),
  83. mAsyncMode(false),
  84. mSharedBufferMode(false),
  85. mAutoRefresh(false),
  86. mSharedBufferSlot(INVALID_BUFFER_SLOT),
  87. mSharedBufferCache(Rect::INVALID_RECT, 0, NATIVE_WINDOW_SCALING_MODE_FREEZE,
  88. HAL_DATASPACE_UNKNOWN),
  89. mLastQueuedSlot(INVALID_BUFFER_SLOT),
  90. mUniqueId(getUniqueId())
  91. {
  92. int numStartingBuffers = getMaxBufferCountLocked();
  93. for (int s = 0; s < numStartingBuffers; s++) {
  94. mFreeSlots.insert(s);
  95. }
  96. for (int s = numStartingBuffers; s < BufferQueueDefs::NUM_BUFFER_SLOTS;
  97. s++) {
  98. mUnusedSlots.push_front(s);
  99. }
  100. }
  101. BufferQueueCore::~BufferQueueCore() {}
  102. void BufferQueueCore::dumpState(const String8& prefix, String8* outResult) const {
  103. std::lock_guard<std::mutex> lock(mMutex);
  104. outResult->appendFormat("%s- BufferQueue ", prefix.string());
  105. outResult->appendFormat("mMaxAcquiredBufferCount=%d mMaxDequeuedBufferCount=%d\n",
  106. mMaxAcquiredBufferCount, mMaxDequeuedBufferCount);
  107. outResult->appendFormat("%s mDequeueBufferCannotBlock=%d mAsyncMode=%d\n", prefix.string(),
  108. mDequeueBufferCannotBlock, mAsyncMode);
  109. outResult->appendFormat("%s mQueueBufferCanDrop=%d mLegacyBufferDrop=%d\n", prefix.string(),
  110. mQueueBufferCanDrop, mLegacyBufferDrop);
  111. outResult->appendFormat("%s default-size=[%dx%d] default-format=%d ", prefix.string(),
  112. mDefaultWidth, mDefaultHeight, mDefaultBufferFormat);
  113. outResult->appendFormat("transform-hint=%02x frame-counter=%" PRIu64, mTransformHint,
  114. mFrameCounter);
  115. outResult->appendFormat("\n%sFIFO(%zu):\n", prefix.string(), mQueue.size());
  116. Fifo::const_iterator current(mQueue.begin());
  117. while (current != mQueue.end()) {
  118. double timestamp = current->mTimestamp / 1e9;
  119. outResult->appendFormat("%s %02d:%p ", prefix.string(), current->mSlot,
  120. current->mGraphicBuffer.get());
  121. outResult->appendFormat("crop=[%d,%d,%d,%d] ", current->mCrop.left, current->mCrop.top,
  122. current->mCrop.right, current->mCrop.bottom);
  123. outResult->appendFormat("xform=0x%02x time=%.4f scale=%s\n", current->mTransform, timestamp,
  124. BufferItem::scalingModeName(current->mScalingMode));
  125. ++current;
  126. }
  127. outResult->appendFormat("%sSlots:\n", prefix.string());
  128. for (int s : mActiveBuffers) {
  129. const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
  130. // A dequeued buffer might be null if it's still being allocated
  131. if (buffer.get()) {
  132. outResult->appendFormat("%s %s[%02d:%p] ", prefix.string(),
  133. (mSlots[s].mBufferState.isAcquired()) ? ">" : " ", s,
  134. buffer.get());
  135. outResult->appendFormat("state=%-8s %p frame=%" PRIu64, mSlots[s].mBufferState.string(),
  136. buffer->handle, mSlots[s].mFrameNumber);
  137. outResult->appendFormat(" [%4ux%4u:%4u,%3X]\n", buffer->width, buffer->height,
  138. buffer->stride, buffer->format);
  139. } else {
  140. outResult->appendFormat("%s [%02d:%p] ", prefix.string(), s, buffer.get());
  141. outResult->appendFormat("state=%-8s frame=%" PRIu64 "\n",
  142. mSlots[s].mBufferState.string(), mSlots[s].mFrameNumber);
  143. }
  144. }
  145. for (int s : mFreeBuffers) {
  146. const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
  147. outResult->appendFormat("%s [%02d:%p] ", prefix.string(), s, buffer.get());
  148. outResult->appendFormat("state=%-8s %p frame=%" PRIu64, mSlots[s].mBufferState.string(),
  149. buffer->handle, mSlots[s].mFrameNumber);
  150. outResult->appendFormat(" [%4ux%4u:%4u,%3X]\n", buffer->width, buffer->height,
  151. buffer->stride, buffer->format);
  152. }
  153. for (int s : mFreeSlots) {
  154. const sp<GraphicBuffer>& buffer(mSlots[s].mGraphicBuffer);
  155. outResult->appendFormat("%s [%02d:%p] state=%-8s\n", prefix.string(), s, buffer.get(),
  156. mSlots[s].mBufferState.string());
  157. }
  158. }
  159. int BufferQueueCore::getMinUndequeuedBufferCountLocked() const {
  160. // If dequeueBuffer is allowed to error out, we don't have to add an
  161. // extra buffer.
  162. if (mAsyncMode || mDequeueBufferCannotBlock) {
  163. return mMaxAcquiredBufferCount + 1;
  164. }
  165. return mMaxAcquiredBufferCount;
  166. }
  167. int BufferQueueCore::getMinMaxBufferCountLocked() const {
  168. return getMinUndequeuedBufferCountLocked() + 1;
  169. }
  170. int BufferQueueCore::getMaxBufferCountLocked(bool asyncMode,
  171. bool dequeueBufferCannotBlock, int maxBufferCount) const {
  172. int maxCount = mMaxAcquiredBufferCount + mMaxDequeuedBufferCount +
  173. ((asyncMode || dequeueBufferCannotBlock) ? 1 : 0);
  174. maxCount = std::min(maxBufferCount, maxCount);
  175. return maxCount;
  176. }
  177. int BufferQueueCore::getMaxBufferCountLocked() const {
  178. int maxBufferCount = mMaxAcquiredBufferCount + mMaxDequeuedBufferCount +
  179. ((mAsyncMode || mDequeueBufferCannotBlock) ? 1 : 0);
  180. // limit maxBufferCount by mMaxBufferCount always
  181. maxBufferCount = std::min(mMaxBufferCount, maxBufferCount);
  182. return maxBufferCount;
  183. }
  184. void BufferQueueCore::clearBufferSlotLocked(int slot) {
  185. BQ_LOGV("clearBufferSlotLocked: slot %d", slot);
  186. mSlots[slot].mGraphicBuffer.clear();
  187. mSlots[slot].mBufferState.reset();
  188. mSlots[slot].mRequestBufferCalled = false;
  189. mSlots[slot].mFrameNumber = 0;
  190. mSlots[slot].mAcquireCalled = false;
  191. mSlots[slot].mNeedsReallocation = true;
  192. // Destroy fence as BufferQueue now takes ownership
  193. if (mSlots[slot].mEglFence != EGL_NO_SYNC_KHR) {
  194. eglDestroySyncKHR(mSlots[slot].mEglDisplay, mSlots[slot].mEglFence);
  195. mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
  196. }
  197. mSlots[slot].mFence = Fence::NO_FENCE;
  198. mSlots[slot].mEglDisplay = EGL_NO_DISPLAY;
  199. if (mLastQueuedSlot == slot) {
  200. mLastQueuedSlot = INVALID_BUFFER_SLOT;
  201. }
  202. }
  203. void BufferQueueCore::freeAllBuffersLocked() {
  204. for (int s : mFreeSlots) {
  205. clearBufferSlotLocked(s);
  206. }
  207. for (int s : mFreeBuffers) {
  208. mFreeSlots.insert(s);
  209. clearBufferSlotLocked(s);
  210. }
  211. mFreeBuffers.clear();
  212. for (int s : mActiveBuffers) {
  213. mFreeSlots.insert(s);
  214. clearBufferSlotLocked(s);
  215. }
  216. mActiveBuffers.clear();
  217. for (auto& b : mQueue) {
  218. b.mIsStale = true;
  219. // We set this to false to force the BufferQueue to resend the buffer
  220. // handle upon acquire, since if we're here due to a producer
  221. // disconnect, the consumer will have been told to purge its cache of
  222. // slot-to-buffer-handle mappings and will not be able to otherwise
  223. // obtain a valid buffer handle.
  224. b.mAcquireCalled = false;
  225. }
  226. VALIDATE_CONSISTENCY();
  227. }
  228. void BufferQueueCore::discardFreeBuffersLocked() {
  229. // Notify producer about the discarded buffers.
  230. if (mConnectedProducerListener != nullptr && mFreeBuffers.size() > 0) {
  231. std::vector<int32_t> freeBuffers(mFreeBuffers.begin(), mFreeBuffers.end());
  232. mConnectedProducerListener->onBuffersDiscarded(freeBuffers);
  233. }
  234. for (int s : mFreeBuffers) {
  235. mFreeSlots.insert(s);
  236. clearBufferSlotLocked(s);
  237. }
  238. mFreeBuffers.clear();
  239. VALIDATE_CONSISTENCY();
  240. }
  241. bool BufferQueueCore::adjustAvailableSlotsLocked(int delta) {
  242. if (delta >= 0) {
  243. // If we're going to fail, do so before modifying anything
  244. if (delta > static_cast<int>(mUnusedSlots.size())) {
  245. return false;
  246. }
  247. while (delta > 0) {
  248. if (mUnusedSlots.empty()) {
  249. return false;
  250. }
  251. int slot = mUnusedSlots.back();
  252. mUnusedSlots.pop_back();
  253. mFreeSlots.insert(slot);
  254. delta--;
  255. }
  256. } else {
  257. // If we're going to fail, do so before modifying anything
  258. if (-delta > static_cast<int>(mFreeSlots.size() +
  259. mFreeBuffers.size())) {
  260. return false;
  261. }
  262. while (delta < 0) {
  263. if (!mFreeSlots.empty()) {
  264. auto slot = mFreeSlots.begin();
  265. clearBufferSlotLocked(*slot);
  266. mUnusedSlots.push_back(*slot);
  267. mFreeSlots.erase(slot);
  268. } else if (!mFreeBuffers.empty()) {
  269. int slot = mFreeBuffers.back();
  270. clearBufferSlotLocked(slot);
  271. mUnusedSlots.push_back(slot);
  272. mFreeBuffers.pop_back();
  273. } else {
  274. return false;
  275. }
  276. delta++;
  277. }
  278. }
  279. return true;
  280. }
  281. void BufferQueueCore::waitWhileAllocatingLocked(std::unique_lock<std::mutex>& lock) const {
  282. ATRACE_CALL();
  283. while (mIsAllocating) {
  284. mIsAllocatingCondition.wait(lock);
  285. }
  286. }
  287. #if DEBUG_ONLY_CODE
  288. void BufferQueueCore::validateConsistencyLocked() const {
  289. static const useconds_t PAUSE_TIME = 0;
  290. int allocatedSlots = 0;
  291. for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
  292. bool isInFreeSlots = mFreeSlots.count(slot) != 0;
  293. bool isInFreeBuffers =
  294. std::find(mFreeBuffers.cbegin(), mFreeBuffers.cend(), slot) !=
  295. mFreeBuffers.cend();
  296. bool isInActiveBuffers = mActiveBuffers.count(slot) != 0;
  297. bool isInUnusedSlots =
  298. std::find(mUnusedSlots.cbegin(), mUnusedSlots.cend(), slot) !=
  299. mUnusedSlots.cend();
  300. if (isInFreeSlots || isInFreeBuffers || isInActiveBuffers) {
  301. allocatedSlots++;
  302. }
  303. if (isInUnusedSlots) {
  304. if (isInFreeSlots) {
  305. BQ_LOGE("Slot %d is in mUnusedSlots and in mFreeSlots", slot);
  306. usleep(PAUSE_TIME);
  307. }
  308. if (isInFreeBuffers) {
  309. BQ_LOGE("Slot %d is in mUnusedSlots and in mFreeBuffers", slot);
  310. usleep(PAUSE_TIME);
  311. }
  312. if (isInActiveBuffers) {
  313. BQ_LOGE("Slot %d is in mUnusedSlots and in mActiveBuffers",
  314. slot);
  315. usleep(PAUSE_TIME);
  316. }
  317. if (!mSlots[slot].mBufferState.isFree()) {
  318. BQ_LOGE("Slot %d is in mUnusedSlots but is not FREE", slot);
  319. usleep(PAUSE_TIME);
  320. }
  321. if (mSlots[slot].mGraphicBuffer != nullptr) {
  322. BQ_LOGE("Slot %d is in mUnusedSluts but has an active buffer",
  323. slot);
  324. usleep(PAUSE_TIME);
  325. }
  326. } else if (isInFreeSlots) {
  327. if (isInUnusedSlots) {
  328. BQ_LOGE("Slot %d is in mFreeSlots and in mUnusedSlots", slot);
  329. usleep(PAUSE_TIME);
  330. }
  331. if (isInFreeBuffers) {
  332. BQ_LOGE("Slot %d is in mFreeSlots and in mFreeBuffers", slot);
  333. usleep(PAUSE_TIME);
  334. }
  335. if (isInActiveBuffers) {
  336. BQ_LOGE("Slot %d is in mFreeSlots and in mActiveBuffers", slot);
  337. usleep(PAUSE_TIME);
  338. }
  339. if (!mSlots[slot].mBufferState.isFree()) {
  340. BQ_LOGE("Slot %d is in mFreeSlots but is not FREE", slot);
  341. usleep(PAUSE_TIME);
  342. }
  343. if (mSlots[slot].mGraphicBuffer != nullptr) {
  344. BQ_LOGE("Slot %d is in mFreeSlots but has a buffer",
  345. slot);
  346. usleep(PAUSE_TIME);
  347. }
  348. } else if (isInFreeBuffers) {
  349. if (isInUnusedSlots) {
  350. BQ_LOGE("Slot %d is in mFreeBuffers and in mUnusedSlots", slot);
  351. usleep(PAUSE_TIME);
  352. }
  353. if (isInFreeSlots) {
  354. BQ_LOGE("Slot %d is in mFreeBuffers and in mFreeSlots", slot);
  355. usleep(PAUSE_TIME);
  356. }
  357. if (isInActiveBuffers) {
  358. BQ_LOGE("Slot %d is in mFreeBuffers and in mActiveBuffers",
  359. slot);
  360. usleep(PAUSE_TIME);
  361. }
  362. if (!mSlots[slot].mBufferState.isFree()) {
  363. BQ_LOGE("Slot %d is in mFreeBuffers but is not FREE", slot);
  364. usleep(PAUSE_TIME);
  365. }
  366. if (mSlots[slot].mGraphicBuffer == nullptr) {
  367. BQ_LOGE("Slot %d is in mFreeBuffers but has no buffer", slot);
  368. usleep(PAUSE_TIME);
  369. }
  370. } else if (isInActiveBuffers) {
  371. if (isInUnusedSlots) {
  372. BQ_LOGE("Slot %d is in mActiveBuffers and in mUnusedSlots",
  373. slot);
  374. usleep(PAUSE_TIME);
  375. }
  376. if (isInFreeSlots) {
  377. BQ_LOGE("Slot %d is in mActiveBuffers and in mFreeSlots", slot);
  378. usleep(PAUSE_TIME);
  379. }
  380. if (isInFreeBuffers) {
  381. BQ_LOGE("Slot %d is in mActiveBuffers and in mFreeBuffers",
  382. slot);
  383. usleep(PAUSE_TIME);
  384. }
  385. if (mSlots[slot].mBufferState.isFree() &&
  386. !mSlots[slot].mBufferState.isShared()) {
  387. BQ_LOGE("Slot %d is in mActiveBuffers but is FREE", slot);
  388. usleep(PAUSE_TIME);
  389. }
  390. if (mSlots[slot].mGraphicBuffer == nullptr && !mIsAllocating) {
  391. BQ_LOGE("Slot %d is in mActiveBuffers but has no buffer", slot);
  392. usleep(PAUSE_TIME);
  393. }
  394. } else {
  395. BQ_LOGE("Slot %d isn't in any of mUnusedSlots, mFreeSlots, "
  396. "mFreeBuffers, or mActiveBuffers", slot);
  397. usleep(PAUSE_TIME);
  398. }
  399. }
  400. if (allocatedSlots != getMaxBufferCountLocked()) {
  401. BQ_LOGE("Number of allocated slots is incorrect. Allocated = %d, "
  402. "Should be %d (%zu free slots, %zu free buffers, "
  403. "%zu activeBuffers, %zu unusedSlots)", allocatedSlots,
  404. getMaxBufferCountLocked(), mFreeSlots.size(),
  405. mFreeBuffers.size(), mActiveBuffers.size(),
  406. mUnusedSlots.size());
  407. }
  408. }
  409. #endif
  410. } // namespace android