1 /*
2 * Copyright 2022 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 // #define LOG_NDEBUG 0
17
18 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
19 #undef LOG_TAG
20 #define LOG_TAG "SurfaceFlinger"
21
22 #include <common/trace.h>
23 #include <log/log.h>
24 #include <private/android_filesystem_config.h>
25 #include <sys/types.h>
26
27 #include <scheduler/Fps.h>
28
29 #include "Layer.h"
30 #include "LayerCreationArgs.h"
31 #include "LayerLog.h"
32 #include "RequestedLayerState.h"
33
34 namespace android::surfaceflinger::frontend {
35 using ftl::Flags;
36 using namespace ftl::flag_operators;
37
38 namespace {
layerIdsToString(const std::vector<uint32_t> & layerIds)39 std::string layerIdsToString(const std::vector<uint32_t>& layerIds) {
40 std::stringstream stream;
41 stream << "{";
42 for (auto layerId : layerIds) {
43 stream << layerId << ",";
44 }
45 stream << "}";
46 return stream.str();
47 }
48
49 } // namespace
50
RequestedLayerState(const LayerCreationArgs & args)51 RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args)
52 : id(args.sequence),
53 name(args.name + "#" + std::to_string(args.sequence)),
54 canBeRoot(args.addToRoot),
55 layerCreationFlags(args.flags),
56 ownerUid(args.ownerUid),
57 ownerPid(args.ownerPid),
58 parentId(args.parentId),
59 layerIdToMirror(args.layerIdToMirror),
60 pendingBuffers(args.pendingBuffers) {
61 layerId = static_cast<int32_t>(args.sequence);
62 changes |= RequestedLayerState::Changes::Created;
63 metadata.merge(args.metadata);
64 changes |= RequestedLayerState::Changes::Metadata;
65 handleAlive = true;
66 // b/271132344 revisit this and see if we can always use the layers uid/pid
67 auto* windowInfo = editWindowInfo();
68 windowInfo->name = name;
69 windowInfo->ownerPid = ownerPid;
70 windowInfo->ownerUid = ownerUid;
71 if (parentId != UNASSIGNED_LAYER_ID) {
72 canBeRoot = false;
73 }
74 if (layerIdToMirror != UNASSIGNED_LAYER_ID) {
75 changes |= RequestedLayerState::Changes::Mirror;
76 } else if (args.layerStackToMirror != ui::INVALID_LAYER_STACK) {
77 layerStackToMirror = args.layerStackToMirror;
78 changes |= RequestedLayerState::Changes::Mirror;
79 }
80
81 flags = 0;
82 if (args.flags & ISurfaceComposerClient::eHidden) flags |= layer_state_t::eLayerHidden;
83 if (args.flags & ISurfaceComposerClient::eOpaque) flags |= layer_state_t::eLayerOpaque;
84 if (args.flags & ISurfaceComposerClient::eSecure) flags |= layer_state_t::eLayerSecure;
85 if (args.flags & ISurfaceComposerClient::eSkipScreenshot) {
86 flags |= layer_state_t::eLayerSkipScreenshot;
87 }
88 premultipliedAlpha = !(args.flags & ISurfaceComposerClient::eNonPremultiplied);
89 potentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;
90 protectedByApp = args.flags & ISurfaceComposerClient::eProtectedByApp;
91 if (args.flags & ISurfaceComposerClient::eNoColorFill) {
92 // Set an invalid color so there is no color fill.
93 // (b/259981098) use an explicit flag instead of relying on invalid values.
94 color.r = -1.0_hf;
95 color.g = -1.0_hf;
96 color.b = -1.0_hf;
97 } else {
98 color.rgb = {0.0_hf, 0.0_hf, 0.0_hf};
99 }
100 LLOGV(layerId, "Created %s flags=%d", getDebugString().c_str(), flags);
101 color.a = 1.0f;
102
103 crop = {0, 0, -1, -1};
104 z = 0;
105 layerStack = ui::DEFAULT_LAYER_STACK;
106 transformToDisplayInverse = false;
107 desiredHdrSdrRatio = -1.f;
108 currentHdrSdrRatio = 1.f;
109 dataspaceRequested = false;
110 hdrMetadata.validTypes = 0;
111 mNotDefCmpState.surfaceDamageRegion = Region::INVALID_REGION;
112 cornerRadius = 0.0f;
113 clientDrawnCornerRadius = 0.0f;
114 backgroundBlurRadius = 0;
115 api = -1;
116 hasColorTransform = false;
117 bufferTransform = 0;
118 requestedTransform.reset();
119 bufferData = std::make_shared<BufferData>();
120 bufferData->frameNumber = 0;
121 bufferData->acquireFence = sp<Fence>::make(-1);
122 acquireFenceTime = std::make_shared<FenceTime>(bufferData->acquireFence);
123 colorSpaceAgnostic = false;
124 frameRateSelectionPriority = Layer::PRIORITY_UNSET;
125 shadowRadius = 0.f;
126 fixedTransformHint = ui::Transform::ROT_INVALID;
127 destinationFrame.makeInvalid();
128 trustedOverlay = gui::TrustedOverlay::UNSET;
129 dropInputMode = gui::DropInputMode::NONE;
130 dimmingEnabled = true;
131 defaultFrameRateCompatibility = static_cast<int8_t>(scheduler::FrameRateCompatibility::Default);
132 frameRateCategory = static_cast<int8_t>(FrameRateCategory::Default);
133 frameRateCategorySmoothSwitchOnly = false;
134 frameRateSelectionStrategy =
135 static_cast<int8_t>(scheduler::LayerInfo::FrameRateSelectionStrategy::Propagate);
136 dataspace = ui::Dataspace::V0_SRGB;
137 gameMode = gui::GameMode::Unsupported;
138 requestedFrameRate = {};
139 cachingHint = gui::CachingHint::Enabled;
140
141 if (name.length() > 77) {
142 std::string shortened;
143 shortened.append(name, 0, 36);
144 shortened.append("[...]");
145 shortened.append(name, name.length() - 36);
146 debugName = std::move(shortened);
147 } else {
148 debugName = name;
149 }
150 }
151
merge(const ResolvedComposerState & resolvedComposerState)152 void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerState) {
153 bool transformWasValid = transformIsValid;
154 const uint32_t oldFlags = flags;
155 const half oldAlpha = color.a;
156 const bool hadBuffer = externalTexture != nullptr;
157 uint64_t oldFramenumber = hadBuffer ? bufferData->frameNumber : 0;
158 const ui::Size oldBufferSize = hadBuffer
159 ? ui::Size(externalTexture->getWidth(), externalTexture->getHeight())
160 : ui::Size();
161 const uint64_t oldUsageFlags = hadBuffer ? externalTexture->getUsage() : 0;
162 const bool oldBufferFormatOpaque = LayerSnapshot::isOpaqueFormat(
163 externalTexture ? externalTexture->getPixelFormat() : PIXEL_FORMAT_NONE);
164
165 const bool hadSideStream = sidebandStream != nullptr;
166 const layer_state_t& clientState = resolvedComposerState.state;
167 const bool hadSomethingToDraw = hasSomethingToDraw();
168 uint64_t clientChanges = what | layer_state_t::diff(clientState);
169 layer_state_t::merge(clientState);
170 what = clientChanges;
171 LLOGV(layerId, "requested=%" PRIu64 " flags=%" PRIu64 " ", clientState.what, clientChanges);
172
173 if (clientState.what & layer_state_t::eFlagsChanged) {
174 if ((oldFlags ^ flags) &
175 (layer_state_t::eLayerHidden | layer_state_t::eLayerOpaque |
176 layer_state_t::eLayerSecure)) {
177 changes |= RequestedLayerState::Changes::Visibility |
178 RequestedLayerState::Changes::VisibleRegion;
179 }
180 if ((oldFlags ^ flags) & layer_state_t::eIgnoreDestinationFrame) {
181 changes |= RequestedLayerState::Changes::Geometry;
182 }
183 if ((oldFlags ^ flags) & layer_state_t::eCanOccludePresentation) {
184 changes |= RequestedLayerState::Changes::Input;
185 }
186 }
187
188 if (clientState.what & layer_state_t::eBufferChanged) {
189 externalTexture = resolvedComposerState.externalTexture;
190 const bool hasBuffer = externalTexture != nullptr;
191 if (hasBuffer || hasBuffer != hadBuffer) {
192 changes |= RequestedLayerState::Changes::Buffer;
193 const ui::Size newBufferSize = hasBuffer
194 ? ui::Size(externalTexture->getWidth(), externalTexture->getHeight())
195 : ui::Size();
196 if (oldBufferSize != newBufferSize) {
197 changes |= RequestedLayerState::Changes::BufferSize;
198 changes |= RequestedLayerState::Changes::Geometry;
199 }
200 const uint64_t usageFlags = hasBuffer ? externalTexture->getUsage() : 0;
201 if (oldUsageFlags != usageFlags) {
202 changes |= RequestedLayerState::Changes::BufferUsageFlags;
203 }
204 }
205
206 if (hasBuffer != hadBuffer) {
207 changes |= RequestedLayerState::Changes::Geometry |
208 RequestedLayerState::Changes::VisibleRegion |
209 RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Input;
210 }
211
212 if (hasBuffer) {
213 const bool frameNumberChanged =
214 bufferData->flags.test(BufferData::BufferDataChange::frameNumberChanged);
215 const uint64_t frameNumber =
216 frameNumberChanged ? bufferData->frameNumber : oldFramenumber + 1;
217 bufferData->frameNumber = frameNumber;
218
219 if ((barrierProducerId > bufferData->producerId) ||
220 ((barrierProducerId == bufferData->producerId) &&
221 (barrierFrameNumber > bufferData->frameNumber))) {
222 ALOGE("Out of order buffers detected for %s producedId=%d frameNumber=%" PRIu64
223 " -> producedId=%d frameNumber=%" PRIu64,
224 getDebugString().c_str(), barrierProducerId, barrierFrameNumber,
225 bufferData->producerId, frameNumber);
226 TransactionTraceWriter::getInstance().invoke("out_of_order_buffers_",
227 /*overwrite=*/false);
228 }
229
230 barrierProducerId = std::max(bufferData->producerId, barrierProducerId);
231 barrierFrameNumber = std::max(bufferData->frameNumber, barrierFrameNumber);
232 }
233
234 const bool newBufferFormatOpaque = LayerSnapshot::isOpaqueFormat(
235 externalTexture ? externalTexture->getPixelFormat() : PIXEL_FORMAT_NONE);
236 if (newBufferFormatOpaque != oldBufferFormatOpaque) {
237 changes |= RequestedLayerState::Changes::Visibility |
238 RequestedLayerState::Changes::VisibleRegion;
239 }
240 }
241
242 if (clientState.what & layer_state_t::eSidebandStreamChanged) {
243 changes |= RequestedLayerState::Changes::SidebandStream;
244 const bool hasSideStream = sidebandStream != nullptr;
245 if (hasSideStream != hadSideStream) {
246 changes |= RequestedLayerState::Changes::Geometry |
247 RequestedLayerState::Changes::VisibleRegion |
248 RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Input;
249 }
250 }
251 if (what & (layer_state_t::eAlphaChanged)) {
252 if (oldAlpha == 0 || color.a == 0) {
253 changes |= RequestedLayerState::Changes::Visibility;
254 }
255 }
256
257 if (hadSomethingToDraw != hasSomethingToDraw()) {
258 changes |= RequestedLayerState::Changes::Visibility |
259 RequestedLayerState::Changes::VisibleRegion;
260 }
261 if (clientChanges & layer_state_t::HIERARCHY_CHANGES)
262 changes |= RequestedLayerState::Changes::Hierarchy;
263 if (clientChanges & layer_state_t::CONTENT_CHANGES)
264 changes |= RequestedLayerState::Changes::Content;
265 if (clientChanges & layer_state_t::GEOMETRY_CHANGES)
266 changes |= RequestedLayerState::Changes::Geometry;
267 if (clientChanges & layer_state_t::AFFECTS_CHILDREN)
268 changes |= RequestedLayerState::Changes::AffectsChildren;
269 if (clientChanges & layer_state_t::INPUT_CHANGES)
270 changes |= RequestedLayerState::Changes::Input;
271 if (clientChanges & layer_state_t::VISIBLE_REGION_CHANGES)
272 changes |= RequestedLayerState::Changes::VisibleRegion;
273 if (clientState.what & layer_state_t::eColorTransformChanged) {
274 static const mat4 identityMatrix = mat4();
275 hasColorTransform = colorTransform != identityMatrix;
276 }
277 if (clientState.what &
278 (layer_state_t::eLayerChanged | layer_state_t::eRelativeLayerChanged |
279 layer_state_t::eLayerStackChanged)) {
280 changes |= RequestedLayerState::Changes::Z;
281 }
282 if (clientState.what & layer_state_t::eReparent) {
283 changes |= RequestedLayerState::Changes::Parent;
284 parentId = resolvedComposerState.parentId;
285 mNotDefCmpState.parentSurfaceControlForChild = nullptr;
286 // Once a layer has be reparented, it cannot be placed at the root. It sounds odd
287 // but thats the existing logic and until we make this behavior more explicit, we need
288 // to maintain this logic.
289 canBeRoot = false;
290 }
291 if (clientState.what & layer_state_t::eRelativeLayerChanged) {
292 changes |= RequestedLayerState::Changes::RelativeParent;
293 relativeParentId = resolvedComposerState.relativeParentId;
294 isRelativeOf = true;
295 mNotDefCmpState.relativeLayerSurfaceControl = nullptr;
296 }
297 if ((clientState.what & layer_state_t::eLayerChanged ||
298 (clientState.what & layer_state_t::eReparent && parentId == UNASSIGNED_LAYER_ID)) &&
299 isRelativeOf) {
300 // clear out relz data
301 relativeParentId = UNASSIGNED_LAYER_ID;
302 isRelativeOf = false;
303 changes |= RequestedLayerState::Changes::RelativeParent;
304 }
305 if (clientState.what & layer_state_t::eReparent && parentId == relativeParentId) {
306 // provide a hint that we are are now a direct child and not a relative child.
307 changes |= RequestedLayerState::Changes::RelativeParent;
308 }
309 if (clientState.what & layer_state_t::eInputInfoChanged) {
310 touchCropId = resolvedComposerState.touchCropId;
311 editWindowInfo()->touchableRegionCropHandle.clear();
312 }
313 if (clientState.what & layer_state_t::eStretchChanged) {
314 stretchEffect.sanitize();
315 }
316
317 if (clientState.what & layer_state_t::eHasListenerCallbacksChanged) {
318 // TODO(b/238781169) handle callbacks
319 }
320
321 if (clientState.what & layer_state_t::ePositionChanged) {
322 requestedTransform.set(x, y);
323 }
324
325 if (clientState.what & layer_state_t::eMatrixChanged) {
326 requestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
327 }
328 if (clientState.what & layer_state_t::eMetadataChanged) {
329 const int32_t requestedGameMode =
330 clientState.metadata.getInt32(gui::METADATA_GAME_MODE, -1);
331 if (requestedGameMode != -1) {
332 // The transaction will be received on the Task layer and needs to be applied to all
333 // child layers.
334 if (static_cast<int32_t>(gameMode) != requestedGameMode) {
335 gameMode = static_cast<gui::GameMode>(requestedGameMode);
336 changes |= RequestedLayerState::Changes::GameMode;
337 }
338 }
339 changes |= RequestedLayerState::Changes::Metadata;
340 }
341 if (clientState.what & layer_state_t::eFrameRateChanged) {
342 const auto compatibility =
343 Layer::FrameRate::convertCompatibility(clientState.frameRateCompatibility);
344 const auto strategy = Layer::FrameRate::convertChangeFrameRateStrategy(
345 clientState.changeFrameRateStrategy);
346 requestedFrameRate.vote =
347 Layer::FrameRate::FrameRateVote(Fps::fromValue(clientState.frameRate),
348 compatibility, strategy);
349 changes |= RequestedLayerState::Changes::FrameRate;
350 }
351 if (clientState.what & layer_state_t::eFrameRateCategoryChanged) {
352 const auto category = Layer::FrameRate::convertCategory(clientState.frameRateCategory);
353 requestedFrameRate.category = category;
354 changes |= RequestedLayerState::Changes::FrameRate;
355 }
356
357 if (clientState.what & layer_state_t::eClientDrawnCornerRadiusChanged) {
358 clientDrawnCornerRadius = clientState.clientDrawnCornerRadius;
359 changes |= RequestedLayerState::Changes::Geometry;
360 }
361
362 // We can't just check requestedTransform here because LayerSnapshotBuilder uses
363 // getTransform which reads destinationFrame or buffer dimensions.
364 // Display rotation does not affect validity so just use ROT_0.
365 transformIsValid = LayerSnapshot::isTransformValid(getTransform(ui::Transform::ROT_0));
366 if (!transformWasValid && transformIsValid) {
367 changes |= RequestedLayerState::Changes::Visibility;
368 }
369 }
370
getUnrotatedBufferSize(uint32_t displayRotationFlags) const371 ui::Size RequestedLayerState::getUnrotatedBufferSize(uint32_t displayRotationFlags) const {
372 uint32_t bufferWidth = externalTexture->getWidth();
373 uint32_t bufferHeight = externalTexture->getHeight();
374 // Undo any transformations on the buffer.
375 if (bufferTransform & ui::Transform::ROT_90) {
376 std::swap(bufferWidth, bufferHeight);
377 }
378 if (transformToDisplayInverse) {
379 if (displayRotationFlags & ui::Transform::ROT_90) {
380 std::swap(bufferWidth, bufferHeight);
381 }
382 }
383 return {bufferWidth, bufferHeight};
384 }
385
getTransform(uint32_t displayRotationFlags) const386 ui::Transform RequestedLayerState::getTransform(uint32_t displayRotationFlags) const {
387 if ((flags & layer_state_t::eIgnoreDestinationFrame) || destinationFrame.isEmpty()) {
388 // If destination frame is not set, use the requested transform set via
389 // Transaction::setPosition and Transaction::setMatrix.
390 return requestedTransform;
391 }
392
393 Rect destRect = destinationFrame;
394 int32_t destW = destRect.width();
395 int32_t destH = destRect.height();
396 if (destRect.left < 0) {
397 destRect.left = 0;
398 destRect.right = destW;
399 }
400 if (destRect.top < 0) {
401 destRect.top = 0;
402 destRect.bottom = destH;
403 }
404
405 if (!externalTexture) {
406 ui::Transform transform;
407 transform.set(static_cast<float>(destRect.left), static_cast<float>(destRect.top));
408 return transform;
409 }
410
411 ui::Size bufferSize = getUnrotatedBufferSize(displayRotationFlags);
412
413 float sx = static_cast<float>(destW) / static_cast<float>(bufferSize.width);
414 float sy = static_cast<float>(destH) / static_cast<float>(bufferSize.height);
415 ui::Transform transform;
416 transform.set(sx, 0, 0, sy);
417 transform.set(static_cast<float>(destRect.left), static_cast<float>(destRect.top));
418 return transform;
419 }
420
getDebugString() const421 std::string RequestedLayerState::getDebugString() const {
422 std::stringstream debug;
423 debug << "RequestedLayerState{" << name;
424 if (parentId != UNASSIGNED_LAYER_ID) debug << " parentId=" << parentId;
425 if (relativeParentId != UNASSIGNED_LAYER_ID) debug << " relativeParentId=" << relativeParentId;
426 if (!mirrorIds.empty()) debug << " mirrorId=" << layerIdsToString(mirrorIds);
427 if (!handleAlive) debug << " !handle";
428 if (z != 0) debug << " z=" << z;
429 if (layerStack.id != 0) debug << " layerStack=" << layerStack.id;
430 debug << "}";
431 return debug.str();
432 }
433
operator <<(std::ostream & out,const scheduler::LayerInfo::FrameRate & obj)434 std::ostream& operator<<(std::ostream& out, const scheduler::LayerInfo::FrameRate& obj) {
435 out << obj.vote.rate;
436 out << " " << ftl::enum_string_full(obj.vote.type);
437 out << " " << ftl::enum_string_full(obj.category);
438 return out;
439 }
440
operator <<(std::ostream & out,const RequestedLayerState & obj)441 std::ostream& operator<<(std::ostream& out, const RequestedLayerState& obj) {
442 out << obj.debugName;
443 if (obj.relativeParentId != UNASSIGNED_LAYER_ID) out << " parent=" << obj.parentId;
444 if (!obj.handleAlive) out << " handleNotAlive";
445 if (obj.requestedFrameRate.isValid())
446 out << " requestedFrameRate: {" << obj.requestedFrameRate << "}";
447 if (obj.dropInputMode != gui::DropInputMode::NONE)
448 out << " dropInputMode=" << static_cast<uint32_t>(obj.dropInputMode);
449 return out;
450 }
451
getDebugStringShort() const452 std::string RequestedLayerState::getDebugStringShort() const {
453 return "[" + std::to_string(id) + "]" + name;
454 }
455
canBeDestroyed() const456 bool RequestedLayerState::canBeDestroyed() const {
457 return !handleAlive && parentId == UNASSIGNED_LAYER_ID;
458 }
isRoot() const459 bool RequestedLayerState::isRoot() const {
460 return canBeRoot && parentId == UNASSIGNED_LAYER_ID;
461 }
isHiddenByPolicy() const462 bool RequestedLayerState::isHiddenByPolicy() const {
463 return (flags & layer_state_t::eLayerHidden) == layer_state_t::eLayerHidden;
464 };
getColor() const465 half4 RequestedLayerState::getColor() const {
466 if (sidebandStream || externalTexture) {
467 return {0._hf, 0._hf, 0._hf, color.a};
468 }
469 return color;
470 }
getBufferSize(uint32_t displayRotationFlags) const471 Rect RequestedLayerState::getBufferSize(uint32_t displayRotationFlags) const {
472 // for buffer state layers we use the display frame size as the buffer size.
473 if (!externalTexture) {
474 return Rect::INVALID_RECT;
475 }
476
477 uint32_t bufWidth = externalTexture->getWidth();
478 uint32_t bufHeight = externalTexture->getHeight();
479
480 // Undo any transformations on the buffer and return the result.
481 if (bufferTransform & ui::Transform::ROT_90) {
482 std::swap(bufWidth, bufHeight);
483 }
484
485 if (transformToDisplayInverse) {
486 uint32_t invTransform = displayRotationFlags;
487 if (invTransform & ui::Transform::ROT_90) {
488 std::swap(bufWidth, bufHeight);
489 }
490 }
491
492 return Rect(0, 0, static_cast<int32_t>(bufWidth), static_cast<int32_t>(bufHeight));
493 }
494
getCroppedBufferSize(const Rect & bufferSize) const495 FloatRect RequestedLayerState::getCroppedBufferSize(const Rect& bufferSize) const {
496 FloatRect size = bufferSize.toFloatRect();
497 if (!crop.isEmpty() && size.isValid()) {
498 size = size.intersect(crop);
499 } else if (!crop.isEmpty()) {
500 size = crop;
501 }
502 return size;
503 }
504
getBufferCrop() const505 Rect RequestedLayerState::getBufferCrop() const {
506 // this is the crop rectangle that applies to the buffer
507 // itself (as opposed to the window)
508 if (!bufferCrop.isEmpty() && externalTexture != nullptr) {
509 // if the buffer crop is defined and there's a valid buffer, intersect buffer size and crop
510 // since the crop should never exceed the size of the buffer.
511 Rect sizeAndCrop;
512 externalTexture->getBounds().intersect(bufferCrop, &sizeAndCrop);
513 return sizeAndCrop;
514 } else if (externalTexture != nullptr) {
515 // otherwise we use the whole buffer
516 return externalTexture->getBounds();
517 } else if (!bufferCrop.isEmpty()) {
518 // if the buffer crop is defined, we use that
519 return bufferCrop;
520 } else {
521 // if we don't have a buffer yet, we use an empty/invalid crop
522 return Rect();
523 }
524 }
525
getCompositionType() const526 aidl::android::hardware::graphics::composer3::Composition RequestedLayerState::getCompositionType()
527 const {
528 using aidl::android::hardware::graphics::composer3::Composition;
529 // TODO(b/238781169) check about sidestream ready flag
530 if (sidebandStream.get()) {
531 return Composition::SIDEBAND;
532 }
533 if (!externalTexture) {
534 return Composition::SOLID_COLOR;
535 }
536 if (flags & layer_state_t::eLayerIsDisplayDecoration) {
537 return Composition::DISPLAY_DECORATION;
538 }
539 if (flags & layer_state_t::eLayerIsRefreshRateIndicator) {
540 return Composition::REFRESH_RATE_INDICATOR;
541 }
542 if (potentialCursor) {
543 return Composition::CURSOR;
544 }
545 return Composition::DEVICE;
546 }
547
reduce(const Rect & win,const Region & exclude)548 Rect RequestedLayerState::reduce(const Rect& win, const Region& exclude) {
549 if (CC_LIKELY(exclude.isEmpty())) {
550 return win;
551 }
552 if (exclude.isRect()) {
553 return win.reduce(exclude.getBounds());
554 }
555 return Region(win).subtract(exclude).getBounds();
556 }
557
558 // Returns true if the layer has a relative parent that is not its own parent. This is an input
559 // error from the client, and this check allows us to handle it gracefully. If both parentId and
560 // relativeParentId is unassigned then the layer does not have a valid relative parent.
561 // If the relative parentid is unassigned, the layer will be considered relative but won't be
562 // reachable.
hasValidRelativeParent() const563 bool RequestedLayerState::hasValidRelativeParent() const {
564 return isRelativeOf &&
565 (parentId != relativeParentId || relativeParentId == UNASSIGNED_LAYER_ID);
566 }
567
hasInputInfo() const568 bool RequestedLayerState::hasInputInfo() const {
569 const auto& windowInfo = getWindowInfo();
570 return windowInfo.token != nullptr ||
571 windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL);
572 }
573
needsInputInfo() const574 bool RequestedLayerState::needsInputInfo() const {
575 if (potentialCursor) {
576 return false;
577 }
578
579 if (hasBufferOrSidebandStream() || fillsColor()) {
580 return true;
581 }
582
583 const auto& windowInfo = getWindowInfo();
584 return windowInfo.token != nullptr ||
585 windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL);
586 }
587
hasBufferOrSidebandStream() const588 bool RequestedLayerState::hasBufferOrSidebandStream() const {
589 return ((sidebandStream != nullptr) || (externalTexture != nullptr));
590 }
591
fillsColor() const592 bool RequestedLayerState::fillsColor() const {
593 return !hasBufferOrSidebandStream() && color.r >= 0.0_hf && color.g >= 0.0_hf &&
594 color.b >= 0.0_hf;
595 }
596
hasBlur() const597 bool RequestedLayerState::hasBlur() const {
598 return backgroundBlurRadius > 0 || blurRegions.size() > 0;
599 }
600
hasFrameUpdate() const601 bool RequestedLayerState::hasFrameUpdate() const {
602 return what & layer_state_t::CONTENT_DIRTY &&
603 (externalTexture || bgColorLayerId != UNASSIGNED_LAYER_ID);
604 }
605
hasReadyFrame() const606 bool RequestedLayerState::hasReadyFrame() const {
607 return hasFrameUpdate() || changes.test(Changes::SidebandStream) || autoRefresh;
608 }
609
hasSidebandStreamFrame() const610 bool RequestedLayerState::hasSidebandStreamFrame() const {
611 return hasFrameUpdate() && sidebandStream.get();
612 }
613
willReleaseBufferOnLatch() const614 bool RequestedLayerState::willReleaseBufferOnLatch() const {
615 return changes.test(Changes::Buffer) && !externalTexture;
616 }
617
backpressureEnabled() const618 bool RequestedLayerState::backpressureEnabled() const {
619 return flags & layer_state_t::eEnableBackpressure;
620 }
621
isSimpleBufferUpdate(const layer_state_t & s) const622 bool RequestedLayerState::isSimpleBufferUpdate(const layer_state_t& s) const {
623 static constexpr uint64_t requiredFlags = layer_state_t::eBufferChanged;
624 if ((s.what & requiredFlags) != requiredFlags) {
625 SFTRACE_FORMAT_INSTANT("%s: false [missing required flags 0x%" PRIx64 "]", __func__,
626 (s.what | requiredFlags) & ~s.what);
627 return false;
628 }
629
630 const uint64_t deniedFlags = layer_state_t::eProducerDisconnect | layer_state_t::eLayerChanged |
631 layer_state_t::eRelativeLayerChanged | layer_state_t::eTransparentRegionChanged |
632 layer_state_t::eBlurRegionsChanged | layer_state_t::eLayerStackChanged |
633 layer_state_t::eReparent |
634 (FlagManager::getInstance().latch_unsignaled_with_auto_refresh_changed()
635 ? 0
636 : (layer_state_t::eAutoRefreshChanged | layer_state_t::eFlagsChanged));
637 if (s.what & deniedFlags) {
638 SFTRACE_FORMAT_INSTANT("%s: false [has denied flags 0x%" PRIx64 "]", __func__,
639 s.what & deniedFlags);
640 return false;
641 }
642
643 const uint64_t changedFlags = diff(s);
644 const uint64_t deniedChanges = layer_state_t::ePositionChanged | layer_state_t::eAlphaChanged |
645 layer_state_t::eColorTransformChanged | layer_state_t::eBackgroundColorChanged |
646 layer_state_t::eMatrixChanged | layer_state_t::eCornerRadiusChanged |
647 layer_state_t::eClientDrawnCornerRadiusChanged |
648 layer_state_t::eBackgroundBlurRadiusChanged | layer_state_t::eBufferTransformChanged |
649 layer_state_t::eTransformToDisplayInverseChanged | layer_state_t::eCropChanged |
650 layer_state_t::eDataspaceChanged | layer_state_t::eHdrMetadataChanged |
651 layer_state_t::eSidebandStreamChanged | layer_state_t::eColorSpaceAgnosticChanged |
652 layer_state_t::eShadowRadiusChanged | layer_state_t::eFixedTransformHintChanged |
653 layer_state_t::eTrustedOverlayChanged | layer_state_t::eStretchChanged |
654 layer_state_t::eEdgeExtensionChanged | layer_state_t::eBufferCropChanged |
655 layer_state_t::eDestinationFrameChanged | layer_state_t::eDimmingEnabledChanged |
656 layer_state_t::eExtendedRangeBrightnessChanged |
657 layer_state_t::eDesiredHdrHeadroomChanged | layer_state_t::eLutsChanged |
658 (FlagManager::getInstance().latch_unsignaled_with_auto_refresh_changed()
659 ? layer_state_t::eFlagsChanged
660 : 0);
661 if (changedFlags & deniedChanges) {
662 SFTRACE_FORMAT_INSTANT("%s: false [has denied changes flags 0x%" PRIx64 "]", __func__,
663 changedFlags & deniedChanges);
664 return false;
665 }
666
667 return true;
668 }
669
isProtected() const670 bool RequestedLayerState::isProtected() const {
671 return externalTexture && externalTexture->getUsage() & GRALLOC_USAGE_PROTECTED;
672 }
673
hasSomethingToDraw() const674 bool RequestedLayerState::hasSomethingToDraw() const {
675 return externalTexture != nullptr || sidebandStream != nullptr || shadowRadius > 0.f ||
676 backgroundBlurRadius > 0 || blurRegions.size() > 0 ||
677 (color.r >= 0.0_hf && color.g >= 0.0_hf && color.b >= 0.0_hf);
678 }
679
clearChanges()680 void RequestedLayerState::clearChanges() {
681 what = 0;
682 changes.clear();
683 }
684
685 } // namespace android::surfaceflinger::frontend
686