1/* * Copyright (C) 2016 The Android Open Source Project
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *      http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include <sstream>
17#include <gtest/gtest.h>
18
19#include "Hwc2TestLayers.h"
20
21Hwc2TestLayers::Hwc2TestLayers(const std::vector<hwc2_layer_t>& layers,
22        Hwc2TestCoverage coverage, const Area& displayArea)
23    : Hwc2TestLayers(layers, coverage, displayArea,
24            std::unordered_map<Hwc2TestPropertyName, Hwc2TestCoverage>()) { }
25
26Hwc2TestLayers::Hwc2TestLayers(const std::vector<hwc2_layer_t>& layers,
27        Hwc2TestCoverage coverage, const Area& displayArea,
28        const std::unordered_map<Hwc2TestPropertyName,
29        Hwc2TestCoverage>& coverageExceptions)
30    : mDisplayArea(displayArea)
31{
32    for (auto layer : layers) {
33        mTestLayers.emplace(std::piecewise_construct,
34                std::forward_as_tuple(layer),
35                std::forward_as_tuple(coverage, displayArea, coverageExceptions));
36    }
37
38    /* Iterate over the layers in order and assign z orders in the same order.
39     * This allows us to iterate over z orders in the same way when computing
40     * visible regions */
41    uint32_t nextZOrder = layers.size();
42
43    for (auto& testLayer : mTestLayers) {
44        testLayer.second.setZOrder(nextZOrder--);
45    }
46
47    setVisibleRegions();
48}
49
50std::string Hwc2TestLayers::dump() const
51{
52    std::stringstream dmp;
53    for (auto& testLayer : mTestLayers) {
54        dmp << testLayer.second.dump();
55    }
56    return dmp.str();
57}
58
59void Hwc2TestLayers::reset()
60{
61    for (auto& testLayer : mTestLayers) {
62        testLayer.second.reset();
63    }
64
65    setVisibleRegions();
66}
67
68bool Hwc2TestLayers::advance()
69{
70    auto itr = mTestLayers.begin();
71    bool optimized;
72
73    while (itr != mTestLayers.end()) {
74        if (itr->second.advance()) {
75            optimized = setVisibleRegions();
76            if (!mOptimize || optimized)
77                return true;
78            itr = mTestLayers.begin();
79        } else {
80            itr->second.reset();
81            ++itr;
82        }
83    }
84    return false;
85}
86
87bool Hwc2TestLayers::advanceVisibleRegions()
88{
89    auto itr = mTestLayers.begin();
90    bool optimized;
91
92    while (itr != mTestLayers.end()) {
93        if (itr->second.advanceVisibleRegion()) {
94            optimized = setVisibleRegions();
95            if (!mOptimize || optimized)
96                return true;
97            itr = mTestLayers.begin();
98        } else {
99            itr->second.reset();
100            ++itr;
101        }
102    }
103    return false;
104}
105
106/* Removes layouts that do not cover the entire display.
107 * Also removes layouts where a layer is completely blocked from view.
108 */
109bool Hwc2TestLayers::optimizeLayouts()
110{
111    mOptimize = true;
112
113    if (setVisibleRegions())
114        return true;
115    return advance();
116}
117
118bool Hwc2TestLayers::contains(hwc2_layer_t layer) const
119{
120    return mTestLayers.count(layer) != 0;
121}
122
123int Hwc2TestLayers::getBuffer(hwc2_layer_t layer, buffer_handle_t* outHandle,
124        int32_t* outAcquireFence)
125{
126    if (mTestLayers.count(layer) == 0) {
127        []() { GTEST_FAIL(); }();
128    }
129    return mTestLayers.at(layer).getBuffer(outHandle, outAcquireFence);
130}
131
132hwc2_blend_mode_t Hwc2TestLayers::getBlendMode(hwc2_layer_t layer) const
133{
134    if (mTestLayers.count(layer) == 0) {
135        []() { GTEST_FAIL(); }();
136    }
137    return mTestLayers.at(layer).getBlendMode();
138}
139
140Area Hwc2TestLayers::getBufferArea(hwc2_layer_t layer) const
141{
142    auto testLayer = mTestLayers.find(layer);
143    if (testLayer == mTestLayers.end())
144        [] () { GTEST_FAIL(); }();
145    return testLayer->second.getBufferArea();
146}
147
148hwc_color_t Hwc2TestLayers::getColor(hwc2_layer_t layer) const
149{
150    if (mTestLayers.count(layer) == 0) {
151        []() { GTEST_FAIL(); }();
152    }
153    return mTestLayers.at(layer).getColor();
154}
155
156hwc2_composition_t Hwc2TestLayers::getComposition(hwc2_layer_t layer) const
157{
158    if (mTestLayers.count(layer) == 0) {
159        []() { GTEST_FAIL(); }();
160    }
161    return mTestLayers.at(layer).getComposition();
162}
163
164hwc_rect_t Hwc2TestLayers::getCursorPosition(hwc2_layer_t layer) const
165{
166    if (mTestLayers.count(layer) == 0) {
167        []() { GTEST_FAIL(); }();
168    }
169    return mTestLayers.at(layer).getCursorPosition();
170}
171
172android_dataspace_t Hwc2TestLayers::getDataspace(hwc2_layer_t layer) const
173{
174    if (mTestLayers.count(layer) == 0) {
175        []() { GTEST_FAIL(); }();
176    }
177    return mTestLayers.at(layer).getDataspace();
178}
179
180hwc_rect_t Hwc2TestLayers::getDisplayFrame(hwc2_layer_t layer) const
181{
182    if (mTestLayers.count(layer) == 0) {
183        []() { GTEST_FAIL(); }();
184    }
185    return mTestLayers.at(layer).getDisplayFrame();
186}
187
188float Hwc2TestLayers::getPlaneAlpha(hwc2_layer_t layer) const
189{
190    if (mTestLayers.count(layer) == 0) {
191        []() { GTEST_FAIL(); }();
192    }
193    return mTestLayers.at(layer).getPlaneAlpha();
194}
195
196hwc_frect_t Hwc2TestLayers::getSourceCrop(hwc2_layer_t layer) const
197{
198    if (mTestLayers.count(layer) == 0) {
199        []() { GTEST_FAIL(); }();
200    }
201    return mTestLayers.at(layer).getSourceCrop();
202}
203
204hwc_region_t Hwc2TestLayers::getSurfaceDamage(hwc2_layer_t layer) const
205{
206    if (mTestLayers.count(layer) == 0) {
207        []() { GTEST_FAIL(); }();
208    }
209    return mTestLayers.at(layer).getSurfaceDamage();
210}
211
212hwc_transform_t Hwc2TestLayers::getTransform(hwc2_layer_t layer) const
213{
214    if (mTestLayers.count(layer) == 0) {
215        []() { GTEST_FAIL(); }();
216    }
217    return mTestLayers.at(layer).getTransform();
218}
219
220hwc_region_t Hwc2TestLayers::getVisibleRegion(hwc2_layer_t layer) const
221{
222    if (mTestLayers.count(layer) == 0) {
223        []() { GTEST_FAIL(); }();
224    }
225    return mTestLayers.at(layer).getVisibleRegion();
226}
227
228uint32_t Hwc2TestLayers::getZOrder(hwc2_layer_t layer) const
229{
230    if (mTestLayers.count(layer) == 0) {
231        []() { GTEST_FAIL(); }();
232    }
233    return mTestLayers.at(layer).getZOrder();
234}
235
236/* Sets the visible regions for a display. Returns false if the layers do not
237 * cover the entire display or if a layer is not visible */
238bool Hwc2TestLayers::setVisibleRegions()
239{
240    /* The region of the display that is covered by layers above the current
241     * layer */
242    android::Region aboveOpaqueLayers;
243
244    bool optimized = true;
245
246    /* Iterate over test layers from max z order to min z order. */
247    for (auto& testLayer : mTestLayers) {
248        android::Region visibleRegion;
249
250        /* Set the visible region of this layer */
251        const hwc_rect_t displayFrame = testLayer.second.getDisplayFrame();
252
253        visibleRegion.set(android::Rect(displayFrame.left, displayFrame.top,
254                displayFrame.right, displayFrame.bottom));
255
256        /* Remove the area covered by opaque layers above this layer
257         * from this layer's visible region */
258        visibleRegion.subtractSelf(aboveOpaqueLayers);
259
260        testLayer.second.setVisibleRegion(visibleRegion);
261
262        /* If a layer is not visible, return false */
263        if (visibleRegion.isEmpty())
264            optimized = false;
265
266        /* If this layer is opaque, store the region it covers */
267        if (testLayer.second.getPlaneAlpha() == 1.0f)
268            aboveOpaqueLayers.orSelf(visibleRegion);
269    }
270
271    /* If the opaque region does not cover the entire display return false */
272    if (!aboveOpaqueLayers.isRect())
273        return false;
274
275    const auto rect = aboveOpaqueLayers.begin();
276    if (rect->left != 0 || rect->top != 0 || rect->right != mDisplayArea.width
277            || rect->bottom != mDisplayArea.height)
278        return false;
279
280    return optimized;
281}
282