blob: 4eeaba154f0e29468dc2f0f59531e600ac29a07d [file] [log] [blame]
Marissa Wall61c58622018-07-18 10:12:20 -07001/*
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
Lloyd Pique9755fb72019-03-26 14:44:40 -070022#include "BufferStateLayer.h"
23
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080024#include <limits>
Marissa Wall61c58622018-07-18 10:12:20 -070025
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +000026#include <FrameTimeline/FrameTimeline.h>
Lloyd Pique9755fb72019-03-26 14:44:40 -070027#include <compositionengine/LayerFECompositionState.h>
Marissa Wall947d34e2019-03-29 14:03:53 -070028#include <gui/BufferQueue.h>
Marissa Wall61c58622018-07-18 10:12:20 -070029#include <private/gui/SyncFeatures.h>
Peiyong Lincbc184f2018-08-22 13:24:10 -070030#include <renderengine/Image.h>
Robert Carr38d25002021-06-11 14:30:09 -070031#include "TunnelModeEnabledReporter.h"
Marissa Wall61c58622018-07-18 10:12:20 -070032
Vishnu Nairfa247b12020-02-11 08:58:26 -080033#include "EffectLayer.h"
Adithya Srinivasanb238cd52021-02-04 17:54:05 +000034#include "FrameTracer/FrameTracer.h"
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080035#include "TimeStats/TimeStats.h"
Valerie Hau0bc09152018-12-20 07:42:47 -080036
Marissa Wall61c58622018-07-18 10:12:20 -070037namespace android {
38
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +000039using PresentState = frametimeline::SurfaceFrame::PresentState;
Vishnu Nair1506b182021-02-22 14:35:15 -080040namespace {
41void callReleaseBufferCallback(const sp<ITransactionCompletedListener>& listener,
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -070042 const sp<GraphicBuffer>& buffer, uint64_t framenumber,
43 const sp<Fence>& releaseFence, uint32_t transformHint,
44 uint32_t currentMaxAcquiredBufferCount) {
Vishnu Nair1506b182021-02-22 14:35:15 -080045 if (!listener) {
46 return;
47 }
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -070048 listener->onReleaseBuffer({buffer->getId(), framenumber},
49 releaseFence ? releaseFence : Fence::NO_FENCE, transformHint,
50 currentMaxAcquiredBufferCount);
Vishnu Nair1506b182021-02-22 14:35:15 -080051}
52} // namespace
53
Marissa Wall947d34e2019-03-29 14:03:53 -070054BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args)
55 : BufferLayer(args), mHwcSlotGenerator(new HwcSlotGenerator()) {
Robert Carr6a160312021-05-17 12:08:20 -070056 mDrawingState.dataspace = ui::Dataspace::V0_SRGB;
Vishnu Nair60356342018-11-13 13:00:45 -080057}
Marissa Wall61c58622018-07-18 10:12:20 -070058
Alec Mouri4545a8a2019-08-08 20:05:32 -070059BufferStateLayer::~BufferStateLayer() {
chaviwb4c6e582019-08-16 14:35:07 -070060 // The original layer and the clone layer share the same texture and buffer. Therefore, only
61 // one of the layers, in this case the original layer, needs to handle the deletion. The
62 // original layer and the clone should be removed at the same time so there shouldn't be any
63 // issue with the clone layer trying to use the texture.
64 if (mBufferInfo.mBuffer != nullptr && !isClone()) {
Alec Mouria90a5702021-04-16 16:36:21 +000065 callReleaseBufferCallback(mDrawingState.releaseBufferListener,
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -070066 mBufferInfo.mBuffer->getBuffer(), mBufferInfo.mFrameNumber,
67 mBufferInfo.mFence, mTransformHint,
Ady Abraham899dcdb2021-06-15 16:56:21 -070068 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
69 mOwnerUid));
Alec Mouri4545a8a2019-08-08 20:05:32 -070070 }
71}
72
Robert Carr8d958532020-11-10 14:09:16 -080073status_t BufferStateLayer::addReleaseFence(const sp<CallbackHandle>& ch,
74 const sp<Fence>& fence) {
75 if (ch == nullptr) {
76 return OK;
77 }
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -070078 ch->previousReleaseCallbackId = mPreviousReleaseCallbackId;
Robert Carr8d958532020-11-10 14:09:16 -080079 if (!ch->previousReleaseFence.get()) {
80 ch->previousReleaseFence = fence;
81 return OK;
82 }
83
84 // Below logic is lifted from ConsumerBase.cpp:
85 // Check status of fences first because merging is expensive.
86 // Merging an invalid fence with any other fence results in an
87 // invalid fence.
88 auto currentStatus = ch->previousReleaseFence->getStatus();
89 if (currentStatus == Fence::Status::Invalid) {
90 ALOGE("Existing fence has invalid state, layer: %s", mName.c_str());
91 return BAD_VALUE;
92 }
93
94 auto incomingStatus = fence->getStatus();
95 if (incomingStatus == Fence::Status::Invalid) {
96 ALOGE("New fence has invalid state, layer: %s", mName.c_str());
97 ch->previousReleaseFence = fence;
98 return BAD_VALUE;
99 }
100
101 // If both fences are signaled or both are unsignaled, we need to merge
102 // them to get an accurate timestamp.
103 if (currentStatus == incomingStatus) {
104 char fenceName[32] = {};
105 snprintf(fenceName, 32, "%.28s", mName.c_str());
106 sp<Fence> mergedFence = Fence::merge(
107 fenceName, ch->previousReleaseFence, fence);
108 if (!mergedFence.get()) {
109 ALOGE("failed to merge release fences, layer: %s", mName.c_str());
110 // synchronization is broken, the best we can do is hope fences
111 // signal in order so the new fence will act like a union
112 ch->previousReleaseFence = fence;
113 return BAD_VALUE;
114 }
115 ch->previousReleaseFence = mergedFence;
116 } else if (incomingStatus == Fence::Status::Unsignaled) {
117 // If one fence has signaled and the other hasn't, the unsignaled
118 // fence will approximately correspond with the correct timestamp.
119 // There's a small race if both fences signal at about the same time
120 // and their statuses are retrieved with unfortunate timing. However,
121 // by this point, they will have both signaled and only the timestamp
122 // will be slightly off; any dependencies after this point will
123 // already have been met.
124 ch->previousReleaseFence = fence;
125 }
126 // else if (currentStatus == Fence::Status::Unsignaled) is a no-op.
127
128 return OK;
129}
130
Marissa Wall61c58622018-07-18 10:12:20 -0700131// -----------------------------------------------------------------------
132// Interface implementation for Layer
133// -----------------------------------------------------------------------
Marissa Wallfda30bb2018-10-12 11:34:28 -0700134void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
Robert Carrccab4242021-09-28 16:53:03 -0700135
136 // If a layer has been displayed again we may need to clear
137 // the mLastClientComposition fence that we use for early release in setBuffer
138 // (as we now have a new fence which won't pass through the client composition path in some cases
139 // e.g. screenshot). We expect one call to onLayerDisplayed after receiving the GL comp fence
140 // from a single composition cycle, and want to clear on the second call
141 // (which we track with mLastClientCompositionDisplayed)
142 if (mLastClientCompositionDisplayed) {
143 mLastClientCompositionFence = nullptr;
144 mLastClientCompositionDisplayed = false;
145 } else if (mLastClientCompositionFence) {
146 mLastClientCompositionDisplayed = true;
147 }
148
Robert Carr8d958532020-11-10 14:09:16 -0800149 if (!releaseFence->isValid()) {
150 return;
151 }
Marissa Wall5a68a772018-12-22 17:43:42 -0800152 // The previous release fence notifies the client that SurfaceFlinger is done with the previous
153 // buffer that was presented on this layer. The first transaction that came in this frame that
154 // replaced the previous buffer on this layer needs this release fence, because the fence will
155 // let the client know when that previous buffer is removed from the screen.
156 //
157 // Every other transaction on this layer does not need a release fence because no other
158 // Transactions that were set on this layer this frame are going to have their preceeding buffer
159 // removed from the display this frame.
160 //
161 // For example, if we have 3 transactions this frame. The first transaction doesn't contain a
162 // buffer so it doesn't need a previous release fence because the layer still needs the previous
163 // buffer. The second transaction contains a buffer so it needs a previous release fence because
164 // the previous buffer will be released this frame. The third transaction also contains a
165 // buffer. It replaces the buffer in the second transaction. The buffer in the second
166 // transaction will now no longer be presented so it is released immediately and the third
167 // transaction doesn't need a previous release fence.
Robert Carr8d958532020-11-10 14:09:16 -0800168 sp<CallbackHandle> ch;
Marissa Wall5a68a772018-12-22 17:43:42 -0800169 for (auto& handle : mDrawingState.callbackHandles) {
chaviw0b06a8d2021-08-06 11:49:08 -0500170 if (handle->releasePreviousBuffer &&
171 mDrawingState.releaseBufferEndpoint == handle->listener) {
Robert Carr8d958532020-11-10 14:09:16 -0800172 ch = handle;
Marissa Wall5a68a772018-12-22 17:43:42 -0800173 break;
174 }
175 }
Robert Carr8d958532020-11-10 14:09:16 -0800176 auto status = addReleaseFence(ch, releaseFence);
177 if (status != OK) {
178 ALOGE("Failed to add release fence for layer %s", getName().c_str());
179 }
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700180
Valerie Haubf784642020-01-29 07:25:23 -0800181 mPreviousReleaseFence = releaseFence;
182
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700183 // Prevent tracing the same release multiple times.
184 if (mPreviousFrameNumber != mPreviousReleasedFrameNumber) {
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700185 mPreviousReleasedFrameNumber = mPreviousFrameNumber;
186 }
Marissa Wall61c58622018-07-18 10:12:20 -0700187}
188
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100189void BufferStateLayer::onSurfaceFrameCreated(
190 const std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame) {
Adithya Srinivasand17c7da2021-03-05 20:43:32 +0000191 while (mPendingJankClassifications.size() >= kPendingClassificationMaxSurfaceFrames) {
192 // Too many SurfaceFrames pending classification. The front of the deque is probably not
193 // tracked by FrameTimeline and will never be presented. This will only result in a memory
194 // leak.
195 ALOGW("Removing the front of pending jank deque from layer - %s to prevent memory leak",
196 mName.c_str());
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000197 std::string miniDump = mPendingJankClassifications.front()->miniDump();
198 ALOGD("Head SurfaceFrame mini dump\n%s", miniDump.c_str());
Adithya Srinivasand17c7da2021-03-05 20:43:32 +0000199 mPendingJankClassifications.pop_front();
200 }
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100201 mPendingJankClassifications.emplace_back(surfaceFrame);
202}
203
Valerie Haubf784642020-01-29 07:25:23 -0800204void BufferStateLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
Valerie Hau32cdc1f2019-10-21 14:45:54 -0700205 for (const auto& handle : mDrawingState.callbackHandles) {
206 handle->transformHint = mTransformHint;
Valerie Hau871d6352020-01-29 08:44:02 -0800207 handle->dequeueReadyTime = dequeueReadyTime;
Ady Abraham899dcdb2021-06-15 16:56:21 -0700208 handle->currentMaxAcquiredBufferCount =
209 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
Valerie Hau32cdc1f2019-10-21 14:45:54 -0700210 }
211
Vishnu Nair1506b182021-02-22 14:35:15 -0800212 for (auto& handle : mDrawingState.callbackHandles) {
chaviw0b06a8d2021-08-06 11:49:08 -0500213 if (handle->releasePreviousBuffer &&
214 mDrawingState.releaseBufferEndpoint == handle->listener) {
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -0700215 handle->previousReleaseCallbackId = mPreviousReleaseCallbackId;
Vishnu Nair1506b182021-02-22 14:35:15 -0800216 break;
217 }
218 }
219
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100220 std::vector<JankData> jankData;
221 jankData.reserve(mPendingJankClassifications.size());
222 while (!mPendingJankClassifications.empty()
223 && mPendingJankClassifications.front()->getJankType()) {
224 std::shared_ptr<frametimeline::SurfaceFrame> surfaceFrame =
225 mPendingJankClassifications.front();
226 mPendingJankClassifications.pop_front();
227 jankData.emplace_back(
228 JankData(surfaceFrame->getToken(), surfaceFrame->getJankType().value()));
229 }
230
Robert Carr3d1047b2021-09-20 18:22:32 -0700231 mFlinger->getTransactionCallbackInvoker().addCallbackHandles(
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100232 mDrawingState.callbackHandles, jankData);
Marissa Wall5a68a772018-12-22 17:43:42 -0800233
234 mDrawingState.callbackHandles = {};
Valerie Haubf784642020-01-29 07:25:23 -0800235
236 const sp<Fence>& releaseFence(mPreviousReleaseFence);
237 std::shared_ptr<FenceTime> releaseFenceTime = std::make_shared<FenceTime>(releaseFence);
238 {
239 Mutex::Autolock lock(mFrameEventHistoryMutex);
240 if (mPreviousFrameNumber != 0) {
241 mFrameEventHistory.addRelease(mPreviousFrameNumber, dequeueReadyTime,
242 std::move(releaseFenceTime));
243 }
244 }
Marissa Wall61c58622018-07-18 10:12:20 -0700245}
246
Valerie Hau871d6352020-01-29 08:44:02 -0800247void BufferStateLayer::finalizeFrameEventHistory(const std::shared_ptr<FenceTime>& glDoneFence,
248 const CompositorTiming& compositorTiming) {
249 for (const auto& handle : mDrawingState.callbackHandles) {
250 handle->gpuCompositionDoneFence = glDoneFence;
251 handle->compositorTiming = compositorTiming;
252 }
253}
254
Marissa Walle2ffb422018-10-12 11:33:52 -0700255bool BufferStateLayer::willPresentCurrentTransaction() const {
256 // Returns true if the most recent Transaction applied to CurrentState will be presented.
Robert Carr321e83c2019-08-19 15:49:30 -0700257 return (getSidebandStreamChanged() || getAutoRefresh() ||
Robert Carr6a160312021-05-17 12:08:20 -0700258 (mDrawingState.modified &&
259 (mDrawingState.buffer != nullptr || mDrawingState.bgColorLayer != nullptr)));
Marissa Wall61c58622018-07-18 10:12:20 -0700260}
261
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000262Rect BufferStateLayer::getCrop(const Layer::State& s) const {
263 return s.crop;
Marissa Wall61c58622018-07-18 10:12:20 -0700264}
265
266bool BufferStateLayer::setTransform(uint32_t transform) {
Robert Carr6a160312021-05-17 12:08:20 -0700267 if (mDrawingState.bufferTransform == transform) return false;
268 mDrawingState.bufferTransform = transform;
269 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700270 setTransactionFlags(eTransactionNeeded);
271 return true;
272}
273
274bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
Robert Carr6a160312021-05-17 12:08:20 -0700275 if (mDrawingState.transformToDisplayInverse == transformToDisplayInverse) return false;
276 mDrawingState.sequence++;
277 mDrawingState.transformToDisplayInverse = transformToDisplayInverse;
278 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700279 setTransactionFlags(eTransactionNeeded);
280 return true;
281}
282
283bool BufferStateLayer::setCrop(const Rect& crop) {
Robert Carr6a160312021-05-17 12:08:20 -0700284 if (mDrawingState.crop == crop) return false;
285 mDrawingState.sequence++;
286 mDrawingState.crop = crop;
Marissa Wall290ad082019-03-06 13:23:47 -0800287
Robert Carr6a160312021-05-17 12:08:20 -0700288 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700289 setTransactionFlags(eTransactionNeeded);
290 return true;
291}
292
chaviwf3f40fe2021-04-27 15:54:02 -0500293bool BufferStateLayer::setBufferCrop(const Rect& bufferCrop) {
Robert Carr6a160312021-05-17 12:08:20 -0700294 if (mDrawingState.bufferCrop == bufferCrop) return false;
chaviwf3f40fe2021-04-27 15:54:02 -0500295
Robert Carr6a160312021-05-17 12:08:20 -0700296 mDrawingState.sequence++;
297 mDrawingState.bufferCrop = bufferCrop;
chaviwf3f40fe2021-04-27 15:54:02 -0500298
Robert Carr6a160312021-05-17 12:08:20 -0700299 mDrawingState.modified = true;
chaviwf3f40fe2021-04-27 15:54:02 -0500300 setTransactionFlags(eTransactionNeeded);
301 return true;
302}
303
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700304bool BufferStateLayer::setDestinationFrame(const Rect& destinationFrame) {
Robert Carr6a160312021-05-17 12:08:20 -0700305 if (mDrawingState.destinationFrame == destinationFrame) return false;
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700306
Robert Carr6a160312021-05-17 12:08:20 -0700307 mDrawingState.sequence++;
308 mDrawingState.destinationFrame = destinationFrame;
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700309
Robert Carr6a160312021-05-17 12:08:20 -0700310 mDrawingState.modified = true;
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700311 setTransactionFlags(eTransactionNeeded);
312 return true;
313}
314
Robert Carr6a160312021-05-17 12:08:20 -0700315static bool assignTransform(ui::Transform* dst, ui::Transform& from) {
316 if (*dst == from) {
317 return false;
318 }
319 *dst = from;
320 return true;
321}
322
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700323// Translate destination frame into scale and position. If a destination frame is not set, use the
324// provided scale and position
Robert Carr6a160312021-05-17 12:08:20 -0700325bool BufferStateLayer::updateGeometry() {
326 if (mDrawingState.destinationFrame.isEmpty()) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700327 // If destination frame is not set, use the requested transform set via
328 // BufferStateLayer::setPosition and BufferStateLayer::setMatrix.
Robert Carr6a160312021-05-17 12:08:20 -0700329 return assignTransform(&mDrawingState.transform, mRequestedTransform);
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700330 }
331
Robert Carr6a160312021-05-17 12:08:20 -0700332 Rect destRect = mDrawingState.destinationFrame;
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700333 int32_t destW = destRect.width();
334 int32_t destH = destRect.height();
335 if (destRect.left < 0) {
336 destRect.left = 0;
337 destRect.right = destW;
338 }
339 if (destRect.top < 0) {
340 destRect.top = 0;
341 destRect.bottom = destH;
342 }
343
Robert Carr6a160312021-05-17 12:08:20 -0700344 if (!mDrawingState.buffer) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700345 ui::Transform t;
346 t.set(destRect.left, destRect.top);
Robert Carr6a160312021-05-17 12:08:20 -0700347 return assignTransform(&mDrawingState.transform, t);
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700348 }
349
Robert Carr6a160312021-05-17 12:08:20 -0700350 uint32_t bufferWidth = mDrawingState.buffer->getBuffer()->getWidth();
351 uint32_t bufferHeight = mDrawingState.buffer->getBuffer()->getHeight();
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700352 // Undo any transformations on the buffer.
Robert Carr6a160312021-05-17 12:08:20 -0700353 if (mDrawingState.bufferTransform & ui::Transform::ROT_90) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700354 std::swap(bufferWidth, bufferHeight);
355 }
356 uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
Robert Carr6a160312021-05-17 12:08:20 -0700357 if (mDrawingState.transformToDisplayInverse) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700358 if (invTransform & ui::Transform::ROT_90) {
359 std::swap(bufferWidth, bufferHeight);
360 }
361 }
362
363 float sx = destW / static_cast<float>(bufferWidth);
364 float sy = destH / static_cast<float>(bufferHeight);
365 ui::Transform t;
366 t.set(sx, 0, 0, sy);
367 t.set(destRect.left, destRect.top);
Robert Carr6a160312021-05-17 12:08:20 -0700368 return assignTransform(&mDrawingState.transform, t);
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700369}
370
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000371bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix,
372 bool allowNonRectPreservingTransforms) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700373 if (mRequestedTransform.dsdx() == matrix.dsdx && mRequestedTransform.dtdy() == matrix.dtdy &&
374 mRequestedTransform.dtdx() == matrix.dtdx && mRequestedTransform.dsdy() == matrix.dsdy) {
Marissa Wall861616d2018-10-22 12:52:23 -0700375 return false;
376 }
377
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000378 ui::Transform t;
379 t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
380
381 if (!allowNonRectPreservingTransforms && !t.preserveRects()) {
382 ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER nor "
383 "ROTATE_SURFACE_FLINGER ignored");
384 return false;
Marissa Wall861616d2018-10-22 12:52:23 -0700385 }
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000386
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700387 mRequestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
chaviw9a93ea62021-03-11 16:44:42 -0600388
Robert Carr6a160312021-05-17 12:08:20 -0700389 mDrawingState.sequence++;
390 mDrawingState.modified = true;
chaviw9a93ea62021-03-11 16:44:42 -0600391 setTransactionFlags(eTransactionNeeded);
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000392
393 return true;
394}
395
396bool BufferStateLayer::setPosition(float x, float y) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700397 if (mRequestedTransform.tx() == x && mRequestedTransform.ty() == y) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000398 return false;
399 }
400
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700401 mRequestedTransform.set(x, y);
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000402
Robert Carr6a160312021-05-17 12:08:20 -0700403 mDrawingState.sequence++;
404 mDrawingState.modified = true;
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000405 setTransactionFlags(eTransactionNeeded);
406
Marissa Wall861616d2018-10-22 12:52:23 -0700407 return true;
408}
409
Valerie Hau871d6352020-01-29 08:44:02 -0800410bool BufferStateLayer::addFrameEvent(const sp<Fence>& acquireFence, nsecs_t postedTime,
411 nsecs_t desiredPresentTime) {
Valerie Haubf784642020-01-29 07:25:23 -0800412 Mutex::Autolock lock(mFrameEventHistoryMutex);
413 mAcquireTimeline.updateSignalTimes();
414 std::shared_ptr<FenceTime> acquireFenceTime =
415 std::make_shared<FenceTime>((acquireFence ? acquireFence : Fence::NO_FENCE));
Robert Carr6a160312021-05-17 12:08:20 -0700416 NewFrameEventsEntry newTimestamps = {mDrawingState.frameNumber, postedTime, desiredPresentTime,
Valerie Haubf784642020-01-29 07:25:23 -0800417 acquireFenceTime};
Valerie Hau871d6352020-01-29 08:44:02 -0800418 mFrameEventHistory.setProducerWantsEvents();
Valerie Haubf784642020-01-29 07:25:23 -0800419 mFrameEventHistory.addQueue(newTimestamps);
420 return true;
421}
422
chaviwba4320c2021-09-15 15:20:53 -0500423std::shared_ptr<renderengine::ExternalTexture> BufferStateLayer::getBufferFromBufferData(
424 const BufferData& bufferData) {
425 bool cacheIdChanged = bufferData.flags.test(BufferData::BufferDataChange::cachedBufferChanged);
426 bool bufferSizeExceedsLimit = false;
427 std::shared_ptr<renderengine::ExternalTexture> buffer = nullptr;
428 if (cacheIdChanged && bufferData.buffer != nullptr) {
429 bufferSizeExceedsLimit =
430 mFlinger->exceedsMaxRenderTargetSize(bufferData.buffer->getWidth(),
431 bufferData.buffer->getHeight());
432 if (!bufferSizeExceedsLimit) {
433 ClientCache::getInstance().add(bufferData.cachedBuffer, bufferData.buffer);
434 buffer = ClientCache::getInstance().get(bufferData.cachedBuffer);
435 }
436 } else if (cacheIdChanged) {
437 buffer = ClientCache::getInstance().get(bufferData.cachedBuffer);
438 } else if (bufferData.buffer != nullptr) {
439 bufferSizeExceedsLimit =
440 mFlinger->exceedsMaxRenderTargetSize(bufferData.buffer->getWidth(),
441 bufferData.buffer->getHeight());
442 if (!bufferSizeExceedsLimit) {
443 buffer = std::make_shared<
444 renderengine::ExternalTexture>(bufferData.buffer, mFlinger->getRenderEngine(),
445 renderengine::ExternalTexture::Usage::READABLE);
446 }
447 }
448 ALOGE_IF(bufferSizeExceedsLimit,
449 "Attempted to create an ExternalTexture for layer %s that exceeds render target size "
450 "limit.",
451 getDebugName());
452 return buffer;
453}
454
455bool BufferStateLayer::setBuffer(const BufferData& bufferData, nsecs_t postTime,
Alec Mouria90a5702021-04-16 16:36:21 +0000456 nsecs_t desiredPresentTime, bool isAutoTimestamp,
chaviwba4320c2021-09-15 15:20:53 -0500457 std::optional<nsecs_t> dequeueTime,
458 const FrameTimelineInfo& info) {
Robert Carr0c1966e2020-10-19 12:12:08 -0700459 ATRACE_CALL();
460
chaviwba4320c2021-09-15 15:20:53 -0500461 const std::shared_ptr<renderengine::ExternalTexture>& buffer =
462 getBufferFromBufferData(bufferData);
463 if (!buffer) {
464 return false;
465 }
466
467 const bool frameNumberChanged =
468 bufferData.flags.test(BufferData::BufferDataChange::frameNumberChanged);
469 const uint64_t frameNumber =
470 frameNumberChanged ? bufferData.frameNumber : mDrawingState.frameNumber + 1;
471
Robert Carr6a160312021-05-17 12:08:20 -0700472 if (mDrawingState.buffer) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700473 mReleasePreviousBuffer = true;
Vishnu Nair52846cd2021-08-05 16:12:48 -0700474 if (mDrawingState.buffer != mBufferInfo.mBuffer ||
475 mDrawingState.frameNumber != mBufferInfo.mFrameNumber) {
Robert Carr6a160312021-05-17 12:08:20 -0700476 // If mDrawingState has a buffer, and we are about to update again
Robert Carr7121caf2020-12-15 13:07:32 -0800477 // before swapping to drawing state, then the first buffer will be
Vishnu Nair1506b182021-02-22 14:35:15 -0800478 // dropped and we should decrement the pending buffer count and
479 // call any release buffer callbacks if set.
Robert Carr6a160312021-05-17 12:08:20 -0700480 callReleaseBufferCallback(mDrawingState.releaseBufferListener,
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -0700481 mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
482 mDrawingState.acquireFence, mTransformHint,
Ady Abraham899dcdb2021-06-15 16:56:21 -0700483 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
484 mOwnerUid));
Robert Carr7121caf2020-12-15 13:07:32 -0800485 decrementPendingBufferCount();
Robert Carr6a160312021-05-17 12:08:20 -0700486 if (mDrawingState.bufferSurfaceFrameTX != nullptr &&
487 mDrawingState.bufferSurfaceFrameTX->getPresentState() != PresentState::Presented) {
488 addSurfaceFrameDroppedForBuffer(mDrawingState.bufferSurfaceFrameTX);
489 mDrawingState.bufferSurfaceFrameTX.reset();
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000490 }
Robert Carrccab4242021-09-28 16:53:03 -0700491 } else if (mLastClientCompositionFence != nullptr) {
492 callReleaseBufferCallback(mDrawingState.releaseBufferListener,
493 mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
494 mLastClientCompositionFence, mTransformHint,
495 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
496 mOwnerUid));
497 mLastClientCompositionFence = nullptr;
Robert Carr7121caf2020-12-15 13:07:32 -0800498 }
Marissa Wallfda30bb2018-10-12 11:34:28 -0700499 }
Robert Carr6a160312021-05-17 12:08:20 -0700500
501 mDrawingState.frameNumber = frameNumber;
chaviwba4320c2021-09-15 15:20:53 -0500502 mDrawingState.releaseBufferListener = bufferData.releaseBufferListener;
Robert Carr6a160312021-05-17 12:08:20 -0700503 mDrawingState.buffer = buffer;
chaviwba4320c2021-09-15 15:20:53 -0500504 mDrawingState.clientCacheId = bufferData.cachedBuffer;
505
506 mDrawingState.acquireFence = bufferData.flags.test(BufferData::BufferDataChange::fenceChanged)
507 ? bufferData.acquireFence
508 : Fence::NO_FENCE;
509 mDrawingState.acquireFenceTime = std::make_unique<FenceTime>(mDrawingState.acquireFence);
510 // The acquire fences of BufferStateLayers have already signaled before they are set
511 mCallbackHandleAcquireTime = mDrawingState.acquireFenceTime->getSignalTime();
512
Robert Carr6a160312021-05-17 12:08:20 -0700513 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700514 setTransactionFlags(eTransactionNeeded);
Ady Abraham09bd3922019-04-08 10:44:56 -0700515
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800516 const int32_t layerId = getSequence();
Robert Carr6a160312021-05-17 12:08:20 -0700517 mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(),
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000518 mOwnerUid, postTime, getGameMode());
Robert Carr6a160312021-05-17 12:08:20 -0700519 mDrawingState.desiredPresentTime = desiredPresentTime;
520 mDrawingState.isAutoTimestamp = isAutoTimestamp;
Ady Abraham09bd3922019-04-08 10:44:56 -0700521
Ady Abrahamb7f15562021-03-15 18:34:08 -0700522 const nsecs_t presentTime = [&] {
523 if (!isAutoTimestamp) return desiredPresentTime;
524
525 const auto prediction =
526 mFlinger->mFrameTimeline->getTokenManager()->getPredictionsForToken(info.vsyncId);
527 if (prediction.has_value()) return prediction->presentTime;
528
529 return static_cast<nsecs_t>(0);
530 }();
531 mFlinger->mScheduler->recordLayerHistory(this, presentTime,
Ady Abraham5def7332020-05-29 16:13:47 -0700532 LayerHistory::LayerUpdateType::Buffer);
Ady Abraham09bd3922019-04-08 10:44:56 -0700533
chaviwba4320c2021-09-15 15:20:53 -0500534 addFrameEvent(mDrawingState.acquireFence, postTime, isAutoTimestamp ? 0 : desiredPresentTime);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000535
Adithya Srinivasan891004e2021-02-12 20:20:47 +0000536 setFrameTimelineVsyncForBufferTransaction(info, postTime);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000537
Alec Mouria90a5702021-04-16 16:36:21 +0000538 if (buffer && dequeueTime && *dequeueTime != 0) {
539 const uint64_t bufferId = buffer->getBuffer()->getId();
Adithya Srinivasanb238cd52021-02-04 17:54:05 +0000540 mFlinger->mFrameTracer->traceNewLayer(layerId, getName().c_str());
541 mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, *dequeueTime,
542 FrameTracer::FrameEvent::DEQUEUE);
543 mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, postTime,
544 FrameTracer::FrameEvent::QUEUE);
545 }
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000546
Robert Carr6a160312021-05-17 12:08:20 -0700547 mDrawingState.width = mDrawingState.buffer->getBuffer()->getWidth();
548 mDrawingState.height = mDrawingState.buffer->getBuffer()->getHeight();
chaviwba4320c2021-09-15 15:20:53 -0500549 mDrawingState.releaseBufferEndpoint = bufferData.releaseBufferEndpoint;
Marissa Wall61c58622018-07-18 10:12:20 -0700550 return true;
551}
552
553bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
Robert Carr6a160312021-05-17 12:08:20 -0700554 if (mDrawingState.dataspace == dataspace) return false;
555 mDrawingState.dataspace = dataspace;
556 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700557 setTransactionFlags(eTransactionNeeded);
558 return true;
559}
560
561bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
Robert Carr6a160312021-05-17 12:08:20 -0700562 if (mDrawingState.hdrMetadata == hdrMetadata) return false;
563 mDrawingState.hdrMetadata = hdrMetadata;
564 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700565 setTransactionFlags(eTransactionNeeded);
566 return true;
567}
568
569bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
Robert Carr6a160312021-05-17 12:08:20 -0700570 mDrawingState.surfaceDamageRegion = surfaceDamage;
571 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700572 setTransactionFlags(eTransactionNeeded);
573 return true;
574}
575
576bool BufferStateLayer::setApi(int32_t api) {
Robert Carr6a160312021-05-17 12:08:20 -0700577 if (mDrawingState.api == api) return false;
578 mDrawingState.api = api;
579 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700580 setTransactionFlags(eTransactionNeeded);
581 return true;
582}
583
584bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
Robert Carr6a160312021-05-17 12:08:20 -0700585 if (mDrawingState.sidebandStream == sidebandStream) return false;
Robert Carr3e2a2992021-06-11 13:42:55 -0700586
587 if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) {
588 mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
589 } else if (sidebandStream != nullptr) {
590 mFlinger->mTunnelModeEnabledReporter->incrementTunnelModeCount();
591 }
592
Robert Carr6a160312021-05-17 12:08:20 -0700593 mDrawingState.sidebandStream = sidebandStream;
594 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700595 setTransactionFlags(eTransactionNeeded);
Marissa Wall61c58622018-07-18 10:12:20 -0700596 if (!mSidebandStreamChanged.exchange(true)) {
597 // mSidebandStreamChanged was false
598 mFlinger->signalLayerUpdate();
599 }
600 return true;
601}
602
Marissa Walle2ffb422018-10-12 11:33:52 -0700603bool BufferStateLayer::setTransactionCompletedListeners(
604 const std::vector<sp<CallbackHandle>>& handles) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700605 // If there is no handle, we will not send a callback so reset mReleasePreviousBuffer and return
Marissa Walle2ffb422018-10-12 11:33:52 -0700606 if (handles.empty()) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700607 mReleasePreviousBuffer = false;
Marissa Walle2ffb422018-10-12 11:33:52 -0700608 return false;
609 }
610
611 const bool willPresent = willPresentCurrentTransaction();
612
613 for (const auto& handle : handles) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700614 // If this transaction set a buffer on this layer, release its previous buffer
615 handle->releasePreviousBuffer = mReleasePreviousBuffer;
616
Marissa Walle2ffb422018-10-12 11:33:52 -0700617 // If this layer will be presented in this frame
618 if (willPresent) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700619 // If this transaction set an acquire fence on this layer, set its acquire time
620 handle->acquireTime = mCallbackHandleAcquireTime;
Robert Carr6a160312021-05-17 12:08:20 -0700621 handle->frameNumber = mDrawingState.frameNumber;
Marissa Wallfda30bb2018-10-12 11:34:28 -0700622
Marissa Walle2ffb422018-10-12 11:33:52 -0700623 // Store so latched time and release fence can be set
Robert Carr6a160312021-05-17 12:08:20 -0700624 mDrawingState.callbackHandles.push_back(handle);
Marissa Walle2ffb422018-10-12 11:33:52 -0700625
626 } else { // If this layer will NOT need to be relatched and presented this frame
627 // Notify the transaction completed thread this handle is done
Robert Carr9a803c32021-01-14 16:57:58 -0800628 mFlinger->getTransactionCallbackInvoker().registerUnpresentedCallbackHandle(handle);
Marissa Walle2ffb422018-10-12 11:33:52 -0700629 }
630 }
631
Marissa Wallfda30bb2018-10-12 11:34:28 -0700632 mReleasePreviousBuffer = false;
633 mCallbackHandleAcquireTime = -1;
634
Marissa Walle2ffb422018-10-12 11:33:52 -0700635 return willPresent;
636}
637
Marissa Wall61c58622018-07-18 10:12:20 -0700638bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
Vishnu Nair27e3ed52021-07-08 18:24:25 -0700639 mDrawingState.sequence++;
Robert Carr6a160312021-05-17 12:08:20 -0700640 mDrawingState.transparentRegionHint = transparent;
641 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700642 setTransactionFlags(eTransactionNeeded);
643 return true;
644}
645
rnleeed20fa42021-08-10 18:00:03 -0700646Rect BufferStateLayer::getBufferSize(const State& /*s*/) const {
Marissa Wall861616d2018-10-22 12:52:23 -0700647 // for buffer state layers we use the display frame size as the buffer size.
Marissa Wall61c58622018-07-18 10:12:20 -0700648
chaviw7e72caf2020-12-02 16:50:43 -0800649 if (mBufferInfo.mBuffer == nullptr) {
650 return Rect::INVALID_RECT;
651 }
652
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700653 uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth();
654 uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight();
655
656 // Undo any transformations on the buffer and return the result.
657 if (mBufferInfo.mTransform & ui::Transform::ROT_90) {
658 std::swap(bufWidth, bufHeight);
659 }
660
661 if (getTransformToDisplayInverse()) {
662 uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
663 if (invTransform & ui::Transform::ROT_90) {
664 std::swap(bufWidth, bufHeight);
Marissa Wall861616d2018-10-22 12:52:23 -0700665 }
666 }
667
rnleeed20fa42021-08-10 18:00:03 -0700668 return Rect(0, 0, static_cast<int32_t>(bufWidth), static_cast<int32_t>(bufHeight));
Marissa Wall61c58622018-07-18 10:12:20 -0700669}
Vishnu Nair4351ad52019-02-11 14:13:02 -0800670
671FloatRect BufferStateLayer::computeSourceBounds(const FloatRect& parentBounds) const {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700672 if (mBufferInfo.mBuffer == nullptr) {
673 return parentBounds;
Vishnu Nair4351ad52019-02-11 14:13:02 -0800674 }
675
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700676 return getBufferSize(getDrawingState()).toFloatRect();
Vishnu Nair4351ad52019-02-11 14:13:02 -0800677}
678
Marissa Wall61c58622018-07-18 10:12:20 -0700679// -----------------------------------------------------------------------
680
681// -----------------------------------------------------------------------
682// Interface implementation for BufferLayer
683// -----------------------------------------------------------------------
684bool BufferStateLayer::fenceHasSignaled() const {
Huihong Luo86c80e32021-06-16 15:41:07 -0700685 if (SurfaceFlinger::enableLatchUnsignaled) {
686 return true;
687 }
688
Alec Mouri91f6df32020-01-30 08:48:58 -0800689 const bool fenceSignaled =
690 getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
691 if (!fenceSignaled) {
692 mFlinger->mTimeStats->incrementLatchSkipped(getSequence(),
693 TimeStats::LatchSkipReason::LateAcquire);
694 }
695
696 return fenceSignaled;
Marissa Wall61c58622018-07-18 10:12:20 -0700697}
698
Dominik Laskowskia8955dd2019-07-10 10:19:09 -0700699bool BufferStateLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const {
Ady Abrahamcd1580c2019-04-29 15:40:03 -0700700 if (!hasFrameUpdate() || isRemovedFromCurrentState()) {
701 return true;
702 }
703
Robert Carr6a160312021-05-17 12:08:20 -0700704 return mDrawingState.isAutoTimestamp || mDrawingState.desiredPresentTime <= expectedPresentTime;
Ady Abrahamcd1580c2019-04-29 15:40:03 -0700705}
706
Valerie Hau871d6352020-01-29 08:44:02 -0800707bool BufferStateLayer::onPreComposition(nsecs_t refreshStartTime) {
708 for (const auto& handle : mDrawingState.callbackHandles) {
709 handle->refreshStartTime = refreshStartTime;
710 }
711 return BufferLayer::onPreComposition(refreshStartTime);
712}
713
Vishnu Naircf26a0a2020-11-13 12:56:20 -0800714void BufferStateLayer::setAutoRefresh(bool autoRefresh) {
715 if (!mAutoRefresh.exchange(autoRefresh)) {
716 mFlinger->signalLayerUpdate();
717 }
Marissa Wall61c58622018-07-18 10:12:20 -0700718}
719
Vishnu Nair6194e2e2019-02-06 12:58:39 -0800720bool BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
baocheng suna663c2b2021-05-13 18:51:28 +0800721 // We need to update the sideband stream if the layer has both a buffer and a sideband stream.
baocheng sun9691b9c2021-08-03 19:27:06 +0800722 editCompositionState()->sidebandStreamHasFrame = hasFrameUpdate() && mSidebandStream.get();
baocheng suna663c2b2021-05-13 18:51:28 +0800723
baocheng sun9691b9c2021-08-03 19:27:06 +0800724 if (mSidebandStreamChanged.exchange(false)) {
Marissa Wall61c58622018-07-18 10:12:20 -0700725 const State& s(getDrawingState());
726 // mSidebandStreamChanged was true
Lloyd Pique0b785d82018-12-04 17:25:27 -0800727 mSidebandStream = s.sidebandStream;
Lloyd Piquede196652020-01-22 17:29:58 -0800728 editCompositionState()->sidebandStream = mSidebandStream;
Lloyd Pique0b785d82018-12-04 17:25:27 -0800729 if (mSidebandStream != nullptr) {
Marissa Wall61c58622018-07-18 10:12:20 -0700730 setTransactionFlags(eTransactionNeeded);
731 mFlinger->setTransactionFlags(eTraversalNeeded);
732 }
733 recomputeVisibleRegions = true;
734
Vishnu Nair6194e2e2019-02-06 12:58:39 -0800735 return true;
Marissa Wall61c58622018-07-18 10:12:20 -0700736 }
Vishnu Nair6194e2e2019-02-06 12:58:39 -0800737 return false;
Marissa Wall61c58622018-07-18 10:12:20 -0700738}
739
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800740bool BufferStateLayer::hasFrameUpdate() const {
Robert Carr6a160312021-05-17 12:08:20 -0700741 const State& c(getDrawingState());
Robert Carr315f3c72021-06-24 21:58:09 -0700742 return (mDrawingStateModified || mDrawingState.modified) && (c.buffer != nullptr || c.bgColorLayer != nullptr);
Marissa Wall61c58622018-07-18 10:12:20 -0700743}
744
Dominik Laskowskia8955dd2019-07-10 10:19:09 -0700745status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
746 nsecs_t /*expectedPresentTime*/) {
Marissa Wall61c58622018-07-18 10:12:20 -0700747 const State& s(getDrawingState());
748
749 if (!s.buffer) {
Valerie Hauaa194562019-02-05 16:21:38 -0800750 if (s.bgColorLayer) {
751 for (auto& handle : mDrawingState.callbackHandles) {
752 handle->latchTime = latchTime;
753 }
754 }
Marissa Wall61c58622018-07-18 10:12:20 -0700755 return NO_ERROR;
756 }
757
Marissa Wall5a68a772018-12-22 17:43:42 -0800758 for (auto& handle : mDrawingState.callbackHandles) {
Vishnu Nair935590e2021-02-10 13:05:52 -0800759 if (handle->frameNumber == mDrawingState.frameNumber) {
760 handle->latchTime = latchTime;
761 }
Marissa Wall5a68a772018-12-22 17:43:42 -0800762 }
Marissa Walle2ffb422018-10-12 11:33:52 -0700763
Vishnu Nairea0de002020-11-17 17:42:37 -0800764 const int32_t layerId = getSequence();
Alec Mouria90a5702021-04-16 16:36:21 +0000765 const uint64_t bufferId = mDrawingState.buffer->getBuffer()->getId();
Adithya Srinivasanb238cd52021-02-04 17:54:05 +0000766 const uint64_t frameNumber = mDrawingState.frameNumber;
767 const auto acquireFence = std::make_shared<FenceTime>(mDrawingState.acquireFence);
768 mFlinger->mTimeStats->setAcquireFence(layerId, frameNumber, acquireFence);
769 mFlinger->mTimeStats->setLatchTime(layerId, frameNumber, latchTime);
770
771 mFlinger->mFrameTracer->traceFence(layerId, bufferId, frameNumber, acquireFence,
772 FrameTracer::FrameEvent::ACQUIRE_FENCE);
773 mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, latchTime,
774 FrameTracer::FrameEvent::LATCH);
Marissa Wall61c58622018-07-18 10:12:20 -0700775
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000776 auto& bufferSurfaceFrame = mDrawingState.bufferSurfaceFrameTX;
777 if (bufferSurfaceFrame != nullptr &&
778 bufferSurfaceFrame->getPresentState() != PresentState::Presented) {
779 // Update only if the bufferSurfaceFrame wasn't already presented. A Presented
780 // bufferSurfaceFrame could be seen here if a pending state was applied successfully and we
781 // are processing the next state.
782 addSurfaceFramePresentedForBuffer(bufferSurfaceFrame,
Ady Abraham6c1b7ac2021-03-31 16:56:03 -0700783 mDrawingState.acquireFenceTime->getSignalTime(),
784 latchTime);
Robert Carr6a160312021-05-17 12:08:20 -0700785 mDrawingState.bufferSurfaceFrameTX.reset();
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000786 }
787
Vishnu Nairfc46c1e2021-04-21 08:31:32 -0700788 std::deque<sp<CallbackHandle>> remainingHandles;
789 mFlinger->getTransactionCallbackInvoker()
Robert Carr3d1047b2021-09-20 18:22:32 -0700790 .addOnCommitCallbackHandles(mDrawingState.callbackHandles, remainingHandles);
Vishnu Nairfc46c1e2021-04-21 08:31:32 -0700791 mDrawingState.callbackHandles = remainingHandles;
792
Robert Carr6a160312021-05-17 12:08:20 -0700793 mDrawingStateModified = false;
Marissa Wall16c112d2019-03-20 13:21:13 -0700794
Marissa Wall61c58622018-07-18 10:12:20 -0700795 return NO_ERROR;
796}
797
798status_t BufferStateLayer::updateActiveBuffer() {
799 const State& s(getDrawingState());
800
801 if (s.buffer == nullptr) {
802 return BAD_VALUE;
803 }
chaviwdf3c5e82021-01-07 13:00:37 -0800804
Alec Mouria90a5702021-04-16 16:36:21 +0000805 if (!mBufferInfo.mBuffer || s.buffer->getBuffer() != mBufferInfo.mBuffer->getBuffer()) {
chaviwdf3c5e82021-01-07 13:00:37 -0800806 decrementPendingBufferCount();
807 }
Marissa Wall61c58622018-07-18 10:12:20 -0700808
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -0700809 mPreviousReleaseCallbackId = {getCurrentBufferId(), mBufferInfo.mFrameNumber};
chaviwd62d3062019-09-04 14:48:02 -0700810 mBufferInfo.mBuffer = s.buffer;
811 mBufferInfo.mFence = s.acquireFence;
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -0700812 mBufferInfo.mFrameNumber = s.frameNumber;
Marissa Wall61c58622018-07-18 10:12:20 -0700813
814 return NO_ERROR;
815}
816
Valerie Haubf784642020-01-29 07:25:23 -0800817status_t BufferStateLayer::updateFrameNumber(nsecs_t latchTime) {
Marissa Wall61c58622018-07-18 10:12:20 -0700818 // TODO(marissaw): support frame history events
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700819 mPreviousFrameNumber = mCurrentFrameNumber;
Valerie Hau134651a2020-01-28 16:21:22 -0800820 mCurrentFrameNumber = mDrawingState.frameNumber;
Valerie Haubf784642020-01-29 07:25:23 -0800821 {
822 Mutex::Autolock lock(mFrameEventHistoryMutex);
823 mFrameEventHistory.addLatch(mCurrentFrameNumber, latchTime);
824 }
Marissa Wall61c58622018-07-18 10:12:20 -0700825 return NO_ERROR;
826}
827
Marissa Wall947d34e2019-03-29 14:03:53 -0700828void BufferStateLayer::HwcSlotGenerator::bufferErased(const client_cache_t& clientCacheId) {
829 std::lock_guard lock(mMutex);
830 if (!clientCacheId.isValid()) {
831 ALOGE("invalid process, failed to erase buffer");
832 return;
833 }
834 eraseBufferLocked(clientCacheId);
835}
836
rnleeed20fa42021-08-10 18:00:03 -0700837int BufferStateLayer::HwcSlotGenerator::getHwcCacheSlot(const client_cache_t& clientCacheId) {
Marissa Wall947d34e2019-03-29 14:03:53 -0700838 std::lock_guard<std::mutex> lock(mMutex);
839 auto itr = mCachedBuffers.find(clientCacheId);
840 if (itr == mCachedBuffers.end()) {
841 return addCachedBuffer(clientCacheId);
842 }
843 auto& [hwcCacheSlot, counter] = itr->second;
844 counter = mCounter++;
845 return hwcCacheSlot;
846}
847
rnleeed20fa42021-08-10 18:00:03 -0700848int BufferStateLayer::HwcSlotGenerator::addCachedBuffer(const client_cache_t& clientCacheId)
Marissa Wall947d34e2019-03-29 14:03:53 -0700849 REQUIRES(mMutex) {
850 if (!clientCacheId.isValid()) {
851 ALOGE("invalid process, returning invalid slot");
852 return BufferQueue::INVALID_BUFFER_SLOT;
853 }
854
855 ClientCache::getInstance().registerErasedRecipient(clientCacheId, wp<ErasedRecipient>(this));
856
rnleeed20fa42021-08-10 18:00:03 -0700857 int hwcCacheSlot = getFreeHwcCacheSlot();
Marissa Wall947d34e2019-03-29 14:03:53 -0700858 mCachedBuffers[clientCacheId] = {hwcCacheSlot, mCounter++};
859 return hwcCacheSlot;
860}
861
rnleeed20fa42021-08-10 18:00:03 -0700862int BufferStateLayer::HwcSlotGenerator::getFreeHwcCacheSlot() REQUIRES(mMutex) {
Marissa Wall947d34e2019-03-29 14:03:53 -0700863 if (mFreeHwcCacheSlots.empty()) {
864 evictLeastRecentlyUsed();
865 }
866
rnleeed20fa42021-08-10 18:00:03 -0700867 int hwcCacheSlot = mFreeHwcCacheSlots.top();
Marissa Wall947d34e2019-03-29 14:03:53 -0700868 mFreeHwcCacheSlots.pop();
869 return hwcCacheSlot;
870}
871
872void BufferStateLayer::HwcSlotGenerator::evictLeastRecentlyUsed() REQUIRES(mMutex) {
873 uint64_t minCounter = UINT_MAX;
874 client_cache_t minClientCacheId = {};
875 for (const auto& [clientCacheId, slotCounter] : mCachedBuffers) {
876 const auto& [hwcCacheSlot, counter] = slotCounter;
877 if (counter < minCounter) {
878 minCounter = counter;
879 minClientCacheId = clientCacheId;
880 }
881 }
882 eraseBufferLocked(minClientCacheId);
883
884 ClientCache::getInstance().unregisterErasedRecipient(minClientCacheId, this);
885}
886
887void BufferStateLayer::HwcSlotGenerator::eraseBufferLocked(const client_cache_t& clientCacheId)
888 REQUIRES(mMutex) {
889 auto itr = mCachedBuffers.find(clientCacheId);
890 if (itr == mCachedBuffers.end()) {
891 return;
892 }
893 auto& [hwcCacheSlot, counter] = itr->second;
894
895 // TODO send to hwc cache and resources
896
897 mFreeHwcCacheSlots.push(hwcCacheSlot);
898 mCachedBuffers.erase(clientCacheId);
899}
chaviw4244e032019-09-04 11:27:49 -0700900
901void BufferStateLayer::gatherBufferInfo() {
chaviwdebadb82020-03-26 14:57:24 -0700902 BufferLayer::gatherBufferInfo();
chaviw4244e032019-09-04 11:27:49 -0700903
chaviwdebadb82020-03-26 14:57:24 -0700904 const State& s(getDrawingState());
chaviw4244e032019-09-04 11:27:49 -0700905 mBufferInfo.mDesiredPresentTime = s.desiredPresentTime;
906 mBufferInfo.mFenceTime = std::make_shared<FenceTime>(s.acquireFence);
907 mBufferInfo.mFence = s.acquireFence;
chaviw766c9c52021-02-10 17:36:47 -0800908 mBufferInfo.mTransform = s.bufferTransform;
Robert Carr167bdde2021-07-28 11:26:51 -0700909 auto lastDataspace = mBufferInfo.mDataspace;
chaviw4244e032019-09-04 11:27:49 -0700910 mBufferInfo.mDataspace = translateDataspace(s.dataspace);
Robert Carr167bdde2021-07-28 11:26:51 -0700911 if (lastDataspace != mBufferInfo.mDataspace) {
912 mFlinger->mSomeDataspaceChanged = true;
913 }
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700914 mBufferInfo.mCrop = computeBufferCrop(s);
chaviw4244e032019-09-04 11:27:49 -0700915 mBufferInfo.mScaleMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
916 mBufferInfo.mSurfaceDamage = s.surfaceDamageRegion;
917 mBufferInfo.mHdrMetadata = s.hdrMetadata;
918 mBufferInfo.mApi = s.api;
chaviw4244e032019-09-04 11:27:49 -0700919 mBufferInfo.mTransformToDisplayInverse = s.transformToDisplayInverse;
chaviwf83ce182019-09-12 14:43:08 -0700920 mBufferInfo.mBufferSlot = mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId);
chaviw4244e032019-09-04 11:27:49 -0700921}
922
Robert Carr916b0362020-10-06 13:53:03 -0700923uint32_t BufferStateLayer::getEffectiveScalingMode() const {
924 return NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
925}
926
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700927Rect BufferStateLayer::computeBufferCrop(const State& s) {
chaviwf3f40fe2021-04-27 15:54:02 -0500928 if (s.buffer && !s.bufferCrop.isEmpty()) {
929 Rect bufferCrop;
930 s.buffer->getBuffer()->getBounds().intersect(s.bufferCrop, &bufferCrop);
931 return bufferCrop;
932 } else if (s.buffer) {
Alec Mouria90a5702021-04-16 16:36:21 +0000933 return s.buffer->getBuffer()->getBounds();
chaviwf3f40fe2021-04-27 15:54:02 -0500934 } else {
935 return s.bufferCrop;
chaviw4244e032019-09-04 11:27:49 -0700936 }
chaviw4244e032019-09-04 11:27:49 -0700937}
938
chaviwb4c6e582019-08-16 14:35:07 -0700939sp<Layer> BufferStateLayer::createClone() {
Dominik Laskowski87a07e42019-10-10 20:38:02 -0700940 LayerCreationArgs args(mFlinger.get(), nullptr, mName + " (Mirror)", 0, 0, 0, LayerMetadata());
chaviwb4c6e582019-08-16 14:35:07 -0700941 args.textureName = mTextureName;
Lloyd Pique1c3a5eb2019-10-03 13:07:08 -0700942 sp<BufferStateLayer> layer = mFlinger->getFactory().createBufferStateLayer(args);
chaviwb4c6e582019-08-16 14:35:07 -0700943 layer->mHwcSlotGenerator = mHwcSlotGenerator;
944 layer->setInitialValuesForClone(this);
945 return layer;
946}
Valerie Hau92bf5482020-02-10 09:49:08 -0800947
Vishnu Naire7f79c52020-10-29 14:45:03 -0700948bool BufferStateLayer::bufferNeedsFiltering() const {
949 const State& s(getDrawingState());
950 if (!s.buffer) {
951 return false;
952 }
953
rnleeed20fa42021-08-10 18:00:03 -0700954 int32_t bufferWidth = s.buffer->getBuffer()->width;
955 int32_t bufferHeight = s.buffer->getBuffer()->height;
Vishnu Naire7f79c52020-10-29 14:45:03 -0700956
957 // Undo any transformations on the buffer and return the result.
chaviw766c9c52021-02-10 17:36:47 -0800958 if (s.bufferTransform & ui::Transform::ROT_90) {
Vishnu Naire7f79c52020-10-29 14:45:03 -0700959 std::swap(bufferWidth, bufferHeight);
960 }
961
962 if (s.transformToDisplayInverse) {
963 uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
964 if (invTransform & ui::Transform::ROT_90) {
965 std::swap(bufferWidth, bufferHeight);
966 }
967 }
968
969 const Rect layerSize{getBounds()};
970 return layerSize.width() != bufferWidth || layerSize.height() != bufferHeight;
971}
Robert Carr7121caf2020-12-15 13:07:32 -0800972
Robert Carr7121caf2020-12-15 13:07:32 -0800973void BufferStateLayer::decrementPendingBufferCount() {
Vishnu Nair8eda69e2021-02-26 10:42:10 -0800974 int32_t pendingBuffers = --mPendingBufferTransactions;
975 tracePendingBufferCount(pendingBuffers);
Robert Carr7121caf2020-12-15 13:07:32 -0800976}
977
Vishnu Nair8eda69e2021-02-26 10:42:10 -0800978void BufferStateLayer::tracePendingBufferCount(int32_t pendingBuffers) {
979 ATRACE_INT(mBlastTransactionName.c_str(), pendingBuffers);
Robert Carr7121caf2020-12-15 13:07:32 -0800980}
981
Robert Carr7121caf2020-12-15 13:07:32 -0800982
chaviw39d01472021-04-08 14:26:24 -0500983/*
984 * We don't want to send the layer's transform to input, but rather the
985 * parent's transform. This is because BufferStateLayer's transform is
986 * information about how the buffer is placed on screen. The parent's
987 * transform makes more sense to send since it's information about how the
988 * layer is placed on screen. This transform is used by input to determine
989 * how to go from screen space back to window space.
990 */
991ui::Transform BufferStateLayer::getInputTransform() const {
Rob Carrc6d2d2b2021-10-25 16:51:49 +0000992 sp<Layer> parent = mDrawingParent.promote();
chaviw39d01472021-04-08 14:26:24 -0500993 if (parent == nullptr) {
994 return ui::Transform();
995 }
996
997 return parent->getTransform();
998}
999
1000/**
1001 * Similar to getInputTransform, we need to update the bounds to include the transform.
1002 * This is because bounds for BSL doesn't include buffer transform, where the input assumes
1003 * that's already included.
1004 */
1005Rect BufferStateLayer::getInputBounds() const {
1006 Rect bufferBounds = getCroppedBufferSize(getDrawingState());
1007 if (mDrawingState.transform.getType() == ui::Transform::IDENTITY || !bufferBounds.isValid()) {
1008 return bufferBounds;
1009 }
1010 return mDrawingState.transform.transform(bufferBounds);
1011}
1012
Marissa Wall61c58622018-07-18 10:12:20 -07001013} // namespace android