blob: e8f41501356528f1eabf3e85ef1b4ea1e9cab128 [file] [log] [blame]
David Sodman0c69cad2017-08-21 12:12:51 -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 "BufferLayer"
20#define ATRACE_TAG ATRACE_TAG_GRAPHICS
21
22#include "BufferLayer.h"
23#include "Colorizer.h"
24#include "DisplayDevice.h"
25#include "LayerRejecter.h"
26#include "clz.h"
27
28#include "RenderEngine/RenderEngine.h"
29
30#include <gui/BufferItem.h>
31#include <gui/BufferQueue.h>
32#include <gui/LayerDebugInfo.h>
33#include <gui/Surface.h>
34
35#include <ui/DebugUtils.h>
36
37#include <utils/Errors.h>
38#include <utils/Log.h>
39#include <utils/NativeHandle.h>
40#include <utils/StopWatch.h>
41#include <utils/Trace.h>
42
43#include <cutils/compiler.h>
44#include <cutils/native_handle.h>
45#include <cutils/properties.h>
46
47#include <math.h>
48#include <stdlib.h>
49#include <mutex>
50
51namespace android {
52
53BufferLayer::BufferLayer(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
54 uint32_t w, uint32_t h, uint32_t flags)
55 : Layer(flinger, client, name, w, h, flags),
David Sodmaneb085e02017-10-05 18:49:04 -070056 mSurfaceFlingerConsumer(nullptr),
Ivan Lozanoeb13f9e2017-11-09 12:39:31 -080057 mTextureName(UINT32_MAX),
David Sodman0c69cad2017-08-21 12:12:51 -070058 mFormat(PIXEL_FORMAT_NONE),
59 mCurrentScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
60 mBufferLatched(false),
61 mPreviousFrameNumber(0),
62 mUpdateTexImageFailed(false),
63 mRefreshPending(false) {
David Sodman0c69cad2017-08-21 12:12:51 -070064 ALOGV("Creating Layer %s", name.string());
David Sodman0c69cad2017-08-21 12:12:51 -070065
66 mFlinger->getRenderEngine().genTextures(1, &mTextureName);
67 mTexture.init(Texture::TEXTURE_EXTERNAL, mTextureName);
68
69 if (flags & ISurfaceComposerClient::eNonPremultiplied) mPremultipliedAlpha = false;
70
71 mCurrentState.requested = mCurrentState.active;
72
73 // drawing state & current state are identical
74 mDrawingState = mCurrentState;
75}
76
77BufferLayer::~BufferLayer() {
78 sp<Client> c(mClientRef.promote());
79 if (c != 0) {
80 c->detachLayer(this);
81 }
82
83 for (auto& point : mRemoteSyncPoints) {
84 point->setTransactionApplied();
85 }
86 for (auto& point : mLocalSyncPoints) {
87 point->setFrameAvailable();
88 }
89 mFlinger->deleteTextureAsync(mTextureName);
90
David Sodman6f65f3e2017-11-03 14:28:09 -070091 if (!getBE().mHwcLayers.empty()) {
David Sodman0c69cad2017-08-21 12:12:51 -070092 ALOGE("Found stale hardware composer layers when destroying "
93 "surface flinger layer %s",
94 mName.string());
95 destroyAllHwcLayers();
96 }
David Sodman0c69cad2017-08-21 12:12:51 -070097}
98
David Sodmaneb085e02017-10-05 18:49:04 -070099void BufferLayer::useSurfaceDamage() {
100 if (mFlinger->mForceFullDamage) {
101 surfaceDamageRegion = Region::INVALID_REGION;
102 } else {
103 surfaceDamageRegion = mSurfaceFlingerConsumer->getSurfaceDamage();
104 }
105}
106
107void BufferLayer::useEmptyDamage() {
108 surfaceDamageRegion.clear();
109}
110
David Sodman41fdfc92017-11-06 16:09:56 -0800111bool BufferLayer::isProtected() const {
David Sodman0cc69182017-11-17 12:12:07 -0800112 const sp<GraphicBuffer>& buffer(getBE().compositionInfo.mBuffer);
David Sodman5b4cffc2017-11-23 13:20:29 -0800113 return (buffer != 0) &&
114 (buffer->getUsage() & GRALLOC_USAGE_PROTECTED);
David Sodman0c69cad2017-08-21 12:12:51 -0700115}
116
117bool BufferLayer::isVisible() const {
118 return !(isHiddenByPolicy()) && getAlpha() > 0.0f &&
David Sodman0cc69182017-11-17 12:12:07 -0800119 (getBE().compositionInfo.mBuffer != NULL || getBE().compositionInfo.hwc.sidebandStream != NULL);
David Sodman0c69cad2017-08-21 12:12:51 -0700120}
121
122bool BufferLayer::isFixedSize() const {
123 return getEffectiveScalingMode() != NATIVE_WINDOW_SCALING_MODE_FREEZE;
124}
125
126status_t BufferLayer::setBuffers(uint32_t w, uint32_t h, PixelFormat format, uint32_t flags) {
127 uint32_t const maxSurfaceDims =
128 min(mFlinger->getMaxTextureSize(), mFlinger->getMaxViewportDims());
129
130 // never allow a surface larger than what our underlying GL implementation
131 // can handle.
132 if ((uint32_t(w) > maxSurfaceDims) || (uint32_t(h) > maxSurfaceDims)) {
133 ALOGE("dimensions too large %u x %u", uint32_t(w), uint32_t(h));
134 return BAD_VALUE;
135 }
136
137 mFormat = format;
138
139 mPotentialCursor = (flags & ISurfaceComposerClient::eCursorWindow) ? true : false;
140 mProtectedByApp = (flags & ISurfaceComposerClient::eProtectedByApp) ? true : false;
141 mCurrentOpacity = getOpacityForFormat(format);
142
143 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
144 mSurfaceFlingerConsumer->setDefaultBufferFormat(format);
145 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
146
147 return NO_ERROR;
148}
149
150static constexpr mat4 inverseOrientation(uint32_t transform) {
David Sodman41fdfc92017-11-06 16:09:56 -0800151 const mat4 flipH(-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
152 const mat4 flipV(1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1);
153 const mat4 rot90(0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1);
David Sodman0c69cad2017-08-21 12:12:51 -0700154 mat4 tr;
155
156 if (transform & NATIVE_WINDOW_TRANSFORM_ROT_90) {
157 tr = tr * rot90;
158 }
159 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_H) {
160 tr = tr * flipH;
161 }
162 if (transform & NATIVE_WINDOW_TRANSFORM_FLIP_V) {
163 tr = tr * flipV;
164 }
165 return inverse(tr);
166}
167
168/*
169 * onDraw will draw the current layer onto the presentable buffer
170 */
171void BufferLayer::onDraw(const RenderArea& renderArea, const Region& clip,
172 bool useIdentityTransform) const {
173 ATRACE_CALL();
174
David Sodman0cc69182017-11-17 12:12:07 -0800175 if (CC_UNLIKELY(getBE().compositionInfo.mBuffer == 0)) {
David Sodman0c69cad2017-08-21 12:12:51 -0700176 // the texture has not been created yet, this Layer has
177 // in fact never been drawn into. This happens frequently with
178 // SurfaceView because the WindowManager can't know when the client
179 // has drawn the first time.
180
181 // If there is nothing under us, we paint the screen in black, otherwise
182 // we just skip this update.
183
184 // figure out if there is something below us
185 Region under;
186 bool finished = false;
187 mFlinger->mDrawingState.traverseInZOrder([&](Layer* layer) {
188 if (finished || layer == static_cast<BufferLayer const*>(this)) {
189 finished = true;
190 return;
191 }
192 under.orSelf(renderArea.getTransform().transform(layer->visibleRegion));
193 });
194 // if not everything below us is covered, we plug the holes!
195 Region holes(clip.subtract(under));
196 if (!holes.isEmpty()) {
197 clearWithOpenGL(renderArea, 0, 0, 0, 1);
198 }
199 return;
200 }
201
202 // Bind the current buffer to the GL texture, and wait for it to be
203 // ready for us to draw into.
204 status_t err = mSurfaceFlingerConsumer->bindTextureImage();
205 if (err != NO_ERROR) {
206 ALOGW("onDraw: bindTextureImage failed (err=%d)", err);
207 // Go ahead and draw the buffer anyway; no matter what we do the screen
208 // is probably going to have something visibly wrong.
209 }
210
211 bool blackOutLayer = isProtected() || (isSecure() && !renderArea.isSecure());
212
213 RenderEngine& engine(mFlinger->getRenderEngine());
214
215 if (!blackOutLayer) {
216 // TODO: we could be more subtle with isFixedSize()
217 const bool useFiltering = getFiltering() || needsFiltering(renderArea) || isFixedSize();
218
219 // Query the texture matrix given our current filtering mode.
220 float textureMatrix[16];
221 mSurfaceFlingerConsumer->setFilteringEnabled(useFiltering);
222 mSurfaceFlingerConsumer->getTransformMatrix(textureMatrix);
223
224 if (getTransformToDisplayInverse()) {
225 /*
226 * the code below applies the primary display's inverse transform to
227 * the texture transform
228 */
229 uint32_t transform = DisplayDevice::getPrimaryDisplayOrientationTransform();
230 mat4 tr = inverseOrientation(transform);
231
232 /**
233 * TODO(b/36727915): This is basically a hack.
234 *
235 * Ensure that regardless of the parent transformation,
236 * this buffer is always transformed from native display
237 * orientation to display orientation. For example, in the case
238 * of a camera where the buffer remains in native orientation,
239 * we want the pixels to always be upright.
240 */
241 sp<Layer> p = mDrawingParent.promote();
242 if (p != nullptr) {
243 const auto parentTransform = p->getTransform();
244 tr = tr * inverseOrientation(parentTransform.getOrientation());
245 }
246
247 // and finally apply it to the original texture matrix
248 const mat4 texTransform(mat4(static_cast<const float*>(textureMatrix)) * tr);
249 memcpy(textureMatrix, texTransform.asArray(), sizeof(textureMatrix));
250 }
251
252 // Set things up for texturing.
David Sodman0cc69182017-11-17 12:12:07 -0800253 mTexture.setDimensions(getBE().compositionInfo.mBuffer->getWidth(),
254 getBE().compositionInfo.mBuffer->getHeight());
David Sodman0c69cad2017-08-21 12:12:51 -0700255 mTexture.setFiltering(useFiltering);
256 mTexture.setMatrix(textureMatrix);
257
258 engine.setupLayerTexturing(mTexture);
259 } else {
260 engine.setupLayerBlackedOut();
261 }
262 drawWithOpenGL(renderArea, useIdentityTransform);
263 engine.disableTexturing();
264}
265
David Sodmaneb085e02017-10-05 18:49:04 -0700266void BufferLayer::onLayerDisplayed(const sp<Fence>& releaseFence) {
David Sodmaneb085e02017-10-05 18:49:04 -0700267 mSurfaceFlingerConsumer->setReleaseFence(releaseFence);
268}
David Sodmaneb085e02017-10-05 18:49:04 -0700269
270void BufferLayer::abandon() {
271 mSurfaceFlingerConsumer->abandon();
272}
273
274bool BufferLayer::shouldPresentNow(const DispSync& dispSync) const {
275 if (mSidebandStreamChanged || mAutoRefresh) {
276 return true;
277 }
278
279 Mutex::Autolock lock(mQueueItemLock);
280 if (mQueueItems.empty()) {
281 return false;
282 }
283 auto timestamp = mQueueItems[0].mTimestamp;
284 nsecs_t expectedPresent = mSurfaceFlingerConsumer->computeExpectedPresent(dispSync);
285
286 // Ignore timestamps more than a second in the future
287 bool isPlausible = timestamp < (expectedPresent + s2ns(1));
288 ALOGW_IF(!isPlausible,
289 "[%s] Timestamp %" PRId64 " seems implausible "
290 "relative to expectedPresent %" PRId64,
291 mName.string(), timestamp, expectedPresent);
292
293 bool isDue = timestamp < expectedPresent;
294 return isDue || !isPlausible;
295}
296
297void BufferLayer::setTransformHint(uint32_t orientation) const {
298 mSurfaceFlingerConsumer->setTransformHint(orientation);
299}
300
David Sodman0c69cad2017-08-21 12:12:51 -0700301bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
302 if (mBufferLatched) {
303 Mutex::Autolock lock(mFrameEventHistoryMutex);
David Sodman9eeae692017-11-02 10:53:32 -0700304 mFrameEventHistory.addPreComposition(mCurrentFrameNumber,
305 refreshStartTime);
David Sodman0c69cad2017-08-21 12:12:51 -0700306 }
307 mRefreshPending = false;
David Sodman9eeae692017-11-02 10:53:32 -0700308 return mQueuedFrames > 0 || mSidebandStreamChanged ||
309 mAutoRefresh;
David Sodman0c69cad2017-08-21 12:12:51 -0700310}
David Sodmaneb085e02017-10-05 18:49:04 -0700311bool BufferLayer::onPostComposition(const std::shared_ptr<FenceTime>& glDoneFence,
312 const std::shared_ptr<FenceTime>& presentFence,
313 const CompositorTiming& compositorTiming) {
314 // mFrameLatencyNeeded is true when a new frame was latched for the
315 // composition.
316 if (!mFrameLatencyNeeded) return false;
317
318 // Update mFrameEventHistory.
319 {
320 Mutex::Autolock lock(mFrameEventHistoryMutex);
David Sodman9eeae692017-11-02 10:53:32 -0700321 mFrameEventHistory.addPostComposition(mCurrentFrameNumber, glDoneFence,
322 presentFence, compositorTiming);
David Sodmaneb085e02017-10-05 18:49:04 -0700323 }
324
325 // Update mFrameTracker.
326 nsecs_t desiredPresentTime = mSurfaceFlingerConsumer->getTimestamp();
327 mFrameTracker.setDesiredPresentTime(desiredPresentTime);
328
329 std::shared_ptr<FenceTime> frameReadyFence = mSurfaceFlingerConsumer->getCurrentFenceTime();
330 if (frameReadyFence->isValid()) {
331 mFrameTracker.setFrameReadyFence(std::move(frameReadyFence));
332 } else {
333 // There was no fence for this frame, so assume that it was ready
334 // to be presented at the desired present time.
335 mFrameTracker.setFrameReadyTime(desiredPresentTime);
336 }
337
338 if (presentFence->isValid()) {
339 mFrameTracker.setActualPresentFence(std::shared_ptr<FenceTime>(presentFence));
340 } else {
341 // The HWC doesn't support present fences, so use the refresh
342 // timestamp instead.
343 mFrameTracker.setActualPresentTime(
344 mFlinger->getHwComposer().getRefreshTimestamp(HWC_DISPLAY_PRIMARY));
345 }
346
347 mFrameTracker.advanceFrame();
348 mFrameLatencyNeeded = false;
349 return true;
350}
351
352std::vector<OccupancyTracker::Segment> BufferLayer::getOccupancyHistory(bool forceFlush) {
353 std::vector<OccupancyTracker::Segment> history;
354 status_t result = mSurfaceFlingerConsumer->getOccupancyHistory(forceFlush, &history);
355 if (result != NO_ERROR) {
356 ALOGW("[%s] Failed to obtain occupancy history (%d)", mName.string(), result);
357 return {};
358 }
359 return history;
360}
361
362bool BufferLayer::getTransformToDisplayInverse() const {
363 return mSurfaceFlingerConsumer->getTransformToDisplayInverse();
364}
David Sodman0c69cad2017-08-21 12:12:51 -0700365
David Sodman0c69cad2017-08-21 12:12:51 -0700366void BufferLayer::releasePendingBuffer(nsecs_t dequeueReadyTime) {
367 if (!mSurfaceFlingerConsumer->releasePendingBuffer()) {
368 return;
369 }
370
371 auto releaseFenceTime =
372 std::make_shared<FenceTime>(mSurfaceFlingerConsumer->getPrevFinalReleaseFence());
373 mReleaseTimeline.updateSignalTimes();
374 mReleaseTimeline.push(releaseFenceTime);
375
376 Mutex::Autolock lock(mFrameEventHistoryMutex);
377 if (mPreviousFrameNumber != 0) {
378 mFrameEventHistory.addRelease(mPreviousFrameNumber, dequeueReadyTime,
379 std::move(releaseFenceTime));
380 }
381}
David Sodman0c69cad2017-08-21 12:12:51 -0700382
383Region BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) {
384 ATRACE_CALL();
385
386 if (android_atomic_acquire_cas(true, false, &mSidebandStreamChanged) == 0) {
387 // mSidebandStreamChanged was true
388 mSidebandStream = mSurfaceFlingerConsumer->getSidebandStream();
David Sodman386c22e2017-11-09 16:34:46 -0800389 // replicated in LayerBE until FE/BE is ready to be synchronized
David Sodman0cc69182017-11-17 12:12:07 -0800390 getBE().compositionInfo.hwc.sidebandStream = mSidebandStream;
391 if (getBE().compositionInfo.hwc.sidebandStream != NULL) {
David Sodman0c69cad2017-08-21 12:12:51 -0700392 setTransactionFlags(eTransactionNeeded);
393 mFlinger->setTransactionFlags(eTraversalNeeded);
394 }
395 recomputeVisibleRegions = true;
396
397 const State& s(getDrawingState());
398 return getTransform().transform(Region(Rect(s.active.w, s.active.h)));
399 }
400
401 Region outDirtyRegion;
402 if (mQueuedFrames <= 0 && !mAutoRefresh) {
403 return outDirtyRegion;
404 }
405
406 // if we've already called updateTexImage() without going through
407 // a composition step, we have to skip this layer at this point
408 // because we cannot call updateTeximage() without a corresponding
409 // compositionComplete() call.
410 // we'll trigger an update in onPreComposition().
411 if (mRefreshPending) {
412 return outDirtyRegion;
413 }
414
415 // If the head buffer's acquire fence hasn't signaled yet, return and
416 // try again later
417 if (!headFenceHasSignaled()) {
418 mFlinger->signalLayerUpdate();
419 return outDirtyRegion;
420 }
421
422 // Capture the old state of the layer for comparisons later
423 const State& s(getDrawingState());
424 const bool oldOpacity = isOpaque(s);
David Sodman0cc69182017-11-17 12:12:07 -0800425 sp<GraphicBuffer> oldBuffer = getBE().compositionInfo.mBuffer;
David Sodman0c69cad2017-08-21 12:12:51 -0700426
427 if (!allTransactionsSignaled()) {
428 mFlinger->signalLayerUpdate();
429 return outDirtyRegion;
430 }
431
432 // This boolean is used to make sure that SurfaceFlinger's shadow copy
433 // of the buffer queue isn't modified when the buffer queue is returning
434 // BufferItem's that weren't actually queued. This can happen in shared
435 // buffer mode.
436 bool queuedBuffer = false;
437 LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions,
David Sodman9eeae692017-11-02 10:53:32 -0700438 getProducerStickyTransform() != 0, mName.string(),
439 mOverrideScalingMode, mFreezeGeometryUpdates);
David Sodman0c69cad2017-08-21 12:12:51 -0700440 status_t updateResult =
David Sodman9eeae692017-11-02 10:53:32 -0700441 mSurfaceFlingerConsumer->updateTexImage(&r, mFlinger->mPrimaryDispSync,
442 &mAutoRefresh, &queuedBuffer,
443 mLastFrameNumberReceived);
David Sodman0c69cad2017-08-21 12:12:51 -0700444 if (updateResult == BufferQueue::PRESENT_LATER) {
445 // Producer doesn't want buffer to be displayed yet. Signal a
446 // layer update so we check again at the next opportunity.
447 mFlinger->signalLayerUpdate();
448 return outDirtyRegion;
449 } else if (updateResult == SurfaceFlingerConsumer::BUFFER_REJECTED) {
450 // If the buffer has been rejected, remove it from the shadow queue
451 // and return early
452 if (queuedBuffer) {
453 Mutex::Autolock lock(mQueueItemLock);
454 mQueueItems.removeAt(0);
455 android_atomic_dec(&mQueuedFrames);
456 }
457 return outDirtyRegion;
458 } else if (updateResult != NO_ERROR || mUpdateTexImageFailed) {
459 // This can occur if something goes wrong when trying to create the
460 // EGLImage for this buffer. If this happens, the buffer has already
461 // been released, so we need to clean up the queue and bug out
462 // early.
463 if (queuedBuffer) {
464 Mutex::Autolock lock(mQueueItemLock);
465 mQueueItems.clear();
466 android_atomic_and(0, &mQueuedFrames);
467 }
468
469 // Once we have hit this state, the shadow queue may no longer
470 // correctly reflect the incoming BufferQueue's contents, so even if
471 // updateTexImage starts working, the only safe course of action is
472 // to continue to ignore updates.
473 mUpdateTexImageFailed = true;
474
475 return outDirtyRegion;
476 }
477
478 if (queuedBuffer) {
479 // Autolock scope
480 auto currentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
481
482 Mutex::Autolock lock(mQueueItemLock);
483
484 // Remove any stale buffers that have been dropped during
485 // updateTexImage
486 while (mQueueItems[0].mFrameNumber != currentFrameNumber) {
487 mQueueItems.removeAt(0);
488 android_atomic_dec(&mQueuedFrames);
489 }
490
491 mQueueItems.removeAt(0);
492 }
493
494 // Decrement the queued-frames count. Signal another event if we
495 // have more frames pending.
David Sodman9eeae692017-11-02 10:53:32 -0700496 if ((queuedBuffer && android_atomic_dec(&mQueuedFrames) > 1) ||
497 mAutoRefresh) {
David Sodman0c69cad2017-08-21 12:12:51 -0700498 mFlinger->signalLayerUpdate();
499 }
500
501 // update the active buffer
David Sodman0cc69182017-11-17 12:12:07 -0800502 getBE().compositionInfo.mBuffer =
503 mSurfaceFlingerConsumer->getCurrentBuffer(&getBE().compositionInfo.mBufferSlot);
David Sodman5b4cffc2017-11-23 13:20:29 -0800504 // replicated in LayerBE until FE/BE is ready to be synchronized
David Sodman0cc69182017-11-17 12:12:07 -0800505 mActiveBuffer = getBE().compositionInfo.mBuffer;
506 if (getBE().compositionInfo.mBuffer == NULL) {
David Sodman0c69cad2017-08-21 12:12:51 -0700507 // this can only happen if the very first buffer was rejected.
508 return outDirtyRegion;
509 }
510
511 mBufferLatched = true;
512 mPreviousFrameNumber = mCurrentFrameNumber;
513 mCurrentFrameNumber = mSurfaceFlingerConsumer->getFrameNumber();
514
515 {
516 Mutex::Autolock lock(mFrameEventHistoryMutex);
517 mFrameEventHistory.addLatch(mCurrentFrameNumber, latchTime);
David Sodman0c69cad2017-08-21 12:12:51 -0700518 }
519
520 mRefreshPending = true;
521 mFrameLatencyNeeded = true;
David Sodman5b4cffc2017-11-23 13:20:29 -0800522 if (oldBuffer == NULL) {
David Sodman0c69cad2017-08-21 12:12:51 -0700523 // the first time we receive a buffer, we need to trigger a
524 // geometry invalidation.
525 recomputeVisibleRegions = true;
526 }
527
528 setDataSpace(mSurfaceFlingerConsumer->getCurrentDataSpace());
529
530 Rect crop(mSurfaceFlingerConsumer->getCurrentCrop());
531 const uint32_t transform(mSurfaceFlingerConsumer->getCurrentTransform());
532 const uint32_t scalingMode(mSurfaceFlingerConsumer->getCurrentScalingMode());
David Sodman9eeae692017-11-02 10:53:32 -0700533 if ((crop != mCurrentCrop) ||
534 (transform != mCurrentTransform) ||
David Sodman0c69cad2017-08-21 12:12:51 -0700535 (scalingMode != mCurrentScalingMode)) {
536 mCurrentCrop = crop;
537 mCurrentTransform = transform;
538 mCurrentScalingMode = scalingMode;
539 recomputeVisibleRegions = true;
540 }
541
David Sodman5b4cffc2017-11-23 13:20:29 -0800542 if (oldBuffer != NULL) {
David Sodman0cc69182017-11-17 12:12:07 -0800543 uint32_t bufWidth = getBE().compositionInfo.mBuffer->getWidth();
544 uint32_t bufHeight = getBE().compositionInfo.mBuffer->getHeight();
David Sodman5b4cffc2017-11-23 13:20:29 -0800545 if (bufWidth != uint32_t(oldBuffer->width) ||
546 bufHeight != uint32_t(oldBuffer->height)) {
David Sodman0c69cad2017-08-21 12:12:51 -0700547 recomputeVisibleRegions = true;
548 }
549 }
550
David Sodman0cc69182017-11-17 12:12:07 -0800551 mCurrentOpacity = getOpacityForFormat(getBE().compositionInfo.mBuffer->format);
David Sodman0c69cad2017-08-21 12:12:51 -0700552 if (oldOpacity != isOpaque(s)) {
553 recomputeVisibleRegions = true;
554 }
555
556 // Remove any sync points corresponding to the buffer which was just
557 // latched
558 {
559 Mutex::Autolock lock(mLocalSyncPointMutex);
560 auto point = mLocalSyncPoints.begin();
561 while (point != mLocalSyncPoints.end()) {
562 if (!(*point)->frameIsAvailable() || !(*point)->transactionIsApplied()) {
563 // This sync point must have been added since we started
564 // latching. Don't drop it yet.
565 ++point;
566 continue;
567 }
568
569 if ((*point)->getFrameNumber() <= mCurrentFrameNumber) {
570 point = mLocalSyncPoints.erase(point);
571 } else {
572 ++point;
573 }
574 }
575 }
576
577 // FIXME: postedRegion should be dirty & bounds
578 Region dirtyRegion(Rect(s.active.w, s.active.h));
579
580 // transform the dirty region to window-manager space
581 outDirtyRegion = (getTransform().transform(dirtyRegion));
582
583 return outDirtyRegion;
584}
585
David Sodmaneb085e02017-10-05 18:49:04 -0700586void BufferLayer::setDefaultBufferSize(uint32_t w, uint32_t h) {
587 mSurfaceFlingerConsumer->setDefaultBufferSize(w, h);
588}
589
David Sodman0c69cad2017-08-21 12:12:51 -0700590void BufferLayer::setPerFrameData(const sp<const DisplayDevice>& displayDevice) {
591 // Apply this display's projection's viewport to the visible region
592 // before giving it to the HWC HAL.
593 const Transform& tr = displayDevice->getTransform();
594 const auto& viewport = displayDevice->getViewport();
595 Region visible = tr.transform(visibleRegion.intersect(viewport));
596 auto hwcId = displayDevice->getHwcDisplayId();
David Sodman6f65f3e2017-11-03 14:28:09 -0700597 auto& hwcInfo = getBE().mHwcLayers[hwcId];
David Sodman0c69cad2017-08-21 12:12:51 -0700598 auto& hwcLayer = hwcInfo.layer;
599 auto error = hwcLayer->setVisibleRegion(visible);
600 if (error != HWC2::Error::None) {
601 ALOGE("[%s] Failed to set visible region: %s (%d)", mName.string(),
602 to_string(error).c_str(), static_cast<int32_t>(error));
603 visible.dump(LOG_TAG);
604 }
605
606 error = hwcLayer->setSurfaceDamage(surfaceDamageRegion);
607 if (error != HWC2::Error::None) {
608 ALOGE("[%s] Failed to set surface damage: %s (%d)", mName.string(),
609 to_string(error).c_str(), static_cast<int32_t>(error));
610 surfaceDamageRegion.dump(LOG_TAG);
611 }
612
613 // Sideband layers
David Sodman0cc69182017-11-17 12:12:07 -0800614 if (getBE().compositionInfo.hwc.sidebandStream.get()) {
David Sodman0c69cad2017-08-21 12:12:51 -0700615 setCompositionType(hwcId, HWC2::Composition::Sideband);
616 ALOGV("[%s] Requesting Sideband composition", mName.string());
David Sodman0cc69182017-11-17 12:12:07 -0800617 error = hwcLayer->setSidebandStream(getBE().compositionInfo.hwc.sidebandStream->handle());
David Sodman0c69cad2017-08-21 12:12:51 -0700618 if (error != HWC2::Error::None) {
619 ALOGE("[%s] Failed to set sideband stream %p: %s (%d)", mName.string(),
David Sodman0cc69182017-11-17 12:12:07 -0800620 getBE().compositionInfo.hwc.sidebandStream->handle(), to_string(error).c_str(),
David Sodman9eeae692017-11-02 10:53:32 -0700621 static_cast<int32_t>(error));
David Sodman0c69cad2017-08-21 12:12:51 -0700622 }
623 return;
624 }
625
David Sodman0c69cad2017-08-21 12:12:51 -0700626 // Device or Cursor layers
627 if (mPotentialCursor) {
628 ALOGV("[%s] Requesting Cursor composition", mName.string());
629 setCompositionType(hwcId, HWC2::Composition::Cursor);
630 } else {
631 ALOGV("[%s] Requesting Device composition", mName.string());
632 setCompositionType(hwcId, HWC2::Composition::Device);
633 }
634
635 ALOGV("setPerFrameData: dataspace = %d", mCurrentState.dataSpace);
636 error = hwcLayer->setDataspace(mCurrentState.dataSpace);
637 if (error != HWC2::Error::None) {
638 ALOGE("[%s] Failed to set dataspace %d: %s (%d)", mName.string(), mCurrentState.dataSpace,
639 to_string(error).c_str(), static_cast<int32_t>(error));
640 }
641
642 uint32_t hwcSlot = 0;
643 sp<GraphicBuffer> hwcBuffer;
David Sodman0cc69182017-11-17 12:12:07 -0800644 hwcInfo.bufferCache.getHwcBuffer(getBE().compositionInfo.mBufferSlot,
645 getBE().compositionInfo.mBuffer, &hwcSlot, &hwcBuffer);
David Sodman0c69cad2017-08-21 12:12:51 -0700646
647 auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
648 error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
649 if (error != HWC2::Error::None) {
David Sodman9eeae692017-11-02 10:53:32 -0700650 ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
David Sodman0cc69182017-11-17 12:12:07 -0800651 getBE().compositionInfo.mBuffer->handle, to_string(error).c_str(),
David Sodman9eeae692017-11-02 10:53:32 -0700652 static_cast<int32_t>(error));
David Sodman0c69cad2017-08-21 12:12:51 -0700653 }
654}
655
David Sodman41fdfc92017-11-06 16:09:56 -0800656bool BufferLayer::isOpaque(const Layer::State& s) const {
David Sodman0c69cad2017-08-21 12:12:51 -0700657 // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the
658 // layer's opaque flag.
David Sodman0cc69182017-11-17 12:12:07 -0800659 if ((getBE().compositionInfo.hwc.sidebandStream == nullptr) && (getBE().compositionInfo.mBuffer == nullptr)) {
David Sodman0c69cad2017-08-21 12:12:51 -0700660 return false;
661 }
662
663 // if the layer has the opaque flag, then we're always opaque,
664 // otherwise we use the current buffer's format.
665 return ((s.flags & layer_state_t::eLayerOpaque) != 0) || mCurrentOpacity;
666}
667
668void BufferLayer::onFirstRef() {
669 // Creates a custom BufferQueue for SurfaceFlingerConsumer to use
670 sp<IGraphicBufferProducer> producer;
671 sp<IGraphicBufferConsumer> consumer;
672 BufferQueue::createBufferQueue(&producer, &consumer, true);
673 mProducer = new MonitoredProducer(producer, mFlinger, this);
674 mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName, this);
675 mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
676 mSurfaceFlingerConsumer->setContentsChangedListener(this);
677 mSurfaceFlingerConsumer->setName(mName);
678
679 if (mFlinger->isLayerTripleBufferingDisabled()) {
680 mProducer->setMaxDequeuedBufferCount(2);
681 }
682
683 const sp<const DisplayDevice> hw(mFlinger->getDefaultDisplayDevice());
684 updateTransformHint(hw);
685}
686
687// ---------------------------------------------------------------------------
688// Interface implementation for SurfaceFlingerConsumer::ContentsChangedListener
689// ---------------------------------------------------------------------------
690
691void BufferLayer::onFrameAvailable(const BufferItem& item) {
692 // Add this buffer from our internal queue tracker
693 { // Autolock scope
694 Mutex::Autolock lock(mQueueItemLock);
695 mFlinger->mInterceptor.saveBufferUpdate(this, item.mGraphicBuffer->getWidth(),
696 item.mGraphicBuffer->getHeight(),
697 item.mFrameNumber);
698 // Reset the frame number tracker when we receive the first buffer after
699 // a frame number reset
700 if (item.mFrameNumber == 1) {
701 mLastFrameNumberReceived = 0;
702 }
703
704 // Ensure that callbacks are handled in order
705 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
David Sodman9eeae692017-11-02 10:53:32 -0700706 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
707 ms2ns(500));
David Sodman0c69cad2017-08-21 12:12:51 -0700708 if (result != NO_ERROR) {
709 ALOGE("[%s] Timed out waiting on callback", mName.string());
710 }
711 }
712
713 mQueueItems.push_back(item);
714 android_atomic_inc(&mQueuedFrames);
715
716 // Wake up any pending callbacks
717 mLastFrameNumberReceived = item.mFrameNumber;
718 mQueueItemCondition.broadcast();
719 }
720
721 mFlinger->signalLayerUpdate();
722}
723
724void BufferLayer::onFrameReplaced(const BufferItem& item) {
725 { // Autolock scope
726 Mutex::Autolock lock(mQueueItemLock);
727
728 // Ensure that callbacks are handled in order
729 while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
David Sodman9eeae692017-11-02 10:53:32 -0700730 status_t result = mQueueItemCondition.waitRelative(mQueueItemLock,
731 ms2ns(500));
David Sodman0c69cad2017-08-21 12:12:51 -0700732 if (result != NO_ERROR) {
733 ALOGE("[%s] Timed out waiting on callback", mName.string());
734 }
735 }
736
737 if (mQueueItems.empty()) {
738 ALOGE("Can't replace a frame on an empty queue");
739 return;
740 }
741 mQueueItems.editItemAt(mQueueItems.size() - 1) = item;
742
743 // Wake up any pending callbacks
744 mLastFrameNumberReceived = item.mFrameNumber;
745 mQueueItemCondition.broadcast();
746 }
747}
748
749void BufferLayer::onSidebandStreamChanged() {
750 if (android_atomic_release_cas(false, true, &mSidebandStreamChanged) == 0) {
751 // mSidebandStreamChanged was false
752 mFlinger->signalLayerUpdate();
753 }
754}
755
756bool BufferLayer::needsFiltering(const RenderArea& renderArea) const {
757 return mNeedsFiltering || renderArea.needsFiltering();
758}
759
760// As documented in libhardware header, formats in the range
761// 0x100 - 0x1FF are specific to the HAL implementation, and
762// are known to have no alpha channel
763// TODO: move definition for device-specific range into
764// hardware.h, instead of using hard-coded values here.
765#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
766
767bool BufferLayer::getOpacityForFormat(uint32_t format) {
768 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
769 return true;
770 }
771 switch (format) {
772 case HAL_PIXEL_FORMAT_RGBA_8888:
773 case HAL_PIXEL_FORMAT_BGRA_8888:
774 case HAL_PIXEL_FORMAT_RGBA_FP16:
775 case HAL_PIXEL_FORMAT_RGBA_1010102:
776 return false;
777 }
778 // in all other case, we have no blending (also for unknown formats)
779 return true;
780}
781
David Sodman41fdfc92017-11-06 16:09:56 -0800782void BufferLayer::drawWithOpenGL(const RenderArea& renderArea, bool useIdentityTransform) const {
David Sodman0c69cad2017-08-21 12:12:51 -0700783 const State& s(getDrawingState());
784
David Sodman9eeae692017-11-02 10:53:32 -0700785 computeGeometry(renderArea, getBE().mMesh, useIdentityTransform);
David Sodman0c69cad2017-08-21 12:12:51 -0700786
787 /*
788 * NOTE: the way we compute the texture coordinates here produces
789 * different results than when we take the HWC path -- in the later case
790 * the "source crop" is rounded to texel boundaries.
791 * This can produce significantly different results when the texture
792 * is scaled by a large amount.
793 *
794 * The GL code below is more logical (imho), and the difference with
795 * HWC is due to a limitation of the HWC API to integers -- a question
796 * is suspend is whether we should ignore this problem or revert to
797 * GL composition when a buffer scaling is applied (maybe with some
798 * minimal value)? Or, we could make GL behave like HWC -- but this feel
799 * like more of a hack.
800 */
801 Rect win(computeBounds());
802
803 Transform t = getTransform();
804 if (!s.finalCrop.isEmpty()) {
805 win = t.transform(win);
806 if (!win.intersect(s.finalCrop, &win)) {
807 win.clear();
808 }
809 win = t.inverse().transform(win);
810 if (!win.intersect(computeBounds(), &win)) {
811 win.clear();
812 }
813 }
814
815 float left = float(win.left) / float(s.active.w);
816 float top = float(win.top) / float(s.active.h);
817 float right = float(win.right) / float(s.active.w);
818 float bottom = float(win.bottom) / float(s.active.h);
819
820 // TODO: we probably want to generate the texture coords with the mesh
821 // here we assume that we only have 4 vertices
David Sodman9eeae692017-11-02 10:53:32 -0700822 Mesh::VertexArray<vec2> texCoords(getBE().mMesh.getTexCoordArray<vec2>());
David Sodman0c69cad2017-08-21 12:12:51 -0700823 texCoords[0] = vec2(left, 1.0f - top);
824 texCoords[1] = vec2(left, 1.0f - bottom);
825 texCoords[2] = vec2(right, 1.0f - bottom);
826 texCoords[3] = vec2(right, 1.0f - top);
827
828 RenderEngine& engine(mFlinger->getRenderEngine());
829 engine.setupLayerBlending(mPremultipliedAlpha, isOpaque(s), false /* disableTexture */,
830 getColor());
David Sodman0c69cad2017-08-21 12:12:51 -0700831 engine.setSourceDataSpace(mCurrentState.dataSpace);
David Sodman9eeae692017-11-02 10:53:32 -0700832 engine.drawMesh(getBE().mMesh);
David Sodman0c69cad2017-08-21 12:12:51 -0700833 engine.disableBlending();
834}
835
836uint32_t BufferLayer::getProducerStickyTransform() const {
837 int producerStickyTransform = 0;
838 int ret = mProducer->query(NATIVE_WINDOW_STICKY_TRANSFORM, &producerStickyTransform);
839 if (ret != OK) {
840 ALOGW("%s: Error %s (%d) while querying window sticky transform.", __FUNCTION__,
841 strerror(-ret), ret);
842 return 0;
843 }
844 return static_cast<uint32_t>(producerStickyTransform);
845}
846
847bool BufferLayer::latchUnsignaledBuffers() {
848 static bool propertyLoaded = false;
849 static bool latch = false;
850 static std::mutex mutex;
851 std::lock_guard<std::mutex> lock(mutex);
852 if (!propertyLoaded) {
853 char value[PROPERTY_VALUE_MAX] = {};
854 property_get("debug.sf.latch_unsignaled", value, "0");
855 latch = atoi(value);
856 propertyLoaded = true;
857 }
858 return latch;
859}
860
861uint64_t BufferLayer::getHeadFrameNumber() const {
862 Mutex::Autolock lock(mQueueItemLock);
863 if (!mQueueItems.empty()) {
864 return mQueueItems[0].mFrameNumber;
865 } else {
866 return mCurrentFrameNumber;
867 }
868}
869
870bool BufferLayer::headFenceHasSignaled() const {
David Sodman0c69cad2017-08-21 12:12:51 -0700871 if (latchUnsignaledBuffers()) {
872 return true;
873 }
874
875 Mutex::Autolock lock(mQueueItemLock);
876 if (mQueueItems.empty()) {
877 return true;
878 }
879 if (mQueueItems[0].mIsDroppable) {
880 // Even though this buffer's fence may not have signaled yet, it could
881 // be replaced by another buffer before it has a chance to, which means
882 // that it's possible to get into a situation where a buffer is never
883 // able to be latched. To avoid this, grab this buffer anyway.
884 return true;
885 }
David Sodman9eeae692017-11-02 10:53:32 -0700886 return mQueueItems[0].mFenceTime->getSignalTime() !=
887 Fence::SIGNAL_TIME_PENDING;
David Sodman0c69cad2017-08-21 12:12:51 -0700888}
889
890uint32_t BufferLayer::getEffectiveScalingMode() const {
891 if (mOverrideScalingMode >= 0) {
892 return mOverrideScalingMode;
893 }
894 return mCurrentScalingMode;
895}
896
897// ----------------------------------------------------------------------------
898// transaction
899// ----------------------------------------------------------------------------
900
901void BufferLayer::notifyAvailableFrames() {
902 auto headFrameNumber = getHeadFrameNumber();
903 bool headFenceSignaled = headFenceHasSignaled();
904 Mutex::Autolock lock(mLocalSyncPointMutex);
905 for (auto& point : mLocalSyncPoints) {
906 if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) {
907 point->setFrameAvailable();
908 }
909 }
910}
911
912sp<IGraphicBufferProducer> BufferLayer::getProducer() const {
913 return mProducer;
914}
915
916// ---------------------------------------------------------------------------
917// h/w composer set-up
918// ---------------------------------------------------------------------------
919
920bool BufferLayer::allTransactionsSignaled() {
921 auto headFrameNumber = getHeadFrameNumber();
922 bool matchingFramesFound = false;
923 bool allTransactionsApplied = true;
924 Mutex::Autolock lock(mLocalSyncPointMutex);
925
926 for (auto& point : mLocalSyncPoints) {
927 if (point->getFrameNumber() > headFrameNumber) {
928 break;
929 }
930 matchingFramesFound = true;
931
932 if (!point->frameIsAvailable()) {
933 // We haven't notified the remote layer that the frame for
934 // this point is available yet. Notify it now, and then
935 // abort this attempt to latch.
936 point->setFrameAvailable();
937 allTransactionsApplied = false;
938 break;
939 }
940
941 allTransactionsApplied = allTransactionsApplied && point->transactionIsApplied();
942 }
943 return !matchingFramesFound || allTransactionsApplied;
944}
945
946} // namespace android
947
948#if defined(__gl_h_)
949#error "don't include gl/gl.h in this file"
950#endif
951
952#if defined(__gl2_h_)
953#error "don't include gl2/gl2.h in this file"
954#endif