blob: 9e159fcfa4b5d49f1515c4d6759bf3ee05f395b7 [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 Carr8d958532020-11-10 14:09:16 -0800135 if (!releaseFence->isValid()) {
136 return;
137 }
Marissa Wall5a68a772018-12-22 17:43:42 -0800138 // The previous release fence notifies the client that SurfaceFlinger is done with the previous
139 // buffer that was presented on this layer. The first transaction that came in this frame that
140 // replaced the previous buffer on this layer needs this release fence, because the fence will
141 // let the client know when that previous buffer is removed from the screen.
142 //
143 // Every other transaction on this layer does not need a release fence because no other
144 // Transactions that were set on this layer this frame are going to have their preceeding buffer
145 // removed from the display this frame.
146 //
147 // For example, if we have 3 transactions this frame. The first transaction doesn't contain a
148 // buffer so it doesn't need a previous release fence because the layer still needs the previous
149 // buffer. The second transaction contains a buffer so it needs a previous release fence because
150 // the previous buffer will be released this frame. The third transaction also contains a
151 // buffer. It replaces the buffer in the second transaction. The buffer in the second
152 // transaction will now no longer be presented so it is released immediately and the third
153 // transaction doesn't need a previous release fence.
Robert Carr8d958532020-11-10 14:09:16 -0800154 sp<CallbackHandle> ch;
Marissa Wall5a68a772018-12-22 17:43:42 -0800155 for (auto& handle : mDrawingState.callbackHandles) {
156 if (handle->releasePreviousBuffer) {
Robert Carr8d958532020-11-10 14:09:16 -0800157 ch = handle;
Marissa Wall5a68a772018-12-22 17:43:42 -0800158 break;
159 }
160 }
Robert Carr8d958532020-11-10 14:09:16 -0800161 auto status = addReleaseFence(ch, releaseFence);
162 if (status != OK) {
163 ALOGE("Failed to add release fence for layer %s", getName().c_str());
164 }
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700165
Valerie Haubf784642020-01-29 07:25:23 -0800166 mPreviousReleaseFence = releaseFence;
167
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700168 // Prevent tracing the same release multiple times.
169 if (mPreviousFrameNumber != mPreviousReleasedFrameNumber) {
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700170 mPreviousReleasedFrameNumber = mPreviousFrameNumber;
171 }
Marissa Wall61c58622018-07-18 10:12:20 -0700172}
173
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100174void BufferStateLayer::onSurfaceFrameCreated(
175 const std::shared_ptr<frametimeline::SurfaceFrame>& surfaceFrame) {
Adithya Srinivasand17c7da2021-03-05 20:43:32 +0000176 while (mPendingJankClassifications.size() >= kPendingClassificationMaxSurfaceFrames) {
177 // Too many SurfaceFrames pending classification. The front of the deque is probably not
178 // tracked by FrameTimeline and will never be presented. This will only result in a memory
179 // leak.
180 ALOGW("Removing the front of pending jank deque from layer - %s to prevent memory leak",
181 mName.c_str());
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000182 std::string miniDump = mPendingJankClassifications.front()->miniDump();
183 ALOGD("Head SurfaceFrame mini dump\n%s", miniDump.c_str());
Adithya Srinivasand17c7da2021-03-05 20:43:32 +0000184 mPendingJankClassifications.pop_front();
185 }
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100186 mPendingJankClassifications.emplace_back(surfaceFrame);
187}
188
Valerie Haubf784642020-01-29 07:25:23 -0800189void BufferStateLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
Valerie Hau32cdc1f2019-10-21 14:45:54 -0700190 for (const auto& handle : mDrawingState.callbackHandles) {
191 handle->transformHint = mTransformHint;
Valerie Hau871d6352020-01-29 08:44:02 -0800192 handle->dequeueReadyTime = dequeueReadyTime;
Ady Abraham899dcdb2021-06-15 16:56:21 -0700193 handle->currentMaxAcquiredBufferCount =
194 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(mOwnerUid);
Valerie Hau32cdc1f2019-10-21 14:45:54 -0700195 }
196
Vishnu Nair1506b182021-02-22 14:35:15 -0800197 // If there are multiple transactions in this frame, set the previous id on the earliest
198 // transacton. We don't need to pass in the released buffer id to multiple transactions.
199 // The buffer id does not have to correspond to any particular transaction as long as the
200 // listening end point is the same but the client expects the first transaction callback that
201 // replaces the presented buffer to contain the release fence. This follows the same logic.
202 // see BufferStateLayer::onLayerDisplayed.
203 for (auto& handle : mDrawingState.callbackHandles) {
204 if (handle->releasePreviousBuffer) {
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -0700205 handle->previousReleaseCallbackId = mPreviousReleaseCallbackId;
Vishnu Nair1506b182021-02-22 14:35:15 -0800206 break;
207 }
208 }
209
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100210 std::vector<JankData> jankData;
211 jankData.reserve(mPendingJankClassifications.size());
212 while (!mPendingJankClassifications.empty()
213 && mPendingJankClassifications.front()->getJankType()) {
214 std::shared_ptr<frametimeline::SurfaceFrame> surfaceFrame =
215 mPendingJankClassifications.front();
216 mPendingJankClassifications.pop_front();
217 jankData.emplace_back(
218 JankData(surfaceFrame->getToken(), surfaceFrame->getJankType().value()));
219 }
220
Robert Carr9a803c32021-01-14 16:57:58 -0800221 mFlinger->getTransactionCallbackInvoker().finalizePendingCallbackHandles(
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100222 mDrawingState.callbackHandles, jankData);
Marissa Wall5a68a772018-12-22 17:43:42 -0800223
224 mDrawingState.callbackHandles = {};
Valerie Haubf784642020-01-29 07:25:23 -0800225
226 const sp<Fence>& releaseFence(mPreviousReleaseFence);
227 std::shared_ptr<FenceTime> releaseFenceTime = std::make_shared<FenceTime>(releaseFence);
228 {
229 Mutex::Autolock lock(mFrameEventHistoryMutex);
230 if (mPreviousFrameNumber != 0) {
231 mFrameEventHistory.addRelease(mPreviousFrameNumber, dequeueReadyTime,
232 std::move(releaseFenceTime));
233 }
234 }
Marissa Wall61c58622018-07-18 10:12:20 -0700235}
236
Valerie Hau871d6352020-01-29 08:44:02 -0800237void BufferStateLayer::finalizeFrameEventHistory(const std::shared_ptr<FenceTime>& glDoneFence,
238 const CompositorTiming& compositorTiming) {
239 for (const auto& handle : mDrawingState.callbackHandles) {
240 handle->gpuCompositionDoneFence = glDoneFence;
241 handle->compositorTiming = compositorTiming;
242 }
243}
244
Marissa Walle2ffb422018-10-12 11:33:52 -0700245bool BufferStateLayer::willPresentCurrentTransaction() const {
246 // Returns true if the most recent Transaction applied to CurrentState will be presented.
Robert Carr321e83c2019-08-19 15:49:30 -0700247 return (getSidebandStreamChanged() || getAutoRefresh() ||
Robert Carr6a160312021-05-17 12:08:20 -0700248 (mDrawingState.modified &&
249 (mDrawingState.buffer != nullptr || mDrawingState.bgColorLayer != nullptr)));
Marissa Wall61c58622018-07-18 10:12:20 -0700250}
251
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000252Rect BufferStateLayer::getCrop(const Layer::State& s) const {
253 return s.crop;
Marissa Wall61c58622018-07-18 10:12:20 -0700254}
255
256bool BufferStateLayer::setTransform(uint32_t transform) {
Robert Carr6a160312021-05-17 12:08:20 -0700257 if (mDrawingState.bufferTransform == transform) return false;
258 mDrawingState.bufferTransform = transform;
259 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700260 setTransactionFlags(eTransactionNeeded);
261 return true;
262}
263
264bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
Robert Carr6a160312021-05-17 12:08:20 -0700265 if (mDrawingState.transformToDisplayInverse == transformToDisplayInverse) return false;
266 mDrawingState.sequence++;
267 mDrawingState.transformToDisplayInverse = transformToDisplayInverse;
268 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700269 setTransactionFlags(eTransactionNeeded);
270 return true;
271}
272
273bool BufferStateLayer::setCrop(const Rect& crop) {
Robert Carr6a160312021-05-17 12:08:20 -0700274 if (mDrawingState.crop == crop) return false;
275 mDrawingState.sequence++;
276 mDrawingState.crop = crop;
Marissa Wall290ad082019-03-06 13:23:47 -0800277
Robert Carr6a160312021-05-17 12:08:20 -0700278 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700279 setTransactionFlags(eTransactionNeeded);
280 return true;
281}
282
chaviwf3f40fe2021-04-27 15:54:02 -0500283bool BufferStateLayer::setBufferCrop(const Rect& bufferCrop) {
Robert Carr6a160312021-05-17 12:08:20 -0700284 if (mDrawingState.bufferCrop == bufferCrop) return false;
chaviwf3f40fe2021-04-27 15:54:02 -0500285
Robert Carr6a160312021-05-17 12:08:20 -0700286 mDrawingState.sequence++;
287 mDrawingState.bufferCrop = bufferCrop;
chaviwf3f40fe2021-04-27 15:54:02 -0500288
Robert Carr6a160312021-05-17 12:08:20 -0700289 mDrawingState.modified = true;
chaviwf3f40fe2021-04-27 15:54:02 -0500290 setTransactionFlags(eTransactionNeeded);
291 return true;
292}
293
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700294bool BufferStateLayer::setDestinationFrame(const Rect& destinationFrame) {
Robert Carr6a160312021-05-17 12:08:20 -0700295 if (mDrawingState.destinationFrame == destinationFrame) return false;
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700296
Robert Carr6a160312021-05-17 12:08:20 -0700297 mDrawingState.sequence++;
298 mDrawingState.destinationFrame = destinationFrame;
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700299
Robert Carr6a160312021-05-17 12:08:20 -0700300 mDrawingState.modified = true;
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700301 setTransactionFlags(eTransactionNeeded);
302 return true;
303}
304
Robert Carr6a160312021-05-17 12:08:20 -0700305static bool assignTransform(ui::Transform* dst, ui::Transform& from) {
306 if (*dst == from) {
307 return false;
308 }
309 *dst = from;
310 return true;
311}
312
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700313// Translate destination frame into scale and position. If a destination frame is not set, use the
314// provided scale and position
Robert Carr6a160312021-05-17 12:08:20 -0700315bool BufferStateLayer::updateGeometry() {
316 if (mDrawingState.destinationFrame.isEmpty()) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700317 // If destination frame is not set, use the requested transform set via
318 // BufferStateLayer::setPosition and BufferStateLayer::setMatrix.
Robert Carr6a160312021-05-17 12:08:20 -0700319 return assignTransform(&mDrawingState.transform, mRequestedTransform);
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700320 }
321
Robert Carr6a160312021-05-17 12:08:20 -0700322 Rect destRect = mDrawingState.destinationFrame;
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700323 int32_t destW = destRect.width();
324 int32_t destH = destRect.height();
325 if (destRect.left < 0) {
326 destRect.left = 0;
327 destRect.right = destW;
328 }
329 if (destRect.top < 0) {
330 destRect.top = 0;
331 destRect.bottom = destH;
332 }
333
Robert Carr6a160312021-05-17 12:08:20 -0700334 if (!mDrawingState.buffer) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700335 ui::Transform t;
336 t.set(destRect.left, destRect.top);
Robert Carr6a160312021-05-17 12:08:20 -0700337 return assignTransform(&mDrawingState.transform, t);
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700338 }
339
Robert Carr6a160312021-05-17 12:08:20 -0700340 uint32_t bufferWidth = mDrawingState.buffer->getBuffer()->getWidth();
341 uint32_t bufferHeight = mDrawingState.buffer->getBuffer()->getHeight();
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700342 // Undo any transformations on the buffer.
Robert Carr6a160312021-05-17 12:08:20 -0700343 if (mDrawingState.bufferTransform & ui::Transform::ROT_90) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700344 std::swap(bufferWidth, bufferHeight);
345 }
346 uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
Robert Carr6a160312021-05-17 12:08:20 -0700347 if (mDrawingState.transformToDisplayInverse) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700348 if (invTransform & ui::Transform::ROT_90) {
349 std::swap(bufferWidth, bufferHeight);
350 }
351 }
352
353 float sx = destW / static_cast<float>(bufferWidth);
354 float sy = destH / static_cast<float>(bufferHeight);
355 ui::Transform t;
356 t.set(sx, 0, 0, sy);
357 t.set(destRect.left, destRect.top);
Robert Carr6a160312021-05-17 12:08:20 -0700358 return assignTransform(&mDrawingState.transform, t);
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700359}
360
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000361bool BufferStateLayer::setMatrix(const layer_state_t::matrix22_t& matrix,
362 bool allowNonRectPreservingTransforms) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700363 if (mRequestedTransform.dsdx() == matrix.dsdx && mRequestedTransform.dtdy() == matrix.dtdy &&
364 mRequestedTransform.dtdx() == matrix.dtdx && mRequestedTransform.dsdy() == matrix.dsdy) {
Marissa Wall861616d2018-10-22 12:52:23 -0700365 return false;
366 }
367
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000368 ui::Transform t;
369 t.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
370
371 if (!allowNonRectPreservingTransforms && !t.preserveRects()) {
372 ALOGW("Attempt to set rotation matrix without permission ACCESS_SURFACE_FLINGER nor "
373 "ROTATE_SURFACE_FLINGER ignored");
374 return false;
Marissa Wall861616d2018-10-22 12:52:23 -0700375 }
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000376
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700377 mRequestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
chaviw9a93ea62021-03-11 16:44:42 -0600378
Robert Carr6a160312021-05-17 12:08:20 -0700379 mDrawingState.sequence++;
380 mDrawingState.modified = true;
chaviw9a93ea62021-03-11 16:44:42 -0600381 setTransactionFlags(eTransactionNeeded);
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000382
383 return true;
384}
385
386bool BufferStateLayer::setPosition(float x, float y) {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700387 if (mRequestedTransform.tx() == x && mRequestedTransform.ty() == y) {
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000388 return false;
389 }
390
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700391 mRequestedTransform.set(x, y);
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000392
Robert Carr6a160312021-05-17 12:08:20 -0700393 mDrawingState.sequence++;
394 mDrawingState.modified = true;
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000395 setTransactionFlags(eTransactionNeeded);
396
Marissa Wall861616d2018-10-22 12:52:23 -0700397 return true;
398}
399
Valerie Hau871d6352020-01-29 08:44:02 -0800400bool BufferStateLayer::addFrameEvent(const sp<Fence>& acquireFence, nsecs_t postedTime,
401 nsecs_t desiredPresentTime) {
Valerie Haubf784642020-01-29 07:25:23 -0800402 Mutex::Autolock lock(mFrameEventHistoryMutex);
403 mAcquireTimeline.updateSignalTimes();
404 std::shared_ptr<FenceTime> acquireFenceTime =
405 std::make_shared<FenceTime>((acquireFence ? acquireFence : Fence::NO_FENCE));
Robert Carr6a160312021-05-17 12:08:20 -0700406 NewFrameEventsEntry newTimestamps = {mDrawingState.frameNumber, postedTime, desiredPresentTime,
Valerie Haubf784642020-01-29 07:25:23 -0800407 acquireFenceTime};
Valerie Hau871d6352020-01-29 08:44:02 -0800408 mFrameEventHistory.setProducerWantsEvents();
Valerie Haubf784642020-01-29 07:25:23 -0800409 mFrameEventHistory.addQueue(newTimestamps);
410 return true;
411}
412
Alec Mouria90a5702021-04-16 16:36:21 +0000413bool BufferStateLayer::setBuffer(const std::shared_ptr<renderengine::ExternalTexture>& buffer,
414 const sp<Fence>& acquireFence, nsecs_t postTime,
415 nsecs_t desiredPresentTime, bool isAutoTimestamp,
Vishnu Nairadf632b2021-01-07 14:05:08 -0800416 const client_cache_t& clientCacheId, uint64_t frameNumber,
Vishnu Nair1506b182021-02-22 14:35:15 -0800417 std::optional<nsecs_t> dequeueTime, const FrameTimelineInfo& info,
418 const sp<ITransactionCompletedListener>& releaseBufferListener) {
Robert Carr0c1966e2020-10-19 12:12:08 -0700419 ATRACE_CALL();
420
Robert Carr6a160312021-05-17 12:08:20 -0700421 if (mDrawingState.buffer) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700422 mReleasePreviousBuffer = true;
Robert Carr6a160312021-05-17 12:08:20 -0700423 if (mDrawingState.buffer != mBufferInfo.mBuffer) {
424 // If mDrawingState has a buffer, and we are about to update again
Robert Carr7121caf2020-12-15 13:07:32 -0800425 // before swapping to drawing state, then the first buffer will be
Vishnu Nair1506b182021-02-22 14:35:15 -0800426 // dropped and we should decrement the pending buffer count and
427 // call any release buffer callbacks if set.
Robert Carr6a160312021-05-17 12:08:20 -0700428 callReleaseBufferCallback(mDrawingState.releaseBufferListener,
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -0700429 mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
430 mDrawingState.acquireFence, mTransformHint,
Ady Abraham899dcdb2021-06-15 16:56:21 -0700431 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
432 mOwnerUid));
Robert Carr7121caf2020-12-15 13:07:32 -0800433 decrementPendingBufferCount();
Robert Carr6a160312021-05-17 12:08:20 -0700434 if (mDrawingState.bufferSurfaceFrameTX != nullptr &&
435 mDrawingState.bufferSurfaceFrameTX->getPresentState() != PresentState::Presented) {
436 addSurfaceFrameDroppedForBuffer(mDrawingState.bufferSurfaceFrameTX);
437 mDrawingState.bufferSurfaceFrameTX.reset();
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000438 }
Robert Carr7121caf2020-12-15 13:07:32 -0800439 }
Marissa Wallfda30bb2018-10-12 11:34:28 -0700440 }
Robert Carr6a160312021-05-17 12:08:20 -0700441
442 mDrawingState.frameNumber = frameNumber;
443 mDrawingState.releaseBufferListener = releaseBufferListener;
444 mDrawingState.buffer = buffer;
445 mDrawingState.clientCacheId = clientCacheId;
446 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700447 setTransactionFlags(eTransactionNeeded);
Ady Abraham09bd3922019-04-08 10:44:56 -0700448
Yiwei Zhang1a88c402019-11-18 10:43:58 -0800449 const int32_t layerId = getSequence();
Robert Carr6a160312021-05-17 12:08:20 -0700450 mFlinger->mTimeStats->setPostTime(layerId, mDrawingState.frameNumber, getName().c_str(),
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000451 mOwnerUid, postTime, getGameMode());
Robert Carr6a160312021-05-17 12:08:20 -0700452 mDrawingState.desiredPresentTime = desiredPresentTime;
453 mDrawingState.isAutoTimestamp = isAutoTimestamp;
Ady Abraham09bd3922019-04-08 10:44:56 -0700454
Ady Abrahamb7f15562021-03-15 18:34:08 -0700455 const nsecs_t presentTime = [&] {
456 if (!isAutoTimestamp) return desiredPresentTime;
457
458 const auto prediction =
459 mFlinger->mFrameTimeline->getTokenManager()->getPredictionsForToken(info.vsyncId);
460 if (prediction.has_value()) return prediction->presentTime;
461
462 return static_cast<nsecs_t>(0);
463 }();
464 mFlinger->mScheduler->recordLayerHistory(this, presentTime,
Ady Abraham5def7332020-05-29 16:13:47 -0700465 LayerHistory::LayerUpdateType::Buffer);
Ady Abraham09bd3922019-04-08 10:44:56 -0700466
Ady Abrahamf0c56492020-12-17 18:04:15 -0800467 addFrameEvent(acquireFence, postTime, isAutoTimestamp ? 0 : desiredPresentTime);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000468
Adithya Srinivasan891004e2021-02-12 20:20:47 +0000469 setFrameTimelineVsyncForBufferTransaction(info, postTime);
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000470
Alec Mouria90a5702021-04-16 16:36:21 +0000471 if (buffer && dequeueTime && *dequeueTime != 0) {
472 const uint64_t bufferId = buffer->getBuffer()->getId();
Adithya Srinivasanb238cd52021-02-04 17:54:05 +0000473 mFlinger->mFrameTracer->traceNewLayer(layerId, getName().c_str());
474 mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, *dequeueTime,
475 FrameTracer::FrameEvent::DEQUEUE);
476 mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, postTime,
477 FrameTracer::FrameEvent::QUEUE);
478 }
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000479
Robert Carr6a160312021-05-17 12:08:20 -0700480 mDrawingState.width = mDrawingState.buffer->getBuffer()->getWidth();
481 mDrawingState.height = mDrawingState.buffer->getBuffer()->getHeight();
Chavi Weingartena5aedbd2021-04-09 13:37:33 +0000482
Marissa Wall61c58622018-07-18 10:12:20 -0700483 return true;
484}
485
486bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) {
Robert Carr6a160312021-05-17 12:08:20 -0700487 mDrawingState.acquireFence = fence;
488 mDrawingState.acquireFenceTime = std::make_unique<FenceTime>(fence);
Ady Abraham6c1b7ac2021-03-31 16:56:03 -0700489
490 // The acquire fences of BufferStateLayers have already signaled before they are set
Robert Carr6a160312021-05-17 12:08:20 -0700491 mCallbackHandleAcquireTime = mDrawingState.acquireFenceTime->getSignalTime();
Ady Abraham6c1b7ac2021-03-31 16:56:03 -0700492
Robert Carr6a160312021-05-17 12:08:20 -0700493 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700494 setTransactionFlags(eTransactionNeeded);
495 return true;
496}
497
498bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
Robert Carr6a160312021-05-17 12:08:20 -0700499 if (mDrawingState.dataspace == dataspace) return false;
500 mDrawingState.dataspace = dataspace;
501 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700502 setTransactionFlags(eTransactionNeeded);
503 return true;
504}
505
506bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
Robert Carr6a160312021-05-17 12:08:20 -0700507 if (mDrawingState.hdrMetadata == hdrMetadata) return false;
508 mDrawingState.hdrMetadata = hdrMetadata;
509 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700510 setTransactionFlags(eTransactionNeeded);
511 return true;
512}
513
514bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
Robert Carr6a160312021-05-17 12:08:20 -0700515 mDrawingState.surfaceDamageRegion = surfaceDamage;
516 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700517 setTransactionFlags(eTransactionNeeded);
518 return true;
519}
520
521bool BufferStateLayer::setApi(int32_t api) {
Robert Carr6a160312021-05-17 12:08:20 -0700522 if (mDrawingState.api == api) return false;
523 mDrawingState.api = api;
524 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700525 setTransactionFlags(eTransactionNeeded);
526 return true;
527}
528
529bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
Robert Carr6a160312021-05-17 12:08:20 -0700530 if (mDrawingState.sidebandStream == sidebandStream) return false;
Robert Carr3e2a2992021-06-11 13:42:55 -0700531
532 if (mDrawingState.sidebandStream != nullptr && sidebandStream == nullptr) {
533 mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
534 } else if (sidebandStream != nullptr) {
535 mFlinger->mTunnelModeEnabledReporter->incrementTunnelModeCount();
536 }
537
Robert Carr6a160312021-05-17 12:08:20 -0700538 mDrawingState.sidebandStream = sidebandStream;
539 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700540 setTransactionFlags(eTransactionNeeded);
Marissa Wall61c58622018-07-18 10:12:20 -0700541 if (!mSidebandStreamChanged.exchange(true)) {
542 // mSidebandStreamChanged was false
543 mFlinger->signalLayerUpdate();
544 }
545 return true;
546}
547
Marissa Walle2ffb422018-10-12 11:33:52 -0700548bool BufferStateLayer::setTransactionCompletedListeners(
549 const std::vector<sp<CallbackHandle>>& handles) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700550 // If there is no handle, we will not send a callback so reset mReleasePreviousBuffer and return
Marissa Walle2ffb422018-10-12 11:33:52 -0700551 if (handles.empty()) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700552 mReleasePreviousBuffer = false;
Marissa Walle2ffb422018-10-12 11:33:52 -0700553 return false;
554 }
555
556 const bool willPresent = willPresentCurrentTransaction();
557
558 for (const auto& handle : handles) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700559 // If this transaction set a buffer on this layer, release its previous buffer
560 handle->releasePreviousBuffer = mReleasePreviousBuffer;
561
Marissa Walle2ffb422018-10-12 11:33:52 -0700562 // If this layer will be presented in this frame
563 if (willPresent) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700564 // If this transaction set an acquire fence on this layer, set its acquire time
565 handle->acquireTime = mCallbackHandleAcquireTime;
Robert Carr6a160312021-05-17 12:08:20 -0700566 handle->frameNumber = mDrawingState.frameNumber;
Marissa Wallfda30bb2018-10-12 11:34:28 -0700567
Marissa Walle2ffb422018-10-12 11:33:52 -0700568 // Notify the transaction completed thread that there is a pending latched callback
569 // handle
Robert Carr9a803c32021-01-14 16:57:58 -0800570 mFlinger->getTransactionCallbackInvoker().registerPendingCallbackHandle(handle);
Marissa Walle2ffb422018-10-12 11:33:52 -0700571
572 // Store so latched time and release fence can be set
Robert Carr6a160312021-05-17 12:08:20 -0700573 mDrawingState.callbackHandles.push_back(handle);
Marissa Walle2ffb422018-10-12 11:33:52 -0700574
575 } else { // If this layer will NOT need to be relatched and presented this frame
576 // Notify the transaction completed thread this handle is done
Robert Carr9a803c32021-01-14 16:57:58 -0800577 mFlinger->getTransactionCallbackInvoker().registerUnpresentedCallbackHandle(handle);
Marissa Walle2ffb422018-10-12 11:33:52 -0700578 }
579 }
580
Marissa Wallfda30bb2018-10-12 11:34:28 -0700581 mReleasePreviousBuffer = false;
582 mCallbackHandleAcquireTime = -1;
583
Marissa Walle2ffb422018-10-12 11:33:52 -0700584 return willPresent;
585}
586
Marissa Wall61c58622018-07-18 10:12:20 -0700587bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
Vishnu Nair27e3ed52021-07-08 18:24:25 -0700588 mDrawingState.sequence++;
Robert Carr6a160312021-05-17 12:08:20 -0700589 mDrawingState.transparentRegionHint = transparent;
590 mDrawingState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700591 setTransactionFlags(eTransactionNeeded);
592 return true;
593}
594
rnleeed20fa42021-08-10 18:00:03 -0700595Rect BufferStateLayer::getBufferSize(const State& /*s*/) const {
Marissa Wall861616d2018-10-22 12:52:23 -0700596 // for buffer state layers we use the display frame size as the buffer size.
Marissa Wall61c58622018-07-18 10:12:20 -0700597
chaviw7e72caf2020-12-02 16:50:43 -0800598 if (mBufferInfo.mBuffer == nullptr) {
599 return Rect::INVALID_RECT;
600 }
601
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700602 uint32_t bufWidth = mBufferInfo.mBuffer->getBuffer()->getWidth();
603 uint32_t bufHeight = mBufferInfo.mBuffer->getBuffer()->getHeight();
604
605 // Undo any transformations on the buffer and return the result.
606 if (mBufferInfo.mTransform & ui::Transform::ROT_90) {
607 std::swap(bufWidth, bufHeight);
608 }
609
610 if (getTransformToDisplayInverse()) {
611 uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
612 if (invTransform & ui::Transform::ROT_90) {
613 std::swap(bufWidth, bufHeight);
Marissa Wall861616d2018-10-22 12:52:23 -0700614 }
615 }
616
rnleeed20fa42021-08-10 18:00:03 -0700617 return Rect(0, 0, static_cast<int32_t>(bufWidth), static_cast<int32_t>(bufHeight));
Marissa Wall61c58622018-07-18 10:12:20 -0700618}
Vishnu Nair4351ad52019-02-11 14:13:02 -0800619
620FloatRect BufferStateLayer::computeSourceBounds(const FloatRect& parentBounds) const {
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700621 if (mBufferInfo.mBuffer == nullptr) {
622 return parentBounds;
Vishnu Nair4351ad52019-02-11 14:13:02 -0800623 }
624
Vishnu Nair6bdec7d2021-05-10 15:01:13 -0700625 return getBufferSize(getDrawingState()).toFloatRect();
Vishnu Nair4351ad52019-02-11 14:13:02 -0800626}
627
Marissa Wall61c58622018-07-18 10:12:20 -0700628// -----------------------------------------------------------------------
629
630// -----------------------------------------------------------------------
631// Interface implementation for BufferLayer
632// -----------------------------------------------------------------------
633bool BufferStateLayer::fenceHasSignaled() const {
Huihong Luo86c80e32021-06-16 15:41:07 -0700634 if (SurfaceFlinger::enableLatchUnsignaled) {
635 return true;
636 }
637
Alec Mouri91f6df32020-01-30 08:48:58 -0800638 const bool fenceSignaled =
639 getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
640 if (!fenceSignaled) {
641 mFlinger->mTimeStats->incrementLatchSkipped(getSequence(),
642 TimeStats::LatchSkipReason::LateAcquire);
643 }
644
645 return fenceSignaled;
Marissa Wall61c58622018-07-18 10:12:20 -0700646}
647
Dominik Laskowskia8955dd2019-07-10 10:19:09 -0700648bool BufferStateLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const {
Ady Abrahamcd1580c2019-04-29 15:40:03 -0700649 if (!hasFrameUpdate() || isRemovedFromCurrentState()) {
650 return true;
651 }
652
Robert Carr6a160312021-05-17 12:08:20 -0700653 return mDrawingState.isAutoTimestamp || mDrawingState.desiredPresentTime <= expectedPresentTime;
Ady Abrahamcd1580c2019-04-29 15:40:03 -0700654}
655
Valerie Hau871d6352020-01-29 08:44:02 -0800656bool BufferStateLayer::onPreComposition(nsecs_t refreshStartTime) {
657 for (const auto& handle : mDrawingState.callbackHandles) {
658 handle->refreshStartTime = refreshStartTime;
659 }
660 return BufferLayer::onPreComposition(refreshStartTime);
661}
662
Dominik Laskowskia8955dd2019-07-10 10:19:09 -0700663uint64_t BufferStateLayer::getFrameNumber(nsecs_t /*expectedPresentTime*/) const {
Valerie Hau134651a2020-01-28 16:21:22 -0800664 return mDrawingState.frameNumber;
Marissa Wall61c58622018-07-18 10:12:20 -0700665}
666
Robert Carrfe1209c2020-02-11 12:25:35 -0800667/**
668 * This is the frameNumber used for deferred transaction signalling. We need to use this because
669 * of cases where we defer a transaction for a surface to itself. In the BLAST world this
670 * may not make a huge amount of sense (Why not just merge the Buffer transaction with the
671 * deferred transaction?) but this is an important legacy use case, for example moving
672 * a window at the same time it draws makes use of this kind of technique. So anyway
673 * imagine we have something like this:
674 *
675 * Transaction { // containing
676 * Buffer -> frameNumber = 2
677 * DeferTransactionUntil -> frameNumber = 2
678 * Random other stuff
679 * }
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -0700680 * Now imagine mFrameNumber returned mDrawingState.frameNumber (or mCurrentFrameNumber).
Robert Carrfe1209c2020-02-11 12:25:35 -0800681 * Prior to doTransaction SurfaceFlinger will call notifyAvailableFrames, but because we
Robert Carr6a160312021-05-17 12:08:20 -0700682 * haven't swapped mDrawingState to mDrawingState yet we will think the sync point
Robert Carrfe1209c2020-02-11 12:25:35 -0800683 * is not ready. So we will return false from applyPendingState and not swap
684 * current state to drawing state. But because we don't swap current state
685 * to drawing state the number will never update and we will be stuck. This way
686 * we can see we need to return the frame number for the buffer we are about
687 * to apply.
688 */
689uint64_t BufferStateLayer::getHeadFrameNumber(nsecs_t /* expectedPresentTime */) const {
Robert Carr6a160312021-05-17 12:08:20 -0700690 return mDrawingState.frameNumber;
Robert Carrfe1209c2020-02-11 12:25:35 -0800691}
692
Vishnu Naircf26a0a2020-11-13 12:56:20 -0800693void BufferStateLayer::setAutoRefresh(bool autoRefresh) {
694 if (!mAutoRefresh.exchange(autoRefresh)) {
695 mFlinger->signalLayerUpdate();
696 }
Marissa Wall61c58622018-07-18 10:12:20 -0700697}
698
Vishnu Nair6194e2e2019-02-06 12:58:39 -0800699bool BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
baocheng suna663c2b2021-05-13 18:51:28 +0800700 // We need to update the sideband stream if the layer has both a buffer and a sideband stream.
701 const bool updateSidebandStream = hasFrameUpdate() && mSidebandStream.get();
702
703 if (mSidebandStreamChanged.exchange(false) || updateSidebandStream) {
Marissa Wall61c58622018-07-18 10:12:20 -0700704 const State& s(getDrawingState());
705 // mSidebandStreamChanged was true
Lloyd Pique0b785d82018-12-04 17:25:27 -0800706 mSidebandStream = s.sidebandStream;
Lloyd Piquede196652020-01-22 17:29:58 -0800707 editCompositionState()->sidebandStream = mSidebandStream;
Lloyd Pique0b785d82018-12-04 17:25:27 -0800708 if (mSidebandStream != nullptr) {
Marissa Wall61c58622018-07-18 10:12:20 -0700709 setTransactionFlags(eTransactionNeeded);
710 mFlinger->setTransactionFlags(eTraversalNeeded);
711 }
712 recomputeVisibleRegions = true;
713
Vishnu Nair6194e2e2019-02-06 12:58:39 -0800714 return true;
Marissa Wall61c58622018-07-18 10:12:20 -0700715 }
Vishnu Nair6194e2e2019-02-06 12:58:39 -0800716 return false;
Marissa Wall61c58622018-07-18 10:12:20 -0700717}
718
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800719bool BufferStateLayer::hasFrameUpdate() const {
Robert Carr6a160312021-05-17 12:08:20 -0700720 const State& c(getDrawingState());
Robert Carr315f3c72021-06-24 21:58:09 -0700721 return (mDrawingStateModified || mDrawingState.modified) && (c.buffer != nullptr || c.bgColorLayer != nullptr);
Marissa Wall61c58622018-07-18 10:12:20 -0700722}
723
Dominik Laskowskia8955dd2019-07-10 10:19:09 -0700724status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
725 nsecs_t /*expectedPresentTime*/) {
Marissa Wall61c58622018-07-18 10:12:20 -0700726 const State& s(getDrawingState());
727
728 if (!s.buffer) {
Valerie Hauaa194562019-02-05 16:21:38 -0800729 if (s.bgColorLayer) {
730 for (auto& handle : mDrawingState.callbackHandles) {
731 handle->latchTime = latchTime;
732 }
733 }
Marissa Wall61c58622018-07-18 10:12:20 -0700734 return NO_ERROR;
735 }
736
Marissa Wall5a68a772018-12-22 17:43:42 -0800737 for (auto& handle : mDrawingState.callbackHandles) {
Vishnu Nair935590e2021-02-10 13:05:52 -0800738 if (handle->frameNumber == mDrawingState.frameNumber) {
739 handle->latchTime = latchTime;
740 }
Marissa Wall5a68a772018-12-22 17:43:42 -0800741 }
Marissa Walle2ffb422018-10-12 11:33:52 -0700742
Vishnu Nairea0de002020-11-17 17:42:37 -0800743 const int32_t layerId = getSequence();
Alec Mouria90a5702021-04-16 16:36:21 +0000744 const uint64_t bufferId = mDrawingState.buffer->getBuffer()->getId();
Adithya Srinivasanb238cd52021-02-04 17:54:05 +0000745 const uint64_t frameNumber = mDrawingState.frameNumber;
746 const auto acquireFence = std::make_shared<FenceTime>(mDrawingState.acquireFence);
747 mFlinger->mTimeStats->setAcquireFence(layerId, frameNumber, acquireFence);
748 mFlinger->mTimeStats->setLatchTime(layerId, frameNumber, latchTime);
749
750 mFlinger->mFrameTracer->traceFence(layerId, bufferId, frameNumber, acquireFence,
751 FrameTracer::FrameEvent::ACQUIRE_FENCE);
752 mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, frameNumber, latchTime,
753 FrameTracer::FrameEvent::LATCH);
Marissa Wall61c58622018-07-18 10:12:20 -0700754
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000755 auto& bufferSurfaceFrame = mDrawingState.bufferSurfaceFrameTX;
756 if (bufferSurfaceFrame != nullptr &&
757 bufferSurfaceFrame->getPresentState() != PresentState::Presented) {
758 // Update only if the bufferSurfaceFrame wasn't already presented. A Presented
759 // bufferSurfaceFrame could be seen here if a pending state was applied successfully and we
760 // are processing the next state.
761 addSurfaceFramePresentedForBuffer(bufferSurfaceFrame,
Ady Abraham6c1b7ac2021-03-31 16:56:03 -0700762 mDrawingState.acquireFenceTime->getSignalTime(),
763 latchTime);
Robert Carr6a160312021-05-17 12:08:20 -0700764 mDrawingState.bufferSurfaceFrameTX.reset();
Adithya Srinivasanb9a7dab2021-01-14 23:49:46 +0000765 }
766
Vishnu Nairfc46c1e2021-04-21 08:31:32 -0700767 std::deque<sp<CallbackHandle>> remainingHandles;
768 mFlinger->getTransactionCallbackInvoker()
769 .finalizeOnCommitCallbackHandles(mDrawingState.callbackHandles, remainingHandles);
770 mDrawingState.callbackHandles = remainingHandles;
771
Robert Carr6a160312021-05-17 12:08:20 -0700772 mDrawingStateModified = false;
Marissa Wall16c112d2019-03-20 13:21:13 -0700773
Marissa Wall61c58622018-07-18 10:12:20 -0700774 return NO_ERROR;
775}
776
777status_t BufferStateLayer::updateActiveBuffer() {
778 const State& s(getDrawingState());
779
780 if (s.buffer == nullptr) {
781 return BAD_VALUE;
782 }
chaviwdf3c5e82021-01-07 13:00:37 -0800783
Alec Mouria90a5702021-04-16 16:36:21 +0000784 if (!mBufferInfo.mBuffer || s.buffer->getBuffer() != mBufferInfo.mBuffer->getBuffer()) {
chaviwdf3c5e82021-01-07 13:00:37 -0800785 decrementPendingBufferCount();
786 }
Marissa Wall61c58622018-07-18 10:12:20 -0700787
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -0700788 mPreviousReleaseCallbackId = {getCurrentBufferId(), mBufferInfo.mFrameNumber};
chaviwd62d3062019-09-04 14:48:02 -0700789 mBufferInfo.mBuffer = s.buffer;
790 mBufferInfo.mFence = s.acquireFence;
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -0700791 mBufferInfo.mFrameNumber = s.frameNumber;
Marissa Wall61c58622018-07-18 10:12:20 -0700792
793 return NO_ERROR;
794}
795
Valerie Haubf784642020-01-29 07:25:23 -0800796status_t BufferStateLayer::updateFrameNumber(nsecs_t latchTime) {
Marissa Wall61c58622018-07-18 10:12:20 -0700797 // TODO(marissaw): support frame history events
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700798 mPreviousFrameNumber = mCurrentFrameNumber;
Valerie Hau134651a2020-01-28 16:21:22 -0800799 mCurrentFrameNumber = mDrawingState.frameNumber;
Valerie Haubf784642020-01-29 07:25:23 -0800800 {
801 Mutex::Autolock lock(mFrameEventHistoryMutex);
802 mFrameEventHistory.addLatch(mCurrentFrameNumber, latchTime);
803 }
Marissa Wall61c58622018-07-18 10:12:20 -0700804 return NO_ERROR;
805}
806
Marissa Wall947d34e2019-03-29 14:03:53 -0700807void BufferStateLayer::HwcSlotGenerator::bufferErased(const client_cache_t& clientCacheId) {
808 std::lock_guard lock(mMutex);
809 if (!clientCacheId.isValid()) {
810 ALOGE("invalid process, failed to erase buffer");
811 return;
812 }
813 eraseBufferLocked(clientCacheId);
814}
815
rnleeed20fa42021-08-10 18:00:03 -0700816int BufferStateLayer::HwcSlotGenerator::getHwcCacheSlot(const client_cache_t& clientCacheId) {
Marissa Wall947d34e2019-03-29 14:03:53 -0700817 std::lock_guard<std::mutex> lock(mMutex);
818 auto itr = mCachedBuffers.find(clientCacheId);
819 if (itr == mCachedBuffers.end()) {
820 return addCachedBuffer(clientCacheId);
821 }
822 auto& [hwcCacheSlot, counter] = itr->second;
823 counter = mCounter++;
824 return hwcCacheSlot;
825}
826
rnleeed20fa42021-08-10 18:00:03 -0700827int BufferStateLayer::HwcSlotGenerator::addCachedBuffer(const client_cache_t& clientCacheId)
Marissa Wall947d34e2019-03-29 14:03:53 -0700828 REQUIRES(mMutex) {
829 if (!clientCacheId.isValid()) {
830 ALOGE("invalid process, returning invalid slot");
831 return BufferQueue::INVALID_BUFFER_SLOT;
832 }
833
834 ClientCache::getInstance().registerErasedRecipient(clientCacheId, wp<ErasedRecipient>(this));
835
rnleeed20fa42021-08-10 18:00:03 -0700836 int hwcCacheSlot = getFreeHwcCacheSlot();
Marissa Wall947d34e2019-03-29 14:03:53 -0700837 mCachedBuffers[clientCacheId] = {hwcCacheSlot, mCounter++};
838 return hwcCacheSlot;
839}
840
rnleeed20fa42021-08-10 18:00:03 -0700841int BufferStateLayer::HwcSlotGenerator::getFreeHwcCacheSlot() REQUIRES(mMutex) {
Marissa Wall947d34e2019-03-29 14:03:53 -0700842 if (mFreeHwcCacheSlots.empty()) {
843 evictLeastRecentlyUsed();
844 }
845
rnleeed20fa42021-08-10 18:00:03 -0700846 int hwcCacheSlot = mFreeHwcCacheSlots.top();
Marissa Wall947d34e2019-03-29 14:03:53 -0700847 mFreeHwcCacheSlots.pop();
848 return hwcCacheSlot;
849}
850
851void BufferStateLayer::HwcSlotGenerator::evictLeastRecentlyUsed() REQUIRES(mMutex) {
852 uint64_t minCounter = UINT_MAX;
853 client_cache_t minClientCacheId = {};
854 for (const auto& [clientCacheId, slotCounter] : mCachedBuffers) {
855 const auto& [hwcCacheSlot, counter] = slotCounter;
856 if (counter < minCounter) {
857 minCounter = counter;
858 minClientCacheId = clientCacheId;
859 }
860 }
861 eraseBufferLocked(minClientCacheId);
862
863 ClientCache::getInstance().unregisterErasedRecipient(minClientCacheId, this);
864}
865
866void BufferStateLayer::HwcSlotGenerator::eraseBufferLocked(const client_cache_t& clientCacheId)
867 REQUIRES(mMutex) {
868 auto itr = mCachedBuffers.find(clientCacheId);
869 if (itr == mCachedBuffers.end()) {
870 return;
871 }
872 auto& [hwcCacheSlot, counter] = itr->second;
873
874 // TODO send to hwc cache and resources
875
876 mFreeHwcCacheSlots.push(hwcCacheSlot);
877 mCachedBuffers.erase(clientCacheId);
878}
chaviw4244e032019-09-04 11:27:49 -0700879
880void BufferStateLayer::gatherBufferInfo() {
chaviwdebadb82020-03-26 14:57:24 -0700881 BufferLayer::gatherBufferInfo();
chaviw4244e032019-09-04 11:27:49 -0700882
chaviwdebadb82020-03-26 14:57:24 -0700883 const State& s(getDrawingState());
chaviw4244e032019-09-04 11:27:49 -0700884 mBufferInfo.mDesiredPresentTime = s.desiredPresentTime;
885 mBufferInfo.mFenceTime = std::make_shared<FenceTime>(s.acquireFence);
886 mBufferInfo.mFence = s.acquireFence;
chaviw766c9c52021-02-10 17:36:47 -0800887 mBufferInfo.mTransform = s.bufferTransform;
Robert Carr167bdde2021-07-28 11:26:51 -0700888 auto lastDataspace = mBufferInfo.mDataspace;
chaviw4244e032019-09-04 11:27:49 -0700889 mBufferInfo.mDataspace = translateDataspace(s.dataspace);
Robert Carr167bdde2021-07-28 11:26:51 -0700890 if (lastDataspace != mBufferInfo.mDataspace) {
891 mFlinger->mSomeDataspaceChanged = true;
892 }
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700893 mBufferInfo.mCrop = computeBufferCrop(s);
chaviw4244e032019-09-04 11:27:49 -0700894 mBufferInfo.mScaleMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
895 mBufferInfo.mSurfaceDamage = s.surfaceDamageRegion;
896 mBufferInfo.mHdrMetadata = s.hdrMetadata;
897 mBufferInfo.mApi = s.api;
chaviw4244e032019-09-04 11:27:49 -0700898 mBufferInfo.mTransformToDisplayInverse = s.transformToDisplayInverse;
chaviwf83ce182019-09-12 14:43:08 -0700899 mBufferInfo.mBufferSlot = mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId);
chaviw4244e032019-09-04 11:27:49 -0700900}
901
Robert Carr916b0362020-10-06 13:53:03 -0700902uint32_t BufferStateLayer::getEffectiveScalingMode() const {
903 return NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
904}
905
Vishnu Nair5cc9ac02021-04-19 13:23:38 -0700906Rect BufferStateLayer::computeBufferCrop(const State& s) {
chaviwf3f40fe2021-04-27 15:54:02 -0500907 if (s.buffer && !s.bufferCrop.isEmpty()) {
908 Rect bufferCrop;
909 s.buffer->getBuffer()->getBounds().intersect(s.bufferCrop, &bufferCrop);
910 return bufferCrop;
911 } else if (s.buffer) {
Alec Mouria90a5702021-04-16 16:36:21 +0000912 return s.buffer->getBuffer()->getBounds();
chaviwf3f40fe2021-04-27 15:54:02 -0500913 } else {
914 return s.bufferCrop;
chaviw4244e032019-09-04 11:27:49 -0700915 }
chaviw4244e032019-09-04 11:27:49 -0700916}
917
chaviwb4c6e582019-08-16 14:35:07 -0700918sp<Layer> BufferStateLayer::createClone() {
Dominik Laskowski87a07e42019-10-10 20:38:02 -0700919 LayerCreationArgs args(mFlinger.get(), nullptr, mName + " (Mirror)", 0, 0, 0, LayerMetadata());
chaviwb4c6e582019-08-16 14:35:07 -0700920 args.textureName = mTextureName;
Lloyd Pique1c3a5eb2019-10-03 13:07:08 -0700921 sp<BufferStateLayer> layer = mFlinger->getFactory().createBufferStateLayer(args);
chaviwb4c6e582019-08-16 14:35:07 -0700922 layer->mHwcSlotGenerator = mHwcSlotGenerator;
923 layer->setInitialValuesForClone(this);
924 return layer;
925}
Valerie Hau92bf5482020-02-10 09:49:08 -0800926
Vishnu Naire7f79c52020-10-29 14:45:03 -0700927bool BufferStateLayer::bufferNeedsFiltering() const {
928 const State& s(getDrawingState());
929 if (!s.buffer) {
930 return false;
931 }
932
rnleeed20fa42021-08-10 18:00:03 -0700933 int32_t bufferWidth = s.buffer->getBuffer()->width;
934 int32_t bufferHeight = s.buffer->getBuffer()->height;
Vishnu Naire7f79c52020-10-29 14:45:03 -0700935
936 // Undo any transformations on the buffer and return the result.
chaviw766c9c52021-02-10 17:36:47 -0800937 if (s.bufferTransform & ui::Transform::ROT_90) {
Vishnu Naire7f79c52020-10-29 14:45:03 -0700938 std::swap(bufferWidth, bufferHeight);
939 }
940
941 if (s.transformToDisplayInverse) {
942 uint32_t invTransform = DisplayDevice::getPrimaryDisplayRotationFlags();
943 if (invTransform & ui::Transform::ROT_90) {
944 std::swap(bufferWidth, bufferHeight);
945 }
946 }
947
948 const Rect layerSize{getBounds()};
949 return layerSize.width() != bufferWidth || layerSize.height() != bufferHeight;
950}
Robert Carr7121caf2020-12-15 13:07:32 -0800951
Robert Carr7121caf2020-12-15 13:07:32 -0800952void BufferStateLayer::decrementPendingBufferCount() {
Vishnu Nair8eda69e2021-02-26 10:42:10 -0800953 int32_t pendingBuffers = --mPendingBufferTransactions;
954 tracePendingBufferCount(pendingBuffers);
Robert Carr7121caf2020-12-15 13:07:32 -0800955}
956
Vishnu Nair8eda69e2021-02-26 10:42:10 -0800957void BufferStateLayer::tracePendingBufferCount(int32_t pendingBuffers) {
958 ATRACE_INT(mBlastTransactionName.c_str(), pendingBuffers);
Robert Carr7121caf2020-12-15 13:07:32 -0800959}
960
Alec Mouria90a5702021-04-16 16:36:21 +0000961void BufferStateLayer::bufferMayChange(const sp<GraphicBuffer>& newBuffer) {
962 if (mDrawingState.buffer != nullptr &&
963 (!mBufferInfo.mBuffer ||
964 mDrawingState.buffer->getBuffer() != mBufferInfo.mBuffer->getBuffer()) &&
965 newBuffer != mDrawingState.buffer->getBuffer()) {
Robert Carr7121caf2020-12-15 13:07:32 -0800966 // If we are about to update mDrawingState.buffer but it has not yet latched
Vishnu Nair1506b182021-02-22 14:35:15 -0800967 // then we will drop a buffer and should decrement the pending buffer count and
968 // call any release buffer callbacks if set.
Alec Mouria90a5702021-04-16 16:36:21 +0000969 callReleaseBufferCallback(mDrawingState.releaseBufferListener,
Vishnu Nair4ba0c2e2021-06-24 11:27:17 -0700970 mDrawingState.buffer->getBuffer(), mDrawingState.frameNumber,
971 mDrawingState.acquireFence, mTransformHint,
Ady Abraham899dcdb2021-06-15 16:56:21 -0700972 mFlinger->getMaxAcquiredBufferCountForCurrentRefreshRate(
973 mOwnerUid));
Robert Carr7121caf2020-12-15 13:07:32 -0800974 decrementPendingBufferCount();
975 }
Robert Carr7121caf2020-12-15 13:07:32 -0800976}
977
chaviw39d01472021-04-08 14:26:24 -0500978/*
979 * We don't want to send the layer's transform to input, but rather the
980 * parent's transform. This is because BufferStateLayer's transform is
981 * information about how the buffer is placed on screen. The parent's
982 * transform makes more sense to send since it's information about how the
983 * layer is placed on screen. This transform is used by input to determine
984 * how to go from screen space back to window space.
985 */
986ui::Transform BufferStateLayer::getInputTransform() const {
987 sp<Layer> parent = mDrawingParent.promote();
988 if (parent == nullptr) {
989 return ui::Transform();
990 }
991
992 return parent->getTransform();
993}
994
995/**
996 * Similar to getInputTransform, we need to update the bounds to include the transform.
997 * This is because bounds for BSL doesn't include buffer transform, where the input assumes
998 * that's already included.
999 */
1000Rect BufferStateLayer::getInputBounds() const {
1001 Rect bufferBounds = getCroppedBufferSize(getDrawingState());
1002 if (mDrawingState.transform.getType() == ui::Transform::IDENTITY || !bufferBounds.isValid()) {
1003 return bufferBounds;
1004 }
1005 return mDrawingState.transform.transform(bufferBounds);
1006}
1007
Marissa Wall61c58622018-07-18 10:12:20 -07001008} // namespace android