BufferQueueConsumer.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  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. #include <inttypes.h>
  17. #define LOG_TAG "BufferQueueConsumer"
  18. #define ATRACE_TAG ATRACE_TAG_GRAPHICS
  19. //#define LOG_NDEBUG 0
  20. #include <gui/BufferItem.h>
  21. #include <gui/BufferQueueConsumer.h>
  22. #include <gui/BufferQueueCore.h>
  23. #include <gui/IConsumerListener.h>
  24. #include <gui/IProducerListener.h>
  25. #include <binder/IPCThreadState.h>
  26. #include <binder/PermissionCache.h>
  27. #include <private/android_filesystem_config.h>
  28. namespace android {
  29. BufferQueueConsumer::BufferQueueConsumer(const sp<BufferQueueCore>& core) :
  30. mCore(core),
  31. mSlots(core->mSlots),
  32. mConsumerName() {}
  33. BufferQueueConsumer::~BufferQueueConsumer() {}
  34. status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
  35. nsecs_t expectedPresent, uint64_t maxFrameNumber) {
  36. ATRACE_CALL();
  37. int numDroppedBuffers = 0;
  38. sp<IProducerListener> listener;
  39. {
  40. Mutex::Autolock lock(mCore->mMutex);
  41. // Check that the consumer doesn't currently have the maximum number of
  42. // buffers acquired. We allow the max buffer count to be exceeded by one
  43. // buffer so that the consumer can successfully set up the newly acquired
  44. // buffer before releasing the old one.
  45. int numAcquiredBuffers = 0;
  46. for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
  47. if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
  48. ++numAcquiredBuffers;
  49. }
  50. }
  51. if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
  52. BQ_LOGE("acquireBuffer: max acquired buffer count reached: %d (max %d)",
  53. numAcquiredBuffers, mCore->mMaxAcquiredBufferCount);
  54. return INVALID_OPERATION;
  55. }
  56. // Check if the queue is empty.
  57. // In asynchronous mode the list is guaranteed to be one buffer deep,
  58. // while in synchronous mode we use the oldest buffer.
  59. if (mCore->mQueue.empty()) {
  60. return NO_BUFFER_AVAILABLE;
  61. }
  62. BufferQueueCore::Fifo::iterator front(mCore->mQueue.begin());
  63. // If expectedPresent is specified, we may not want to return a buffer yet.
  64. // If it's specified and there's more than one buffer queued, we may want
  65. // to drop a buffer.
  66. if (expectedPresent != 0) {
  67. const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second
  68. // The 'expectedPresent' argument indicates when the buffer is expected
  69. // to be presented on-screen. If the buffer's desired present time is
  70. // earlier (less) than expectedPresent -- meaning it will be displayed
  71. // on time or possibly late if we show it as soon as possible -- we
  72. // acquire and return it. If we don't want to display it until after the
  73. // expectedPresent time, we return PRESENT_LATER without acquiring it.
  74. //
  75. // To be safe, we don't defer acquisition if expectedPresent is more
  76. // than one second in the future beyond the desired present time
  77. // (i.e., we'd be holding the buffer for a long time).
  78. //
  79. // NOTE: Code assumes monotonic time values from the system clock
  80. // are positive.
  81. // Start by checking to see if we can drop frames. We skip this check if
  82. // the timestamps are being auto-generated by Surface. If the app isn't
  83. // generating timestamps explicitly, it probably doesn't want frames to
  84. // be discarded based on them.
  85. while (mCore->mQueue.size() > 1 && !mCore->mQueue[0].mIsAutoTimestamp) {
  86. const BufferItem& bufferItem(mCore->mQueue[1]);
  87. // If dropping entry[0] would leave us with a buffer that the
  88. // consumer is not yet ready for, don't drop it.
  89. if (maxFrameNumber && bufferItem.mFrameNumber > maxFrameNumber) {
  90. break;
  91. }
  92. // If entry[1] is timely, drop entry[0] (and repeat). We apply an
  93. // additional criterion here: we only drop the earlier buffer if our
  94. // desiredPresent falls within +/- 1 second of the expected present.
  95. // Otherwise, bogus desiredPresent times (e.g., 0 or a small
  96. // relative timestamp), which normally mean "ignore the timestamp
  97. // and acquire immediately", would cause us to drop frames.
  98. //
  99. // We may want to add an additional criterion: don't drop the
  100. // earlier buffer if entry[1]'s fence hasn't signaled yet.
  101. nsecs_t desiredPresent = bufferItem.mTimestamp;
  102. if (desiredPresent < expectedPresent - MAX_REASONABLE_NSEC ||
  103. desiredPresent > expectedPresent) {
  104. // This buffer is set to display in the near future, or
  105. // desiredPresent is garbage. Either way we don't want to drop
  106. // the previous buffer just to get this on the screen sooner.
  107. BQ_LOGV("acquireBuffer: nodrop desire=%" PRId64 " expect=%"
  108. PRId64 " (%" PRId64 ") now=%" PRId64,
  109. desiredPresent, expectedPresent,
  110. desiredPresent - expectedPresent,
  111. systemTime(CLOCK_MONOTONIC));
  112. break;
  113. }
  114. BQ_LOGV("acquireBuffer: drop desire=%" PRId64 " expect=%" PRId64
  115. " size=%zu",
  116. desiredPresent, expectedPresent, mCore->mQueue.size());
  117. if (mCore->stillTracking(front)) {
  118. // Front buffer is still in mSlots, so mark the slot as free
  119. mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
  120. mCore->mFreeBuffers.push_back(front->mSlot);
  121. listener = mCore->mConnectedProducerListener;
  122. ++numDroppedBuffers;
  123. }
  124. mCore->mQueue.erase(front);
  125. front = mCore->mQueue.begin();
  126. }
  127. // See if the front buffer is ready to be acquired
  128. nsecs_t desiredPresent = front->mTimestamp;
  129. bool bufferIsDue = desiredPresent <= expectedPresent ||
  130. desiredPresent > expectedPresent + MAX_REASONABLE_NSEC;
  131. bool consumerIsReady = maxFrameNumber > 0 ?
  132. front->mFrameNumber <= maxFrameNumber : true;
  133. if (!bufferIsDue || !consumerIsReady) {
  134. BQ_LOGV("acquireBuffer: defer desire=%" PRId64 " expect=%" PRId64
  135. " (%" PRId64 ") now=%" PRId64 " frame=%" PRIu64
  136. " consumer=%" PRIu64,
  137. desiredPresent, expectedPresent,
  138. desiredPresent - expectedPresent,
  139. systemTime(CLOCK_MONOTONIC),
  140. front->mFrameNumber, maxFrameNumber);
  141. return PRESENT_LATER;
  142. }
  143. BQ_LOGV("acquireBuffer: accept desire=%" PRId64 " expect=%" PRId64 " "
  144. "(%" PRId64 ") now=%" PRId64, desiredPresent, expectedPresent,
  145. desiredPresent - expectedPresent,
  146. systemTime(CLOCK_MONOTONIC));
  147. }
  148. int slot = front->mSlot;
  149. *outBuffer = *front;
  150. ATRACE_BUFFER_INDEX(slot);
  151. BQ_LOGV("acquireBuffer: acquiring { slot=%d/%" PRIu64 " buffer=%p }",
  152. slot, front->mFrameNumber, front->mGraphicBuffer->handle);
  153. // If the front buffer is still being tracked, update its slot state
  154. if (mCore->stillTracking(front)) {
  155. mSlots[slot].mAcquireCalled = true;
  156. mSlots[slot].mNeedsCleanupOnRelease = false;
  157. mSlots[slot].mBufferState = BufferSlot::ACQUIRED;
  158. mSlots[slot].mFence = Fence::NO_FENCE;
  159. }
  160. // If the buffer has previously been acquired by the consumer, set
  161. // mGraphicBuffer to NULL to avoid unnecessarily remapping this buffer
  162. // on the consumer side
  163. if (outBuffer->mAcquireCalled) {
  164. outBuffer->mGraphicBuffer = NULL;
  165. }
  166. mCore->mQueue.erase(front);
  167. // We might have freed a slot while dropping old buffers, or the producer
  168. // may be blocked waiting for the number of buffers in the queue to
  169. // decrease.
  170. mCore->mDequeueCondition.broadcast();
  171. ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
  172. mCore->validateConsistencyLocked();
  173. }
  174. if (listener != NULL) {
  175. for (int i = 0; i < numDroppedBuffers; ++i) {
  176. listener->onBufferReleased();
  177. }
  178. }
  179. return NO_ERROR;
  180. }
  181. status_t BufferQueueConsumer::detachBuffer(int slot) {
  182. ATRACE_CALL();
  183. ATRACE_BUFFER_INDEX(slot);
  184. BQ_LOGV("detachBuffer(C): slot %d", slot);
  185. Mutex::Autolock lock(mCore->mMutex);
  186. if (mCore->mIsAbandoned) {
  187. BQ_LOGE("detachBuffer(C): BufferQueue has been abandoned");
  188. return NO_INIT;
  189. }
  190. if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
  191. BQ_LOGE("detachBuffer(C): slot index %d out of range [0, %d)",
  192. slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
  193. return BAD_VALUE;
  194. } else if (mSlots[slot].mBufferState != BufferSlot::ACQUIRED) {
  195. BQ_LOGE("detachBuffer(C): slot %d is not owned by the consumer "
  196. "(state = %d)", slot, mSlots[slot].mBufferState);
  197. return BAD_VALUE;
  198. }
  199. mCore->freeBufferLocked(slot);
  200. mCore->mDequeueCondition.broadcast();
  201. mCore->validateConsistencyLocked();
  202. return NO_ERROR;
  203. }
  204. status_t BufferQueueConsumer::attachBuffer(int* outSlot,
  205. const sp<android::GraphicBuffer>& buffer) {
  206. ATRACE_CALL();
  207. if (outSlot == NULL) {
  208. BQ_LOGE("attachBuffer(P): outSlot must not be NULL");
  209. return BAD_VALUE;
  210. } else if (buffer == NULL) {
  211. BQ_LOGE("attachBuffer(P): cannot attach NULL buffer");
  212. return BAD_VALUE;
  213. }
  214. Mutex::Autolock lock(mCore->mMutex);
  215. // Make sure we don't have too many acquired buffers
  216. int numAcquiredBuffers = 0;
  217. for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
  218. if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
  219. ++numAcquiredBuffers;
  220. }
  221. }
  222. if (numAcquiredBuffers >= mCore->mMaxAcquiredBufferCount + 1) {
  223. BQ_LOGE("attachBuffer(P): max acquired buffer count reached: %d "
  224. "(max %d)", numAcquiredBuffers,
  225. mCore->mMaxAcquiredBufferCount);
  226. return INVALID_OPERATION;
  227. }
  228. if (buffer->getGenerationNumber() != mCore->mGenerationNumber) {
  229. BQ_LOGE("attachBuffer: generation number mismatch [buffer %u] "
  230. "[queue %u]", buffer->getGenerationNumber(),
  231. mCore->mGenerationNumber);
  232. return BAD_VALUE;
  233. }
  234. // Find a free slot to put the buffer into
  235. int found = BufferQueueCore::INVALID_BUFFER_SLOT;
  236. if (!mCore->mFreeSlots.empty()) {
  237. auto slot = mCore->mFreeSlots.begin();
  238. found = *slot;
  239. mCore->mFreeSlots.erase(slot);
  240. } else if (!mCore->mFreeBuffers.empty()) {
  241. found = mCore->mFreeBuffers.front();
  242. mCore->mFreeBuffers.remove(found);
  243. }
  244. if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
  245. BQ_LOGE("attachBuffer(P): could not find free buffer slot");
  246. return NO_MEMORY;
  247. }
  248. *outSlot = found;
  249. ATRACE_BUFFER_INDEX(*outSlot);
  250. BQ_LOGV("attachBuffer(C): returning slot %d", *outSlot);
  251. mSlots[*outSlot].mGraphicBuffer = buffer;
  252. mSlots[*outSlot].mBufferState = BufferSlot::ACQUIRED;
  253. mSlots[*outSlot].mAttachedByConsumer = true;
  254. mSlots[*outSlot].mNeedsCleanupOnRelease = false;
  255. mSlots[*outSlot].mFence = Fence::NO_FENCE;
  256. mSlots[*outSlot].mFrameNumber = 0;
  257. // mAcquireCalled tells BufferQueue that it doesn't need to send a valid
  258. // GraphicBuffer pointer on the next acquireBuffer call, which decreases
  259. // Binder traffic by not un/flattening the GraphicBuffer. However, it
  260. // requires that the consumer maintain a cached copy of the slot <--> buffer
  261. // mappings, which is why the consumer doesn't need the valid pointer on
  262. // acquire.
  263. //
  264. // The StreamSplitter is one of the primary users of the attach/detach
  265. // logic, and while it is running, all buffers it acquires are immediately
  266. // detached, and all buffers it eventually releases are ones that were
  267. // attached (as opposed to having been obtained from acquireBuffer), so it
  268. // doesn't make sense to maintain the slot/buffer mappings, which would
  269. // become invalid for every buffer during detach/attach. By setting this to
  270. // false, the valid GraphicBuffer pointer will always be sent with acquire
  271. // for attached buffers.
  272. mSlots[*outSlot].mAcquireCalled = false;
  273. mCore->validateConsistencyLocked();
  274. return NO_ERROR;
  275. }
  276. status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
  277. const sp<Fence>& releaseFence, EGLDisplay eglDisplay,
  278. EGLSyncKHR eglFence) {
  279. ATRACE_CALL();
  280. ATRACE_BUFFER_INDEX(slot);
  281. if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS ||
  282. releaseFence == NULL) {
  283. BQ_LOGE("releaseBuffer: slot %d out of range or fence %p NULL", slot,
  284. releaseFence.get());
  285. return BAD_VALUE;
  286. }
  287. sp<IProducerListener> listener;
  288. { // Autolock scope
  289. Mutex::Autolock lock(mCore->mMutex);
  290. // If the frame number has changed because the buffer has been reallocated,
  291. // we can ignore this releaseBuffer for the old buffer
  292. if (frameNumber != mSlots[slot].mFrameNumber) {
  293. return STALE_BUFFER_SLOT;
  294. }
  295. // Make sure this buffer hasn't been queued while acquired by the consumer
  296. BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
  297. while (current != mCore->mQueue.end()) {
  298. if (current->mSlot == slot) {
  299. BQ_LOGE("releaseBuffer: buffer slot %d pending release is "
  300. "currently queued", slot);
  301. return BAD_VALUE;
  302. }
  303. ++current;
  304. }
  305. if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
  306. mSlots[slot].mEglDisplay = eglDisplay;
  307. mSlots[slot].mEglFence = eglFence;
  308. mSlots[slot].mFence = releaseFence;
  309. mSlots[slot].mBufferState = BufferSlot::FREE;
  310. mCore->mFreeBuffers.push_back(slot);
  311. listener = mCore->mConnectedProducerListener;
  312. BQ_LOGV("releaseBuffer: releasing slot %d", slot);
  313. } else if (mSlots[slot].mNeedsCleanupOnRelease) {
  314. BQ_LOGV("releaseBuffer: releasing a stale buffer slot %d "
  315. "(state = %d)", slot, mSlots[slot].mBufferState);
  316. mSlots[slot].mNeedsCleanupOnRelease = false;
  317. return STALE_BUFFER_SLOT;
  318. } else {
  319. BQ_LOGE("releaseBuffer: attempted to release buffer slot %d "
  320. "but its state was %d", slot, mSlots[slot].mBufferState);
  321. return BAD_VALUE;
  322. }
  323. mCore->mDequeueCondition.broadcast();
  324. mCore->validateConsistencyLocked();
  325. } // Autolock scope
  326. // Call back without lock held
  327. if (listener != NULL) {
  328. listener->onBufferReleased();
  329. }
  330. return NO_ERROR;
  331. }
  332. status_t BufferQueueConsumer::connect(
  333. const sp<IConsumerListener>& consumerListener, bool controlledByApp) {
  334. ATRACE_CALL();
  335. if (consumerListener == NULL) {
  336. BQ_LOGE("connect(C): consumerListener may not be NULL");
  337. return BAD_VALUE;
  338. }
  339. BQ_LOGV("connect(C): controlledByApp=%s",
  340. controlledByApp ? "true" : "false");
  341. Mutex::Autolock lock(mCore->mMutex);
  342. if (mCore->mIsAbandoned) {
  343. BQ_LOGE("connect(C): BufferQueue has been abandoned");
  344. return NO_INIT;
  345. }
  346. mCore->mConsumerListener = consumerListener;
  347. mCore->mConsumerControlledByApp = controlledByApp;
  348. return NO_ERROR;
  349. }
  350. status_t BufferQueueConsumer::disconnect() {
  351. ATRACE_CALL();
  352. BQ_LOGV("disconnect(C)");
  353. Mutex::Autolock lock(mCore->mMutex);
  354. if (mCore->mConsumerListener == NULL) {
  355. BQ_LOGE("disconnect(C): no consumer is connected");
  356. return BAD_VALUE;
  357. }
  358. mCore->mIsAbandoned = true;
  359. mCore->mConsumerListener = NULL;
  360. mCore->mQueue.clear();
  361. mCore->freeAllBuffersLocked();
  362. mCore->mDequeueCondition.broadcast();
  363. return NO_ERROR;
  364. }
  365. status_t BufferQueueConsumer::getReleasedBuffers(uint64_t *outSlotMask) {
  366. ATRACE_CALL();
  367. if (outSlotMask == NULL) {
  368. BQ_LOGE("getReleasedBuffers: outSlotMask may not be NULL");
  369. return BAD_VALUE;
  370. }
  371. Mutex::Autolock lock(mCore->mMutex);
  372. if (mCore->mIsAbandoned) {
  373. BQ_LOGE("getReleasedBuffers: BufferQueue has been abandoned");
  374. return NO_INIT;
  375. }
  376. uint64_t mask = 0;
  377. for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
  378. if (!mSlots[s].mAcquireCalled) {
  379. mask |= (1ULL << s);
  380. }
  381. }
  382. // Remove from the mask queued buffers for which acquire has been called,
  383. // since the consumer will not receive their buffer addresses and so must
  384. // retain their cached information
  385. BufferQueueCore::Fifo::iterator current(mCore->mQueue.begin());
  386. while (current != mCore->mQueue.end()) {
  387. if (current->mAcquireCalled) {
  388. mask &= ~(1ULL << current->mSlot);
  389. }
  390. ++current;
  391. }
  392. BQ_LOGV("getReleasedBuffers: returning mask %#" PRIx64, mask);
  393. *outSlotMask = mask;
  394. return NO_ERROR;
  395. }
  396. status_t BufferQueueConsumer::setDefaultBufferSize(uint32_t width,
  397. uint32_t height) {
  398. ATRACE_CALL();
  399. if (width == 0 || height == 0) {
  400. BQ_LOGV("setDefaultBufferSize: dimensions cannot be 0 (width=%u "
  401. "height=%u)", width, height);
  402. return BAD_VALUE;
  403. }
  404. BQ_LOGV("setDefaultBufferSize: width=%u height=%u", width, height);
  405. Mutex::Autolock lock(mCore->mMutex);
  406. mCore->mDefaultWidth = width;
  407. mCore->mDefaultHeight = height;
  408. return NO_ERROR;
  409. }
  410. status_t BufferQueueConsumer::setDefaultMaxBufferCount(int bufferCount) {
  411. ATRACE_CALL();
  412. Mutex::Autolock lock(mCore->mMutex);
  413. return mCore->setDefaultMaxBufferCountLocked(bufferCount);
  414. }
  415. status_t BufferQueueConsumer::disableAsyncBuffer() {
  416. ATRACE_CALL();
  417. Mutex::Autolock lock(mCore->mMutex);
  418. if (mCore->mConsumerListener != NULL) {
  419. BQ_LOGE("disableAsyncBuffer: consumer already connected");
  420. return INVALID_OPERATION;
  421. }
  422. BQ_LOGV("disableAsyncBuffer");
  423. mCore->mUseAsyncBuffer = false;
  424. return NO_ERROR;
  425. }
  426. status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
  427. int maxAcquiredBuffers) {
  428. ATRACE_CALL();
  429. if (maxAcquiredBuffers < 1 ||
  430. maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
  431. BQ_LOGE("setMaxAcquiredBufferCount: invalid count %d",
  432. maxAcquiredBuffers);
  433. return BAD_VALUE;
  434. }
  435. Mutex::Autolock lock(mCore->mMutex);
  436. if (mCore->mConnectedApi != BufferQueueCore::NO_CONNECTED_API) {
  437. BQ_LOGE("setMaxAcquiredBufferCount: producer is already connected");
  438. return INVALID_OPERATION;
  439. }
  440. BQ_LOGV("setMaxAcquiredBufferCount: %d", maxAcquiredBuffers);
  441. mCore->mMaxAcquiredBufferCount = maxAcquiredBuffers;
  442. return NO_ERROR;
  443. }
  444. void BufferQueueConsumer::setConsumerName(const String8& name) {
  445. ATRACE_CALL();
  446. BQ_LOGV("setConsumerName: '%s'", name.string());
  447. Mutex::Autolock lock(mCore->mMutex);
  448. mCore->mConsumerName = name;
  449. mConsumerName = name;
  450. }
  451. status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
  452. ATRACE_CALL();
  453. BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
  454. Mutex::Autolock lock(mCore->mMutex);
  455. mCore->mDefaultBufferFormat = defaultFormat;
  456. return NO_ERROR;
  457. }
  458. status_t BufferQueueConsumer::setDefaultBufferDataSpace(
  459. android_dataspace defaultDataSpace) {
  460. ATRACE_CALL();
  461. BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
  462. Mutex::Autolock lock(mCore->mMutex);
  463. mCore->mDefaultBufferDataSpace = defaultDataSpace;
  464. return NO_ERROR;
  465. }
  466. status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
  467. ATRACE_CALL();
  468. BQ_LOGV("setConsumerUsageBits: %#x", usage);
  469. Mutex::Autolock lock(mCore->mMutex);
  470. mCore->mConsumerUsageBits = usage;
  471. return NO_ERROR;
  472. }
  473. status_t BufferQueueConsumer::setTransformHint(uint32_t hint) {
  474. ATRACE_CALL();
  475. BQ_LOGV("setTransformHint: %#x", hint);
  476. Mutex::Autolock lock(mCore->mMutex);
  477. mCore->mTransformHint = hint;
  478. return NO_ERROR;
  479. }
  480. sp<NativeHandle> BufferQueueConsumer::getSidebandStream() const {
  481. Mutex::Autolock lock(mCore->mMutex);
  482. return mCore->mSidebandStream;
  483. }
  484. void BufferQueueConsumer::dump(String8& result, const char* prefix) const {
  485. const IPCThreadState* ipc = IPCThreadState::self();
  486. const pid_t pid = ipc->getCallingPid();
  487. const uid_t uid = ipc->getCallingUid();
  488. if ((uid != AID_SHELL)
  489. && !PermissionCache::checkPermission(String16(
  490. "android.permission.DUMP"), pid, uid)) {
  491. result.appendFormat("Permission Denial: can't dump BufferQueueConsumer "
  492. "from pid=%d, uid=%d\n", pid, uid);
  493. android_errorWriteWithInfoLog(0x534e4554, "27046057", uid, NULL, 0);
  494. } else {
  495. mCore->dump(result, prefix);
  496. }
  497. }
  498. } // namespace android