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