blob: 1c219680650800eda3885ed3e30ca7318546b0b7 [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
22#include "BufferStateLayer.h"
Marissa Wall61c58622018-07-18 10:12:20 -070023
24#include <private/gui/SyncFeatures.h>
Peiyong Lincbc184f2018-08-22 13:24:10 -070025#include <renderengine/Image.h>
Marissa Wall61c58622018-07-18 10:12:20 -070026
27namespace android {
28
Lloyd Pique42ab75e2018-09-12 20:46:03 -070029// clang-format off
30const std::array<float, 16> BufferStateLayer::IDENTITY_MATRIX{
31 1, 0, 0, 0,
32 0, 1, 0, 0,
33 0, 0, 1, 0,
34 0, 0, 0, 1
35};
36// clang-format on
Marissa Wall61c58622018-07-18 10:12:20 -070037
Vishnu Nair60356342018-11-13 13:00:45 -080038BufferStateLayer::BufferStateLayer(const LayerCreationArgs& args) : BufferLayer(args) {
39 mOverrideScalingMode = NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
40}
Lloyd Pique42ab75e2018-09-12 20:46:03 -070041BufferStateLayer::~BufferStateLayer() = default;
Marissa Wall61c58622018-07-18 10:12:20 -070042
43// -----------------------------------------------------------------------
44// Interface implementation for Layer
45// -----------------------------------------------------------------------
Marissa Wallfda30bb2018-10-12 11:34:28 -070046void BufferStateLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
47 // The transaction completed callback can only be sent if the release fence from the PREVIOUS
48 // frame has fired. In practice, we should never actually wait on the previous release fence
49 // but we should store it just in case.
50 mPreviousReleaseFence = releaseFence;
Marissa Wall61c58622018-07-18 10:12:20 -070051}
52
53void BufferStateLayer::setTransformHint(uint32_t /*orientation*/) const {
54 // TODO(marissaw): send the transform hint to buffer owner
55 return;
56}
57
58void BufferStateLayer::releasePendingBuffer(nsecs_t /*dequeueReadyTime*/) {
Marissa Wall61c58622018-07-18 10:12:20 -070059 return;
60}
61
Ana Krulec010d2192018-10-08 06:29:54 -070062bool BufferStateLayer::shouldPresentNow(nsecs_t /*expectedPresentTime*/) const {
Marissa Wall61c58622018-07-18 10:12:20 -070063 if (getSidebandStreamChanged() || getAutoRefresh()) {
64 return true;
65 }
66
Marissa Wall024a1912018-08-13 13:55:35 -070067 return hasFrameUpdate();
Marissa Wall61c58622018-07-18 10:12:20 -070068}
69
Marissa Walle2ffb422018-10-12 11:33:52 -070070bool BufferStateLayer::willPresentCurrentTransaction() const {
71 // Returns true if the most recent Transaction applied to CurrentState will be presented.
72 return getSidebandStreamChanged() || getAutoRefresh() ||
73 (mCurrentState.modified && mCurrentState.buffer != nullptr);
Marissa Wall61c58622018-07-18 10:12:20 -070074}
75
76bool BufferStateLayer::getTransformToDisplayInverse() const {
77 return mCurrentState.transformToDisplayInverse;
78}
79
80void BufferStateLayer::pushPendingState() {
81 if (!mCurrentState.modified) {
82 return;
83 }
84 mPendingStates.push_back(mCurrentState);
85 ATRACE_INT(mTransactionName.string(), mPendingStates.size());
86}
87
88bool BufferStateLayer::applyPendingStates(Layer::State* stateToCommit) {
89 const bool stateUpdateAvailable = !mPendingStates.empty();
90 while (!mPendingStates.empty()) {
91 popPendingState(stateToCommit);
92 }
Marissa Wall024a1912018-08-13 13:55:35 -070093 mCurrentStateModified = stateUpdateAvailable && mCurrentState.modified;
Marissa Wall61c58622018-07-18 10:12:20 -070094 mCurrentState.modified = false;
95 return stateUpdateAvailable;
96}
97
Marissa Wall861616d2018-10-22 12:52:23 -070098// Crop that applies to the window
99Rect BufferStateLayer::getCrop(const Layer::State& /*s*/) const {
100 return Rect::INVALID_RECT;
Marissa Wall61c58622018-07-18 10:12:20 -0700101}
102
103bool BufferStateLayer::setTransform(uint32_t transform) {
104 if (mCurrentState.transform == transform) return false;
105 mCurrentState.sequence++;
106 mCurrentState.transform = transform;
107 mCurrentState.modified = true;
108 setTransactionFlags(eTransactionNeeded);
109 return true;
110}
111
112bool BufferStateLayer::setTransformToDisplayInverse(bool transformToDisplayInverse) {
113 if (mCurrentState.transformToDisplayInverse == transformToDisplayInverse) return false;
114 mCurrentState.sequence++;
115 mCurrentState.transformToDisplayInverse = transformToDisplayInverse;
116 mCurrentState.modified = true;
117 setTransactionFlags(eTransactionNeeded);
118 return true;
119}
120
121bool BufferStateLayer::setCrop(const Rect& crop) {
122 if (mCurrentState.crop == crop) return false;
123 mCurrentState.sequence++;
124 mCurrentState.crop = crop;
125 mCurrentState.modified = true;
126 setTransactionFlags(eTransactionNeeded);
127 return true;
128}
129
Marissa Wall861616d2018-10-22 12:52:23 -0700130bool BufferStateLayer::setFrame(const Rect& frame) {
131 int x = frame.left;
132 int y = frame.top;
133 int w = frame.getWidth();
134 int h = frame.getHeight();
135
136 if (mCurrentState.active.transform.tx() == x && mCurrentState.active.transform.ty() == y &&
137 mCurrentState.active.w == w && mCurrentState.active.h == h) {
138 return false;
139 }
140
141 if (!frame.isValid()) {
142 x = y = w = h = 0;
143 }
144 mCurrentState.active.transform.set(x, y);
145 mCurrentState.active.w = w;
146 mCurrentState.active.h = h;
147
148 mCurrentState.sequence++;
149 mCurrentState.modified = true;
150 setTransactionFlags(eTransactionNeeded);
151 return true;
152}
153
Marissa Wallfda30bb2018-10-12 11:34:28 -0700154bool BufferStateLayer::setBuffer(const sp<GraphicBuffer>& buffer) {
155 if (mCurrentState.buffer) {
156 mReleasePreviousBuffer = true;
157 }
158
Marissa Wall61c58622018-07-18 10:12:20 -0700159 mCurrentState.sequence++;
160 mCurrentState.buffer = buffer;
161 mCurrentState.modified = true;
162 setTransactionFlags(eTransactionNeeded);
163 return true;
164}
165
166bool BufferStateLayer::setAcquireFence(const sp<Fence>& fence) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700167 // The acquire fences of BufferStateLayers have already signaled before they are set
168 mCallbackHandleAcquireTime = fence->getSignalTime();
169
Marissa Wall61c58622018-07-18 10:12:20 -0700170 mCurrentState.acquireFence = fence;
171 mCurrentState.modified = true;
172 setTransactionFlags(eTransactionNeeded);
173 return true;
174}
175
176bool BufferStateLayer::setDataspace(ui::Dataspace dataspace) {
177 if (mCurrentState.dataspace == dataspace) return false;
178 mCurrentState.sequence++;
179 mCurrentState.dataspace = dataspace;
180 mCurrentState.modified = true;
181 setTransactionFlags(eTransactionNeeded);
182 return true;
183}
184
185bool BufferStateLayer::setHdrMetadata(const HdrMetadata& hdrMetadata) {
186 if (mCurrentState.hdrMetadata == hdrMetadata) return false;
187 mCurrentState.sequence++;
188 mCurrentState.hdrMetadata = hdrMetadata;
189 mCurrentState.modified = true;
190 setTransactionFlags(eTransactionNeeded);
191 return true;
192}
193
194bool BufferStateLayer::setSurfaceDamageRegion(const Region& surfaceDamage) {
195 mCurrentState.sequence++;
196 mCurrentState.surfaceDamageRegion = surfaceDamage;
197 mCurrentState.modified = true;
198 setTransactionFlags(eTransactionNeeded);
199 return true;
200}
201
202bool BufferStateLayer::setApi(int32_t api) {
203 if (mCurrentState.api == api) return false;
204 mCurrentState.sequence++;
205 mCurrentState.api = api;
206 mCurrentState.modified = true;
207 setTransactionFlags(eTransactionNeeded);
208 return true;
209}
210
211bool BufferStateLayer::setSidebandStream(const sp<NativeHandle>& sidebandStream) {
212 if (mCurrentState.sidebandStream == sidebandStream) return false;
213 mCurrentState.sequence++;
214 mCurrentState.sidebandStream = sidebandStream;
215 mCurrentState.modified = true;
216 setTransactionFlags(eTransactionNeeded);
217
218 if (!mSidebandStreamChanged.exchange(true)) {
219 // mSidebandStreamChanged was false
220 mFlinger->signalLayerUpdate();
221 }
222 return true;
223}
224
Marissa Walle2ffb422018-10-12 11:33:52 -0700225bool BufferStateLayer::setTransactionCompletedListeners(
226 const std::vector<sp<CallbackHandle>>& handles) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700227 // If there is no handle, we will not send a callback so reset mReleasePreviousBuffer and return
Marissa Walle2ffb422018-10-12 11:33:52 -0700228 if (handles.empty()) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700229 mReleasePreviousBuffer = false;
Marissa Walle2ffb422018-10-12 11:33:52 -0700230 return false;
231 }
232
233 const bool willPresent = willPresentCurrentTransaction();
234
235 for (const auto& handle : handles) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700236 // If this transaction set a buffer on this layer, release its previous buffer
237 handle->releasePreviousBuffer = mReleasePreviousBuffer;
238
Marissa Walle2ffb422018-10-12 11:33:52 -0700239 // If this layer will be presented in this frame
240 if (willPresent) {
Marissa Wallfda30bb2018-10-12 11:34:28 -0700241 // If this transaction set an acquire fence on this layer, set its acquire time
242 handle->acquireTime = mCallbackHandleAcquireTime;
243
Marissa Walle2ffb422018-10-12 11:33:52 -0700244 // Notify the transaction completed thread that there is a pending latched callback
245 // handle
246 mFlinger->getTransactionCompletedThread().registerPendingLatchedCallbackHandle(handle);
247
248 // Store so latched time and release fence can be set
249 mCurrentState.callbackHandles.push_back(handle);
250
251 } else { // If this layer will NOT need to be relatched and presented this frame
252 // Notify the transaction completed thread this handle is done
253 mFlinger->getTransactionCompletedThread().addUnlatchedCallbackHandle(handle);
254 }
255 }
256
Marissa Wallfda30bb2018-10-12 11:34:28 -0700257 mReleasePreviousBuffer = false;
258 mCallbackHandleAcquireTime = -1;
259
Marissa Walle2ffb422018-10-12 11:33:52 -0700260 return willPresent;
261}
262
Marissa Wall61c58622018-07-18 10:12:20 -0700263bool BufferStateLayer::setTransparentRegionHint(const Region& transparent) {
264 mCurrentState.transparentRegionHint = transparent;
265 mCurrentState.modified = true;
266 setTransactionFlags(eTransactionNeeded);
267 return true;
268}
269
Marissa Wall861616d2018-10-22 12:52:23 -0700270Rect BufferStateLayer::getBufferSize(const State& s) const {
271 // for buffer state layers we use the display frame size as the buffer size.
272 if (getActiveWidth(s) < UINT32_MAX && getActiveHeight(s) < UINT32_MAX) {
273 return Rect(getActiveWidth(s), getActiveHeight(s));
Marissa Wall61c58622018-07-18 10:12:20 -0700274 }
275
Marissa Wall861616d2018-10-22 12:52:23 -0700276 // if the display frame is not defined, use the parent bounds as the buffer size.
277 const auto& p = mDrawingParent.promote();
278 if (p != nullptr) {
279 Rect parentBounds = Rect(p->computeBounds(Region()));
280 if (!parentBounds.isEmpty()) {
281 return parentBounds;
282 }
283 }
284
285 // if there is no parent layer, use the buffer's bounds as the buffer size
286 if (s.buffer) {
287 return s.buffer->getBounds();
288 }
289 return Rect::INVALID_RECT;
Marissa Wall61c58622018-07-18 10:12:20 -0700290}
291// -----------------------------------------------------------------------
292
293// -----------------------------------------------------------------------
294// Interface implementation for BufferLayer
295// -----------------------------------------------------------------------
296bool BufferStateLayer::fenceHasSignaled() const {
297 if (latchUnsignaledBuffers()) {
298 return true;
299 }
300
301 return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled;
302}
303
304nsecs_t BufferStateLayer::getDesiredPresentTime() {
305 // TODO(marissaw): support an equivalent to desiredPresentTime for timestats metrics
306 return 0;
307}
308
309std::shared_ptr<FenceTime> BufferStateLayer::getCurrentFenceTime() const {
310 return std::make_shared<FenceTime>(getDrawingState().acquireFence);
311}
312
313void BufferStateLayer::getDrawingTransformMatrix(float *matrix) {
314 std::copy(std::begin(mTransformMatrix), std::end(mTransformMatrix), matrix);
315}
316
317uint32_t BufferStateLayer::getDrawingTransform() const {
318 return getDrawingState().transform;
319}
320
321ui::Dataspace BufferStateLayer::getDrawingDataSpace() const {
322 return getDrawingState().dataspace;
323}
324
Marissa Wall861616d2018-10-22 12:52:23 -0700325// Crop that applies to the buffer
Marissa Wall61c58622018-07-18 10:12:20 -0700326Rect BufferStateLayer::getDrawingCrop() const {
Marissa Wall861616d2018-10-22 12:52:23 -0700327 const State& s(getDrawingState());
328
329 if (s.crop.isEmpty() && s.buffer) {
330 return s.buffer->getBounds();
331 }
332 return s.crop;
Marissa Wall61c58622018-07-18 10:12:20 -0700333}
334
335uint32_t BufferStateLayer::getDrawingScalingMode() const {
Marissa Wallec463ac2018-10-08 12:35:04 -0700336 return NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW;
Marissa Wall61c58622018-07-18 10:12:20 -0700337}
338
339Region BufferStateLayer::getDrawingSurfaceDamage() const {
340 return getDrawingState().surfaceDamageRegion;
341}
342
343const HdrMetadata& BufferStateLayer::getDrawingHdrMetadata() const {
344 return getDrawingState().hdrMetadata;
345}
346
347int BufferStateLayer::getDrawingApi() const {
348 return getDrawingState().api;
349}
350
351PixelFormat BufferStateLayer::getPixelFormat() const {
Marissa Wall5aec6412018-11-14 11:49:18 -0800352 if (!mActiveBuffer) {
353 return PIXEL_FORMAT_NONE;
354 }
Marissa Wall61c58622018-07-18 10:12:20 -0700355 return mActiveBuffer->format;
356}
357
358uint64_t BufferStateLayer::getFrameNumber() const {
359 return mFrameNumber;
360}
361
362bool BufferStateLayer::getAutoRefresh() const {
363 // TODO(marissaw): support shared buffer mode
364 return false;
365}
366
367bool BufferStateLayer::getSidebandStreamChanged() const {
368 return mSidebandStreamChanged.load();
369}
370
371std::optional<Region> BufferStateLayer::latchSidebandStream(bool& recomputeVisibleRegions) {
372 if (mSidebandStreamChanged.exchange(false)) {
373 const State& s(getDrawingState());
374 // mSidebandStreamChanged was true
375 // replicated in LayerBE until FE/BE is ready to be synchronized
376 getBE().compositionInfo.hwc.sidebandStream = s.sidebandStream;
377 if (getBE().compositionInfo.hwc.sidebandStream != nullptr) {
378 setTransactionFlags(eTransactionNeeded);
379 mFlinger->setTransactionFlags(eTraversalNeeded);
380 }
381 recomputeVisibleRegions = true;
382
383 return getTransform().transform(Region(Rect(s.active.w, s.active.h)));
384 }
385 return {};
386}
387
Marissa Wall024a1912018-08-13 13:55:35 -0700388bool BufferStateLayer::hasFrameUpdate() const {
389 return mCurrentStateModified && getCurrentState().buffer != nullptr;
Marissa Wall61c58622018-07-18 10:12:20 -0700390}
391
392void BufferStateLayer::setFilteringEnabled(bool enabled) {
393 GLConsumer::computeTransformMatrix(mTransformMatrix.data(), mActiveBuffer, mCurrentCrop,
394 mCurrentTransform, enabled);
395}
396
Alec Mouri39801c02018-10-10 10:44:47 -0700397status_t BufferStateLayer::bindTextureImage() {
Marissa Wall61c58622018-07-18 10:12:20 -0700398 const State& s(getDrawingState());
399 auto& engine(mFlinger->getRenderEngine());
400
Marissa Wall61c58622018-07-18 10:12:20 -0700401 engine.checkErrors();
402
Alec Mouri39801c02018-10-10 10:44:47 -0700403 // TODO(marissaw): once buffers are cached, don't create a new image everytime
404 mTextureImage = engine.createImage();
Marissa Wall61c58622018-07-18 10:12:20 -0700405
406 bool created =
407 mTextureImage->setNativeWindowBuffer(s.buffer->getNativeBuffer(),
408 s.buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
409 if (!created) {
410 ALOGE("Failed to create image. size=%ux%u st=%u usage=%#" PRIx64 " fmt=%d",
411 s.buffer->getWidth(), s.buffer->getHeight(), s.buffer->getStride(),
412 s.buffer->getUsage(), s.buffer->getPixelFormat());
413 engine.bindExternalTextureImage(mTextureName, *engine.createImage());
414 return NO_INIT;
415 }
416
417 engine.bindExternalTextureImage(mTextureName, *mTextureImage);
418
419 // Wait for the new buffer to be ready.
420 if (s.acquireFence->isValid()) {
421 if (SyncFeatures::getInstance().useWaitSync()) {
422 base::unique_fd fenceFd(s.acquireFence->dup());
423 if (fenceFd == -1) {
424 ALOGE("error dup'ing fence fd: %d", errno);
425 return -errno;
426 }
427 if (!engine.waitFence(std::move(fenceFd))) {
428 ALOGE("failed to wait on fence fd");
429 return UNKNOWN_ERROR;
430 }
431 } else {
432 status_t err = s.acquireFence->waitForever("BufferStateLayer::bindTextureImage");
433 if (err != NO_ERROR) {
434 ALOGE("error waiting for fence: %d", err);
435 return err;
436 }
437 }
438 }
439
440 return NO_ERROR;
441}
442
Alec Mouri86770e52018-09-24 22:40:58 +0000443status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime,
444 const sp<Fence>& releaseFence) {
Marissa Wall61c58622018-07-18 10:12:20 -0700445 const State& s(getDrawingState());
446
447 if (!s.buffer) {
448 return NO_ERROR;
449 }
450
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700451 const int32_t layerID = getSequence();
452
Marissa Wall61c58622018-07-18 10:12:20 -0700453 // Reject if the layer is invalid
454 uint32_t bufferWidth = s.buffer->width;
455 uint32_t bufferHeight = s.buffer->height;
456
Peiyong Linefefaac2018-08-17 12:27:51 -0700457 if (s.transform & ui::Transform::ROT_90) {
Peiyong Lin3db42342018-08-16 09:15:59 -0700458 std::swap(bufferWidth, bufferHeight);
Marissa Wall61c58622018-07-18 10:12:20 -0700459 }
460
461 if (s.transformToDisplayInverse) {
462 uint32_t invTransform = DisplayDevice::getPrimaryDisplayOrientationTransform();
Peiyong Linefefaac2018-08-17 12:27:51 -0700463 if (invTransform & ui::Transform::ROT_90) {
Peiyong Lin3db42342018-08-16 09:15:59 -0700464 std::swap(bufferWidth, bufferHeight);
Marissa Wall61c58622018-07-18 10:12:20 -0700465 }
466 }
467
Vishnu Nair60356342018-11-13 13:00:45 -0800468 if (getEffectiveScalingMode() == NATIVE_WINDOW_SCALING_MODE_FREEZE &&
Marissa Wall61c58622018-07-18 10:12:20 -0700469 (s.active.w != bufferWidth || s.active.h != bufferHeight)) {
470 ALOGE("[%s] rejecting buffer: "
471 "bufferWidth=%d, bufferHeight=%d, front.active.{w=%d, h=%d}",
472 mName.string(), bufferWidth, bufferHeight, s.active.w, s.active.h);
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700473 mTimeStats.removeTimeRecord(layerID, getFrameNumber());
Marissa Wall61c58622018-07-18 10:12:20 -0700474 return BAD_VALUE;
475 }
476
Marissa Wallfda30bb2018-10-12 11:34:28 -0700477 mFlinger->getTransactionCompletedThread()
478 .addLatchedCallbackHandles(getDrawingState().callbackHandles, latchTime,
479 mPreviousReleaseFence);
Marissa Walle2ffb422018-10-12 11:33:52 -0700480
Marissa Wall61c58622018-07-18 10:12:20 -0700481 // Handle sync fences
Alec Mouri86770e52018-09-24 22:40:58 +0000482 if (SyncFeatures::getInstance().useNativeFenceSync() && releaseFence != Fence::NO_FENCE) {
483 // TODO(alecmouri): Fail somewhere upstream if the fence is invalid.
484 if (!releaseFence->isValid()) {
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700485 mTimeStats.clearLayerRecord(layerID);
Marissa Wall61c58622018-07-18 10:12:20 -0700486 return UNKNOWN_ERROR;
487 }
488
Marissa Wall61c58622018-07-18 10:12:20 -0700489 // Check status of fences first because merging is expensive.
490 // Merging an invalid fence with any other fence results in an
491 // invalid fence.
492 auto currentStatus = s.acquireFence->getStatus();
493 if (currentStatus == Fence::Status::Invalid) {
494 ALOGE("Existing fence has invalid state");
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700495 mTimeStats.clearLayerRecord(layerID);
Marissa Wall61c58622018-07-18 10:12:20 -0700496 return BAD_VALUE;
497 }
498
Alec Mouri86770e52018-09-24 22:40:58 +0000499 auto incomingStatus = releaseFence->getStatus();
Marissa Wall61c58622018-07-18 10:12:20 -0700500 if (incomingStatus == Fence::Status::Invalid) {
501 ALOGE("New fence has invalid state");
Alec Mouri86770e52018-09-24 22:40:58 +0000502 mDrawingState.acquireFence = releaseFence;
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700503 mTimeStats.clearLayerRecord(layerID);
Marissa Wall61c58622018-07-18 10:12:20 -0700504 return BAD_VALUE;
505 }
506
507 // If both fences are signaled or both are unsignaled, we need to merge
508 // them to get an accurate timestamp.
509 if (currentStatus == incomingStatus) {
510 char fenceName[32] = {};
511 snprintf(fenceName, 32, "%.28s:%d", mName.string(), mFrameNumber);
Alec Mouri86770e52018-09-24 22:40:58 +0000512 sp<Fence> mergedFence =
513 Fence::merge(fenceName, mDrawingState.acquireFence, releaseFence);
Marissa Wall61c58622018-07-18 10:12:20 -0700514 if (!mergedFence.get()) {
515 ALOGE("failed to merge release fences");
516 // synchronization is broken, the best we can do is hope fences
517 // signal in order so the new fence will act like a union
Alec Mouri86770e52018-09-24 22:40:58 +0000518 mDrawingState.acquireFence = releaseFence;
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700519 mTimeStats.clearLayerRecord(layerID);
Marissa Wall61c58622018-07-18 10:12:20 -0700520 return BAD_VALUE;
521 }
522 mDrawingState.acquireFence = mergedFence;
523 } else if (incomingStatus == Fence::Status::Unsignaled) {
524 // If one fence has signaled and the other hasn't, the unsignaled
525 // fence will approximately correspond with the correct timestamp.
526 // There's a small race if both fences signal at about the same time
527 // and their statuses are retrieved with unfortunate timing. However,
528 // by this point, they will have both signaled and only the timestamp
529 // will be slightly off; any dependencies after this point will
530 // already have been met.
Alec Mouri86770e52018-09-24 22:40:58 +0000531 mDrawingState.acquireFence = releaseFence;
Marissa Wall61c58622018-07-18 10:12:20 -0700532 }
533 } else {
534 // Bind the new buffer to the GL texture.
535 //
536 // Older devices require the "implicit" synchronization provided
537 // by glEGLImageTargetTexture2DOES, which this method calls. Newer
538 // devices will either call this in Layer::onDraw, or (if it's not
539 // a GL-composited layer) not at all.
540 status_t err = bindTextureImage();
541 if (err != NO_ERROR) {
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700542 mTimeStats.clearLayerRecord(layerID);
Marissa Wall61c58622018-07-18 10:12:20 -0700543 return BAD_VALUE;
544 }
545 }
546
547 // TODO(marissaw): properly support mTimeStats
Yiwei Zhang8e8fe522018-11-02 18:34:07 -0700548 mTimeStats.setPostTime(layerID, getFrameNumber(), getName().c_str(), latchTime);
Yiwei Zhang9689e2f2018-05-11 12:33:23 -0700549 mTimeStats.setAcquireFence(layerID, getFrameNumber(), getCurrentFenceTime());
550 mTimeStats.setLatchTime(layerID, getFrameNumber(), latchTime);
Marissa Wall61c58622018-07-18 10:12:20 -0700551
552 return NO_ERROR;
553}
554
555status_t BufferStateLayer::updateActiveBuffer() {
556 const State& s(getDrawingState());
557
558 if (s.buffer == nullptr) {
559 return BAD_VALUE;
560 }
561
562 mActiveBuffer = s.buffer;
563 getBE().compositionInfo.mBuffer = mActiveBuffer;
564 getBE().compositionInfo.mBufferSlot = 0;
565
566 return NO_ERROR;
567}
568
569status_t BufferStateLayer::updateFrameNumber(nsecs_t /*latchTime*/) {
570 // TODO(marissaw): support frame history events
571 mCurrentFrameNumber = mFrameNumber;
572 return NO_ERROR;
573}
574
Dominik Laskowski075d3172018-05-24 15:50:06 -0700575void BufferStateLayer::setHwcLayerBuffer(DisplayId displayId) {
Marissa Wall61c58622018-07-18 10:12:20 -0700576 auto& hwcInfo = getBE().mHwcLayers[displayId];
577 auto& hwcLayer = hwcInfo.layer;
578
579 const State& s(getDrawingState());
580
581 // TODO(marissaw): support more than one slot
582 uint32_t hwcSlot = 0;
583
584 auto error = hwcLayer->setBuffer(hwcSlot, s.buffer, s.acquireFence);
585 if (error != HWC2::Error::None) {
586 ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
587 s.buffer->handle, to_string(error).c_str(), static_cast<int32_t>(error));
588 }
589
Marissa Wall024a1912018-08-13 13:55:35 -0700590 mCurrentStateModified = false;
Marissa Wall61c58622018-07-18 10:12:20 -0700591 mFrameNumber++;
592}
593
594void BufferStateLayer::onFirstRef() {
Dan Stoza7b1b5a82018-07-31 16:00:21 -0700595 BufferLayer::onFirstRef();
596
Marissa Wall61c58622018-07-18 10:12:20 -0700597 if (const auto display = mFlinger->getDefaultDisplayDevice()) {
598 updateTransformHint(display);
599 }
600}
601
602} // namespace android