blob: e7d1b63b03ecfebc895244d2d315adb5c6a8d35a [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 Pique37c2c9b2018-12-04 17:25:10 -080022#include <limits>
Marissa Wall61c58622018-07-18 10:12:20 -070023
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080024#include <compositionengine/Display.h>
Lloyd Pique0b785d82018-12-04 17:25:27 -080025#include <compositionengine/Layer.h>
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080026#include <compositionengine/OutputLayer.h>
Lloyd Pique0b785d82018-12-04 17:25:27 -080027#include <compositionengine/impl/LayerCompositionState.h>
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080028#include <compositionengine/impl/OutputLayerCompositionState.h>
Marissa Wall947d34e2019-03-29 14:03:53 -070029#include <gui/BufferQueue.h>
Marissa Wall61c58622018-07-18 10:12:20 -070030#include <private/gui/SyncFeatures.h>
Peiyong Lincbc184f2018-08-22 13:24:10 -070031#include <renderengine/Image.h>
Marissa Wall61c58622018-07-18 10:12:20 -070032
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080033#include "BufferStateLayer.h"
34#include "ColorLayer.h"
Mikael Pessa90092f42019-08-26 17:22:04 -070035#include "FrameTracer/FrameTracer.h"
Lloyd Pique37c2c9b2018-12-04 17:25:10 -080036#include "TimeStats/TimeStats.h"
Valerie Hau0bc09152018-12-20 07:42:47 -080037
Marissa Wall61c58622018-07-18 10:12:20 -070038namespace android {
39
Lloyd Pique42ab75e2018-09-12 20:46:03 -070040// clang-format off
41const std::array<float, 16> BufferStateLayer::IDENTITY_MATRIX{
42 1, 0, 0, 0,
43 0, 1, 0, 0,
44 0, 0, 1, 0,
45 0, 0, 0, 1
46};
47// clang-format on
Marissa Wall61c58622018-07-18 10:12:20 -070048
Marissa Wall947d34e2019-03-29 14:03:53 -070049BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args)
50 : BufferLayer(args), mHwcSlotGenerator(new HwcSlotGenerator()) {
Vishnu Nair60356342018-11-13 13:00:45 -080051 mOverrideScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
Marissa Wall3ff826c2019-02-07 11:58:25 -080052 mCurrentState.dataspace = ui::Dataspace::V0_SRGB;
Vishnu Nair60356342018-11-13 13:00:45 -080053}
Marissa Wall61c58622018-07-18 10:12:20 -070054
Alec Mouri4545a8a2019-08-08 20:05:32 -070055BufferStateLayer::~BufferStateLayer() {
56 if (mActiveBuffer != nullptr) {
57 // Ensure that mActiveBuffer is uncached from RenderEngine here, as
58 // RenderEngine may have been using the buffer as an external texture
59 // after the client uncached the buffer.
60 auto& engine(mFlinger->getRenderEngine());
61 engine.unbindExternalTextureBuffer(mActiveBuffer->getId());
62 }
63}
64
Marissa Wall61c58622018-07-18 10:12:20 -070065// -----------------------------------------------------------------------
66// Interface implementation for Layer
67// -----------------------------------------------------------------------
Marissa Wallfda30bb2018-10-12 11:34:28 -070068void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
Marissa Wall5a68a772018-12-22 17:43:42 -080069 // The previous release fence notifies the client that SurfaceFlinger is done with the previous
70 // buffer that was presented on this layer. The first transaction that came in this frame that
71 // replaced the previous buffer on this layer needs this release fence, because the fence will
72 // let the client know when that previous buffer is removed from the screen.
73 //
74 // Every other transaction on this layer does not need a release fence because no other
75 // Transactions that were set on this layer this frame are going to have their preceeding buffer
76 // removed from the display this frame.
77 //
78 // For example, if we have 3 transactions this frame. The first transaction doesn't contain a
79 // buffer so it doesn't need a previous release fence because the layer still needs the previous
80 // buffer. The second transaction contains a buffer so it needs a previous release fence because
81 // the previous buffer will be released this frame. The third transaction also contains a
82 // buffer. It replaces the buffer in the second transaction. The buffer in the second
83 // transaction will now no longer be presented so it is released immediately and the third
84 // transaction doesn't need a previous release fence.
85 for (auto& handle : mDrawingState.callbackHandles) {
86 if (handle->releasePreviousBuffer) {
87 handle->previousReleaseFence = releaseFence;
88 break;
89 }
90 }
Mikael Pessa2e1608f2019-07-19 11:25:35 -070091
92 // Prevent tracing the same release multiple times.
93 if (mPreviousFrameNumber != mPreviousReleasedFrameNumber) {
Mikael Pessa90092f42019-08-26 17:22:04 -070094 mFlinger->mFrameTracer->traceFence(getSequence(), mPreviousBufferId, mPreviousFrameNumber,
95 std::make_shared<FenceTime>(releaseFence),
96 FrameTracer::FrameEvent::RELEASE_FENCE);
Mikael Pessa2e1608f2019-07-19 11:25:35 -070097 mPreviousReleasedFrameNumber = mPreviousFrameNumber;
98 }
Marissa Wall61c58622018-07-18 10:12:20 -070099}
100
101void BufferStateLayer::setTransformHint(uint32_t /*orientation*/) const {
102 // TODO(marissaw): send the transform hint to buffer owner
103 return;
104}
105
106void BufferStateLayer::releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) {
Marissa Wallefb71af2019-06-27 14:45:53 -0700107 mFlinger->getTransactionCompletedThread().finalizePendingCallbackHandles(
Marissa Wall5a68a772018-12-22 17:43:42 -0800108 mDrawingState.callbackHandles);
109
110 mDrawingState.callbackHandles = {};
Marissa Wall61c58622018-07-18 10:12:20 -0700111}
112
Ana Krulec010d2192018-10-08 06:29:54 -0700113bool BufferStateLayer::shouldPresentNow(nsecs_t /*expectedPresentTime*/) const {
Marissa Wall61c58622018-07-18 10:12:20 -0700114 if (getSidebandStreamChanged() || getAutoRefresh()) {
115 return true;
116 }
117
Marissa Wall024a1912018-08-13 13:55:35 -0700118 return hasFrameUpdate();
Marissa Wall61c58622018-07-18 10:12:20 -0700119}
120
Marissa Walle2ffb422018-10-12 11:33:52 -0700121bool BufferStateLayer::willPresentCurrentTransaction() const {
122 // Returns true if the most recent Transaction applied to CurrentState will be presented.
123 return getSidebandStreamChanged() || getAutoRefresh() ||
Valerie Hauaa194562019-02-05 16:21:38 -0800124 (mCurrentState.modified &&
125 (mCurrentState.buffer != nullptr || mCurrentState.bgColorLayer != nullptr));
Marissa Wall61c58622018-07-18 10:12:20 -0700126}
127
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800128bool BufferStateLayer::getTransformToDisplayInverse() const {
129 return mCurrentState.transformToDisplayInverse;
Marissa Wall61c58622018-07-18 10:12:20 -0700130}
131
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800132void BufferStateLayer::pushPendingState() {
133 if (!mCurrentState.modified) {
Marissa Wall61c58622018-07-18 10:12:20 -0700134 return;
135 }
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800136 mPendingStates.push_back(mCurrentState);
137 ATRACE_INT(mTransactionName.string(), mPendingStates.size());
Marissa Wall61c58622018-07-18 10:12:20 -0700138}
139
140bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) {
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800141 const bool stateUpdateAvailable = !mPendingStates.empty();
142 while (!mPendingStates.empty()) {
Marissa Wall61c58622018-07-18 10:12:20 -0700143 popPendingState(stateToCommit);
144 }
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800145 mCurrentStateModified = stateUpdateAvailable && mCurrentState.modified;
146 mCurrentState.modified = false;
Marissa Wall61c58622018-07-18 10:12:20 -0700147 return stateUpdateAvailable;
148}
149
Marissa Wall861616d2018-10-22 12:52:23 -0700150// Crop that applies to the window
151Rect BufferStateLayer::getCrop(const Layer::State& /*s*/) const {
152 return Rect::INVALID_RECT;
Marissa Wall61c58622018-07-18 10:12:20 -0700153}
154
155bool BufferStateLayer::setTransform(uint32_t transform) {
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800156 if (mCurrentState.transform == transform) return false;
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800157 mCurrentState.transform = transform;
158 mCurrentState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700159 setTransactionFlags(eTransactionNeeded);
160 return true;
161}
162
163bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800164 if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false;
165 mCurrentState.sequence++;
166 mCurrentState.transformToDisplayInverse = transformToDisplayInverse;
167 mCurrentState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700168 setTransactionFlags(eTransactionNeeded);
169 return true;
170}
171
172bool BufferStateLayer::setCrop(const Rect& crop) {
Marissa Wall290ad082019-03-06 13:23:47 -0800173 Rect c = crop;
174 if (c.left < 0) {
175 c.left = 0;
176 }
177 if (c.top < 0) {
178 c.top = 0;
179 }
180 // If the width and/or height are < 0, make it [0, 0, -1, -1] so the equality comparision below
181 // treats all invalid rectangles the same.
182 if (!c.isValid()) {
183 c.makeInvalid();
184 }
185
186 if (mCurrentState.crop == c) return false;
Marissa Wall290ad082019-03-06 13:23:47 -0800187 mCurrentState.crop = c;
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800188 mCurrentState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700189 setTransactionFlags(eTransactionNeeded);
190 return true;
191}
192
Marissa Wall861616d2018-10-22 12:52:23 -0700193bool BufferStateLayer::setFrame(const Rect& frame) {
194 int x = frame.left;
195 int y = frame.top;
196 int w = frame.getWidth();
197 int h = frame.getHeight();
198
Marissa Wall0f3242d2018-12-20 15:10:22 -0800199 if (x < 0) {
200 x = 0;
201 w = frame.right;
202 }
203
204 if (y < 0) {
205 y = 0;
206 h = frame.bottom;
207 }
208
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800209 if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y &&
210 mCurrentState.active.w == w && mCurrentState.active.h == h) {
Marissa Wall861616d2018-10-22 12:52:23 -0700211 return false;
212 }
213
214 if (!frame.isValid()) {
215 x = y = w = h = 0;
216 }
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800217 mCurrentState.active.transform.set(x, y);
218 mCurrentState.active.w = w;
219 mCurrentState.active.h = h;
Marissa Wall861616d2018-10-22 12:52:23 -0700220
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800221 mCurrentState.sequence++;
222 mCurrentState.modified = true;
Marissa Wall861616d2018-10-22 12:52:23 -0700223 setTransactionFlags(eTransactionNeeded);
224 return true;
225}
226
Ady Abraham09bd3922019-04-08 10:44:56 -0700227bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer, nsecs_t postTime,
Marissa Wall947d34e2019-03-29 14:03:53 -0700228 nsecs_t desiredPresentTime, const client_cache_t& clientCacheId) {
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800229 if (mCurrentState.buffer) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700230 mReleasePreviousBuffer = true;
231 }
232
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800233 mCurrentState.buffer = buffer;
Marissa Wall947d34e2019-03-29 14:03:53 -0700234 mCurrentState.clientCacheId = clientCacheId;
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800235 mCurrentState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700236 setTransactionFlags(eTransactionNeeded);
Ady Abraham09bd3922019-04-08 10:44:56 -0700237
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700238 const int32_t layerID = getSequence();
239 mFlinger->mTimeStats->setPostTime(layerID, mFrameNumber, getName().c_str(), postTime);
Mikael Pessa90092f42019-08-26 17:22:04 -0700240 mFlinger->mFrameTracer->traceNewLayer(layerID, getName().c_str());
241 mFlinger->mFrameTracer->traceTimestamp(layerID, buffer->getId(), mFrameNumber, postTime,
242 FrameTracer::FrameEvent::POST);
chaviwfa67b552019-08-12 16:51:55 -0700243 mCurrentState.desiredPresentTime = desiredPresentTime;
Ady Abraham09bd3922019-04-08 10:44:56 -0700244
245 if (mFlinger->mUseSmart90ForVideo) {
chaviwfa67b552019-08-12 16:51:55 -0700246 const nsecs_t presentTime = (desiredPresentTime == -1) ? 0 : desiredPresentTime;
Ady Abrahama315ce72019-04-24 14:35:20 -0700247 mFlinger->mScheduler->addLayerPresentTimeAndHDR(mSchedulerLayerHandle, presentTime,
248 mCurrentState.hdrMetadata.validTypes != 0);
Ady Abraham09bd3922019-04-08 10:44:56 -0700249 }
250
Marissa Wall61c58622018-07-18 10:12:20 -0700251 return true;
252}
253
254bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700255 // The acquire fences of BufferStateLayers have already signaled before they are set
256 mCallbackHandleAcquireTime = fence->getSignalTime();
257
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800258 mCurrentState.acquireFence = fence;
259 mCurrentState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700260 setTransactionFlags(eTransactionNeeded);
261 return true;
262}
263
264bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800265 if (mCurrentState.dataspace == dataspace) return false;
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800266 mCurrentState.dataspace = dataspace;
267 mCurrentState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700268 setTransactionFlags(eTransactionNeeded);
269 return true;
270}
271
272bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800273 if (mCurrentState.hdrMetadata == hdrMetadata) return false;
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800274 mCurrentState.hdrMetadata = hdrMetadata;
275 mCurrentState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700276 setTransactionFlags(eTransactionNeeded);
277 return true;
278}
279
280bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800281 mCurrentState.surfaceDamageRegion = surfaceDamage;
282 mCurrentState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700283 setTransactionFlags(eTransactionNeeded);
284 return true;
285}
286
287bool BufferStateLayer::setApi(int32_t api) {
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800288 if (mCurrentState.api == api) return false;
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800289 mCurrentState.api = api;
290 mCurrentState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700291 setTransactionFlags(eTransactionNeeded);
292 return true;
293}
294
295bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800296 if (mCurrentState.sidebandStream == sidebandStream) return false;
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800297 mCurrentState.sidebandStream = sidebandStream;
298 mCurrentState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700299 setTransactionFlags(eTransactionNeeded);
300
301 if (!mSidebandStreamChanged.exchange(true)) {
302 // mSidebandStreamChanged was false
303 mFlinger->signalLayerUpdate();
304 }
305 return true;
306}
307
Marissa Walle2ffb422018-10-12 11:33:52 -0700308bool BufferStateLayer::setTransactionCompletedListeners(
309 const std::vector<sp<CallbackHandle>>& handles) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700310 // If there is no handle, we will not send a callback so reset mReleasePreviousBuffer and return
Marissa Walle2ffb422018-10-12 11:33:52 -0700311 if (handles.empty()) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700312 mReleasePreviousBuffer = false;
Marissa Walle2ffb422018-10-12 11:33:52 -0700313 return false;
314 }
315
316 const bool willPresent = willPresentCurrentTransaction();
317
318 for (const auto& handle : handles) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700319 // If this transaction set a buffer on this layer, release its previous buffer
320 handle->releasePreviousBuffer = mReleasePreviousBuffer;
321
Marissa Walle2ffb422018-10-12 11:33:52 -0700322 // If this layer will be presented in this frame
323 if (willPresent) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700324 // If this transaction set an acquire fence on this layer, set its acquire time
325 handle->acquireTime = mCallbackHandleAcquireTime;
326
Marissa Walle2ffb422018-10-12 11:33:52 -0700327 // Notify the transaction completed thread that there is a pending latched callback
328 // handle
Marissa Wall5a68a772018-12-22 17:43:42 -0800329 mFlinger->getTransactionCompletedThread().registerPendingCallbackHandle(handle);
Marissa Walle2ffb422018-10-12 11:33:52 -0700330
331 // Store so latched time and release fence can be set
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800332 mCurrentState.callbackHandles.push_back(handle);
Marissa Walle2ffb422018-10-12 11:33:52 -0700333
334 } else { // If this layer will NOT need to be relatched and presented this frame
335 // Notify the transaction completed thread this handle is done
Marissa Wallefb71af2019-06-27 14:45:53 -0700336 mFlinger->getTransactionCompletedThread().registerUnpresentedCallbackHandle(handle);
Marissa Walle2ffb422018-10-12 11:33:52 -0700337 }
338 }
339
Marissa Wallfda30bb2018-10-12 11:34:28 -0700340 mReleasePreviousBuffer = false;
341 mCallbackHandleAcquireTime = -1;
342
Marissa Walle2ffb422018-10-12 11:33:52 -0700343 return willPresent;
344}
345
Marissa Wall61c58622018-07-18 10:12:20 -0700346bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800347 mCurrentState.transparentRegionHint = transparent;
348 mCurrentState.modified = true;
Marissa Wall61c58622018-07-18 10:12:20 -0700349 setTransactionFlags(eTransactionNeeded);
350 return true;
351}
352
Marissa Wall861616d2018-10-22 12:52:23 -0700353Rect BufferStateLayer::getBufferSize(const State& s) const {
354 // for buffer state layers we use the display frame size as the buffer size.
355 if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) {
356 return Rect(getActiveWidth(s), getActiveHeight(s));
Marissa Wall61c58622018-07-18 10:12:20 -0700357 }
358
Marissa Wall861616d2018-10-22 12:52:23 -0700359 // if the display frame is not defined, use the parent bounds as the buffer size.
360 const auto& p = mDrawingParent.promote();
361 if (p != nullptr) {
Vishnu Nair4351ad52019-02-11 14:13:02 -0800362 Rect parentBounds = Rect(p->getBounds(Region()));
Marissa Wall861616d2018-10-22 12:52:23 -0700363 if (!parentBounds.isEmpty()) {
364 return parentBounds;
365 }
366 }
367
Marissa Wall861616d2018-10-22 12:52:23 -0700368 return Rect::INVALID_RECT;
Marissa Wall61c58622018-07-18 10:12:20 -0700369}
Vishnu Nair4351ad52019-02-11 14:13:02 -0800370
371FloatRect BufferStateLayer::computeSourceBounds(const FloatRect& parentBounds) const {
372 const State& s(getDrawingState());
373 // for buffer state layers we use the display frame size as the buffer size.
374 if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) {
375 return FloatRect(0, 0, getActiveWidth(s), getActiveHeight(s));
376 }
377
378 // if the display frame is not defined, use the parent bounds as the buffer size.
379 return parentBounds;
380}
381
Marissa Wall61c58622018-07-18 10:12:20 -0700382// -----------------------------------------------------------------------
383
384// -----------------------------------------------------------------------
385// Interface implementation for BufferLayer
386// -----------------------------------------------------------------------
387bool BufferStateLayer::fenceHasSignaled() const {
388 if (latchUnsignaledBuffers()) {
389 return true;
390 }
391
392 return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
393}
394
Dominik Laskowskia8955dd2019-07-10 10:19:09 -0700395bool BufferStateLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) const {
Ady Abrahamcd1580c2019-04-29 15:40:03 -0700396 if (!hasFrameUpdate() || isRemovedFromCurrentState()) {
397 return true;
398 }
399
chaviwfa67b552019-08-12 16:51:55 -0700400 return mCurrentState.desiredPresentTime <= expectedPresentTime;
Ady Abrahamcd1580c2019-04-29 15:40:03 -0700401}
402
Marissa Wall61c58622018-07-18 10:12:20 -0700403nsecs_t BufferStateLayer::getDesiredPresentTime() {
chaviwfa67b552019-08-12 16:51:55 -0700404 return getDrawingState().desiredPresentTime;
Marissa Wall61c58622018-07-18 10:12:20 -0700405}
406
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800407std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const {
Marissa Wall61c58622018-07-18 10:12:20 -0700408 return std::make_shared<FenceTime>(getDrawingState().acquireFence);
409}
410
411void BufferStateLayer::getDrawingTransformMatrix(float *matrix) {
412 std::copy(std::begin(mTransformMatrix), std::end(mTransformMatrix), matrix);
413}
414
415uint32_t BufferStateLayer::getDrawingTransform() const {
416 return getDrawingState().transform;
417}
418
419ui::Dataspace BufferStateLayer::getDrawingDataSpace() const {
420 return getDrawingState().dataspace;
421}
422
Marissa Wall861616d2018-10-22 12:52:23 -0700423// Crop that applies to the buffer
Marissa Wall61c58622018-07-18 10:12:20 -0700424Rect BufferStateLayer::getDrawingCrop() const {
Marissa Wall861616d2018-10-22 12:52:23 -0700425 const State& s(getDrawingState());
426
427 if (s.crop.isEmpty() && s.buffer) {
428 return s.buffer->getBounds();
Valerie Hau0bc09152018-12-20 07:42:47 -0800429 } else if (s.buffer) {
430 Rect crop = s.crop;
431 crop.left = std::max(crop.left, 0);
432 crop.top = std::max(crop.top, 0);
433 uint32_t bufferWidth = s.buffer->getWidth();
434 uint32_t bufferHeight = s.buffer->getHeight();
435 if (bufferHeight <= std::numeric_limits<int32_t>::max() &&
436 bufferWidth <= std::numeric_limits<int32_t>::max()) {
437 crop.right = std::min(crop.right, static_cast<int32_t>(bufferWidth));
438 crop.bottom = std::min(crop.bottom, static_cast<int32_t>(bufferHeight));
439 }
440 if (!crop.isValid()) {
441 // Crop rect is out of bounds, return whole buffer
442 return s.buffer->getBounds();
443 }
444 return crop;
Marissa Wall861616d2018-10-22 12:52:23 -0700445 }
446 return s.crop;
Marissa Wall61c58622018-07-18 10:12:20 -0700447}
448
449uint32_t BufferStateLayer::getDrawingScalingMode() const {
Marissa Wallec463ac2018-10-08 12:35:04 -0700450 return NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
Marissa Wall61c58622018-07-18 10:12:20 -0700451}
452
453Region BufferStateLayer::getDrawingSurfaceDamage() const {
Marissa Wall0ef8d602019-04-23 14:09:28 -0700454 return getDrawingState().surfaceDamageRegion;
Marissa Wall61c58622018-07-18 10:12:20 -0700455}
456
457const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const {
458 return getDrawingState().hdrMetadata;
459}
460
461int BufferStateLayer::getDrawingApi() const {
462 return getDrawingState().api;
463}
464
465PixelFormat BufferStateLayer::getPixelFormat() const {
Marissa Wall5aec6412018-11-14 11:49:18 -0800466 if (!mActiveBuffer) {
467 return PIXEL_FORMAT_NONE;
468 }
Marissa Wall61c58622018-07-18 10:12:20 -0700469 return mActiveBuffer->format;
470}
471
Dominik Laskowskia8955dd2019-07-10 10:19:09 -0700472uint64_t BufferStateLayer::getFrameNumber(nsecs_t /*expectedPresentTime*/) const {
Marissa Wall61c58622018-07-18 10:12:20 -0700473 return mFrameNumber;
474}
475
476bool BufferStateLayer::getAutoRefresh() const {
477 // TODO(marissaw): support shared buffer mode
478 return false;
479}
480
481bool BufferStateLayer::getSidebandStreamChanged() const {
482 return mSidebandStreamChanged.load();
483}
484
Vishnu Nair6194e2e2019-02-06 12:58:39 -0800485bool BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
Marissa Wall61c58622018-07-18 10:12:20 -0700486 if (mSidebandStreamChanged.exchange(false)) {
487 const State& s(getDrawingState());
488 // mSidebandStreamChanged was true
Lloyd Pique0b785d82018-12-04 17:25:27 -0800489 LOG_ALWAYS_FATAL_IF(!getCompositionLayer());
490 mSidebandStream = s.sidebandStream;
491 getCompositionLayer()->editState().frontEnd.sidebandStream = mSidebandStream;
492 if (mSidebandStream != nullptr) {
Marissa Wall61c58622018-07-18 10:12:20 -0700493 setTransactionFlags(eTransactionNeeded);
494 mFlinger->setTransactionFlags(eTraversalNeeded);
495 }
496 recomputeVisibleRegions = true;
497
Vishnu Nair6194e2e2019-02-06 12:58:39 -0800498 return true;
Marissa Wall61c58622018-07-18 10:12:20 -0700499 }
Vishnu Nair6194e2e2019-02-06 12:58:39 -0800500 return false;
Marissa Wall61c58622018-07-18 10:12:20 -0700501}
502
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800503bool BufferStateLayer::hasFrameUpdate() const {
Valerie Hauaa194562019-02-05 16:21:38 -0800504 const State& c(getCurrentState());
505 return mCurrentStateModified && (c.buffer != nullptr || c.bgColorLayer != nullptr);
Marissa Wall61c58622018-07-18 10:12:20 -0700506}
507
508void BufferStateLayer::setFilteringEnabled(bool enabled) {
509 GLConsumer::computeTransformMatrix(mTransformMatrix.data(), mActiveBuffer, mCurrentCrop,
510 mCurrentTransform, enabled);
511}
512
Alec Mouri39801c02018-10-10 10:44:47 -0700513status_t BufferStateLayer::bindTextureImage() {
Marissa Wall61c58622018-07-18 10:12:20 -0700514 const State& s(getDrawingState());
515 auto& engine(mFlinger->getRenderEngine());
516
Alec Mourib5c4f352019-02-19 19:46:38 -0800517 return engine.bindExternalTextureBuffer(mTextureName, s.buffer, s.acquireFence);
Marissa Wall61c58622018-07-18 10:12:20 -0700518}
519
Dominik Laskowskia8955dd2019-07-10 10:19:09 -0700520status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
521 nsecs_t /*expectedPresentTime*/) {
Marissa Wall61c58622018-07-18 10:12:20 -0700522 const State& s(getDrawingState());
523
524 if (!s.buffer) {
Valerie Hauaa194562019-02-05 16:21:38 -0800525 if (s.bgColorLayer) {
526 for (auto& handle : mDrawingState.callbackHandles) {
527 handle->latchTime = latchTime;
528 }
529 }
Marissa Wall61c58622018-07-18 10:12:20 -0700530 return NO_ERROR;
531 }
532
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700533 const int32_t layerID = getSequence();
534
Marissa Wall61c58622018-07-18 10:12:20 -0700535 // Reject if the layer is invalid
536 uint32_t bufferWidth = s.buffer->width;
537 uint32_t bufferHeight = s.buffer->height;
538
Peiyong Linefefaac2018-08-17 12:27:51 -0700539 if (s.transform & ui::Transform::ROT_90) {
Peiyong Lin3db42342018-08-16 09:15:59 -0700540 std::swap(bufferWidth, bufferHeight);
Marissa Wall61c58622018-07-18 10:12:20 -0700541 }
542
543 if (s.transformToDisplayInverse) {
544 uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
Peiyong Linefefaac2018-08-17 12:27:51 -0700545 if (invTransform & ui::Transform::ROT_90) {
Peiyong Lin3db42342018-08-16 09:15:59 -0700546 std::swap(bufferWidth, bufferHeight);
Marissa Wall61c58622018-07-18 10:12:20 -0700547 }
548 }
549
Vishnu Nair60356342018-11-13 13:00:45 -0800550 if (getEffectiveScalingMode() == NATIVE_WINDOW_SCALING_MODE_FREEZE &&
Marissa Wall61c58622018-07-18 10:12:20 -0700551 (s.active.w != bufferWidth || s.active.h != bufferHeight)) {
552 ALOGE("[%s] rejecting buffer: "
553 "bufferWidth=%d, bufferHeight=%d, front.active.{w=%d, h=%d}",
554 mName.string(), bufferWidth, bufferHeight, s.active.w, s.active.h);
Dominik Laskowskia8955dd2019-07-10 10:19:09 -0700555 mFlinger->mTimeStats->removeTimeRecord(layerID, mFrameNumber);
Marissa Wall61c58622018-07-18 10:12:20 -0700556 return BAD_VALUE;
557 }
558
Marissa Wall5a68a772018-12-22 17:43:42 -0800559 for (auto& handle : mDrawingState.callbackHandles) {
560 handle->latchTime = latchTime;
561 }
Marissa Walle2ffb422018-10-12 11:33:52 -0700562
Alec Mouri56e538f2019-01-14 15:22:01 -0800563 if (!SyncFeatures::getInstance().useNativeFenceSync()) {
Marissa Wall61c58622018-07-18 10:12:20 -0700564 // Bind the new buffer to the GL texture.
565 //
566 // Older devices require the "implicit" synchronization provided
567 // by glEGLImageTargetTexture2DOES, which this method calls. Newer
568 // devices will either call this in Layer::onDraw, or (if it's not
569 // a GL-composited layer) not at all.
Lloyd Pique0449b0f2018-12-20 16:23:45 -0800570 status_t err = bindTextureImage();
Marissa Wall61c58622018-07-18 10:12:20 -0700571 if (err != NO_ERROR) {
Yiwei Zhangaf8ee942018-11-22 00:15:23 -0800572 mFlinger->mTimeStats->onDestroy(layerID);
Mikael Pessa90092f42019-08-26 17:22:04 -0700573 mFlinger->mFrameTracer->onDestroy(layerID);
Marissa Wall61c58622018-07-18 10:12:20 -0700574 return BAD_VALUE;
575 }
576 }
577
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700578 const uint64_t bufferID = getCurrentBufferId();
Dominik Laskowskia8955dd2019-07-10 10:19:09 -0700579 mFlinger->mTimeStats->setAcquireFence(layerID, mFrameNumber, getCurrentFenceTime());
Mikael Pessa90092f42019-08-26 17:22:04 -0700580 mFlinger->mFrameTracer->traceFence(layerID, bufferID, mFrameNumber, getCurrentFenceTime(),
581 FrameTracer::FrameEvent::ACQUIRE_FENCE);
Dominik Laskowskia8955dd2019-07-10 10:19:09 -0700582 mFlinger->mTimeStats->setLatchTime(layerID, mFrameNumber, latchTime);
Mikael Pessa90092f42019-08-26 17:22:04 -0700583 mFlinger->mFrameTracer->traceTimestamp(layerID, bufferID, mFrameNumber, latchTime,
584 FrameTracer::FrameEvent::LATCH);
Marissa Wall61c58622018-07-18 10:12:20 -0700585
Marissa Wall16c112d2019-03-20 13:21:13 -0700586 mCurrentStateModified = false;
587
Marissa Wall61c58622018-07-18 10:12:20 -0700588 return NO_ERROR;
589}
590
591status_t BufferStateLayer::updateActiveBuffer() {
592 const State& s(getDrawingState());
593
594 if (s.buffer == nullptr) {
595 return BAD_VALUE;
596 }
597
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700598 mPreviousBufferId = getCurrentBufferId();
Marissa Wall61c58622018-07-18 10:12:20 -0700599 mActiveBuffer = s.buffer;
Alec Mourie7d1d4a2019-02-05 01:13:46 +0000600 mActiveBufferFence = s.acquireFence;
Lloyd Pique0b785d82018-12-04 17:25:27 -0800601 auto& layerCompositionState = getCompositionLayer()->editState().frontEnd;
602 layerCompositionState.buffer = mActiveBuffer;
Marissa Wall61c58622018-07-18 10:12:20 -0700603
604 return NO_ERROR;
605}
606
607status_t BufferStateLayer::updateFrameNumber(nsecs_t /*latchTime*/) {
608 // TODO(marissaw): support frame history events
Mikael Pessa2e1608f2019-07-19 11:25:35 -0700609 mPreviousFrameNumber = mCurrentFrameNumber;
Marissa Wall61c58622018-07-18 10:12:20 -0700610 mCurrentFrameNumber = mFrameNumber;
611 return NO_ERROR;
612}
613
Lloyd Piquef5275482019-01-29 18:42:42 -0800614void BufferStateLayer::latchPerFrameState(
615 compositionengine::LayerFECompositionState& compositionState) const {
616 BufferLayer::latchPerFrameState(compositionState);
617 if (compositionState.compositionType == Hwc2::IComposerClient::Composition::SIDEBAND) {
618 return;
619 }
Marissa Wall61c58622018-07-18 10:12:20 -0700620
621 const State& s(getDrawingState());
622
Lloyd Piquef5275482019-01-29 18:42:42 -0800623 compositionState.buffer = s.buffer;
624 compositionState.bufferSlot = mHwcSlotGenerator->getHwcCacheSlot(s.clientCacheId);
625 compositionState.acquireFence = s.acquireFence;
Marissa Wall61c58622018-07-18 10:12:20 -0700626
627 mFrameNumber++;
628}
629
630void BufferStateLayer::onFirstRef() {
Dan Stoza7b1b5a82018-07-31 16:00:21 -0700631 BufferLayer::onFirstRef();
632
Marissa Wall61c58622018-07-18 10:12:20 -0700633 if (const auto display = mFlinger->getDefaultDisplayDevice()) {
634 updateTransformHint(display);
635 }
636}
637
Marissa Wall947d34e2019-03-29 14:03:53 -0700638void BufferStateLayer::HwcSlotGenerator::bufferErased(const client_cache_t& clientCacheId) {
639 std::lock_guard lock(mMutex);
640 if (!clientCacheId.isValid()) {
641 ALOGE("invalid process, failed to erase buffer");
642 return;
643 }
644 eraseBufferLocked(clientCacheId);
645}
646
647uint32_t BufferStateLayer::HwcSlotGenerator::getHwcCacheSlot(const client_cache_t& clientCacheId) {
648 std::lock_guard<std::mutex> lock(mMutex);
649 auto itr = mCachedBuffers.find(clientCacheId);
650 if (itr == mCachedBuffers.end()) {
651 return addCachedBuffer(clientCacheId);
652 }
653 auto& [hwcCacheSlot, counter] = itr->second;
654 counter = mCounter++;
655 return hwcCacheSlot;
656}
657
658uint32_t BufferStateLayer::HwcSlotGenerator::addCachedBuffer(const client_cache_t& clientCacheId)
659 REQUIRES(mMutex) {
660 if (!clientCacheId.isValid()) {
661 ALOGE("invalid process, returning invalid slot");
662 return BufferQueue::INVALID_BUFFER_SLOT;
663 }
664
665 ClientCache::getInstance().registerErasedRecipient(clientCacheId, wp<ErasedRecipient>(this));
666
667 uint32_t hwcCacheSlot = getFreeHwcCacheSlot();
668 mCachedBuffers[clientCacheId] = {hwcCacheSlot, mCounter++};
669 return hwcCacheSlot;
670}
671
672uint32_t BufferStateLayer::HwcSlotGenerator::getFreeHwcCacheSlot() REQUIRES(mMutex) {
673 if (mFreeHwcCacheSlots.empty()) {
674 evictLeastRecentlyUsed();
675 }
676
677 uint32_t hwcCacheSlot = mFreeHwcCacheSlots.top();
678 mFreeHwcCacheSlots.pop();
679 return hwcCacheSlot;
680}
681
682void BufferStateLayer::HwcSlotGenerator::evictLeastRecentlyUsed() REQUIRES(mMutex) {
683 uint64_t minCounter = UINT_MAX;
684 client_cache_t minClientCacheId = {};
685 for (const auto& [clientCacheId, slotCounter] : mCachedBuffers) {
686 const auto& [hwcCacheSlot, counter] = slotCounter;
687 if (counter < minCounter) {
688 minCounter = counter;
689 minClientCacheId = clientCacheId;
690 }
691 }
692 eraseBufferLocked(minClientCacheId);
693
694 ClientCache::getInstance().unregisterErasedRecipient(minClientCacheId, this);
695}
696
697void BufferStateLayer::HwcSlotGenerator::eraseBufferLocked(const client_cache_t& clientCacheId)
698 REQUIRES(mMutex) {
699 auto itr = mCachedBuffers.find(clientCacheId);
700 if (itr == mCachedBuffers.end()) {
701 return;
702 }
703 auto& [hwcCacheSlot, counter] = itr->second;
704
705 // TODO send to hwc cache and resources
706
707 mFreeHwcCacheSlots.push(hwcCacheSlot);
708 mCachedBuffers.erase(clientCacheId);
709}
Marissa Wall61c58622018-07-18 10:12:20 -0700710} // namespace android