xref: /aosp_15_r20/frameworks/native/services/surfaceflinger/CompositionEngine/src/planner/LayerState.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright 2021 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 <common/FlagManager.h>
18 #include <compositionengine/impl/planner/LayerState.h>
19 
20 namespace {
__asan_default_options()21 extern "C" const char* __attribute__((unused)) __asan_default_options() {
22     return "detect_container_overflow=0";
23 }
24 } // namespace
25 
26 namespace android::compositionengine::impl::planner {
27 
LayerState(compositionengine::OutputLayer * layer)28 LayerState::LayerState(compositionengine::OutputLayer* layer)
29       : mOutputLayer(layer),
30         mColorTransform({[](auto layer) {
31                              const auto state = layer->getLayerFE().getCompositionState();
32                              return state->colorTransformIsIdentity ? mat4{}
33                                                                     : state->colorTransform;
34                          },
35                          [](const mat4& mat) {
36                              using namespace std::string_literals;
37                              std::vector<std::string> split =
38                                      base::Split(std::string(mat.asString().c_str()), "\n"s);
39                              split.pop_back(); // Strip the last (empty) line
40                              return split;
41                          }}) {
42     update(layer);
43 }
44 
update(compositionengine::OutputLayer * layer)45 ftl::Flags<LayerStateField> LayerState::update(compositionengine::OutputLayer* layer) {
46     ALOGE_IF(mOutputLayer != layer && layer->getLayerFE().getSequence() != mId.get(),
47              "[%s] Expected mOutputLayer ID to never change: %d, %d", __func__,
48              layer->getLayerFE().getSequence(), mId.get());
49 
50     // It's possible for the OutputLayer pointer to change even when the layer is logically the
51     // same, i.e., the LayerFE is the same. An example use-case is screen rotation.
52     mOutputLayer = layer;
53 
54     ftl::Flags<LayerStateField> differences;
55 
56     // Update the unique fields as well, since we have to set them at least
57     // once from the OutputLayer
58     differences |= mId.update(layer);
59     differences |= mName.update(layer);
60 
61     for (StateInterface* field : getNonUniqueFields()) {
62         differences |= field->update(layer);
63     }
64 
65     return differences;
66 }
67 
getHash() const68 size_t LayerState::getHash() const {
69     size_t hash = 0;
70     for (const StateInterface* field : getNonUniqueFields()) {
71         if (field->getField() == LayerStateField::Buffer) {
72             continue;
73         }
74         if (FlagManager::getInstance().cache_when_source_crop_layer_only_moved() &&
75             field->getField() == LayerStateField::SourceCrop) {
76             continue;
77         }
78         android::hashCombineSingleHashed(hash, field->getHash());
79     }
80 
81     return hash;
82 }
83 
isSourceCropSizeEqual(const LayerState & other) const84 bool LayerState::isSourceCropSizeEqual(const LayerState& other) const {
85     return mSourceCrop.get().getWidth() == other.mSourceCrop.get().getWidth() &&
86             mSourceCrop.get().getHeight() == other.mSourceCrop.get().getHeight();
87 }
88 
getDifferingFields(const LayerState & other) const89 ftl::Flags<LayerStateField> LayerState::getDifferingFields(const LayerState& other) const {
90     ftl::Flags<LayerStateField> differences;
91     auto myFields = getNonUniqueFields();
92     auto otherFields = other.getNonUniqueFields();
93     for (size_t i = 0; i < myFields.size(); ++i) {
94         if (myFields[i]->getField() == LayerStateField::Buffer) {
95             continue;
96         }
97 
98         differences |= myFields[i]->getFieldIfDifferent(otherFields[i]);
99     }
100 
101     return differences;
102 }
103 
dump(std::string & result) const104 void LayerState::dump(std::string& result) const {
105     for (const StateInterface* field : getNonUniqueFields()) {
106         base::StringAppendF(&result, "  %16s: ", ftl::flag_string(field->getField()).c_str());
107 
108         bool first = true;
109         for (const std::string& line : field->toStrings()) {
110             base::StringAppendF(&result, "%s%s\n", first ? "" : "                    ",
111                                 line.c_str());
112             first = false;
113         }
114     }
115     result.append("\n");
116 }
117 
compare(const LayerState & other) const118 std::optional<std::string> LayerState::compare(const LayerState& other) const {
119     std::string result;
120 
121     const auto& thisFields = getNonUniqueFields();
122     const auto& otherFields = other.getNonUniqueFields();
123     for (size_t f = 0; f < thisFields.size(); ++f) {
124         const auto& thisField = thisFields[f];
125         const auto& otherField = otherFields[f];
126         // Skip comparing buffers
127         if (thisField->getField() == LayerStateField::Buffer) {
128             continue;
129         }
130 
131         if (thisField->equals(otherField)) {
132             continue;
133         }
134 
135         base::StringAppendF(&result, "  %16s: ", ftl::flag_string(thisField->getField()).c_str());
136 
137         const auto& thisStrings = thisField->toStrings();
138         const auto& otherStrings = otherField->toStrings();
139         bool first = true;
140         for (size_t line = 0; line < std::max(thisStrings.size(), otherStrings.size()); ++line) {
141             if (!first) {
142                 result.append("                    ");
143             }
144             first = false;
145 
146             if (line < thisStrings.size()) {
147                 base::StringAppendF(&result, "%-48.48s", thisStrings[line].c_str());
148             } else {
149                 result.append("                                                ");
150             }
151 
152             if (line < otherStrings.size()) {
153                 base::StringAppendF(&result, "%-48.48s", otherStrings[line].c_str());
154             } else {
155                 result.append("                                                ");
156             }
157             result.append("\n");
158         }
159     }
160 
161     return result.empty() ? std::nullopt : std::make_optional(result);
162 }
163 
operator ==(const LayerState & lhs,const LayerState & rhs)164 bool operator==(const LayerState& lhs, const LayerState& rhs) {
165     return lhs.mId == rhs.mId && lhs.mName == rhs.mName && lhs.mDisplayFrame == rhs.mDisplayFrame &&
166             lhs.mSourceCrop == rhs.mSourceCrop && lhs.mBufferTransform == rhs.mBufferTransform &&
167             lhs.mBlendMode == rhs.mBlendMode && lhs.mAlpha == rhs.mAlpha &&
168             lhs.mLayerMetadata == rhs.mLayerMetadata && lhs.mVisibleRegion == rhs.mVisibleRegion &&
169             lhs.mOutputDataspace == rhs.mOutputDataspace && lhs.mPixelFormat == rhs.mPixelFormat &&
170             lhs.mColorTransform == rhs.mColorTransform &&
171             lhs.mCompositionType == rhs.mCompositionType &&
172             lhs.mSidebandStream == rhs.mSidebandStream && lhs.mBuffer == rhs.mBuffer &&
173             (lhs.mCompositionType.get() !=
174                      aidl::android::hardware::graphics::composer3::Composition::SOLID_COLOR ||
175              lhs.mSolidColor == rhs.mSolidColor);
176 }
177 
getNonBufferHash(const std::vector<const LayerState * > & layers)178 NonBufferHash getNonBufferHash(const std::vector<const LayerState*>& layers) {
179     size_t hash = 0;
180     for (const auto layer : layers) {
181         android::hashCombineSingleHashed(hash, layer->getHash());
182     }
183 
184     return hash;
185 }
186 
187 } // namespace android::compositionengine::impl::planner
188