• 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 <log/log.h>
23 #include <private/android_filesystem_config.h>
24 #include <sys/types.h>
25 
26 #include "Layer.h"
27 #include "LayerCreationArgs.h"
28 #include "LayerLog.h"
29 #include "RequestedLayerState.h"
30 
31 namespace android::surfaceflinger::frontend {
32 using ftl::Flags;
33 using namespace ftl::flag_operators;
34 
35 namespace {
layerIdsToString(const std::vector<uint32_t> & layerIds)36 std::string layerIdsToString(const std::vector<uint32_t>& layerIds) {
37     std::stringstream stream;
38     stream << "{";
39     for (auto layerId : layerIds) {
40         stream << layerId << ",";
41     }
42     stream << "}";
43     return stream.str();
44 }
45 
46 } // namespace
47 
RequestedLayerState(const LayerCreationArgs & args)48 RequestedLayerState::RequestedLayerState(const LayerCreationArgs& args)
49       : id(args.sequence),
50         name(args.name + "#" + std::to_string(args.sequence)),
51         canBeRoot(args.addToRoot),
52         layerCreationFlags(args.flags),
53         textureName(args.textureName),
54         ownerUid(args.ownerUid),
55         ownerPid(args.ownerPid),
56         parentId(args.parentId),
57         layerIdToMirror(args.layerIdToMirror) {
58     layerId = static_cast<int32_t>(args.sequence);
59     changes |= RequestedLayerState::Changes::Created;
60     metadata.merge(args.metadata);
61     changes |= RequestedLayerState::Changes::Metadata;
62     handleAlive = true;
63     if (parentId != UNASSIGNED_LAYER_ID) {
64         canBeRoot = false;
65     }
66     if (layerIdToMirror != UNASSIGNED_LAYER_ID) {
67         changes |= RequestedLayerState::Changes::Mirror;
68     } else if (args.layerStackToMirror != ui::INVALID_LAYER_STACK) {
69         layerStackToMirror = args.layerStackToMirror;
70         changes |= RequestedLayerState::Changes::Mirror;
71     }
72 
73     flags = 0;
74     if (args.flags & ISurfaceComposerClient::eHidden) flags |= layer_state_t::eLayerHidden;
75     if (args.flags & ISurfaceComposerClient::eOpaque) flags |= layer_state_t::eLayerOpaque;
76     if (args.flags & ISurfaceComposerClient::eSecure) flags |= layer_state_t::eLayerSecure;
77     if (args.flags & ISurfaceComposerClient::eSkipScreenshot) {
78         flags |= layer_state_t::eLayerSkipScreenshot;
79     }
80     premultipliedAlpha = !(args.flags & ISurfaceComposerClient::eNonPremultiplied);
81     potentialCursor = args.flags & ISurfaceComposerClient::eCursorWindow;
82     protectedByApp = args.flags & ISurfaceComposerClient::eProtectedByApp;
83     if (args.flags & ISurfaceComposerClient::eNoColorFill) {
84         // Set an invalid color so there is no color fill.
85         // (b/259981098) use an explicit flag instead of relying on invalid values.
86         color.r = -1.0_hf;
87         color.g = -1.0_hf;
88         color.b = -1.0_hf;
89     } else {
90         color.rgb = {0.0_hf, 0.0_hf, 0.0_hf};
91     }
92     LLOGV(layerId, "Created %s flags=%d", getDebugString().c_str(), flags);
93     color.a = 1.0f;
94 
95     crop.makeInvalid();
96     z = 0;
97     layerStack = ui::DEFAULT_LAYER_STACK;
98     transformToDisplayInverse = false;
99     dataspace = ui::Dataspace::UNKNOWN;
100     desiredHdrSdrRatio = 1.f;
101     currentHdrSdrRatio = 1.f;
102     dataspaceRequested = false;
103     hdrMetadata.validTypes = 0;
104     surfaceDamageRegion = Region::INVALID_REGION;
105     cornerRadius = 0.0f;
106     backgroundBlurRadius = 0;
107     api = -1;
108     hasColorTransform = false;
109     bufferTransform = 0;
110     requestedTransform.reset();
111     bufferData = std::make_shared<BufferData>();
112     bufferData->frameNumber = 0;
113     bufferData->acquireFence = sp<Fence>::make(-1);
114     acquireFenceTime = std::make_shared<FenceTime>(bufferData->acquireFence);
115     colorSpaceAgnostic = false;
116     frameRateSelectionPriority = Layer::PRIORITY_UNSET;
117     shadowRadius = 0.f;
118     fixedTransformHint = ui::Transform::ROT_INVALID;
119     destinationFrame.makeInvalid();
120     isTrustedOverlay = false;
121     dropInputMode = gui::DropInputMode::NONE;
122     dimmingEnabled = true;
123     defaultFrameRateCompatibility =
124             static_cast<int8_t>(scheduler::LayerInfo::FrameRateCompatibility::Default);
125     dataspace = ui::Dataspace::V0_SRGB;
126     gameMode = gui::GameMode::Unsupported;
127     requestedFrameRate = {};
128     cachingHint = gui::CachingHint::Enabled;
129 }
130 
merge(const ResolvedComposerState & resolvedComposerState)131 void RequestedLayerState::merge(const ResolvedComposerState& resolvedComposerState) {
132     const uint32_t oldFlags = flags;
133     const half oldAlpha = color.a;
134     const bool hadBuffer = externalTexture != nullptr;
135     uint64_t oldFramenumber = hadBuffer ? bufferData->frameNumber : 0;
136     const ui::Size oldBufferSize = hadBuffer
137             ? ui::Size(externalTexture->getWidth(), externalTexture->getHeight())
138             : ui::Size();
139     const bool hadSideStream = sidebandStream != nullptr;
140     const layer_state_t& clientState = resolvedComposerState.state;
141     const bool hadBlur = hasBlur();
142     uint64_t clientChanges = what | layer_state_t::diff(clientState);
143     layer_state_t::merge(clientState);
144     what = clientChanges;
145     LLOGV(layerId, "requested=%" PRIu64 "flags=%" PRIu64, clientState.what, clientChanges);
146 
147     if (clientState.what & layer_state_t::eFlagsChanged) {
148         if ((oldFlags ^ flags) & layer_state_t::eLayerHidden) {
149             changes |= RequestedLayerState::Changes::Visibility |
150                     RequestedLayerState::Changes::VisibleRegion;
151         }
152         if ((oldFlags ^ flags) & layer_state_t::eIgnoreDestinationFrame) {
153             changes |= RequestedLayerState::Changes::Geometry;
154         }
155     }
156 
157     if (clientState.what & layer_state_t::eBufferChanged) {
158         externalTexture = resolvedComposerState.externalTexture;
159         const bool hasBuffer = externalTexture != nullptr;
160         if (hasBuffer || hasBuffer != hadBuffer) {
161             changes |= RequestedLayerState::Changes::Buffer;
162             const ui::Size newBufferSize = hasBuffer
163                     ? ui::Size(externalTexture->getWidth(), externalTexture->getHeight())
164                     : ui::Size();
165             if (oldBufferSize != newBufferSize) {
166                 changes |= RequestedLayerState::Changes::BufferSize;
167                 changes |= RequestedLayerState::Changes::Geometry;
168             }
169         }
170 
171         if (hasBuffer != hadBuffer) {
172             changes |= RequestedLayerState::Changes::Geometry |
173                     RequestedLayerState::Changes::VisibleRegion |
174                     RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Input;
175         }
176 
177         if (hasBuffer) {
178             const bool frameNumberChanged =
179                     bufferData->flags.test(BufferData::BufferDataChange::frameNumberChanged);
180             const uint64_t frameNumber =
181                     frameNumberChanged ? bufferData->frameNumber : oldFramenumber + 1;
182             bufferData->frameNumber = frameNumber;
183 
184             if ((barrierProducerId > bufferData->producerId) ||
185                 ((barrierProducerId == bufferData->producerId) &&
186                  (barrierFrameNumber > bufferData->frameNumber))) {
187                 ALOGE("Out of order buffers detected for %s producedId=%d frameNumber=%" PRIu64
188                       " -> producedId=%d frameNumber=%" PRIu64,
189                       getDebugString().c_str(), bufferData->producerId, bufferData->frameNumber,
190                       bufferData->producerId, frameNumber);
191                 TransactionTraceWriter::getInstance().invoke("out_of_order_buffers_",
192                                                              /*overwrite=*/false);
193             }
194 
195             barrierProducerId = std::max(bufferData->producerId, barrierProducerId);
196             barrierFrameNumber = std::max(bufferData->frameNumber, barrierFrameNumber);
197         }
198     }
199 
200     if (clientState.what & layer_state_t::eSidebandStreamChanged) {
201         changes |= RequestedLayerState::Changes::SidebandStream;
202         const bool hasSideStream = sidebandStream != nullptr;
203         if (hasSideStream != hadSideStream) {
204             changes |= RequestedLayerState::Changes::Geometry |
205                     RequestedLayerState::Changes::VisibleRegion |
206                     RequestedLayerState::Changes::Visibility | RequestedLayerState::Changes::Input;
207         }
208     }
209     if (what & (layer_state_t::eAlphaChanged)) {
210         if (oldAlpha == 0 || color.a == 0) {
211             changes |= RequestedLayerState::Changes::Visibility |
212                     RequestedLayerState::Changes::VisibleRegion;
213         }
214     }
215     if (what & (layer_state_t::eBackgroundBlurRadiusChanged | layer_state_t::eBlurRegionsChanged)) {
216         if (hadBlur != hasBlur()) {
217             changes |= RequestedLayerState::Changes::Visibility |
218                     RequestedLayerState::Changes::VisibleRegion;
219         }
220     }
221     if (clientChanges & layer_state_t::HIERARCHY_CHANGES)
222         changes |= RequestedLayerState::Changes::Hierarchy;
223     if (clientChanges & layer_state_t::CONTENT_CHANGES)
224         changes |= RequestedLayerState::Changes::Content;
225     if (clientChanges & layer_state_t::GEOMETRY_CHANGES)
226         changes |= RequestedLayerState::Changes::Geometry;
227     if (clientChanges & layer_state_t::AFFECTS_CHILDREN)
228         changes |= RequestedLayerState::Changes::AffectsChildren;
229     if (clientChanges & layer_state_t::INPUT_CHANGES)
230         changes |= RequestedLayerState::Changes::Input;
231     if (clientChanges & layer_state_t::VISIBLE_REGION_CHANGES)
232         changes |= RequestedLayerState::Changes::VisibleRegion;
233     if (clientState.what & layer_state_t::eColorTransformChanged) {
234         static const mat4 identityMatrix = mat4();
235         hasColorTransform = colorTransform != identityMatrix;
236     }
237     if (clientState.what &
238         (layer_state_t::eLayerChanged | layer_state_t::eRelativeLayerChanged |
239          layer_state_t::eLayerStackChanged)) {
240         changes |= RequestedLayerState::Changes::Z;
241     }
242     if (clientState.what & layer_state_t::eReparent) {
243         changes |= RequestedLayerState::Changes::Parent;
244         parentId = resolvedComposerState.parentId;
245         parentSurfaceControlForChild = nullptr;
246         // Once a layer has be reparented, it cannot be placed at the root. It sounds odd
247         // but thats the existing logic and until we make this behavior more explicit, we need
248         // to maintain this logic.
249         canBeRoot = false;
250     }
251     if (clientState.what & layer_state_t::eRelativeLayerChanged) {
252         changes |= RequestedLayerState::Changes::RelativeParent;
253         relativeParentId = resolvedComposerState.relativeParentId;
254         isRelativeOf = true;
255         relativeLayerSurfaceControl = nullptr;
256     }
257     if ((clientState.what & layer_state_t::eLayerChanged ||
258          (clientState.what & layer_state_t::eReparent && parentId == UNASSIGNED_LAYER_ID)) &&
259         isRelativeOf) {
260         // clear out relz data
261         relativeParentId = UNASSIGNED_LAYER_ID;
262         isRelativeOf = false;
263         changes |= RequestedLayerState::Changes::RelativeParent;
264     }
265     if (clientState.what & layer_state_t::eReparent && parentId == relativeParentId) {
266         // provide a hint that we are are now a direct child and not a relative child.
267         changes |= RequestedLayerState::Changes::RelativeParent;
268     }
269     if (clientState.what & layer_state_t::eInputInfoChanged) {
270         touchCropId = resolvedComposerState.touchCropId;
271         windowInfoHandle->editInfo()->touchableRegionCropHandle.clear();
272     }
273     if (clientState.what & layer_state_t::eStretchChanged) {
274         stretchEffect.sanitize();
275     }
276 
277     if (clientState.what & layer_state_t::eHasListenerCallbacksChanged) {
278         // TODO(b/238781169) handle callbacks
279     }
280 
281     if (clientState.what & layer_state_t::ePositionChanged) {
282         requestedTransform.set(x, y);
283     }
284 
285     if (clientState.what & layer_state_t::eMatrixChanged) {
286         requestedTransform.set(matrix.dsdx, matrix.dtdy, matrix.dtdx, matrix.dsdy);
287     }
288     if (clientState.what & layer_state_t::eMetadataChanged) {
289         const int32_t requestedGameMode =
290                 clientState.metadata.getInt32(gui::METADATA_GAME_MODE, -1);
291         if (requestedGameMode != -1) {
292             // The transaction will be received on the Task layer and needs to be applied to all
293             // child layers.
294             if (static_cast<int32_t>(gameMode) != requestedGameMode) {
295                 gameMode = static_cast<gui::GameMode>(requestedGameMode);
296                 changes |= RequestedLayerState::Changes::GameMode;
297             }
298         }
299     }
300     if (clientState.what & layer_state_t::eFrameRateChanged) {
301         const auto compatibility =
302                 Layer::FrameRate::convertCompatibility(clientState.frameRateCompatibility);
303         const auto strategy = Layer::FrameRate::convertChangeFrameRateStrategy(
304                 clientState.changeFrameRateStrategy);
305         requestedFrameRate =
306                 Layer::FrameRate(Fps::fromValue(clientState.frameRate), compatibility, strategy);
307         changes |= RequestedLayerState::Changes::FrameRate;
308     }
309 }
310 
getUnrotatedBufferSize(uint32_t displayRotationFlags) const311 ui::Size RequestedLayerState::getUnrotatedBufferSize(uint32_t displayRotationFlags) const {
312     uint32_t bufferWidth = externalTexture->getWidth();
313     uint32_t bufferHeight = externalTexture->getHeight();
314     // Undo any transformations on the buffer.
315     if (bufferTransform & ui::Transform::ROT_90) {
316         std::swap(bufferWidth, bufferHeight);
317     }
318     if (transformToDisplayInverse) {
319         if (displayRotationFlags & ui::Transform::ROT_90) {
320             std::swap(bufferWidth, bufferHeight);
321         }
322     }
323     return {bufferWidth, bufferHeight};
324 }
325 
getTransform(uint32_t displayRotationFlags) const326 ui::Transform RequestedLayerState::getTransform(uint32_t displayRotationFlags) const {
327     if ((flags & layer_state_t::eIgnoreDestinationFrame) || destinationFrame.isEmpty()) {
328         // If destination frame is not set, use the requested transform set via
329         // Transaction::setPosition and Transaction::setMatrix.
330         return requestedTransform;
331     }
332 
333     Rect destRect = destinationFrame;
334     int32_t destW = destRect.width();
335     int32_t destH = destRect.height();
336     if (destRect.left < 0) {
337         destRect.left = 0;
338         destRect.right = destW;
339     }
340     if (destRect.top < 0) {
341         destRect.top = 0;
342         destRect.bottom = destH;
343     }
344 
345     if (!externalTexture) {
346         ui::Transform transform;
347         transform.set(static_cast<float>(destRect.left), static_cast<float>(destRect.top));
348         return transform;
349     }
350 
351     ui::Size bufferSize = getUnrotatedBufferSize(displayRotationFlags);
352 
353     float sx = static_cast<float>(destW) / static_cast<float>(bufferSize.width);
354     float sy = static_cast<float>(destH) / static_cast<float>(bufferSize.height);
355     ui::Transform transform;
356     transform.set(sx, 0, 0, sy);
357     transform.set(static_cast<float>(destRect.left), static_cast<float>(destRect.top));
358     return transform;
359 }
360 
getDebugString() const361 std::string RequestedLayerState::getDebugString() const {
362     std::stringstream debug;
363     debug << "RequestedLayerState{" << name;
364     if (parentId != UNASSIGNED_LAYER_ID) debug << " parentId=" << parentId;
365     if (relativeParentId != UNASSIGNED_LAYER_ID) debug << " relativeParentId=" << relativeParentId;
366     if (!mirrorIds.empty()) debug << " mirrorId=" << layerIdsToString(mirrorIds);
367     if (!handleAlive) debug << " !handle";
368     if (z != 0) debug << " z=" << z;
369     if (layerStack.id != 0) debug << " layerStack=" << layerStack.id;
370     return debug.str();
371 }
372 
getDebugStringShort() const373 std::string RequestedLayerState::getDebugStringShort() const {
374     return "[" + std::to_string(id) + "]" + name;
375 }
376 
canBeDestroyed() const377 bool RequestedLayerState::canBeDestroyed() const {
378     return !handleAlive && parentId == UNASSIGNED_LAYER_ID;
379 }
isRoot() const380 bool RequestedLayerState::isRoot() const {
381     return canBeRoot && parentId == UNASSIGNED_LAYER_ID;
382 }
isHiddenByPolicy() const383 bool RequestedLayerState::isHiddenByPolicy() const {
384     return (flags & layer_state_t::eLayerHidden) == layer_state_t::eLayerHidden;
385 };
getColor() const386 half4 RequestedLayerState::getColor() const {
387     if (sidebandStream || externalTexture) {
388         return {0._hf, 0._hf, 0._hf, color.a};
389     }
390     return color;
391 }
getBufferSize(uint32_t displayRotationFlags) const392 Rect RequestedLayerState::getBufferSize(uint32_t displayRotationFlags) const {
393     // for buffer state layers we use the display frame size as the buffer size.
394     if (!externalTexture) {
395         return Rect::INVALID_RECT;
396     }
397 
398     uint32_t bufWidth = externalTexture->getWidth();
399     uint32_t bufHeight = externalTexture->getHeight();
400 
401     // Undo any transformations on the buffer and return the result.
402     if (bufferTransform & ui::Transform::ROT_90) {
403         std::swap(bufWidth, bufHeight);
404     }
405 
406     if (transformToDisplayInverse) {
407         uint32_t invTransform = displayRotationFlags;
408         if (invTransform & ui::Transform::ROT_90) {
409             std::swap(bufWidth, bufHeight);
410         }
411     }
412 
413     return Rect(0, 0, static_cast<int32_t>(bufWidth), static_cast<int32_t>(bufHeight));
414 }
415 
getCroppedBufferSize(const Rect & bufferSize) const416 Rect RequestedLayerState::getCroppedBufferSize(const Rect& bufferSize) const {
417     Rect size = bufferSize;
418     if (!crop.isEmpty() && size.isValid()) {
419         size.intersect(crop, &size);
420     } else if (!crop.isEmpty()) {
421         size = crop;
422     }
423     return size;
424 }
425 
getBufferCrop() const426 Rect RequestedLayerState::getBufferCrop() const {
427     // this is the crop rectangle that applies to the buffer
428     // itself (as opposed to the window)
429     if (!bufferCrop.isEmpty()) {
430         // if the buffer crop is defined, we use that
431         return bufferCrop;
432     } else if (externalTexture != nullptr) {
433         // otherwise we use the whole buffer
434         return externalTexture->getBounds();
435     } else {
436         // if we don't have a buffer yet, we use an empty/invalid crop
437         return Rect();
438     }
439 }
440 
getCompositionType() const441 aidl::android::hardware::graphics::composer3::Composition RequestedLayerState::getCompositionType()
442         const {
443     using aidl::android::hardware::graphics::composer3::Composition;
444     // TODO(b/238781169) check about sidestream ready flag
445     if (sidebandStream.get()) {
446         return Composition::SIDEBAND;
447     }
448     if (!externalTexture) {
449         return Composition::SOLID_COLOR;
450     }
451     if (flags & layer_state_t::eLayerIsDisplayDecoration) {
452         return Composition::DISPLAY_DECORATION;
453     }
454     if (potentialCursor) {
455         return Composition::CURSOR;
456     }
457     return Composition::DEVICE;
458 }
459 
reduce(const Rect & win,const Region & exclude)460 Rect RequestedLayerState::reduce(const Rect& win, const Region& exclude) {
461     if (CC_LIKELY(exclude.isEmpty())) {
462         return win;
463     }
464     if (exclude.isRect()) {
465         return win.reduce(exclude.getBounds());
466     }
467     return Region(win).subtract(exclude).getBounds();
468 }
469 
470 // Returns true if the layer has a relative parent that is not its own parent. This is an input
471 // error from the client, and this check allows us to handle it gracefully. If both parentId and
472 // relativeParentId is unassigned then the layer does not have a valid relative parent.
473 // If the relative parentid is unassigned, the layer will be considered relative but won't be
474 // reachable.
hasValidRelativeParent() const475 bool RequestedLayerState::hasValidRelativeParent() const {
476     return isRelativeOf &&
477             (parentId != relativeParentId || relativeParentId == UNASSIGNED_LAYER_ID);
478 }
479 
hasInputInfo() const480 bool RequestedLayerState::hasInputInfo() const {
481     if (!windowInfoHandle) {
482         return false;
483     }
484     const auto windowInfo = windowInfoHandle->getInfo();
485     return windowInfo->token != nullptr ||
486             windowInfo->inputConfig.test(gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL);
487 }
488 
hasBlur() const489 bool RequestedLayerState::hasBlur() const {
490     return backgroundBlurRadius > 0 || blurRegions.size() > 0;
491 }
492 
hasFrameUpdate() const493 bool RequestedLayerState::hasFrameUpdate() const {
494     return what & layer_state_t::CONTENT_DIRTY &&
495             (externalTexture || bgColorLayerId != UNASSIGNED_LAYER_ID);
496 }
497 
hasReadyFrame() const498 bool RequestedLayerState::hasReadyFrame() const {
499     return hasFrameUpdate() || changes.test(Changes::SidebandStream) || autoRefresh;
500 }
501 
hasSidebandStreamFrame() const502 bool RequestedLayerState::hasSidebandStreamFrame() const {
503     return hasFrameUpdate() && sidebandStream.get();
504 }
505 
willReleaseBufferOnLatch() const506 bool RequestedLayerState::willReleaseBufferOnLatch() const {
507     return changes.test(Changes::Buffer) && !externalTexture;
508 }
509 
clearChanges()510 void RequestedLayerState::clearChanges() {
511     what = 0;
512     changes.clear();
513 }
514 
515 } // namespace android::surfaceflinger::frontend
516