• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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