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