• 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 #undef LOG_TAG
18 #define LOG_TAG "BufferQueueLayer"
19 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
20 #include <compositionengine/Display.h>
21 #include <compositionengine/Layer.h>
22 #include <compositionengine/OutputLayer.h>
23 #include <compositionengine/impl/LayerCompositionState.h>
24 #include <compositionengine/impl/OutputLayerCompositionState.h>
25 #include <gui/BufferQueueConsumer.h>
26 #include <system/window.h>
27 
28 #include "BufferQueueLayer.h"
29 #include "LayerRejecter.h"
30 #include "SurfaceInterceptor.h"
31 
32 #include "TimeStats/TimeStats.h"
33 
34 namespace android {
35 
BufferQueueLayer(const LayerCreationArgs & args)36 BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) {}
37 
~BufferQueueLayer()38 BufferQueueLayer::~BufferQueueLayer() {
39     mConsumer->abandon();
40 }
41 
42 // -----------------------------------------------------------------------
43 // Interface implementation for Layer
44 // -----------------------------------------------------------------------
45 
onLayerDisplayed(const sp<Fence> & releaseFence)46 void BufferQueueLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
47     mConsumer->setReleaseFence(releaseFence);
48 }
49 
setTransformHint(uint32_t orientation) const50 void BufferQueueLayer::setTransformHint(uint32_t orientation) const {
51     mConsumer->setTransformHint(orientation);
52 }
53 
getOccupancyHistory(bool forceFlush)54 std::vector<OccupancyTracker::Segment> BufferQueueLayer::getOccupancyHistory(bool forceFlush) {
55     std::vector<OccupancyTracker::Segment> history;
56     status_t result = mConsumer->getOccupancyHistory(forceFlush, &history);
57     if (result != NO_ERROR) {
58         ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result);
59         return {};
60     }
61     return history;
62 }
63 
getTransformToDisplayInverse() const64 bool BufferQueueLayer::getTransformToDisplayInverse() const {
65     return mConsumer->getTransformToDisplayInverse();
66 }
67 
releasePendingBuffer(nsecs_t dequeueReadyTime)68 void BufferQueueLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
69     if (!mConsumer->releasePendingBuffer()) {
70         return;
71     }
72 
73     auto releaseFenceTime = std::make_shared<FenceTime>(mConsumer->getPrevFinalReleaseFence());
74     mReleaseTimeline.updateSignalTimes();
75     mReleaseTimeline.push(releaseFenceTime);
76 
77     Mutex::Autolock lock(mFrameEventHistoryMutex);
78     if (mPreviousFrameNumber != 0) {
79         mFrameEventHistory.addRelease(mPreviousFrameNumber, dequeueReadyTime,
80                                       std::move(releaseFenceTime));
81     }
82 }
83 
setDefaultBufferSize(uint32_t w,uint32_t h)84 void BufferQueueLayer::setDefaultBufferSize(uint32_t w, uint32_t h) {
85     mConsumer->setDefaultBufferSize(w, h);
86 }
87 
getQueuedFrameCount() const88 int32_t BufferQueueLayer::getQueuedFrameCount() const {
89     return mQueuedFrames;
90 }
91 
shouldPresentNow(nsecs_t expectedPresentTime) const92 bool BufferQueueLayer::shouldPresentNow(nsecs_t expectedPresentTime) const {
93     if (getSidebandStreamChanged() || getAutoRefresh()) {
94         return true;
95     }
96 
97     if (!hasFrameUpdate()) {
98         return false;
99     }
100 
101     Mutex::Autolock lock(mQueueItemLock);
102 
103     const int64_t addedTime = mQueueItems[0].mTimestamp;
104 
105     // Ignore timestamps more than a second in the future
106     const bool isPlausible = addedTime < (expectedPresentTime + s2ns(1));
107     ALOGW_IF(!isPlausible,
108              "[%s] Timestamp %" PRId64 " seems implausible "
109              "relative to expectedPresent %" PRId64,
110              mName.string(), addedTime, expectedPresentTime);
111 
112     const bool isDue = addedTime < expectedPresentTime;
113     return isDue || !isPlausible;
114 }
115 
116 // -----------------------------------------------------------------------
117 // Interface implementation for BufferLayer
118 // -----------------------------------------------------------------------
119 
fenceHasSignaled() const120 bool BufferQueueLayer::fenceHasSignaled() const {
121     if (latchUnsignaledBuffers()) {
122         return true;
123     }
124 
125     if (!hasFrameUpdate()) {
126         return true;
127     }
128 
129     Mutex::Autolock lock(mQueueItemLock);
130     if (mQueueItems[0].mIsDroppable) {
131         // Even though this buffer's fence may not have signaled yet, it could
132         // be replaced by another buffer before it has a chance to, which means
133         // that it's possible to get into a situation where a buffer is never
134         // able to be latched. To avoid this, grab this buffer anyway.
135         return true;
136     }
137     return mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
138 }
139 
framePresentTimeIsCurrent() const140 bool BufferQueueLayer::framePresentTimeIsCurrent() const {
141     if (!hasFrameUpdate() || isRemovedFromCurrentState()) {
142         return true;
143     }
144 
145     Mutex::Autolock lock(mQueueItemLock);
146     return mQueueItems[0].mTimestamp <= mFlinger->mScheduler->expectedPresentTime();
147 }
148 
getDesiredPresentTime()149 nsecs_t BufferQueueLayer::getDesiredPresentTime() {
150     return mConsumer->getTimestamp();
151 }
152 
getCurrentFenceTime() const153 std::shared_ptr<FenceTime> BufferQueueLayer::getCurrentFenceTime() const {
154     return mConsumer->getCurrentFenceTime();
155 }
156 
getDrawingTransformMatrix(float * matrix)157 void BufferQueueLayer::getDrawingTransformMatrix(float *matrix) {
158     return mConsumer->getTransformMatrix(matrix);
159 }
160 
161 // NOTE: SurfaceFlinger's definitions of "Current" and "Drawing" do not neatly map to BufferQueue's
162 // These functions get the fields for the frame that is currently in SurfaceFlinger's Drawing state
163 // so the functions start with "getDrawing". The data is retrieved from the BufferQueueConsumer's
164 // current buffer so the consumer functions start with "getCurrent".
165 //
166 // This results in the rather confusing functions below.
getDrawingTransform() const167 uint32_t BufferQueueLayer::getDrawingTransform() const {
168     return mConsumer->getCurrentTransform();
169 }
170 
getDrawingDataSpace() const171 ui::Dataspace BufferQueueLayer::getDrawingDataSpace() const {
172     return mConsumer->getCurrentDataSpace();
173 }
174 
getDrawingCrop() const175 Rect BufferQueueLayer::getDrawingCrop() const {
176     return mConsumer->getCurrentCrop();
177 }
178 
getDrawingScalingMode() const179 uint32_t BufferQueueLayer::getDrawingScalingMode() const {
180     return mConsumer->getCurrentScalingMode();
181 }
182 
getDrawingSurfaceDamage() const183 Region BufferQueueLayer::getDrawingSurfaceDamage() const {
184     return mConsumer->getSurfaceDamage();
185 }
186 
getDrawingHdrMetadata() const187 const HdrMetadata& BufferQueueLayer::getDrawingHdrMetadata() const {
188     return mConsumer->getCurrentHdrMetadata();
189 }
190 
getDrawingApi() const191 int BufferQueueLayer::getDrawingApi() const {
192     return mConsumer->getCurrentApi();
193 }
194 
getPixelFormat() const195 PixelFormat BufferQueueLayer::getPixelFormat() const {
196     return mFormat;
197 }
198 
getFrameNumber() const199 uint64_t BufferQueueLayer::getFrameNumber() const {
200     Mutex::Autolock lock(mQueueItemLock);
201     uint64_t frameNumber = mQueueItems[0].mFrameNumber;
202 
203     // The head of the queue will be dropped if there are signaled and timely frames behind it
204     nsecs_t expectedPresentTime = mFlinger->mScheduler->expectedPresentTime();
205 
206     if (isRemovedFromCurrentState()) {
207         expectedPresentTime = 0;
208     }
209 
210     for (int i = 1; i < mQueueItems.size(); i++) {
211         const bool fenceSignaled =
212                 mQueueItems[i].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
213         if (!fenceSignaled) {
214             break;
215         }
216 
217         // We don't drop frames without explicit timestamps
218         if (mQueueItems[i].mIsAutoTimestamp) {
219             break;
220         }
221 
222         const nsecs_t desiredPresent = mQueueItems[i].mTimestamp;
223         if (desiredPresent < expectedPresentTime - BufferQueueConsumer::MAX_REASONABLE_NSEC ||
224             desiredPresent > expectedPresentTime) {
225             break;
226         }
227 
228         frameNumber = mQueueItems[i].mFrameNumber;
229     }
230 
231     return frameNumber;
232 }
233 
getAutoRefresh() const234 bool BufferQueueLayer::getAutoRefresh() const {
235     return mAutoRefresh;
236 }
237 
getSidebandStreamChanged() const238 bool BufferQueueLayer::getSidebandStreamChanged() const {
239     return mSidebandStreamChanged;
240 }
241 
latchSidebandStream(bool & recomputeVisibleRegions)242 bool BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
243     bool sidebandStreamChanged = true;
244     if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) {
245         // mSidebandStreamChanged was changed to false
246         auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
247         layerCompositionState.sidebandStream = mConsumer->getSidebandStream();
248         if (layerCompositionState.sidebandStream != nullptr) {
249             setTransactionFlags(eTransactionNeeded);
250             mFlinger->setTransactionFlags(eTraversalNeeded);
251         }
252         recomputeVisibleRegions = true;
253 
254         return true;
255     }
256     return false;
257 }
258 
hasFrameUpdate() const259 bool BufferQueueLayer::hasFrameUpdate() const {
260     return mQueuedFrames > 0;
261 }
262 
setFilteringEnabled(bool enabled)263 void BufferQueueLayer::setFilteringEnabled(bool enabled) {
264     return mConsumer->setFilteringEnabled(enabled);
265 }
266 
bindTextureImage()267 status_t BufferQueueLayer::bindTextureImage() {
268     return mConsumer->bindTextureImage();
269 }
270 
updateTexImage(bool & recomputeVisibleRegions,nsecs_t latchTime)271 status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime) {
272     // This boolean is used to make sure that SurfaceFlinger's shadow copy
273     // of the buffer queue isn't modified when the buffer queue is returning
274     // BufferItem's that weren't actually queued. This can happen in shared
275     // buffer mode.
276     bool queuedBuffer = false;
277     const int32_t layerID = getSequence();
278     LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
279                     getProducerStickyTransform() != 0, mName.string(), mOverrideScalingMode,
280                     getTransformToDisplayInverse(), mFreezeGeometryUpdates);
281 
282     nsecs_t expectedPresentTime = mFlinger->mScheduler->expectedPresentTime();
283 
284     if (isRemovedFromCurrentState()) {
285         expectedPresentTime = 0;
286     }
287 
288     // updateTexImage() below might drop the some buffers at the head of the queue if there is a
289     // buffer behind them which is timely to be presented. However this buffer may not be signaled
290     // yet. The code below makes sure that this wouldn't happen by setting maxFrameNumber to the
291     // last buffer that was signaled.
292     uint64_t lastSignaledFrameNumber = mLastFrameNumberReceived;
293     {
294         Mutex::Autolock lock(mQueueItemLock);
295         for (int i = 0; i < mQueueItems.size(); i++) {
296             bool fenceSignaled =
297                     mQueueItems[i].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING;
298             if (!fenceSignaled) {
299                 break;
300             }
301             lastSignaledFrameNumber = mQueueItems[i].mFrameNumber;
302         }
303     }
304     const uint64_t maxFrameNumberToAcquire =
305             std::min(mLastFrameNumberReceived.load(), lastSignaledFrameNumber);
306 
307     status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh,
308                                                       &queuedBuffer, maxFrameNumberToAcquire);
309     if (updateResult == BufferQueue::PRESENT_LATER) {
310         // Producer doesn't want buffer to be displayed yet.  Signal a
311         // layer update so we check again at the next opportunity.
312         mFlinger->signalLayerUpdate();
313         return BAD_VALUE;
314     } else if (updateResult == BufferLayerConsumer::BUFFER_REJECTED) {
315         // If the buffer has been rejected, remove it from the shadow queue
316         // and return early
317         if (queuedBuffer) {
318             Mutex::Autolock lock(mQueueItemLock);
319             mFlinger->mTimeStats->removeTimeRecord(layerID, mQueueItems[0].mFrameNumber);
320             mQueueItems.removeAt(0);
321             mQueuedFrames--;
322         }
323         return BAD_VALUE;
324     } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
325         // This can occur if something goes wrong when trying to create the
326         // EGLImage for this buffer. If this happens, the buffer has already
327         // been released, so we need to clean up the queue and bug out
328         // early.
329         if (queuedBuffer) {
330             Mutex::Autolock lock(mQueueItemLock);
331             mQueueItems.clear();
332             mQueuedFrames = 0;
333             mFlinger->mTimeStats->onDestroy(layerID);
334         }
335 
336         // Once we have hit this state, the shadow queue may no longer
337         // correctly reflect the incoming BufferQueue's contents, so even if
338         // updateTexImage starts working, the only safe course of action is
339         // to continue to ignore updates.
340         mUpdateTexImageFailed = true;
341 
342         return BAD_VALUE;
343     }
344 
345     if (queuedBuffer) {
346         // Autolock scope
347         auto currentFrameNumber = mConsumer->getFrameNumber();
348 
349         Mutex::Autolock lock(mQueueItemLock);
350 
351         // Remove any stale buffers that have been dropped during
352         // updateTexImage
353         while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
354             mFlinger->mTimeStats->removeTimeRecord(layerID, mQueueItems[0].mFrameNumber);
355             mQueueItems.removeAt(0);
356             mQueuedFrames--;
357         }
358 
359         mFlinger->mTimeStats->setAcquireFence(layerID, currentFrameNumber,
360                                               mQueueItems[0].mFenceTime);
361         mFlinger->mTimeStats->setLatchTime(layerID, currentFrameNumber, latchTime);
362 
363         mQueueItems.removeAt(0);
364     }
365 
366     // Decrement the queued-frames count.  Signal another event if we
367     // have more frames pending.
368     if ((queuedBuffer && mQueuedFrames.fetch_sub(1) > 1) || mAutoRefresh) {
369         mFlinger->signalLayerUpdate();
370     }
371 
372     return NO_ERROR;
373 }
374 
updateActiveBuffer()375 status_t BufferQueueLayer::updateActiveBuffer() {
376     // update the active buffer
377     mActiveBuffer = mConsumer->getCurrentBuffer(&mActiveBufferSlot, &mActiveBufferFence);
378     auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
379     layerCompositionState.buffer = mActiveBuffer;
380     layerCompositionState.bufferSlot = mActiveBufferSlot;
381 
382     if (mActiveBuffer == nullptr) {
383         // this can only happen if the very first buffer was rejected.
384         return BAD_VALUE;
385     }
386     return NO_ERROR;
387 }
388 
updateFrameNumber(nsecs_t latchTime)389 status_t BufferQueueLayer::updateFrameNumber(nsecs_t latchTime) {
390     mPreviousFrameNumber = mCurrentFrameNumber;
391     mCurrentFrameNumber = mConsumer->getFrameNumber();
392 
393     {
394         Mutex::Autolock lock(mFrameEventHistoryMutex);
395         mFrameEventHistory.addLatch(mCurrentFrameNumber, latchTime);
396     }
397     return NO_ERROR;
398 }
399 
setHwcLayerBuffer(const sp<const DisplayDevice> & display)400 void BufferQueueLayer::setHwcLayerBuffer(const sp<const DisplayDevice>& display) {
401     const auto outputLayer = findOutputLayerForDisplay(display);
402     LOG_FATAL_IF(!outputLayer);
403     LOG_FATAL_IF(!outputLayer->getState.hwc);
404     auto& hwcLayer = (*outputLayer->getState().hwc).hwcLayer;
405 
406     uint32_t hwcSlot = 0;
407     sp<GraphicBuffer> hwcBuffer;
408 
409     // INVALID_BUFFER_SLOT is used to identify BufferStateLayers.  Default to 0
410     // for BufferQueueLayers
411     int slot = (mActiveBufferSlot == BufferQueue::INVALID_BUFFER_SLOT) ? 0 : mActiveBufferSlot;
412     (*outputLayer->editState().hwc)
413             .hwcBufferCache.getHwcBuffer(slot, mActiveBuffer, &hwcSlot, &hwcBuffer);
414 
415     auto acquireFence = mConsumer->getCurrentFence();
416     auto error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
417     if (error != HWC2::Error::None) {
418         ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(), mActiveBuffer->handle,
419               to_string(error).c_str(), static_cast<int32_t>(error));
420     }
421 
422     auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
423     layerCompositionState.bufferSlot = mActiveBufferSlot;
424     layerCompositionState.buffer = mActiveBuffer;
425     layerCompositionState.acquireFence = acquireFence;
426 }
427 
428 // -----------------------------------------------------------------------
429 // Interface implementation for BufferLayerConsumer::ContentsChangedListener
430 // -----------------------------------------------------------------------
431 
fakeVsync()432 void BufferQueueLayer::fakeVsync() {
433     mRefreshPending = false;
434     bool ignored = false;
435     latchBuffer(ignored, systemTime());
436     usleep(16000);
437     releasePendingBuffer(systemTime());
438 }
439 
onFrameAvailable(const BufferItem & item)440 void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
441     ATRACE_CALL();
442     // Add this buffer from our internal queue tracker
443     { // Autolock scope
444         if (mFlinger->mUseSmart90ForVideo) {
445             const nsecs_t presentTime = item.mIsAutoTimestamp ? 0 : item.mTimestamp;
446             mFlinger->mScheduler->addLayerPresentTimeAndHDR(mSchedulerLayerHandle, presentTime,
447                                                             item.mHdrMetadata.validTypes != 0);
448         }
449 
450         Mutex::Autolock lock(mQueueItemLock);
451         // Reset the frame number tracker when we receive the first buffer after
452         // a frame number reset
453         if (item.mFrameNumber == 1) {
454             mLastFrameNumberReceived = 0;
455         }
456 
457         // Ensure that callbacks are handled in order
458         while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
459             status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500));
460             if (result != NO_ERROR) {
461                 ALOGE("[%s] Timed out waiting on callback", mName.string());
462             }
463         }
464 
465         mQueueItems.push_back(item);
466         mQueuedFrames++;
467 
468         // Wake up any pending callbacks
469         mLastFrameNumberReceived = item.mFrameNumber;
470         mQueueItemCondition.broadcast();
471     }
472 
473     mFlinger->mInterceptor->saveBufferUpdate(this, item.mGraphicBuffer->getWidth(),
474                                              item.mGraphicBuffer->getHeight(), item.mFrameNumber);
475 
476     // If this layer is orphaned, then we run a fake vsync pulse so that
477     // dequeueBuffer doesn't block indefinitely.
478     if (isRemovedFromCurrentState()) {
479         fakeVsync();
480     } else {
481         mFlinger->signalLayerUpdate();
482     }
483     mConsumer->onBufferAvailable(item);
484 }
485 
onFrameReplaced(const BufferItem & item)486 void BufferQueueLayer::onFrameReplaced(const BufferItem& item) {
487     ATRACE_CALL();
488     { // Autolock scope
489         Mutex::Autolock lock(mQueueItemLock);
490 
491         // Ensure that callbacks are handled in order
492         while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
493             status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500));
494             if (result != NO_ERROR) {
495                 ALOGE("[%s] Timed out waiting on callback", mName.string());
496             }
497         }
498 
499         if (!hasFrameUpdate()) {
500             ALOGE("Can't replace a frame on an empty queue");
501             return;
502         }
503         mQueueItems.editItemAt(mQueueItems.size() - 1) = item;
504 
505         // Wake up any pending callbacks
506         mLastFrameNumberReceived = item.mFrameNumber;
507         mQueueItemCondition.broadcast();
508     }
509     mConsumer->onBufferAvailable(item);
510 }
511 
onSidebandStreamChanged()512 void BufferQueueLayer::onSidebandStreamChanged() {
513     bool sidebandStreamChanged = false;
514     if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, true)) {
515         // mSidebandStreamChanged was changed to true
516         mFlinger->signalLayerUpdate();
517     }
518 }
519 
520 // -----------------------------------------------------------------------
521 
onFirstRef()522 void BufferQueueLayer::onFirstRef() {
523     BufferLayer::onFirstRef();
524 
525     // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
526     sp<IGraphicBufferProducer> producer;
527     sp<IGraphicBufferConsumer> consumer;
528     BufferQueue::createBufferQueue(&producer, &consumer, true);
529     mProducer = new MonitoredProducer(producer, mFlinger, this);
530     {
531         // Grab the SF state lock during this since it's the only safe way to access RenderEngine
532         Mutex::Autolock lock(mFlinger->mStateLock);
533         mConsumer =
534                 new BufferLayerConsumer(consumer, mFlinger->getRenderEngine(), mTextureName, this);
535     }
536     mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
537     mConsumer->setContentsChangedListener(this);
538     mConsumer->setName(mName);
539 
540     // BufferQueueCore::mMaxDequeuedBufferCount is default to 1
541     if (!mFlinger->isLayerTripleBufferingDisabled()) {
542         mProducer->setMaxDequeuedBufferCount(2);
543     }
544 
545     if (const auto display = mFlinger->getDefaultDisplayDevice()) {
546         updateTransformHint(display);
547     }
548 }
549 
setDefaultBufferProperties(uint32_t w,uint32_t h,PixelFormat format)550 status_t BufferQueueLayer::setDefaultBufferProperties(uint32_t w, uint32_t h, PixelFormat format) {
551     uint32_t const maxSurfaceDims =
552           std::min(mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
553 
554     // never allow a surface larger than what our underlying GL implementation
555     // can handle.
556     if ((uint32_t(w) > maxSurfaceDims) || (uint32_t(h) > maxSurfaceDims)) {
557         ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
558         return BAD_VALUE;
559     }
560 
561     mFormat = format;
562 
563     setDefaultBufferSize(w, h);
564     mConsumer->setDefaultBufferFormat(format);
565     mConsumer->setConsumerUsageBits(getEffectiveUsage(0));
566 
567     return NO_ERROR;
568 }
569 
getProducer() const570 sp<IGraphicBufferProducer> BufferQueueLayer::getProducer() const {
571     return mProducer;
572 }
573 
getProducerStickyTransform() const574 uint32_t BufferQueueLayer::getProducerStickyTransform() const {
575     int producerStickyTransform = 0;
576     int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
577     if (ret != OK) {
578         ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
579               strerror(-ret), ret);
580         return 0;
581     }
582     return static_cast<uint32_t>(producerStickyTransform);
583 }
584 
585 } // namespace android
586