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