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