blob: dcc16e8db7f64d0b67e2ed4732adb7b51b205994 [file] [log] [blame]
Vishnu Nairdc4d31b2022-11-17 03:20:58 +00001/*
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
17#include "FrontEnd/LayerCreationArgs.h"
18#define ATRACE_TAG ATRACE_TAG_GRAPHICS
19#undef LOG_TAG
20#define LOG_TAG "RequestedLayerState"
21
22#include <private/android_filesystem_config.h>
23#include <sys/types.h>
24
25#include "Layer.h"
26#include "LayerHandle.h"
27#include "RequestedLayerState.h"
28
29namespace android::surfaceflinger::frontend {
30using ftl::Flags;
31using namespace ftl::flag_operators;
32
33namespace {
34uint32_t getLayerIdFromSurfaceControl(sp<SurfaceControl> surfaceControl) {
35 if (!surfaceControl) {
36 return UNASSIGNED_LAYER_ID;
37 }
38
39 return LayerHandle::getLayerId(surfaceControl->getHandle());
40}
41
42std::string layerIdToString(uint32_t layerId) {
Vishnu Nair04f89692022-11-16 23:21:05 +000043 return layerId == UNASSIGNED_LAYER_ID ? "none" : std::to_string(layerId);
Vishnu Nairdc4d31b2022-11-17 03:20:58 +000044}
45
46} // namespace
47
48RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args)
49 : id(args.sequence),
50 name(args.name),
51 canBeRoot(args.addToRoot),
52 layerCreationFlags(args.flags),
53 textureName(args.textureName),
54 ownerUid(args.ownerUid),
55 ownerPid(args.ownerPid) {
56 layerId = static_cast<int32_t>(args.sequence);
57 changes |= RequestedLayerState::Changes::Created;
58 metadata.merge(args.metadata);
59 changes |= RequestedLayerState::Changes::Metadata;
60 handleAlive = true;
61 parentId = LayerHandle::getLayerId(args.parentHandle.promote());
62 mirrorId = LayerHandle::getLayerId(args.mirrorLayerHandle.promote());
63 if (mirrorId != UNASSIGNED_LAYER_ID) {
64 changes |= RequestedLayerState::Changes::Mirror;
65 }
66
67 flags = 0;
68 if (args.flags & ISurfaceComposerClient::eHidden) flags |= layer_state_t::eLayerHidden;
69 if (args.flags & ISurfaceComposerClient::eOpaque) flags |= layer_state_t::eLayerOpaque;
70 if (args.flags & ISurfaceComposerClient::eSecure) flags |= layer_state_t::eLayerSecure;
71 if (args.flags & ISurfaceComposerClient::eSkipScreenshot) {
72 flags |= layer_state_t::eLayerSkipScreenshot;
73 }
74 premultipliedAlpha = !(args.flags & ISurfaceComposerClient::eNonPremultiplied);
75 potentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;
76 protectedByApp = args.flags & ISurfaceComposerClient::eProtectedByApp;
77 if (args.flags & ISurfaceComposerClient::eNoColorFill) {
78 // Set an invalid color so there is no color fill.
79 // (b/259981098) use an explicit flag instead of relying on invalid values.
80 color.r = -1.0_hf;
81 color.g = -1.0_hf;
82 color.b = -1.0_hf;
83 } else {
84 color.rgb = {0.0_hf, 0.0_hf, 0.0_hf};
85 }
86 color.a = 1.0f;
87
88 crop.makeInvalid();
89 z = 0;
90 layerStack = ui::DEFAULT_LAYER_STACK;
91 transformToDisplayInverse = false;
92 dataspace = ui::Dataspace::UNKNOWN;
93 dataspaceRequested = false;
94 hdrMetadata.validTypes = 0;
95 surfaceDamageRegion = Region::INVALID_REGION;
96 cornerRadius = 0.0f;
97 backgroundBlurRadius = 0;
98 api = -1;
99 hasColorTransform = false;
100 bufferTransform = 0;
101 requestedTransform.reset();
102 bufferData = std::make_shared<BufferData>();
103 bufferData->frameNumber = 0;
104 bufferData->acquireFence = sp<Fence>::make(-1);
105 acquireFenceTime = std::make_shared<FenceTime>(bufferData->acquireFence);
106 colorSpaceAgnostic = false;
107 frameRateSelectionPriority = Layer::PRIORITY_UNSET;
108 shadowRadius = 0.f;
109 fixedTransformHint = ui::Transform::ROT_INVALID;
110 destinationFrame.makeInvalid();
111 isTrustedOverlay = false;
112 dropInputMode = gui::DropInputMode::NONE;
113 dimmingEnabled = true;
114 defaultFrameRateCompatibility =
115 static_cast<int8_t>(scheduler::LayerInfo::FrameRateCompatibility::Default);
116 dataspace = ui::Dataspace::V0_SRGB;
117}
118
119void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerState) {
120 bool oldFlags = flags;
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000121 Rect oldBufferSize = getBufferSize(0);
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000122 const layer_state_t& clientState = resolvedComposerState.state;
123
124 uint64_t clientChanges = what | layer_state_t::diff(clientState);
125 layer_state_t::merge(clientState);
126 what = clientChanges;
127
128 if (clientState.what & layer_state_t::eFlagsChanged) {
129 if ((oldFlags ^ flags) & layer_state_t::eLayerHidden) {
130 changes |= RequestedLayerState::Changes::Visibility;
131 }
132 if ((oldFlags ^ flags) & layer_state_t::eIgnoreDestinationFrame) {
133 changes |= RequestedLayerState::Changes::Geometry;
134 }
135 }
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000136 if (clientState.what & layer_state_t::eBufferChanged && oldBufferSize != getBufferSize(0)) {
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000137 changes |= RequestedLayerState::Changes::Geometry;
138 }
139 if (clientChanges & layer_state_t::HIERARCHY_CHANGES)
140 changes |= RequestedLayerState::Changes::Hierarchy;
141 if (clientChanges & layer_state_t::CONTENT_CHANGES)
142 changes |= RequestedLayerState::Changes::Content;
143 if (clientChanges & layer_state_t::GEOMETRY_CHANGES)
144 changes |= RequestedLayerState::Changes::Geometry;
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000145 if (clientChanges & layer_state_t::AFFECTS_CHILDREN)
146 changes |= RequestedLayerState::Changes::AffectsChildren;
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000147
148 if (clientState.what & layer_state_t::eColorTransformChanged) {
149 static const mat4 identityMatrix = mat4();
150 hasColorTransform = colorTransform != identityMatrix;
151 }
Vishnu Nair04f89692022-11-16 23:21:05 +0000152 if (clientState.what & (layer_state_t::eLayerChanged | layer_state_t::eRelativeLayerChanged)) {
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000153 changes |= RequestedLayerState::Changes::Z;
154 }
155 if (clientState.what & layer_state_t::eReparent) {
156 changes |= RequestedLayerState::Changes::Parent;
157 parentId = getLayerIdFromSurfaceControl(clientState.parentSurfaceControlForChild);
158 parentSurfaceControlForChild = nullptr;
Vishnu Nair04f89692022-11-16 23:21:05 +0000159 // Once a layer has be reparented, it cannot be placed at the root. It sounds odd
160 // but thats the existing logic and until we make this behavior more explicit, we need
161 // to maintain this logic.
162 canBeRoot = false;
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000163 }
164 if (clientState.what & layer_state_t::eRelativeLayerChanged) {
165 changes |= RequestedLayerState::Changes::RelativeParent;
166 relativeParentId = getLayerIdFromSurfaceControl(clientState.relativeLayerSurfaceControl);
167 isRelativeOf = true;
168 relativeLayerSurfaceControl = nullptr;
169 }
170 if ((clientState.what & layer_state_t::eLayerChanged ||
171 (clientState.what & layer_state_t::eReparent && parentId == UNASSIGNED_LAYER_ID)) &&
172 isRelativeOf) {
173 // clear out relz data
174 relativeParentId = UNASSIGNED_LAYER_ID;
175 isRelativeOf = false;
176 changes |= RequestedLayerState::Changes::RelativeParent;
177 }
178 if (clientState.what & layer_state_t::eReparent && parentId == relativeParentId) {
179 // provide a hint that we are are now a direct child and not a relative child.
180 changes |= RequestedLayerState::Changes::RelativeParent;
181 }
182 if (clientState.what & layer_state_t::eInputInfoChanged) {
183 wp<IBinder>& touchableRegionCropHandle =
184 windowInfoHandle->editInfo()->touchableRegionCropHandle;
185 touchCropId = LayerHandle::getLayerId(touchableRegionCropHandle.promote());
186 changes |= RequestedLayerState::Changes::Input;
187 touchableRegionCropHandle.clear();
188 }
189 if (clientState.what & layer_state_t::eStretchChanged) {
190 stretchEffect.sanitize();
191 }
192
193 if (clientState.what & layer_state_t::eHasListenerCallbacksChanged) {
194 // TODO(b/238781169) handle callbacks
195 }
196
197 if (clientState.what & layer_state_t::eBufferChanged) {
198 externalTexture = resolvedComposerState.externalTexture;
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000199 }
200
201 if (clientState.what & layer_state_t::ePositionChanged) {
202 requestedTransform.set(x, y);
203 }
204
205 if (clientState.what & layer_state_t::eMatrixChanged) {
206 requestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
207 }
208}
209
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000210ui::Size RequestedLayerState::getUnrotatedBufferSize(uint32_t displayRotationFlags) const {
211 uint32_t bufferWidth = externalTexture->getWidth();
212 uint32_t bufferHeight = externalTexture->getHeight();
213 // Undo any transformations on the buffer.
214 if (bufferTransform & ui::Transform::ROT_90) {
215 std::swap(bufferWidth, bufferHeight);
216 }
217 if (transformToDisplayInverse) {
218 if (displayRotationFlags & ui::Transform::ROT_90) {
219 std::swap(bufferWidth, bufferHeight);
220 }
221 }
222 return {bufferWidth, bufferHeight};
223}
224
225ui::Transform RequestedLayerState::getTransform(uint32_t displayRotationFlags) const {
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000226 if ((flags & layer_state_t::eIgnoreDestinationFrame) || destinationFrame.isEmpty()) {
227 // If destination frame is not set, use the requested transform set via
228 // Transaction::setPosition and Transaction::setMatrix.
229 return requestedTransform;
230 }
231
232 Rect destRect = destinationFrame;
233 int32_t destW = destRect.width();
234 int32_t destH = destRect.height();
235 if (destRect.left < 0) {
236 destRect.left = 0;
237 destRect.right = destW;
238 }
239 if (destRect.top < 0) {
240 destRect.top = 0;
241 destRect.bottom = destH;
242 }
243
244 if (!externalTexture) {
245 ui::Transform transform;
246 transform.set(static_cast<float>(destRect.left), static_cast<float>(destRect.top));
247 return transform;
248 }
249
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000250 ui::Size bufferSize = getUnrotatedBufferSize(displayRotationFlags);
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000251
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000252 float sx = static_cast<float>(destW) / static_cast<float>(bufferSize.width);
253 float sy = static_cast<float>(destH) / static_cast<float>(bufferSize.height);
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000254 ui::Transform transform;
255 transform.set(sx, 0, 0, sy);
256 transform.set(static_cast<float>(destRect.left), static_cast<float>(destRect.top));
257 return transform;
258}
259
260std::string RequestedLayerState::getDebugString() const {
261 return "[" + std::to_string(id) + "]" + name + ",parent=" + layerIdToString(parentId) +
262 ",relativeParent=" + layerIdToString(relativeParentId) +
263 ",isRelativeOf=" + std::to_string(isRelativeOf) +
264 ",mirrorId=" + layerIdToString(mirrorId) +
Vishnu Nair04f89692022-11-16 23:21:05 +0000265 ",handleAlive=" + std::to_string(handleAlive) + ",z=" + std::to_string(z);
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000266}
267
268std::string RequestedLayerState::getDebugStringShort() const {
269 return "[" + std::to_string(id) + "]" + name;
270}
271
272bool RequestedLayerState::canBeDestroyed() const {
273 return !handleAlive && parentId == UNASSIGNED_LAYER_ID;
274}
275bool RequestedLayerState::isRoot() const {
276 return canBeRoot && parentId == UNASSIGNED_LAYER_ID;
277}
278bool RequestedLayerState::isHiddenByPolicy() const {
279 return (flags & layer_state_t::eLayerHidden) == layer_state_t::eLayerHidden;
280};
281half4 RequestedLayerState::getColor() const {
282 if ((sidebandStream != nullptr) || (externalTexture != nullptr)) {
283 return {0._hf, 0._hf, 0._hf, color.a};
284 }
285 return color;
286}
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000287Rect RequestedLayerState::getBufferSize(uint32_t displayRotationFlags) const {
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000288 // for buffer state layers we use the display frame size as the buffer size.
289 if (!externalTexture) {
290 return Rect::INVALID_RECT;
291 }
292
293 uint32_t bufWidth = externalTexture->getWidth();
294 uint32_t bufHeight = externalTexture->getHeight();
295
296 // Undo any transformations on the buffer and return the result.
297 if (bufferTransform & ui::Transform::ROT_90) {
298 std::swap(bufWidth, bufHeight);
299 }
300
301 if (transformToDisplayInverse) {
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000302 uint32_t invTransform = displayRotationFlags;
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000303 if (invTransform & ui::Transform::ROT_90) {
304 std::swap(bufWidth, bufHeight);
305 }
306 }
307
308 return Rect(0, 0, static_cast<int32_t>(bufWidth), static_cast<int32_t>(bufHeight));
309}
310
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000311Rect RequestedLayerState::getCroppedBufferSize(const Rect& bufferSize) const {
312 Rect size = bufferSize;
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000313 if (!crop.isEmpty() && size.isValid()) {
314 size.intersect(crop, &size);
315 } else if (!crop.isEmpty()) {
316 size = crop;
317 }
318 return size;
319}
320
321Rect RequestedLayerState::getBufferCrop() const {
322 // this is the crop rectangle that applies to the buffer
323 // itself (as opposed to the window)
324 if (!bufferCrop.isEmpty()) {
325 // if the buffer crop is defined, we use that
326 return bufferCrop;
327 } else if (externalTexture != nullptr) {
328 // otherwise we use the whole buffer
329 return externalTexture->getBounds();
330 } else {
331 // if we don't have a buffer yet, we use an empty/invalid crop
332 return Rect();
333 }
334}
335
336aidl::android::hardware::graphics::composer3::Composition RequestedLayerState::getCompositionType()
337 const {
338 using aidl::android::hardware::graphics::composer3::Composition;
339 // TODO(b/238781169) check about sidestream ready flag
340 if (sidebandStream.get()) {
341 return Composition::SIDEBAND;
342 }
343 if (!externalTexture) {
344 return Composition::SOLID_COLOR;
345 }
346 if (flags & layer_state_t::eLayerIsDisplayDecoration) {
347 return Composition::DISPLAY_DECORATION;
348 }
349 if (potentialCursor) {
350 return Composition::CURSOR;
351 }
352 return Composition::DEVICE;
353}
354
355Rect RequestedLayerState::reduce(const Rect& win, const Region& exclude) {
356 if (CC_LIKELY(exclude.isEmpty())) {
357 return win;
358 }
359 if (exclude.isRect()) {
360 return win.reduce(exclude.getBounds());
361 }
362 return Region(win).subtract(exclude).getBounds();
363}
364
Vishnu Nair04f89692022-11-16 23:21:05 +0000365// Returns true if the layer has a relative parent that is not its own parent. This is an input
366// error from the client, and this check allows us to handle it gracefully. If both parentId and
367// relativeParentId is unassigned then the layer does not have a valid relative parent.
368// If the relative parentid is unassigned, the layer will be considered relative but won't be
369// reachable.
370bool RequestedLayerState::hasValidRelativeParent() const {
371 return isRelativeOf && parentId != relativeParentId;
372}
373
Vishnu Nair8fc721b2022-12-22 20:06:32 +0000374bool RequestedLayerState::hasInputInfo() const {
375 if (!windowInfoHandle) {
376 return false;
377 }
378 const auto windowInfo = windowInfoHandle->getInfo();
379 return windowInfo->token != nullptr ||
380 windowInfo->inputConfig.test(gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL);
381}
382
Vishnu Nairdc4d31b2022-11-17 03:20:58 +0000383} // namespace android::surfaceflinger::frontend