BufferStateLayer.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. /*
  2. * Copyright (C) 2017 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_NDEBUG 0
  17. #undef LOG_TAG
  18. #define LOG_TAG "BufferStateLayer"
  19. #define ATRACE_TAG ATRACE_TAG_GRAPHICS
  20. #include <limits>
  21. #include <compositionengine/Display.h>
  22. #include <compositionengine/Layer.h>
  23. #include <compositionengine/OutputLayer.h>
  24. #include <compositionengine/impl/LayerCompositionState.h>
  25. #include <compositionengine/impl/OutputLayerCompositionState.h>
  26. #include <gui/BufferQueue.h>
  27. #include <private/gui/SyncFeatures.h>
  28. #include <renderengine/Image.h>
  29. #include "BufferStateLayer.h"
  30. #include "ColorLayer.h"
  31. #include "TimeStats/TimeStats.h"
  32. namespace android {
  33. // clang-format off
  34. const std::array<float, 16> BufferStateLayer::IDENTITY_MATRIX{
  35. 1, 0, 0, 0,
  36. 0, 1, 0, 0,
  37. 0, 0, 1, 0,
  38. 0, 0, 0, 1
  39. };
  40. // clang-format on
  41. BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args)
  42. : BufferLayer(args), mHwcSlotGenerator(new HwcSlotGenerator()) {
  43. mOverrideScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
  44. mCurrentState.dataspace = ui::Dataspace::V0_SRGB;
  45. }
  46. BufferStateLayer::~BufferStateLayer() {
  47. if (mActiveBuffer != nullptr) {
  48. // Ensure that mActiveBuffer is uncached from RenderEngine here, as
  49. // RenderEngine may have been using the buffer as an external texture
  50. // after the client uncached the buffer.
  51. auto& engine(mFlinger->getRenderEngine());
  52. engine.unbindExternalTextureBuffer(mActiveBuffer->getId());
  53. }
  54. }
  55. // -----------------------------------------------------------------------
  56. // Interface implementation for Layer
  57. // -----------------------------------------------------------------------
  58. void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
  59. // The previous release fence notifies the client that SurfaceFlinger is done with the previous
  60. // buffer that was presented on this layer. The first transaction that came in this frame that
  61. // replaced the previous buffer on this layer needs this release fence, because the fence will
  62. // let the client know when that previous buffer is removed from the screen.
  63. //
  64. // Every other transaction on this layer does not need a release fence because no other
  65. // Transactions that were set on this layer this frame are going to have their preceeding buffer
  66. // removed from the display this frame.
  67. //
  68. // For example, if we have 3 transactions this frame. The first transaction doesn't contain a
  69. // buffer so it doesn't need a previous release fence because the layer still needs the previous
  70. // buffer. The second transaction contains a buffer so it needs a previous release fence because
  71. // the previous buffer will be released this frame. The third transaction also contains a
  72. // buffer. It replaces the buffer in the second transaction. The buffer in the second
  73. // transaction will now no longer be presented so it is released immediately and the third
  74. // transaction doesn't need a previous release fence.
  75. for (auto& handle : mDrawingState.callbackHandles) {
  76. if (handle->releasePreviousBuffer) {
  77. handle->previousReleaseFence = releaseFence;
  78. break;
  79. }
  80. }
  81. }
  82. void BufferStateLayer::setTransformHint(uint32_t /*orientation*/) const {
  83. // TODO(marissaw): send the transform hint to buffer owner
  84. return;
  85. }
  86. void BufferStateLayer::releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) {
  87. mFlinger->getTransactionCompletedThread().addPresentedCallbackHandles(
  88. mDrawingState.callbackHandles);
  89. mDrawingState.callbackHandles = {};
  90. }
  91. bool BufferStateLayer::shouldPresentNow(nsecs_t /*expectedPresentTime*/) const {
  92. if (getSidebandStreamChanged() || getAutoRefresh()) {
  93. return true;
  94. }
  95. return hasFrameUpdate();
  96. }
  97. bool BufferStateLayer::willPresentCurrentTransaction() const {
  98. // Returns true if the most recent Transaction applied to CurrentState will be presented.
  99. return getSidebandStreamChanged() || getAutoRefresh() ||
  100. (mCurrentState.modified &&
  101. (mCurrentState.buffer != nullptr || mCurrentState.bgColorLayer != nullptr));
  102. }
  103. bool BufferStateLayer::getTransformToDisplayInverse() const {
  104. return mCurrentState.transformToDisplayInverse;
  105. }
  106. void BufferStateLayer::pushPendingState() {
  107. if (!mCurrentState.modified) {
  108. return;
  109. }
  110. mPendingStates.push_back(mCurrentState);
  111. ATRACE_INT(mTransactionName.string(), mPendingStates.size());
  112. }
  113. bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) {
  114. const bool stateUpdateAvailable = !mPendingStates.empty();
  115. while (!mPendingStates.empty()) {
  116. popPendingState(stateToCommit);
  117. }
  118. mCurrentStateModified = stateUpdateAvailable && mCurrentState.modified;
  119. mCurrentState.modified = false;
  120. return stateUpdateAvailable;
  121. }
  122. // Crop that applies to the window
  123. Rect BufferStateLayer::getCrop(const Layer::State& /*s*/) const {
  124. return Rect::INVALID_RECT;
  125. }
  126. bool BufferStateLayer::setTransform(uint32_t transform) {
  127. if (mCurrentState.transform == transform) return false;
  128. mCurrentState.transform = transform;
  129. mCurrentState.modified = true;
  130. setTransactionFlags(eTransactionNeeded);
  131. return true;
  132. }
  133. bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
  134. if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false;
  135. mCurrentState.sequence++;
  136. mCurrentState.transformToDisplayInverse = transformToDisplayInverse;
  137. mCurrentState.modified = true;
  138. setTransactionFlags(eTransactionNeeded);
  139. return true;
  140. }
  141. bool BufferStateLayer::setCrop(const Rect& crop) {
  142. Rect c = crop;
  143. if (c.left < 0) {
  144. c.left = 0;
  145. }
  146. if (c.top < 0) {
  147. c.top = 0;
  148. }
  149. // If the width and/or height are < 0, make it [0, 0, -1, -1] so the equality comparision below
  150. // treats all invalid rectangles the same.
  151. if (!c.isValid()) {
  152. c.makeInvalid();
  153. }
  154. if (mCurrentState.crop == c) return false;
  155. mCurrentState.crop = c;
  156. mCurrentState.modified = true;
  157. setTransactionFlags(eTransactionNeeded);
  158. return true;
  159. }
  160. bool BufferStateLayer::setFrame(const Rect& frame) {
  161. int x = frame.left;
  162. int y = frame.top;
  163. int w = frame.getWidth();
  164. int h = frame.getHeight();
  165. if (x < 0) {
  166. x = 0;
  167. w = frame.right;
  168. }
  169. if (y < 0) {
  170. y = 0;
  171. h = frame.bottom;
  172. }
  173. if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y &&
  174. mCurrentState.active.w == w && mCurrentState.active.h == h) {
  175. return false;
  176. }
  177. if (!frame.isValid()) {
  178. x = y = w = h = 0;
  179. }
  180. mCurrentState.active.transform.set(x, y);
  181. mCurrentState.active.w = w;
  182. mCurrentState.active.h = h;
  183. mCurrentState.sequence++;
  184. mCurrentState.modified = true;
  185. setTransactionFlags(eTransactionNeeded);
  186. return true;
  187. }
  188. bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, nsecs_t postTime,
  189. nsecs_t desiredPresentTime, const client_cache_t& clientCacheId) {
  190. if (mCurrentState.buffer) {
  191. mReleasePreviousBuffer = true;
  192. }
  193. mCurrentState.buffer = buffer;
  194. mCurrentState.clientCacheId = clientCacheId;
  195. mCurrentState.modified = true;
  196. setTransactionFlags(eTransactionNeeded);
  197. mFlinger->mTimeStats->setPostTime(getSequence(), getFrameNumber(), getName().c_str(), postTime);
  198. mDesiredPresentTime = desiredPresentTime;
  199. if (mFlinger->mUseSmart90ForVideo) {
  200. const nsecs_t presentTime = (mDesiredPresentTime == -1) ? 0 : mDesiredPresentTime;
  201. mFlinger->mScheduler->addLayerPresentTimeAndHDR(mSchedulerLayerHandle, presentTime,
  202. mCurrentState.hdrMetadata.validTypes != 0);
  203. }
  204. return true;
  205. }
  206. bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) {
  207. // The acquire fences of BufferStateLayers have already signaled before they are set
  208. mCallbackHandleAcquireTime = fence->getSignalTime();
  209. mCurrentState.acquireFence = fence;
  210. mCurrentState.modified = true;
  211. setTransactionFlags(eTransactionNeeded);
  212. return true;
  213. }
  214. bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
  215. if (mCurrentState.dataspace == dataspace) return false;
  216. mCurrentState.dataspace = dataspace;
  217. mCurrentState.modified = true;
  218. setTransactionFlags(eTransactionNeeded);
  219. return true;
  220. }
  221. bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
  222. if (mCurrentState.hdrMetadata == hdrMetadata) return false;
  223. mCurrentState.hdrMetadata = hdrMetadata;
  224. mCurrentState.modified = true;
  225. setTransactionFlags(eTransactionNeeded);
  226. return true;
  227. }
  228. bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
  229. mCurrentState.surfaceDamageRegion = surfaceDamage;
  230. mCurrentState.modified = true;
  231. setTransactionFlags(eTransactionNeeded);
  232. return true;
  233. }
  234. bool BufferStateLayer::setApi(int32_t api) {
  235. if (mCurrentState.api == api) return false;
  236. mCurrentState.api = api;
  237. mCurrentState.modified = true;
  238. setTransactionFlags(eTransactionNeeded);
  239. return true;
  240. }
  241. bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
  242. if (mCurrentState.sidebandStream == sidebandStream) return false;
  243. mCurrentState.sidebandStream = sidebandStream;
  244. mCurrentState.modified = true;
  245. setTransactionFlags(eTransactionNeeded);
  246. if (!mSidebandStreamChanged.exchange(true)) {
  247. // mSidebandStreamChanged was false
  248. mFlinger->signalLayerUpdate();
  249. }
  250. return true;
  251. }
  252. bool BufferStateLayer::setTransactionCompletedListeners(
  253. const std::vector<sp<CallbackHandle>>& handles) {
  254. // If there is no handle, we will not send a callback so reset mReleasePreviousBuffer and return
  255. if (handles.empty()) {
  256. mReleasePreviousBuffer = false;
  257. return false;
  258. }
  259. const bool willPresent = willPresentCurrentTransaction();
  260. for (const auto& handle : handles) {
  261. // If this transaction set a buffer on this layer, release its previous buffer
  262. handle->releasePreviousBuffer = mReleasePreviousBuffer;
  263. // If this layer will be presented in this frame
  264. if (willPresent) {
  265. // If this transaction set an acquire fence on this layer, set its acquire time
  266. handle->acquireTime = mCallbackHandleAcquireTime;
  267. // Notify the transaction completed thread that there is a pending latched callback
  268. // handle
  269. mFlinger->getTransactionCompletedThread().registerPendingCallbackHandle(handle);
  270. // Store so latched time and release fence can be set
  271. mCurrentState.callbackHandles.push_back(handle);
  272. } else { // If this layer will NOT need to be relatched and presented this frame
  273. // Notify the transaction completed thread this handle is done
  274. mFlinger->getTransactionCompletedThread().addUnpresentedCallbackHandle(handle);
  275. }
  276. }
  277. mReleasePreviousBuffer = false;
  278. mCallbackHandleAcquireTime = -1;
  279. return willPresent;
  280. }
  281. bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
  282. mCurrentState.transparentRegionHint = transparent;
  283. mCurrentState.modified = true;
  284. setTransactionFlags(eTransactionNeeded);
  285. return true;
  286. }
  287. Rect BufferStateLayer::getBufferSize(const State& s) const {
  288. // for buffer state layers we use the display frame size as the buffer size.
  289. if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) {
  290. return Rect(getActiveWidth(s), getActiveHeight(s));
  291. }
  292. // if the display frame is not defined, use the parent bounds as the buffer size.
  293. const auto& p = mDrawingParent.promote();
  294. if (p != nullptr) {
  295. Rect parentBounds = Rect(p->getBounds(Region()));
  296. if (!parentBounds.isEmpty()) {
  297. return parentBounds;
  298. }
  299. }
  300. return Rect::INVALID_RECT;
  301. }
  302. FloatRect BufferStateLayer::computeSourceBounds(const FloatRect& parentBounds) const {
  303. const State& s(getDrawingState());
  304. // for buffer state layers we use the display frame size as the buffer size.
  305. if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) {
  306. return FloatRect(0, 0, getActiveWidth(s), getActiveHeight(s));
  307. }
  308. // if the display frame is not defined, use the parent bounds as the buffer size.
  309. return parentBounds;
  310. }
  311. // -----------------------------------------------------------------------
  312. // -----------------------------------------------------------------------
  313. // Interface implementation for BufferLayer
  314. // -----------------------------------------------------------------------
  315. bool BufferStateLayer::fenceHasSignaled() const {
  316. if (latchUnsignaledBuffers()) {
  317. return true;
  318. }
  319. return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
  320. }
  321. bool BufferStateLayer::framePresentTimeIsCurrent() const {
  322. if (!hasFrameUpdate() || isRemovedFromCurrentState()) {
  323. return true;
  324. }
  325. return mDesiredPresentTime <= mFlinger->getExpectedPresentTime();
  326. }
  327. nsecs_t BufferStateLayer::getDesiredPresentTime() {
  328. return mDesiredPresentTime;
  329. }
  330. std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const {
  331. return std::make_shared<FenceTime>(getDrawingState().acquireFence);
  332. }
  333. void BufferStateLayer::getDrawingTransformMatrix(float *matrix) {
  334. std::copy(std::begin(mTransformMatrix), std::end(mTransformMatrix), matrix);
  335. }
  336. uint32_t BufferStateLayer::getDrawingTransform() const {
  337. return getDrawingState().transform;
  338. }
  339. ui::Dataspace BufferStateLayer::getDrawingDataSpace() const {
  340. return getDrawingState().dataspace;
  341. }
  342. // Crop that applies to the buffer
  343. Rect BufferStateLayer::getDrawingCrop() const {
  344. const State& s(getDrawingState());
  345. if (s.crop.isEmpty() && s.buffer) {
  346. return s.buffer->getBounds();
  347. } else if (s.buffer) {
  348. Rect crop = s.crop;
  349. crop.left = std::max(crop.left, 0);
  350. crop.top = std::max(crop.top, 0);
  351. uint32_t bufferWidth = s.buffer->getWidth();
  352. uint32_t bufferHeight = s.buffer->getHeight();
  353. if (bufferHeight <= std::numeric_limits<int32_t>::max() &&
  354. bufferWidth <= std::numeric_limits<int32_t>::max()) {
  355. crop.right = std::min(crop.right, static_cast<int32_t>(bufferWidth));
  356. crop.bottom = std::min(crop.bottom, static_cast<int32_t>(bufferHeight));
  357. }
  358. if (!crop.isValid()) {
  359. // Crop rect is out of bounds, return whole buffer
  360. return s.buffer->getBounds();
  361. }
  362. return crop;
  363. }
  364. return s.crop;
  365. }
  366. uint32_t BufferStateLayer::getDrawingScalingMode() const {
  367. return NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
  368. }
  369. Region BufferStateLayer::getDrawingSurfaceDamage() const {
  370. return getDrawingState().surfaceDamageRegion;
  371. }
  372. const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const {
  373. return getDrawingState().hdrMetadata;
  374. }
  375. int BufferStateLayer::getDrawingApi() const {
  376. return getDrawingState().api;
  377. }
  378. PixelFormat BufferStateLayer::getPixelFormat() const {
  379. if (!mActiveBuffer) {
  380. return PIXEL_FORMAT_NONE;
  381. }
  382. return mActiveBuffer->format;
  383. }
  384. uint64_t BufferStateLayer::getFrameNumber() const {
  385. return mFrameNumber;
  386. }
  387. bool BufferStateLayer::getAutoRefresh() const {
  388. // TODO(marissaw): support shared buffer mode
  389. return false;
  390. }
  391. bool BufferStateLayer::getSidebandStreamChanged() const {
  392. return mSidebandStreamChanged.load();
  393. }
  394. bool BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
  395. if (mSidebandStreamChanged.exchange(false)) {
  396. const State& s(getDrawingState());
  397. // mSidebandStreamChanged was true
  398. LOG_ALWAYS_FATAL_IF(!getCompositionLayer());
  399. mSidebandStream = s.sidebandStream;
  400. getCompositionLayer()->editState().frontEnd.sidebandStream = mSidebandStream;
  401. if (mSidebandStream != nullptr) {
  402. setTransactionFlags(eTransactionNeeded);
  403. mFlinger->setTransactionFlags(eTraversalNeeded);
  404. }
  405. recomputeVisibleRegions = true;
  406. return true;
  407. }
  408. return false;
  409. }
  410. bool BufferStateLayer::hasFrameUpdate() const {
  411. const State& c(getCurrentState());
  412. return mCurrentStateModified && (c.buffer != nullptr || c.bgColorLayer != nullptr);
  413. }
  414. void BufferStateLayer::setFilteringEnabled(bool enabled) {
  415. GLConsumer::computeTransformMatrix(mTransformMatrix.data(), mActiveBuffer, mCurrentCrop,
  416. mCurrentTransform, enabled);
  417. }
  418. status_t BufferStateLayer::bindTextureImage() {
  419. const State& s(getDrawingState());
  420. auto& engine(mFlinger->getRenderEngine());
  421. return engine.bindExternalTextureBuffer(mTextureName, s.buffer, s.acquireFence);
  422. }
  423. status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime) {
  424. const State& s(getDrawingState());
  425. if (!s.buffer) {
  426. if (s.bgColorLayer) {
  427. for (auto& handle : mDrawingState.callbackHandles) {
  428. handle->latchTime = latchTime;
  429. }
  430. }
  431. return NO_ERROR;
  432. }
  433. const int32_t layerID = getSequence();
  434. // Reject if the layer is invalid
  435. uint32_t bufferWidth = s.buffer->width;
  436. uint32_t bufferHeight = s.buffer->height;
  437. if (s.transform & ui::Transform::ROT_90) {
  438. std::swap(bufferWidth, bufferHeight);
  439. }
  440. if (s.transformToDisplayInverse) {
  441. uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
  442. if (invTransform & ui::Transform::ROT_90) {
  443. std::swap(bufferWidth, bufferHeight);
  444. }
  445. }
  446. if (getEffectiveScalingMode() == NATIVE_WINDOW_SCALING_MODE_FREEZE &&
  447. (s.active.w != bufferWidth || s.active.h != bufferHeight)) {
  448. ALOGE("[%s] rejecting buffer: "
  449. "bufferWidth=%d, bufferHeight=%d, front.active.{w=%d, h=%d}",
  450. mName.string(), bufferWidth, bufferHeight, s.active.w, s.active.h);
  451. mFlinger->mTimeStats->removeTimeRecord(layerID, getFrameNumber());
  452. return BAD_VALUE;
  453. }
  454. for (auto& handle : mDrawingState.callbackHandles) {
  455. handle->latchTime = latchTime;
  456. }
  457. if (!SyncFeatures::getInstance().useNativeFenceSync()) {
  458. // Bind the new buffer to the GL texture.
  459. //
  460. // Older devices require the "implicit" synchronization provided
  461. // by glEGLImageTargetTexture2DOES, which this method calls. Newer
  462. // devices will either call this in Layer::onDraw, or (if it's not
  463. // a GL-composited layer) not at all.
  464. status_t err = bindTextureImage();
  465. if (err != NO_ERROR) {
  466. mFlinger->mTimeStats->onDestroy(layerID);
  467. return BAD_VALUE;
  468. }
  469. }
  470. mFlinger->mTimeStats->setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
  471. mFlinger->mTimeStats->setLatchTime(layerID, getFrameNumber(), latchTime);
  472. mCurrentStateModified = false;
  473. return NO_ERROR;
  474. }
  475. status_t BufferStateLayer::updateActiveBuffer() {
  476. const State& s(getDrawingState());
  477. if (s.buffer == nullptr) {
  478. return BAD_VALUE;
  479. }
  480. mActiveBuffer = s.buffer;
  481. mActiveBufferFence = s.acquireFence;
  482. auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
  483. layerCompositionState.buffer = mActiveBuffer;
  484. layerCompositionState.bufferSlot = 0;
  485. return NO_ERROR;
  486. }
  487. status_t BufferStateLayer::updateFrameNumber(nsecs_t /*latchTime*/) {
  488. // TODO(marissaw): support frame history events
  489. mCurrentFrameNumber = mFrameNumber;
  490. return NO_ERROR;
  491. }
  492. void BufferStateLayer::setHwcLayerBuffer(const sp<const DisplayDevice>& display) {
  493. const auto outputLayer = findOutputLayerForDisplay(display);
  494. LOG_FATAL_IF(!outputLayer || !outputLayer->getState().hwc);
  495. auto& hwcInfo = *outputLayer->editState().hwc;
  496. auto& hwcLayer = hwcInfo.hwcLayer;
  497. const State& s(getDrawingState());
  498. uint32_t hwcSlot;
  499. sp<GraphicBuffer> buffer;
  500. hwcInfo.hwcBufferCache.getHwcBuffer(mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId),
  501. s.buffer, &hwcSlot, &buffer);
  502. auto error = hwcLayer->setBuffer(hwcSlot, buffer, s.acquireFence);
  503. if (error != HWC2::Error::None) {
  504. ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
  505. s.buffer->handle, to_string(error).c_str(), static_cast<int32_t>(error));
  506. }
  507. mFrameNumber++;
  508. }
  509. void BufferStateLayer::onFirstRef() {
  510. BufferLayer::onFirstRef();
  511. if (const auto display = mFlinger->getDefaultDisplayDevice()) {
  512. updateTransformHint(display);
  513. }
  514. }
  515. void BufferStateLayer::HwcSlotGenerator::bufferErased(const client_cache_t& clientCacheId) {
  516. std::lock_guard lock(mMutex);
  517. if (!clientCacheId.isValid()) {
  518. ALOGE("invalid process, failed to erase buffer");
  519. return;
  520. }
  521. eraseBufferLocked(clientCacheId);
  522. }
  523. uint32_t BufferStateLayer::HwcSlotGenerator::getHwcCacheSlot(const client_cache_t& clientCacheId) {
  524. std::lock_guard<std::mutex> lock(mMutex);
  525. auto itr = mCachedBuffers.find(clientCacheId);
  526. if (itr == mCachedBuffers.end()) {
  527. return addCachedBuffer(clientCacheId);
  528. }
  529. auto& [hwcCacheSlot, counter] = itr->second;
  530. counter = mCounter++;
  531. return hwcCacheSlot;
  532. }
  533. uint32_t BufferStateLayer::HwcSlotGenerator::addCachedBuffer(const client_cache_t& clientCacheId)
  534. REQUIRES(mMutex) {
  535. if (!clientCacheId.isValid()) {
  536. ALOGE("invalid process, returning invalid slot");
  537. return BufferQueue::INVALID_BUFFER_SLOT;
  538. }
  539. ClientCache::getInstance().registerErasedRecipient(clientCacheId, wp<ErasedRecipient>(this));
  540. uint32_t hwcCacheSlot = getFreeHwcCacheSlot();
  541. mCachedBuffers[clientCacheId] = {hwcCacheSlot, mCounter++};
  542. return hwcCacheSlot;
  543. }
  544. uint32_t BufferStateLayer::HwcSlotGenerator::getFreeHwcCacheSlot() REQUIRES(mMutex) {
  545. if (mFreeHwcCacheSlots.empty()) {
  546. evictLeastRecentlyUsed();
  547. }
  548. uint32_t hwcCacheSlot = mFreeHwcCacheSlots.top();
  549. mFreeHwcCacheSlots.pop();
  550. return hwcCacheSlot;
  551. }
  552. void BufferStateLayer::HwcSlotGenerator::evictLeastRecentlyUsed() REQUIRES(mMutex) {
  553. uint64_t minCounter = UINT_MAX;
  554. client_cache_t minClientCacheId = {};
  555. for (const auto& [clientCacheId, slotCounter] : mCachedBuffers) {
  556. const auto& [hwcCacheSlot, counter] = slotCounter;
  557. if (counter < minCounter) {
  558. minCounter = counter;
  559. minClientCacheId = clientCacheId;
  560. }
  561. }
  562. eraseBufferLocked(minClientCacheId);
  563. ClientCache::getInstance().unregisterErasedRecipient(minClientCacheId, this);
  564. }
  565. void BufferStateLayer::HwcSlotGenerator::eraseBufferLocked(const client_cache_t& clientCacheId)
  566. REQUIRES(mMutex) {
  567. auto itr = mCachedBuffers.find(clientCacheId);
  568. if (itr == mCachedBuffers.end()) {
  569. return;
  570. }
  571. auto& [hwcCacheSlot, counter] = itr->second;
  572. // TODO send to hwc cache and resources
  573. mFreeHwcCacheSlots.push(hwcCacheSlot);
  574. mCachedBuffers.erase(clientCacheId);
  575. }
  576. } // namespace android