blob: d483a9982427359a06ecca6c851cab902aedad58 [file] [log] [blame]
Vishnu Nair8fc721b2022-12-22 20:06:32 +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#define ATRACE_TAG ATRACE_TAG_GRAPHICS
18#undef LOG_TAG
19#define LOG_TAG "LayerSnapshot"
20
21#include "LayerSnapshot.h"
22
23namespace android::surfaceflinger::frontend {
24
25using namespace ftl::flag_operators;
26
27LayerSnapshot::LayerSnapshot(const RequestedLayerState& state,
28 const LayerHierarchy::TraversalPath& path)
29 : path(path) {
30 sequence = static_cast<int32_t>(state.id);
31 name = state.name;
32 textureName = state.textureName;
33 premultipliedAlpha = state.premultipliedAlpha;
34 inputInfo.name = state.name;
35 inputInfo.id = static_cast<int32_t>(state.id);
36 inputInfo.ownerUid = static_cast<int32_t>(state.ownerUid);
37 inputInfo.ownerPid = state.ownerPid;
38}
39
40// As documented in libhardware header, formats in the range
41// 0x100 - 0x1FF are specific to the HAL implementation, and
42// are known to have no alpha channel
43// TODO: move definition for device-specific range into
44// hardware.h, instead of using hard-coded values here.
45#define HARDWARE_IS_DEVICE_FORMAT(f) ((f) >= 0x100 && (f) <= 0x1FF)
46
47bool LayerSnapshot::isOpaqueFormat(PixelFormat format) {
48 if (HARDWARE_IS_DEVICE_FORMAT(format)) {
49 return true;
50 }
51 switch (format) {
52 case PIXEL_FORMAT_RGBA_8888:
53 case PIXEL_FORMAT_BGRA_8888:
54 case PIXEL_FORMAT_RGBA_FP16:
55 case PIXEL_FORMAT_RGBA_1010102:
56 case PIXEL_FORMAT_R_8:
57 return false;
58 }
59 // in all other case, we have no blending (also for unknown formats)
60 return true;
61}
62
63bool LayerSnapshot::hasBufferOrSidebandStream() const {
64 return ((sidebandStream != nullptr) || (buffer != nullptr));
65}
66
67bool LayerSnapshot::drawShadows() const {
68 return shadowSettings.length > 0.f;
69}
70
71bool LayerSnapshot::fillsColor() const {
72 return !hasBufferOrSidebandStream() && color.r >= 0.0_hf && color.g >= 0.0_hf &&
73 color.b >= 0.0_hf;
74}
75
76bool LayerSnapshot::hasBlur() const {
77 return backgroundBlurRadius > 0 || blurRegions.size() > 0;
78}
79
80bool LayerSnapshot::hasEffect() const {
81 return fillsColor() || drawShadows() || hasBlur();
82}
83
84bool LayerSnapshot::hasSomethingToDraw() const {
85 return hasEffect() || hasBufferOrSidebandStream();
86}
87
88bool LayerSnapshot::isContentOpaque() const {
89 // if we don't have a buffer or sidebandStream yet, we're translucent regardless of the
90 // layer's opaque flag.
91 if (!hasSomethingToDraw()) {
92 return false;
93 }
94
95 // if the layer has the opaque flag, then we're always opaque
96 if (layerOpaqueFlagSet) {
97 return true;
98 }
99
100 // If the buffer has no alpha channel, then we are opaque
101 if (hasBufferOrSidebandStream() &&
102 isOpaqueFormat(buffer ? buffer->getPixelFormat() : PIXEL_FORMAT_NONE)) {
103 return true;
104 }
105
106 // Lastly consider the layer opaque if drawing a color with alpha == 1.0
107 return fillsColor() && color.a == 1.0_hf;
108}
109
110bool LayerSnapshot::isHiddenByPolicy() const {
111 if (CC_UNLIKELY(invalidTransform)) {
112 ALOGW("Hide layer %s because it has invalid transformation.", name.c_str());
113 return true;
114 }
115 return isHiddenByPolicyFromParent || isHiddenByPolicyFromRelativeParent;
116}
117
118bool LayerSnapshot::getIsVisible() const {
119 if (!hasSomethingToDraw()) {
120 return false;
121 }
122
123 if (isHiddenByPolicy()) {
124 return false;
125 }
126
127 return color.a > 0.0f || hasBlur();
128}
129
130std::string LayerSnapshot::getIsVisibleReason() const {
131 if (!hasSomethingToDraw()) {
132 return "!hasSomethingToDraw";
133 }
134
135 if (isHiddenByPolicy()) {
136 return "isHiddenByPolicy";
137 }
138
139 if (color.a > 0.0f || hasBlur()) {
140 return "";
141 }
142
143 return "alpha = 0 and !hasBlur";
144}
145
146bool LayerSnapshot::canReceiveInput() const {
147 return !isHiddenByPolicy() && (!hasBufferOrSidebandStream() || color.a > 0.0f);
148}
149
150bool LayerSnapshot::isTransformValid(const ui::Transform& t) {
151 float transformDet = t.det();
152 return transformDet != 0 && !isinf(transformDet) && !isnan(transformDet);
153}
154
155std::string LayerSnapshot::getDebugString() const {
156 return "Snapshot(" + base::StringPrintf("%p", this) + "){" + path.toString() + name +
157 " isHidden=" + std::to_string(isHiddenByPolicyFromParent) +
158 " isHiddenRelative=" + std::to_string(isHiddenByPolicyFromRelativeParent) +
159 " isVisible=" + std::to_string(isVisible) + " " + getIsVisibleReason() + "}";
160}
161
162} // namespace android::surfaceflinger::frontend