• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 // TODO(b/129481165): remove the #pragma below and fix conversion issues
18 #pragma clang diagnostic push
19 #pragma clang diagnostic ignored "-Wconversion"
20 #pragma clang diagnostic ignored "-Wextra"
21 
22 #undef LOG_TAG
23 #define LOG_TAG "BufferQueueLayer"
24 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
25 #include "BufferQueueLayer.h"
26 
27 #include <compositionengine/LayerFECompositionState.h>
28 #include <gui/BufferQueueConsumer.h>
29 #include <system/window.h>
30 
31 #include "LayerRejecter.h"
32 #include "SurfaceInterceptor.h"
33 
34 #include "FrameTracer/FrameTracer.h"
35 #include "Scheduler/LayerHistory.h"
36 #include "TimeStats/TimeStats.h"
37 
38 namespace android {
39 using PresentState = frametimeline::SurfaceFrame::PresentState;
40 
BufferQueueLayer(const LayerCreationArgs & args)41 BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) {}
42 
~BufferQueueLayer()43 BufferQueueLayer::~BufferQueueLayer() {
44     mContentsChangedListener->abandon();
45     mConsumer->abandon();
46 }
47 
48 // -----------------------------------------------------------------------
49 // Interface implementation for Layer
50 // -----------------------------------------------------------------------
51 
onLayerDisplayed(const sp<Fence> & releaseFence)52 void BufferQueueLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
53     mConsumer->setReleaseFence(releaseFence);
54 
55     // Prevent tracing the same release multiple times.
56     if (mPreviousFrameNumber != mPreviousReleasedFrameNumber) {
57         mFlinger->mFrameTracer->traceFence(getSequence(), mPreviousBufferId, mPreviousFrameNumber,
58                                            std::make_shared<FenceTime>(releaseFence),
59                                            FrameTracer::FrameEvent::RELEASE_FENCE);
60         mPreviousReleasedFrameNumber = mPreviousFrameNumber;
61     }
62 }
63 
setTransformHint(ui::Transform::RotationFlags displayTransformHint)64 void BufferQueueLayer::setTransformHint(ui::Transform::RotationFlags displayTransformHint) {
65     BufferLayer::setTransformHint(displayTransformHint);
66     mConsumer->setTransformHint(mTransformHint);
67 }
68 
getOccupancyHistory(bool forceFlush)69 std::vector<OccupancyTracker::Segment> BufferQueueLayer::getOccupancyHistory(bool forceFlush) {
70     std::vector<OccupancyTracker::Segment> history;
71     status_t result = mConsumer->getOccupancyHistory(forceFlush, &history);
72     if (result != NO_ERROR) {
73         ALOGW("[%s] Failed to obtain occupancy history (%d)", getDebugName(), result);
74         return {};
75     }
76     return history;
77 }
78 
releasePendingBuffer(nsecs_t dequeueReadyTime)79 void BufferQueueLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
80     if (!mConsumer->releasePendingBuffer()) {
81         return;
82     }
83 
84     auto releaseFenceTime = std::make_shared<FenceTime>(mConsumer->getPrevFinalReleaseFence());
85     mReleaseTimeline.updateSignalTimes();
86     mReleaseTimeline.push(releaseFenceTime);
87 
88     Mutex::Autolock lock(mFrameEventHistoryMutex);
89     if (mPreviousFrameNumber != 0) {
90         mFrameEventHistory.addRelease(mPreviousFrameNumber, dequeueReadyTime,
91                                       std::move(releaseFenceTime));
92     }
93 }
94 
setDefaultBufferSize(uint32_t w,uint32_t h)95 void BufferQueueLayer::setDefaultBufferSize(uint32_t w, uint32_t h) {
96     mConsumer->setDefaultBufferSize(w, h);
97 }
98 
getQueuedFrameCount() const99 int32_t BufferQueueLayer::getQueuedFrameCount() const {
100     return mQueuedFrames;
101 }
102 
isBufferDue(nsecs_t expectedPresentTime) const103 bool BufferQueueLayer::isBufferDue(nsecs_t expectedPresentTime) const {
104     Mutex::Autolock lock(mQueueItemLock);
105 
106     const int64_t addedTime = mQueueItems[0].item.mTimestamp;
107 
108     // Ignore timestamps more than a second in the future
109     const bool isPlausible = addedTime < (expectedPresentTime + s2ns(1));
110     ALOGW_IF(!isPlausible,
111              "[%s] Timestamp %" PRId64 " seems implausible "
112              "relative to expectedPresent %" PRId64,
113              getDebugName(), addedTime, expectedPresentTime);
114 
115     if (!isPlausible) {
116         mFlinger->mTimeStats->incrementBadDesiredPresent(getSequence());
117     }
118 
119     const bool isDue = addedTime < expectedPresentTime;
120     return isDue || !isPlausible;
121 }
122 
123 // -----------------------------------------------------------------------
124 // Interface implementation for BufferLayer
125 // -----------------------------------------------------------------------
126 
fenceHasSignaled() const127 bool BufferQueueLayer::fenceHasSignaled() const {
128     Mutex::Autolock lock(mQueueItemLock);
129 
130     if (SurfaceFlinger::enableLatchUnsignaled) {
131         return true;
132     }
133 
134     if (!hasFrameUpdate()) {
135         return true;
136     }
137 
138     if (mQueueItems[0].item.mIsDroppable) {
139         // Even though this buffer's fence may not have signaled yet, it could
140         // be replaced by another buffer before it has a chance to, which means
141         // that it's possible to get into a situation where a buffer is never
142         // able to be latched. To avoid this, grab this buffer anyway.
143         return true;
144     }
145     const bool fenceSignaled =
146             mQueueItems[0].item.mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
147     if (!fenceSignaled) {
148         mFlinger->mTimeStats->incrementLatchSkipped(getSequence(),
149                                                     TimeStats::LatchSkipReason::LateAcquire);
150     }
151 
152     return fenceSignaled;
153 }
154 
framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const155 bool BufferQueueLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const {
156     if (!hasFrameUpdate() || isRemovedFromCurrentState()) {
157         return true;
158     }
159 
160     Mutex::Autolock lock(mQueueItemLock);
161     return mQueueItems[0].item.mTimestamp <= expectedPresentTime;
162 }
163 
getFrameNumber(nsecs_t expectedPresentTime) const164 uint64_t BufferQueueLayer::getFrameNumber(nsecs_t expectedPresentTime) const {
165     Mutex::Autolock lock(mQueueItemLock);
166     uint64_t frameNumber = mQueueItems[0].item.mFrameNumber;
167 
168     // The head of the queue will be dropped if there are signaled and timely frames behind it
169     if (isRemovedFromCurrentState()) {
170         expectedPresentTime = 0;
171     }
172 
173     for (int i = 1; i < mQueueItems.size(); i++) {
174         const bool fenceSignaled =
175                 mQueueItems[i].item.mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
176         if (!fenceSignaled) {
177             break;
178         }
179 
180         // We don't drop frames without explicit timestamps
181         if (mQueueItems[i].item.mIsAutoTimestamp) {
182             break;
183         }
184 
185         const nsecs_t desiredPresent = mQueueItems[i].item.mTimestamp;
186         if (desiredPresent < expectedPresentTime - BufferQueueConsumer::MAX_REASONABLE_NSEC ||
187             desiredPresent > expectedPresentTime) {
188             break;
189         }
190 
191         frameNumber = mQueueItems[i].item.mFrameNumber;
192     }
193 
194     return frameNumber;
195 }
196 
latchSidebandStream(bool & recomputeVisibleRegions)197 bool BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
198     // We need to update the sideband stream if the layer has both a buffer and a sideband stream.
199     const bool updateSidebandStream = hasFrameUpdate() && mSidebandStream.get();
200 
201     bool sidebandStreamChanged = true;
202     if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false) ||
203         updateSidebandStream) {
204         // mSidebandStreamChanged was changed to false
205         mSidebandStream = mConsumer->getSidebandStream();
206         auto* layerCompositionState = editCompositionState();
207         layerCompositionState->sidebandStream = mSidebandStream;
208         if (layerCompositionState->sidebandStream != nullptr) {
209             setTransactionFlags(eTransactionNeeded);
210             mFlinger->setTransactionFlags(eTraversalNeeded);
211         }
212         recomputeVisibleRegions = true;
213 
214         return true;
215     }
216     return false;
217 }
218 
hasFrameUpdate() const219 bool BufferQueueLayer::hasFrameUpdate() const {
220     return mQueuedFrames > 0;
221 }
222 
updateTexImage(bool & recomputeVisibleRegions,nsecs_t latchTime,nsecs_t expectedPresentTime)223 status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime,
224                                           nsecs_t expectedPresentTime) {
225     // This boolean is used to make sure that SurfaceFlinger's shadow copy
226     // of the buffer queue isn't modified when the buffer queue is returning
227     // BufferItem's that weren't actually queued. This can happen in shared
228     // buffer mode.
229     bool queuedBuffer = false;
230     const int32_t layerId = getSequence();
231     LayerRejecter r(mDrawingState, getDrawingState(), recomputeVisibleRegions,
232                     getProducerStickyTransform() != 0, mName,
233                     getTransformToDisplayInverse());
234 
235     if (isRemovedFromCurrentState()) {
236         expectedPresentTime = 0;
237     }
238 
239     // updateTexImage() below might drop the some buffers at the head of the queue if there is a
240     // buffer behind them which is timely to be presented. However this buffer may not be signaled
241     // yet. The code below makes sure that this wouldn't happen by setting maxFrameNumber to the
242     // last buffer that was signaled.
243     uint64_t lastSignaledFrameNumber = mLastFrameNumberReceived;
244     {
245         Mutex::Autolock lock(mQueueItemLock);
246         for (int i = 0; i < mQueueItems.size(); i++) {
247             bool fenceSignaled =
248                     mQueueItems[i].item.mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
249             if (!fenceSignaled) {
250                 break;
251             }
252             lastSignaledFrameNumber = mQueueItems[i].item.mFrameNumber;
253         }
254     }
255     const uint64_t maxFrameNumberToAcquire =
256             std::min(mLastFrameNumberReceived.load(), lastSignaledFrameNumber);
257 
258     bool autoRefresh;
259     status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &autoRefresh,
260                                                       &queuedBuffer, maxFrameNumberToAcquire);
261     mAutoRefresh = autoRefresh;
262     if (updateResult == BufferQueue::PRESENT_LATER) {
263         // Producer doesn't want buffer to be displayed yet.  Signal a
264         // layer update so we check again at the next opportunity.
265         mFlinger->signalLayerUpdate();
266         return BAD_VALUE;
267     } else if (updateResult == BufferLayerConsumer::BUFFER_REJECTED) {
268         // If the buffer has been rejected, remove it from the shadow queue
269         // and return early
270         if (queuedBuffer) {
271             Mutex::Autolock lock(mQueueItemLock);
272             mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
273             mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
274             if (mQueueItems[0].surfaceFrame) {
275                 addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame);
276             }
277             mQueueItems.erase(mQueueItems.begin());
278             mQueuedFrames--;
279         }
280         return BAD_VALUE;
281     } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
282         // This can occur if something goes wrong when trying to create the
283         // EGLImage for this buffer. If this happens, the buffer has already
284         // been released, so we need to clean up the queue and bug out
285         // early.
286         if (queuedBuffer) {
287             Mutex::Autolock lock(mQueueItemLock);
288             for (auto& [item, surfaceFrame] : mQueueItems) {
289                 if (surfaceFrame) {
290                     addSurfaceFrameDroppedForBuffer(surfaceFrame);
291                 }
292             }
293             mQueueItems.clear();
294             mQueuedFrames = 0;
295             mFlinger->mTimeStats->onDestroy(layerId);
296             mFlinger->mFrameTracer->onDestroy(layerId);
297         }
298 
299         // Once we have hit this state, the shadow queue may no longer
300         // correctly reflect the incoming BufferQueue's contents, so even if
301         // updateTexImage starts working, the only safe course of action is
302         // to continue to ignore updates.
303         mUpdateTexImageFailed = true;
304 
305         return BAD_VALUE;
306     }
307 
308     if (queuedBuffer) {
309         // Autolock scope
310         auto currentFrameNumber = mConsumer->getFrameNumber();
311 
312         Mutex::Autolock lock(mQueueItemLock);
313 
314         // Remove any stale buffers that have been dropped during
315         // updateTexImage
316         while (mQueueItems[0].item.mFrameNumber != currentFrameNumber) {
317             mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage);
318             mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber);
319             if (mQueueItems[0].surfaceFrame) {
320                 addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame);
321             }
322             mQueueItems.erase(mQueueItems.begin());
323             mQueuedFrames--;
324         }
325 
326         uint64_t bufferID = mQueueItems[0].item.mGraphicBuffer->getId();
327         mFlinger->mTimeStats->setLatchTime(layerId, currentFrameNumber, latchTime);
328         mFlinger->mFrameTracer->traceTimestamp(layerId, bufferID, currentFrameNumber, latchTime,
329                                                FrameTracer::FrameEvent::LATCH);
330 
331         if (mQueueItems[0].surfaceFrame) {
332             addSurfaceFramePresentedForBuffer(mQueueItems[0].surfaceFrame,
333                                               mQueueItems[0].item.mFenceTime->getSignalTime(),
334                                               latchTime);
335         }
336         mQueueItems.erase(mQueueItems.begin());
337     }
338 
339     // Decrement the queued-frames count.  Signal another event if we
340     // have more frames pending.
341     if ((queuedBuffer && mQueuedFrames.fetch_sub(1) > 1) || mAutoRefresh) {
342         mFlinger->signalLayerUpdate();
343     }
344 
345     return NO_ERROR;
346 }
347 
updateActiveBuffer()348 status_t BufferQueueLayer::updateActiveBuffer() {
349     // update the active buffer
350     mPreviousBufferId = getCurrentBufferId();
351     mBufferInfo.mBuffer =
352             mConsumer->getCurrentBuffer(&mBufferInfo.mBufferSlot, &mBufferInfo.mFence);
353 
354     if (mBufferInfo.mBuffer == nullptr) {
355         // this can only happen if the very first buffer was rejected.
356         return BAD_VALUE;
357     }
358     return NO_ERROR;
359 }
360 
updateFrameNumber(nsecs_t latchTime)361 status_t BufferQueueLayer::updateFrameNumber(nsecs_t latchTime) {
362     mPreviousFrameNumber = mCurrentFrameNumber;
363     mCurrentFrameNumber = mConsumer->getFrameNumber();
364 
365     {
366         Mutex::Autolock lock(mFrameEventHistoryMutex);
367         mFrameEventHistory.addLatch(mCurrentFrameNumber, latchTime);
368     }
369     return NO_ERROR;
370 }
371 
setFrameTimelineInfoForBuffer(const FrameTimelineInfo & frameTimelineInfo)372 void BufferQueueLayer::setFrameTimelineInfoForBuffer(const FrameTimelineInfo& frameTimelineInfo) {
373     mFrameTimelineInfo = frameTimelineInfo;
374 }
375 
376 // -----------------------------------------------------------------------
377 // Interface implementation for BufferLayerConsumer::ContentsChangedListener
378 // -----------------------------------------------------------------------
379 
onFrameDequeued(const uint64_t bufferId)380 void BufferQueueLayer::onFrameDequeued(const uint64_t bufferId) {
381     const int32_t layerId = getSequence();
382     mFlinger->mFrameTracer->traceNewLayer(layerId, getName().c_str());
383     mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, FrameTracer::UNSPECIFIED_FRAME_NUMBER,
384                                            systemTime(), FrameTracer::FrameEvent::DEQUEUE);
385 }
386 
onFrameDetached(const uint64_t bufferId)387 void BufferQueueLayer::onFrameDetached(const uint64_t bufferId) {
388     const int32_t layerId = getSequence();
389     mFlinger->mFrameTracer->traceNewLayer(layerId, getName().c_str());
390     mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, FrameTracer::UNSPECIFIED_FRAME_NUMBER,
391                                            systemTime(), FrameTracer::FrameEvent::DETACH);
392 }
393 
onFrameCancelled(const uint64_t bufferId)394 void BufferQueueLayer::onFrameCancelled(const uint64_t bufferId) {
395     const int32_t layerId = getSequence();
396     mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, FrameTracer::UNSPECIFIED_FRAME_NUMBER,
397                                            systemTime(), FrameTracer::FrameEvent::CANCEL);
398 }
399 
onFrameAvailable(const BufferItem & item)400 void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
401     const int32_t layerId = getSequence();
402     const uint64_t bufferId = item.mGraphicBuffer->getId();
403     mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, item.mFrameNumber, systemTime(),
404                                            FrameTracer::FrameEvent::QUEUE);
405     mFlinger->mFrameTracer->traceFence(layerId, bufferId, item.mFrameNumber,
406                                        std::make_shared<FenceTime>(item.mFence),
407                                        FrameTracer::FrameEvent::ACQUIRE_FENCE);
408 
409     ATRACE_CALL();
410     // Add this buffer from our internal queue tracker
411     { // Autolock scope
412         const nsecs_t presentTime = item.mIsAutoTimestamp ? 0 : item.mTimestamp;
413         mFlinger->mScheduler->recordLayerHistory(this, presentTime,
414                                                  LayerHistory::LayerUpdateType::Buffer);
415 
416         Mutex::Autolock lock(mQueueItemLock);
417         // Reset the frame number tracker when we receive the first buffer after
418         // a frame number reset
419         if (item.mFrameNumber == 1) {
420             mLastFrameNumberReceived = 0;
421         }
422 
423         // Ensure that callbacks are handled in order
424         while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
425             status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500));
426             if (result != NO_ERROR) {
427                 ALOGE("[%s] Timed out waiting on callback", getDebugName());
428                 break;
429             }
430         }
431 
432         auto surfaceFrame = createSurfaceFrameForBuffer(mFrameTimelineInfo, systemTime(), mName);
433 
434         mQueueItems.push_back({item, surfaceFrame});
435         mQueuedFrames++;
436 
437         // Wake up any pending callbacks
438         mLastFrameNumberReceived = item.mFrameNumber;
439         mQueueItemCondition.broadcast();
440     }
441 
442     mFlinger->mInterceptor->saveBufferUpdate(layerId, item.mGraphicBuffer->getWidth(),
443                                              item.mGraphicBuffer->getHeight(), item.mFrameNumber);
444 
445     mFlinger->signalLayerUpdate();
446     mConsumer->onBufferAvailable(item);
447 }
448 
onFrameReplaced(const BufferItem & item)449 void BufferQueueLayer::onFrameReplaced(const BufferItem& item) {
450     ATRACE_CALL();
451     { // Autolock scope
452         Mutex::Autolock lock(mQueueItemLock);
453 
454         // Ensure that callbacks are handled in order
455         while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
456             status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500));
457             if (result != NO_ERROR) {
458                 ALOGE("[%s] Timed out waiting on callback", getDebugName());
459                 break;
460             }
461         }
462 
463         if (!hasFrameUpdate()) {
464             ALOGE("Can't replace a frame on an empty queue");
465             return;
466         }
467 
468         auto surfaceFrame = createSurfaceFrameForBuffer(mFrameTimelineInfo, systemTime(), mName);
469         mQueueItems[mQueueItems.size() - 1].item = item;
470         mQueueItems[mQueueItems.size() - 1].surfaceFrame = std::move(surfaceFrame);
471 
472         // Wake up any pending callbacks
473         mLastFrameNumberReceived = item.mFrameNumber;
474         mQueueItemCondition.broadcast();
475     }
476 
477     const int32_t layerId = getSequence();
478     const uint64_t bufferId = item.mGraphicBuffer->getId();
479     mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, item.mFrameNumber, systemTime(),
480                                            FrameTracer::FrameEvent::QUEUE);
481     mFlinger->mFrameTracer->traceFence(layerId, bufferId, item.mFrameNumber,
482                                        std::make_shared<FenceTime>(item.mFence),
483                                        FrameTracer::FrameEvent::ACQUIRE_FENCE);
484     mConsumer->onBufferAvailable(item);
485 }
486 
onSidebandStreamChanged()487 void BufferQueueLayer::onSidebandStreamChanged() {
488     bool sidebandStreamChanged = false;
489     if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, true)) {
490         // mSidebandStreamChanged was changed to true
491         mFlinger->signalLayerUpdate();
492     }
493 }
494 
495 // -----------------------------------------------------------------------
496 
onFirstRef()497 void BufferQueueLayer::onFirstRef() {
498     BufferLayer::onFirstRef();
499 
500     // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
501     sp<IGraphicBufferProducer> producer;
502     sp<IGraphicBufferConsumer> consumer;
503     mFlinger->getFactory().createBufferQueue(&producer, &consumer, true);
504     mProducer = mFlinger->getFactory().createMonitoredProducer(producer, mFlinger, this);
505     mConsumer =
506             mFlinger->getFactory().createBufferLayerConsumer(consumer, mFlinger->getRenderEngine(),
507                                                              mTextureName, this);
508     mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
509 
510     mContentsChangedListener = new ContentsChangedListener(this);
511     mConsumer->setContentsChangedListener(mContentsChangedListener);
512     mConsumer->setName(String8(mName.data(), mName.size()));
513 
514     mProducer->setMaxDequeuedBufferCount(2);
515 }
516 
setDefaultBufferProperties(uint32_t w,uint32_t h,PixelFormat format)517 status_t BufferQueueLayer::setDefaultBufferProperties(uint32_t w, uint32_t h, PixelFormat format) {
518     uint32_t const maxSurfaceDims =
519           std::min(mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
520 
521     // never allow a surface larger than what our underlying GL implementation
522     // can handle.
523     if ((uint32_t(w) > maxSurfaceDims) || (uint32_t(h) > maxSurfaceDims)) {
524         ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
525         return BAD_VALUE;
526     }
527 
528     setDefaultBufferSize(w, h);
529     mConsumer->setDefaultBufferFormat(format);
530     mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
531 
532     return NO_ERROR;
533 }
534 
getProducer() const535 sp<IGraphicBufferProducer> BufferQueueLayer::getProducer() const {
536     return mProducer;
537 }
538 
getProducerStickyTransform() const539 uint32_t BufferQueueLayer::getProducerStickyTransform() const {
540     int producerStickyTransform = 0;
541     int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
542     if (ret != OK) {
543         ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
544               strerror(-ret), ret);
545         return 0;
546     }
547     return static_cast<uint32_t>(producerStickyTransform);
548 }
549 
gatherBufferInfo()550 void BufferQueueLayer::gatherBufferInfo() {
551     BufferLayer::gatherBufferInfo();
552 
553     mBufferInfo.mDesiredPresentTime = mConsumer->getTimestamp();
554     mBufferInfo.mFenceTime = mConsumer->getCurrentFenceTime();
555     mBufferInfo.mFence = mConsumer->getCurrentFence();
556     mBufferInfo.mTransform = mConsumer->getCurrentTransform();
557     mBufferInfo.mDataspace = translateDataspace(mConsumer->getCurrentDataSpace());
558     mBufferInfo.mCrop = mConsumer->getCurrentCrop();
559     mBufferInfo.mScaleMode = mConsumer->getCurrentScalingMode();
560     mBufferInfo.mSurfaceDamage = mConsumer->getSurfaceDamage();
561     mBufferInfo.mHdrMetadata = mConsumer->getCurrentHdrMetadata();
562     mBufferInfo.mApi = mConsumer->getCurrentApi();
563     mBufferInfo.mTransformToDisplayInverse = mConsumer->getTransformToDisplayInverse();
564 }
565 
createClone()566 sp<Layer> BufferQueueLayer::createClone() {
567     LayerCreationArgs args(mFlinger.get(), nullptr, mName + " (Mirror)", 0, 0, 0, LayerMetadata());
568     args.textureName = mTextureName;
569     sp<BufferQueueLayer> layer = mFlinger->getFactory().createBufferQueueLayer(args);
570     layer->setInitialValuesForClone(this);
571 
572     return layer;
573 }
574 
575 // -----------------------------------------------------------------------
576 // Interface implementation for BufferLayerConsumer::ContentsChangedListener
577 // -----------------------------------------------------------------------
578 
onFrameAvailable(const BufferItem & item)579 void BufferQueueLayer::ContentsChangedListener::onFrameAvailable(const BufferItem& item) {
580     Mutex::Autolock lock(mMutex);
581     if (mBufferQueueLayer != nullptr) {
582         mBufferQueueLayer->onFrameAvailable(item);
583     }
584 }
585 
onFrameReplaced(const BufferItem & item)586 void BufferQueueLayer::ContentsChangedListener::onFrameReplaced(const BufferItem& item) {
587     Mutex::Autolock lock(mMutex);
588     if (mBufferQueueLayer != nullptr) {
589         mBufferQueueLayer->onFrameReplaced(item);
590     }
591 }
592 
onSidebandStreamChanged()593 void BufferQueueLayer::ContentsChangedListener::onSidebandStreamChanged() {
594     Mutex::Autolock lock(mMutex);
595     if (mBufferQueueLayer != nullptr) {
596         mBufferQueueLayer->onSidebandStreamChanged();
597     }
598 }
599 
onFrameDequeued(const uint64_t bufferId)600 void BufferQueueLayer::ContentsChangedListener::onFrameDequeued(const uint64_t bufferId) {
601     Mutex::Autolock lock(mMutex);
602     if (mBufferQueueLayer != nullptr) {
603         mBufferQueueLayer->onFrameDequeued(bufferId);
604     }
605 }
606 
onFrameDetached(const uint64_t bufferId)607 void BufferQueueLayer::ContentsChangedListener::onFrameDetached(const uint64_t bufferId) {
608     Mutex::Autolock lock(mMutex);
609     if (mBufferQueueLayer != nullptr) {
610         mBufferQueueLayer->onFrameDetached(bufferId);
611     }
612 }
613 
onFrameCancelled(const uint64_t bufferId)614 void BufferQueueLayer::ContentsChangedListener::onFrameCancelled(const uint64_t bufferId) {
615     Mutex::Autolock lock(mMutex);
616     if (mBufferQueueLayer != nullptr) {
617         mBufferQueueLayer->onFrameCancelled(bufferId);
618     }
619 }
620 
abandon()621 void BufferQueueLayer::ContentsChangedListener::abandon() {
622     Mutex::Autolock lock(mMutex);
623     mBufferQueueLayer = nullptr;
624 }
625 
626 // -----------------------------------------------------------------------
627 
628 } // namespace android
629 
630 // TODO(b/129481165): remove the #pragma below and fix conversion issues
631 #pragma clang diagnostic pop // ignored "-Wconversion -Wextra"
632