• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #pragma once
18 
19 #include <android-base/strings.h>
20 #include <compositionengine/LayerFE.h>
21 #include <compositionengine/LayerFECompositionState.h>
22 #include <compositionengine/OutputLayer.h>
23 #include <compositionengine/impl/OutputLayerCompositionState.h>
24 #include <input/Flags.h>
25 
26 #include <string>
27 
28 #include "DisplayHardware/Hal.h"
29 #include "math/HashCombine.h"
30 
31 namespace std {
32 template <typename T>
33 struct hash<android::sp<T>> {
34     size_t operator()(const android::sp<T>& p) { return std::hash<void*>()(p.get()); }
35 };
36 
37 template <typename T>
38 struct hash<android::wp<T>> {
39     size_t operator()(const android::wp<T>& p) {
40         android::sp<T> promoted = p.promote();
41         return std::hash<void*>()(promoted ? promoted.get() : nullptr);
42     }
43 };
44 } // namespace std
45 
46 namespace android::compositionengine::impl::planner {
47 
48 using LayerId = int32_t;
49 
50 // clang-format off
51 enum class LayerStateField : uint32_t {
52     None                  = 0u,
53     Id                    = 1u << 0,
54     Name                  = 1u << 1,
55     DisplayFrame          = 1u << 2,
56     SourceCrop            = 1u << 3,
57     BufferTransform       = 1u << 4,
58     BlendMode             = 1u << 5,
59     Alpha                 = 1u << 6,
60     LayerMetadata         = 1u << 7,
61     VisibleRegion         = 1u << 8,
62     Dataspace             = 1u << 9,
63     PixelFormat           = 1u << 10,
64     ColorTransform        = 1u << 11,
65     SurfaceDamage         = 1u << 12,
66     CompositionType       = 1u << 13,
67     SidebandStream        = 1u << 14,
68     Buffer                = 1u << 15,
69     SolidColor            = 1u << 16,
70     BackgroundBlurRadius  = 1u << 17,
71     BlurRegions           = 1u << 18,
72 };
73 // clang-format on
74 
75 std::string to_string(LayerStateField field);
76 
77 // An abstract interface allows us to iterate over all of the OutputLayerState fields
78 // without having to worry about their templated types.
79 // See `LayerState::getNonUniqueFields` below.
80 class StateInterface {
81 public:
82     virtual ~StateInterface() = default;
83 
84     virtual Flags<LayerStateField> update(const compositionengine::OutputLayer* layer) = 0;
85 
86     virtual size_t getHash() const = 0;
87 
88     virtual LayerStateField getField() const = 0;
89 
90     virtual Flags<LayerStateField> getFieldIfDifferent(const StateInterface* other) const = 0;
91 
92     virtual bool equals(const StateInterface* other) const = 0;
93 
94     virtual std::vector<std::string> toStrings() const = 0;
95 };
96 
97 template <typename T, LayerStateField FIELD>
98 class OutputLayerState : public StateInterface {
99 public:
100     using ReadFromLayerState = std::function<T(const compositionengine::OutputLayer* layer)>;
101     using ToStrings = std::function<std::vector<std::string>(const T&)>;
102     using Equals = std::function<bool(const T&, const T&)>;
103     using Hashes = std::function<size_t(const T&)>;
104 
105     static ToStrings getDefaultToStrings() {
106         return [](const T& value) {
107             using std::to_string;
108             return std::vector<std::string>{to_string(value)};
109         };
110     }
111 
112     static ToStrings getHalToStrings() {
113         return [](const T& value) { return std::vector<std::string>{toString(value)}; };
114     }
115 
116     static ToStrings getRegionToStrings() {
117         return [](const Region& region) {
118             using namespace std::string_literals;
119             std::string dump;
120             region.dump(dump, "");
121             std::vector<std::string> split = base::Split(dump, "\n"s);
122             split.erase(split.begin()); // Strip the header
123             split.pop_back();           // Strip the last (empty) line
124             for (std::string& line : split) {
125                 line.erase(0, 4); // Strip leading padding before each rect
126             }
127             return split;
128         };
129     }
130 
131     static Equals getDefaultEquals() {
132         return [](const T& lhs, const T& rhs) { return lhs == rhs; };
133     }
134 
135     static Equals getRegionEquals() {
136         return [](const Region& lhs, const Region& rhs) { return lhs.hasSameRects(rhs); };
137     }
138 
139     static Hashes getDefaultHashes() {
140         return [](const T& value) { return std::hash<T>{}(value); };
141     }
142 
143     OutputLayerState(ReadFromLayerState reader,
144                      ToStrings toStrings = OutputLayerState::getDefaultToStrings(),
145                      Equals equals = OutputLayerState::getDefaultEquals(),
146                      Hashes hashes = OutputLayerState::getDefaultHashes())
147           : mReader(reader), mToStrings(toStrings), mEquals(equals), mHashes(hashes) {}
148 
149     ~OutputLayerState() override = default;
150 
151     // Returns this member's field flag if it was changed
152     Flags<LayerStateField> update(const compositionengine::OutputLayer* layer) override {
153         T newValue = mReader(layer);
154         return update(newValue);
155     }
156 
157     Flags<LayerStateField> update(const T& newValue) {
158         if (!mEquals(mValue, newValue)) {
159             mValue = newValue;
160             mHash = {};
161             return FIELD;
162         }
163         return {};
164     }
165 
166     LayerStateField getField() const override { return FIELD; }
167     const T& get() const { return mValue; }
168 
169     size_t getHash() const override {
170         if (!mHash) {
171             mHash = mHashes(mValue);
172         }
173         return *mHash;
174     }
175 
176     Flags<LayerStateField> getFieldIfDifferent(const StateInterface* other) const override {
177         if (other->getField() != FIELD) {
178             return {};
179         }
180 
181         // The early return ensures that this downcast is sound
182         const OutputLayerState* otherState = static_cast<const OutputLayerState*>(other);
183         return *this != *otherState ? FIELD : Flags<LayerStateField>{};
184     }
185 
186     bool equals(const StateInterface* other) const override {
187         if (other->getField() != FIELD) {
188             return false;
189         }
190 
191         // The early return ensures that this downcast is sound
192         const OutputLayerState* otherState = static_cast<const OutputLayerState*>(other);
193         return *this == *otherState;
194     }
195 
196     std::vector<std::string> toStrings() const override { return mToStrings(mValue); }
197 
198     bool operator==(const OutputLayerState& other) const { return mEquals(mValue, other.mValue); }
199     bool operator!=(const OutputLayerState& other) const { return !(*this == other); }
200 
201 private:
202     const ReadFromLayerState mReader;
203     const ToStrings mToStrings;
204     const Equals mEquals;
205     const Hashes mHashes;
206     T mValue = {};
207     mutable std::optional<size_t> mHash = {};
208 };
209 
210 class LayerState {
211 public:
212     LayerState(compositionengine::OutputLayer* layer);
213 
214     // Returns which fields were updated
215     Flags<LayerStateField> update(compositionengine::OutputLayer*);
216 
217     // Computes a hash for this LayerState.
218     // The hash is only computed from NonUniqueFields, and excludes GraphicBuffers since they are
219     // not guaranteed to live longer than the LayerState object.
220     size_t getHash() const;
221 
222     // Returns the bit-set of differing fields between this LayerState and another LayerState.
223     // This bit-set is based on NonUniqueFields only, and excludes GraphicBuffers.
224     Flags<LayerStateField> getDifferingFields(const LayerState& other) const;
225 
226     compositionengine::OutputLayer* getOutputLayer() const { return mOutputLayer; }
227     int32_t getId() const { return mId.get(); }
228     const std::string& getName() const { return mName.get(); }
229     Rect getDisplayFrame() const { return mDisplayFrame.get(); }
230     const Region& getVisibleRegion() const { return mVisibleRegion.get(); }
231     bool hasBlurBehind() const {
232         return mBackgroundBlurRadius.get() > 0 || !mBlurRegions.get().empty();
233     }
234     int32_t getBackgroundBlurRadius() const { return mBackgroundBlurRadius.get(); }
235     hardware::graphics::composer::hal::Composition getCompositionType() const {
236         return mCompositionType.get();
237     }
238 
239     void incrementFramesSinceBufferUpdate() { ++mFramesSinceBufferUpdate; }
240     void resetFramesSinceBufferUpdate() { mFramesSinceBufferUpdate = 0; }
241     int64_t getFramesSinceBufferUpdate() const { return mFramesSinceBufferUpdate; }
242 
243     ui::Dataspace getDataspace() const { return mOutputDataspace.get(); }
244 
245     bool isProtected() const {
246         return getOutputLayer()->getLayerFE().getCompositionState()->hasProtectedContent;
247     }
248 
249     void dump(std::string& result) const;
250     std::optional<std::string> compare(const LayerState& other) const;
251 
252     // This makes LayerState's private members accessible to the operator
253     friend bool operator==(const LayerState& lhs, const LayerState& rhs);
254     friend bool operator!=(const LayerState& lhs, const LayerState& rhs) { return !(lhs == rhs); }
255 
256 private:
257     compositionengine::OutputLayer* mOutputLayer = nullptr;
258 
259     OutputLayerState<LayerId, LayerStateField::Id> mId{
260             [](const compositionengine::OutputLayer* layer) {
261                 return layer->getLayerFE().getSequence();
262             }};
263 
264     OutputLayerState<std::string, LayerStateField::Name>
265             mName{[](auto layer) { return layer->getLayerFE().getDebugName(); },
266                   [](const std::string& name) { return std::vector<std::string>{name}; }};
267 
268     // Output-dependent geometry state
269 
270     OutputLayerState<Rect, LayerStateField::DisplayFrame>
271             mDisplayFrame{[](auto layer) { return layer->getState().displayFrame; },
272                           [](const Rect& rect) {
273                               return std::vector<std::string>{
274                                       base::StringPrintf("[%d, %d, %d, %d]", rect.left, rect.top,
275                                                          rect.right, rect.bottom)};
276                           }};
277 
278     OutputLayerState<FloatRect, LayerStateField::SourceCrop>
279             mSourceCrop{[](auto layer) { return layer->getState().sourceCrop; },
280                         [](const FloatRect& rect) {
281                             return std::vector<std::string>{
282                                     base::StringPrintf("[%.2f, %.2f, %.2f, %.2f]", rect.left,
283                                                        rect.top, rect.right, rect.bottom)};
284                         }};
285 
286     using BufferTransformState = OutputLayerState<hardware::graphics::composer::hal::Transform,
287                                                   LayerStateField::BufferTransform>;
288     BufferTransformState mBufferTransform{[](auto layer) {
289                                               return layer->getState().bufferTransform;
290                                           },
291                                           BufferTransformState::getHalToStrings()};
292 
293     // Output-independent geometry state
294 
295     using BlendModeState = OutputLayerState<hardware::graphics::composer::hal::BlendMode,
296                                             LayerStateField::BlendMode>;
297     BlendModeState mBlendMode{[](auto layer) {
298                                   return layer->getLayerFE().getCompositionState()->blendMode;
299                               },
300                               BlendModeState::getHalToStrings()};
301 
302     OutputLayerState<float, LayerStateField::Alpha> mAlpha{
303             [](auto layer) { return layer->getLayerFE().getCompositionState()->alpha; }};
304 
305     using LayerMetadataState =
306             OutputLayerState<GenericLayerMetadataMap, LayerStateField::LayerMetadata>;
307     LayerMetadataState
308             mLayerMetadata{[](auto layer) {
309                                return layer->getLayerFE().getCompositionState()->metadata;
310                            },
311                            [](const GenericLayerMetadataMap& metadata) {
312                                std::vector<std::string> result;
313                                if (metadata.empty()) {
314                                    result.push_back("{}");
315                                    return result;
316                                }
317                                result.push_back("{");
318                                for (const auto& [key, value] : metadata) {
319                                    std::string keyValueDump;
320                                    keyValueDump.append("           ");
321                                    keyValueDump.append(key);
322                                    keyValueDump.append("=");
323                                    keyValueDump.append(value.dumpAsString());
324                                    result.push_back(keyValueDump);
325                                }
326                                result.push_back("}");
327                                return result;
328                            },
329                            LayerMetadataState::getDefaultEquals(),
330                            [](const GenericLayerMetadataMap& metadata) {
331                                size_t hash = 0;
332                                for (const auto& [key, value] : metadata) {
333                                    size_t entryHash = 0;
334                                    hashCombineSingleHashed(entryHash,
335                                                            std::hash<std::string>{}(key));
336                                    hashCombineSingleHashed(entryHash,
337                                                            GenericLayerMetadataEntry::Hasher{}(
338                                                                    value));
339                                    hash ^= entryHash;
340                                }
341                                return hash;
342                            }};
343 
344     // Output-dependent per-frame state
345 
346     using VisibleRegionState = OutputLayerState<Region, LayerStateField::VisibleRegion>;
347     VisibleRegionState mVisibleRegion{[](auto layer) { return layer->getState().visibleRegion; },
348                                       VisibleRegionState::getRegionToStrings(),
349                                       VisibleRegionState::getRegionEquals()};
350 
351     using DataspaceState = OutputLayerState<ui::Dataspace, LayerStateField::Dataspace>;
352     DataspaceState mOutputDataspace{[](auto layer) { return layer->getState().dataspace; },
353                                     DataspaceState::getHalToStrings()};
354 
355     // Output-independent per-frame state
356 
357     using PixelFormatState = OutputLayerState<hardware::graphics::composer::hal::PixelFormat,
358                                               LayerStateField::PixelFormat>;
359     PixelFormatState
360             mPixelFormat{[](auto layer) {
361                              return layer->getLayerFE().getCompositionState()->buffer
362                                      ? static_cast<hardware::graphics::composer::hal::PixelFormat>(
363                                                layer->getLayerFE()
364                                                        .getCompositionState()
365                                                        ->buffer->getPixelFormat())
366                                      : hardware::graphics::composer::hal::PixelFormat::RGBA_8888;
367                          },
368                          PixelFormatState::getHalToStrings()};
369 
370     OutputLayerState<mat4, LayerStateField::ColorTransform> mColorTransform;
371 
372     using CompositionTypeState = OutputLayerState<hardware::graphics::composer::hal::Composition,
373                                                   LayerStateField::CompositionType>;
374     CompositionTypeState
375             mCompositionType{[](auto layer) {
376                                  return layer->getState().forceClientComposition
377                                          ? hardware::graphics::composer::hal::Composition::CLIENT
378                                          : layer->getLayerFE()
379                                                    .getCompositionState()
380                                                    ->compositionType;
381                              },
382                              CompositionTypeState::getHalToStrings()};
383 
384     OutputLayerState<void*, LayerStateField::SidebandStream>
385             mSidebandStream{[](auto layer) {
386                                 return layer->getLayerFE()
387                                         .getCompositionState()
388                                         ->sidebandStream.get();
389                             },
390                             [](void* p) {
391                                 return std::vector<std::string>{base::StringPrintf("%p", p)};
392                             }};
393 
394     OutputLayerState<wp<GraphicBuffer>, LayerStateField::Buffer>
395             mBuffer{[](auto layer) { return layer->getLayerFE().getCompositionState()->buffer; },
396                     [](const wp<GraphicBuffer>& buffer) {
397                         sp<GraphicBuffer> promotedBuffer = buffer.promote();
398                         return std::vector<std::string>{
399                                 base::StringPrintf("%p",
400                                                    promotedBuffer ? promotedBuffer.get()
401                                                                   : nullptr)};
402                     }};
403 
404     int64_t mFramesSinceBufferUpdate = 0;
405 
406     OutputLayerState<half4, LayerStateField::SolidColor>
407             mSolidColor{[](auto layer) { return layer->getLayerFE().getCompositionState()->color; },
408                         [](const half4& vec) {
409                             std::stringstream stream;
410                             stream << vec;
411                             return std::vector<std::string>{stream.str()};
412                         }};
413 
414     OutputLayerState<int32_t, LayerStateField::BackgroundBlurRadius> mBackgroundBlurRadius{
415             [](auto layer) {
416                 return layer->getLayerFE().getCompositionState()->backgroundBlurRadius;
417             }};
418 
419     using BlurRegionsState =
420             OutputLayerState<std::vector<BlurRegion>, LayerStateField::BlurRegions>;
421     BlurRegionsState mBlurRegions{[](auto layer) {
422                                       return layer->getLayerFE().getCompositionState()->blurRegions;
423                                   },
424                                   [](const std::vector<BlurRegion>& regions) {
425                                       std::vector<std::string> result;
426                                       for (const auto region : regions) {
427                                           std::string str;
428                                           base::StringAppendF(&str,
429                                                               "{radius=%du, cornerRadii=[%f, %f, "
430                                                               "%f, %f], alpha=%f, rect=[%d, "
431                                                               "%d, %d, %d]",
432                                                               region.blurRadius,
433                                                               region.cornerRadiusTL,
434                                                               region.cornerRadiusTR,
435                                                               region.cornerRadiusBL,
436                                                               region.cornerRadiusBR, region.alpha,
437                                                               region.left, region.top, region.right,
438                                                               region.bottom);
439                                           result.push_back(str);
440                                       }
441                                       return result;
442                                   },
443                                   BlurRegionsState::getDefaultEquals(),
444                                   [](const std::vector<BlurRegion>& regions) {
445                                       size_t hash = 0;
446                                       for (const auto& region : regions) {
447                                           android::hashCombineSingle(hash, region);
448                                       }
449                                       return hash;
450                                   }};
451 
452     static const constexpr size_t kNumNonUniqueFields = 16;
453 
454     std::array<StateInterface*, kNumNonUniqueFields> getNonUniqueFields() {
455         std::array<const StateInterface*, kNumNonUniqueFields> constFields =
456                 const_cast<const LayerState*>(this)->getNonUniqueFields();
457         std::array<StateInterface*, kNumNonUniqueFields> fields;
458         std::transform(constFields.cbegin(), constFields.cend(), fields.begin(),
459                        [](const StateInterface* constField) {
460                            return const_cast<StateInterface*>(constField);
461                        });
462         return fields;
463     }
464 
465     std::array<const StateInterface*, kNumNonUniqueFields> getNonUniqueFields() const {
466         return {
467                 &mDisplayFrame, &mSourceCrop,     &mBufferTransform,      &mBlendMode,
468                 &mAlpha,        &mLayerMetadata,  &mVisibleRegion,        &mOutputDataspace,
469                 &mPixelFormat,  &mColorTransform, &mCompositionType,      &mSidebandStream,
470                 &mBuffer,       &mSolidColor,     &mBackgroundBlurRadius, &mBlurRegions,
471         };
472     }
473 };
474 
475 using NonBufferHash = size_t;
476 NonBufferHash getNonBufferHash(const std::vector<const LayerState*>&);
477 
478 } // namespace android::compositionengine::impl::planner
479