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