| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright 2015 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 LOG_NDEBUG 0 | 
 | 18 |  | 
 | 19 | #undef LOG_TAG | 
 | 20 | #define LOG_TAG "HWC2" | 
 | 21 | #define ATRACE_TAG ATRACE_TAG_GRAPHICS | 
 | 22 |  | 
 | 23 | #include "HWC2.h" | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 24 | #include "ComposerHal.h" | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 25 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 26 | #include <ui/Fence.h> | 
| Dan Stoza | 5a423ea | 2017-02-16 14:10:39 -0800 | [diff] [blame] | 27 | #include <ui/FloatRect.h> | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 28 | #include <ui/GraphicBuffer.h> | 
 | 29 | #include <ui/Region.h> | 
 | 30 |  | 
 | 31 | #include <android/configuration.h> | 
 | 32 |  | 
 | 33 | #include <inttypes.h> | 
| Lloyd Pique | 3c085a0 | 2018-05-09 19:38:32 -0700 | [diff] [blame] | 34 | #include <algorithm> | 
 | 35 | #include <iterator> | 
| Peiyong Lin | 2c327ac | 2018-04-19 22:06:34 -0700 | [diff] [blame] | 36 | #include <set> | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 37 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 38 | using android::Fence; | 
| Dan Stoza | 5a423ea | 2017-02-16 14:10:39 -0800 | [diff] [blame] | 39 | using android::FloatRect; | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 40 | using android::GraphicBuffer; | 
| Dan Stoza | 7d7ae73 | 2016-03-16 12:23:40 -0700 | [diff] [blame] | 41 | using android::HdrCapabilities; | 
| Courtney Goeltzenleuchter | f9c98e5 | 2018-02-12 07:23:17 -0700 | [diff] [blame] | 42 | using android::HdrMetadata; | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 43 | using android::Rect; | 
 | 44 | using android::Region; | 
 | 45 | using android::sp; | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 46 | using android::hardware::Return; | 
 | 47 | using android::hardware::Void; | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 48 |  | 
 | 49 | namespace HWC2 { | 
 | 50 |  | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 51 | namespace Hwc2 = android::Hwc2; | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 52 | using android::ui::ColorMode; | 
 | 53 | using android::ui::Dataspace; | 
 | 54 | using android::ui::PixelFormat; | 
| Peiyong Lin | 0e7a791 | 2018-04-05 14:36:36 -0700 | [diff] [blame] | 55 | using android::ui::RenderIntent; | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 56 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 57 | namespace { | 
 | 58 |  | 
| Peiyong Lin | 2c327ac | 2018-04-19 22:06:34 -0700 | [diff] [blame] | 59 | inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys, | 
 | 60 |                            const Hwc2::PerFrameMetadataKey& key) { | 
 | 61 |     return keys.find(key) != keys.end(); | 
 | 62 | } | 
 | 63 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 64 | class ComposerCallbackBridge : public Hwc2::IComposerCallback { | 
 | 65 | public: | 
 | 66 |     ComposerCallbackBridge(ComposerCallback* callback, int32_t sequenceId) | 
| Lloyd Pique | 715a2c1 | 2017-12-14 17:18:08 -0800 | [diff] [blame] | 67 |             : mCallback(callback), mSequenceId(sequenceId) {} | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 68 |  | 
 | 69 |     Return<void> onHotplug(Hwc2::Display display, | 
 | 70 |                            IComposerCallback::Connection conn) override | 
 | 71 |     { | 
 | 72 |         HWC2::Connection connection = static_cast<HWC2::Connection>(conn); | 
| Lloyd Pique | 715a2c1 | 2017-12-14 17:18:08 -0800 | [diff] [blame] | 73 |         mCallback->onHotplugReceived(mSequenceId, display, connection); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 74 |         return Void(); | 
 | 75 |     } | 
 | 76 |  | 
 | 77 |     Return<void> onRefresh(Hwc2::Display display) override | 
 | 78 |     { | 
 | 79 |         mCallback->onRefreshReceived(mSequenceId, display); | 
 | 80 |         return Void(); | 
 | 81 |     } | 
 | 82 |  | 
 | 83 |     Return<void> onVsync(Hwc2::Display display, int64_t timestamp) override | 
 | 84 |     { | 
 | 85 |         mCallback->onVsyncReceived(mSequenceId, display, timestamp); | 
 | 86 |         return Void(); | 
 | 87 |     } | 
 | 88 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 89 | private: | 
 | 90 |     ComposerCallback* mCallback; | 
 | 91 |     int32_t mSequenceId; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 92 | }; | 
 | 93 |  | 
 | 94 | } // namespace anonymous | 
 | 95 |  | 
 | 96 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 97 | // Device methods | 
 | 98 |  | 
| Lloyd Pique | a822d52 | 2017-12-20 16:42:57 -0800 | [diff] [blame] | 99 | Device::Device(std::unique_ptr<android::Hwc2::Composer> composer) : mComposer(std::move(composer)) { | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 100 |     loadCapabilities(); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 101 | } | 
 | 102 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 103 | void Device::registerCallback(ComposerCallback* callback, int32_t sequenceId) { | 
 | 104 |     if (mRegisteredCallback) { | 
 | 105 |         ALOGW("Callback already registered. Ignored extra registration " | 
 | 106 |                 "attempt."); | 
 | 107 |         return; | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 108 |     } | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 109 |     mRegisteredCallback = true; | 
 | 110 |     sp<ComposerCallbackBridge> callbackBridge( | 
 | 111 |             new ComposerCallbackBridge(callback, sequenceId)); | 
 | 112 |     mComposer->registerCallback(callbackBridge); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 113 | } | 
 | 114 |  | 
 | 115 | // Required by HWC2 device | 
 | 116 |  | 
 | 117 | std::string Device::dump() const | 
 | 118 | { | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 119 |     return mComposer->dumpDebugInfo(); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 120 | } | 
 | 121 |  | 
 | 122 | uint32_t Device::getMaxVirtualDisplayCount() const | 
 | 123 | { | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 124 |     return mComposer->getMaxVirtualDisplayCount(); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 125 | } | 
 | 126 |  | 
 | 127 | Error Device::createVirtualDisplay(uint32_t width, uint32_t height, | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 128 |         PixelFormat* format, Display** outDisplay) | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 129 | { | 
 | 130 |     ALOGI("Creating virtual display"); | 
 | 131 |  | 
 | 132 |     hwc2_display_t displayId = 0; | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 133 |     auto intError = mComposer->createVirtualDisplay(width, height, | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 134 |             format, &displayId); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 135 |     auto error = static_cast<Error>(intError); | 
 | 136 |     if (error != Error::None) { | 
 | 137 |         return error; | 
 | 138 |     } | 
 | 139 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 140 |     auto display = std::make_unique<Display>( | 
| Michael Wright | 1509a23 | 2018-06-21 02:50:34 +0100 | [diff] [blame] | 141 |             *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, DisplayType::Virtual); | 
| Lloyd Pique | bc79209 | 2018-01-17 11:52:30 -0800 | [diff] [blame] | 142 |     display->setConnected(true); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 143 |     *outDisplay = display.get(); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 144 |     mDisplays.emplace(displayId, std::move(display)); | 
 | 145 |     ALOGI("Created virtual display"); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 146 |     return Error::None; | 
 | 147 | } | 
 | 148 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 149 | void Device::destroyDisplay(hwc2_display_t displayId) | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 150 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 151 |     ALOGI("Destroying display %" PRIu64, displayId); | 
 | 152 |     mDisplays.erase(displayId); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 153 | } | 
 | 154 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 155 | void Device::onHotplug(hwc2_display_t displayId, Connection connection) { | 
 | 156 |     if (connection == Connection::Connected) { | 
| Steven Thomas | 3bed052 | 2018-03-20 15:40:48 -0700 | [diff] [blame] | 157 |         // If we get a hotplug connected event for a display we already have, | 
 | 158 |         // destroy the display and recreate it. This will force us to requery | 
 | 159 |         // the display params and recreate all layers on that display. | 
 | 160 |         auto oldDisplay = getDisplayById(displayId); | 
 | 161 |         if (oldDisplay != nullptr && oldDisplay->isConnected()) { | 
 | 162 |             ALOGI("Hotplug connecting an already connected display." | 
 | 163 |                     " Clearing old display state."); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 164 |         } | 
| Steven Thomas | 3bed052 | 2018-03-20 15:40:48 -0700 | [diff] [blame] | 165 |         mDisplays.erase(displayId); | 
 | 166 |  | 
 | 167 |         DisplayType displayType; | 
 | 168 |         auto intError = mComposer->getDisplayType(displayId, | 
 | 169 |                 reinterpret_cast<Hwc2::IComposerClient::DisplayType *>( | 
 | 170 |                         &displayType)); | 
 | 171 |         auto error = static_cast<Error>(intError); | 
 | 172 |         if (error != Error::None) { | 
 | 173 |             ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d). " | 
 | 174 |                     "Aborting hotplug attempt.", | 
 | 175 |                     displayId, to_string(error).c_str(), intError); | 
 | 176 |             return; | 
 | 177 |         } | 
 | 178 |  | 
 | 179 |         auto newDisplay = std::make_unique<Display>( | 
| Michael Wright | 1509a23 | 2018-06-21 02:50:34 +0100 | [diff] [blame] | 180 |                 *mComposer.get(), mPowerAdvisor, mCapabilities, displayId, displayType); | 
| Lloyd Pique | bc79209 | 2018-01-17 11:52:30 -0800 | [diff] [blame] | 181 |         newDisplay->setConnected(true); | 
| Steven Thomas | 3bed052 | 2018-03-20 15:40:48 -0700 | [diff] [blame] | 182 |         mDisplays.emplace(displayId, std::move(newDisplay)); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 183 |     } else if (connection == Connection::Disconnected) { | 
 | 184 |         // The display will later be destroyed by a call to | 
 | 185 |         // destroyDisplay(). For now we just mark it disconnected. | 
 | 186 |         auto display = getDisplayById(displayId); | 
 | 187 |         if (display) { | 
 | 188 |             display->setConnected(false); | 
 | 189 |         } else { | 
 | 190 |             ALOGW("Attempted to disconnect unknown display %" PRIu64, | 
 | 191 |                   displayId); | 
 | 192 |         } | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 193 |     } | 
 | 194 | } | 
 | 195 |  | 
 | 196 | // Other Device methods | 
 | 197 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 198 | Display* Device::getDisplayById(hwc2_display_t id) { | 
 | 199 |     auto iter = mDisplays.find(id); | 
 | 200 |     return iter == mDisplays.end() ? nullptr : iter->second.get(); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 201 | } | 
 | 202 |  | 
 | 203 | // Device initialization methods | 
 | 204 |  | 
 | 205 | void Device::loadCapabilities() | 
 | 206 | { | 
 | 207 |     static_assert(sizeof(Capability) == sizeof(int32_t), | 
 | 208 |             "Capability size has changed"); | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 209 |     auto capabilities = mComposer->getCapabilities(); | 
 | 210 |     for (auto capability : capabilities) { | 
 | 211 |         mCapabilities.emplace(static_cast<Capability>(capability)); | 
 | 212 |     } | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 213 | } | 
 | 214 |  | 
| Chia-I Wu | ae5a6b8 | 2017-10-10 09:09:22 -0700 | [diff] [blame] | 215 | Error Device::flushCommands() | 
 | 216 | { | 
 | 217 |     return static_cast<Error>(mComposer->executeCommands()); | 
 | 218 | } | 
 | 219 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 220 | // Display methods | 
 | 221 |  | 
| Michael Wright | 1509a23 | 2018-06-21 02:50:34 +0100 | [diff] [blame] | 222 | Display::Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor& advisor, | 
| Lloyd Pique | bc79209 | 2018-01-17 11:52:30 -0800 | [diff] [blame] | 223 |                  const std::unordered_set<Capability>& capabilities, hwc2_display_t id, | 
 | 224 |                  DisplayType type) | 
 | 225 |       : mComposer(composer), | 
| Michael Wright | 1509a23 | 2018-06-21 02:50:34 +0100 | [diff] [blame] | 226 |         mPowerAdvisor(advisor), | 
| Lloyd Pique | bc79209 | 2018-01-17 11:52:30 -0800 | [diff] [blame] | 227 |         mCapabilities(capabilities), | 
 | 228 |         mId(id), | 
 | 229 |         mIsConnected(false), | 
 | 230 |         mType(type) { | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 231 |     ALOGV("Created display %" PRIu64, id); | 
 | 232 | } | 
 | 233 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 234 | Display::~Display() { | 
 | 235 |     mLayers.clear(); | 
 | 236 |  | 
| Chris Forbes | ceb67d1 | 2017-04-11 12:20:00 -0700 | [diff] [blame] | 237 |     if (mType == DisplayType::Virtual) { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 238 |         ALOGV("Destroying virtual display"); | 
 | 239 |         auto intError = mComposer.destroyVirtualDisplay(mId); | 
 | 240 |         auto error = static_cast<Error>(intError); | 
 | 241 |         ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64 | 
 | 242 |                 ") failed: %s (%d)", mId, to_string(error).c_str(), intError); | 
 | 243 |     } else if (mType == DisplayType::Physical) { | 
 | 244 |         auto error = setVsyncEnabled(HWC2::Vsync::Disable); | 
 | 245 |         if (error != Error::None) { | 
 | 246 |             ALOGE("~Display: Failed to disable vsync for display %" PRIu64 | 
 | 247 |                     ": %s (%d)", mId, to_string(error).c_str(), | 
 | 248 |                     static_cast<int32_t>(error)); | 
 | 249 |         } | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 250 |     } | 
 | 251 | } | 
 | 252 |  | 
 | 253 | Display::Config::Config(Display& display, hwc2_config_t id) | 
 | 254 |   : mDisplay(display), | 
 | 255 |     mId(id), | 
 | 256 |     mWidth(-1), | 
 | 257 |     mHeight(-1), | 
 | 258 |     mVsyncPeriod(-1), | 
 | 259 |     mDpiX(-1), | 
 | 260 |     mDpiY(-1) {} | 
 | 261 |  | 
 | 262 | Display::Config::Builder::Builder(Display& display, hwc2_config_t id) | 
 | 263 |   : mConfig(new Config(display, id)) {} | 
 | 264 |  | 
 | 265 | float Display::Config::Builder::getDefaultDensity() { | 
 | 266 |     // Default density is based on TVs: 1080p displays get XHIGH density, lower- | 
 | 267 |     // resolution displays get TV density. Maybe eventually we'll need to update | 
 | 268 |     // it for 4k displays, though hopefully those will just report accurate DPI | 
 | 269 |     // information to begin with. This is also used for virtual displays and | 
 | 270 |     // older HWC implementations, so be careful about orientation. | 
 | 271 |  | 
 | 272 |     auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight); | 
 | 273 |     if (longDimension >= 1080) { | 
 | 274 |         return ACONFIGURATION_DENSITY_XHIGH; | 
 | 275 |     } else { | 
 | 276 |         return ACONFIGURATION_DENSITY_TV; | 
 | 277 |     } | 
 | 278 | } | 
 | 279 |  | 
 | 280 | // Required by HWC2 display | 
 | 281 |  | 
 | 282 | Error Display::acceptChanges() | 
 | 283 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 284 |     auto intError = mComposer.acceptDisplayChanges(mId); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 285 |     return static_cast<Error>(intError); | 
 | 286 | } | 
 | 287 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 288 | Error Display::createLayer(Layer** outLayer) | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 289 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 290 |     if (!outLayer) { | 
 | 291 |         return Error::BadParameter; | 
 | 292 |     } | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 293 |     hwc2_layer_t layerId = 0; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 294 |     auto intError = mComposer.createLayer(mId, &layerId); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 295 |     auto error = static_cast<Error>(intError); | 
 | 296 |     if (error != Error::None) { | 
 | 297 |         return error; | 
 | 298 |     } | 
 | 299 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 300 |     auto layer = std::make_unique<Layer>( | 
 | 301 |             mComposer, mCapabilities, mId, layerId); | 
 | 302 |     *outLayer = layer.get(); | 
 | 303 |     mLayers.emplace(layerId, std::move(layer)); | 
 | 304 |     return Error::None; | 
 | 305 | } | 
 | 306 |  | 
 | 307 | Error Display::destroyLayer(Layer* layer) | 
 | 308 | { | 
 | 309 |     if (!layer) { | 
 | 310 |         return Error::BadParameter; | 
 | 311 |     } | 
 | 312 |     mLayers.erase(layer->getId()); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 313 |     return Error::None; | 
 | 314 | } | 
 | 315 |  | 
 | 316 | Error Display::getActiveConfig( | 
 | 317 |         std::shared_ptr<const Display::Config>* outConfig) const | 
 | 318 | { | 
 | 319 |     ALOGV("[%" PRIu64 "] getActiveConfig", mId); | 
 | 320 |     hwc2_config_t configId = 0; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 321 |     auto intError = mComposer.getActiveConfig(mId, &configId); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 322 |     auto error = static_cast<Error>(intError); | 
 | 323 |  | 
 | 324 |     if (error != Error::None) { | 
| Fabien Sanglard | b7432cc | 2016-11-11 09:40:27 -0800 | [diff] [blame] | 325 |         ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId); | 
 | 326 |         *outConfig = nullptr; | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 327 |         return error; | 
 | 328 |     } | 
 | 329 |  | 
 | 330 |     if (mConfigs.count(configId) != 0) { | 
 | 331 |         *outConfig = mConfigs.at(configId); | 
 | 332 |     } else { | 
 | 333 |         ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, | 
 | 334 |                 configId); | 
 | 335 |         // Return no error, but the caller needs to check for a null pointer to | 
 | 336 |         // detect this case | 
 | 337 |         *outConfig = nullptr; | 
 | 338 |     } | 
 | 339 |  | 
 | 340 |     return Error::None; | 
 | 341 | } | 
 | 342 |  | 
| Lloyd Pique | 3c085a0 | 2018-05-09 19:38:32 -0700 | [diff] [blame] | 343 | Error Display::getActiveConfigIndex(int* outIndex) const { | 
 | 344 |     ALOGV("[%" PRIu64 "] getActiveConfigIndex", mId); | 
 | 345 |     hwc2_config_t configId = 0; | 
 | 346 |     auto intError = mComposer.getActiveConfig(mId, &configId); | 
 | 347 |     auto error = static_cast<Error>(intError); | 
 | 348 |  | 
 | 349 |     if (error != Error::None) { | 
 | 350 |         ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId); | 
 | 351 |         *outIndex = -1; | 
 | 352 |         return error; | 
 | 353 |     } | 
 | 354 |  | 
 | 355 |     auto pos = mConfigs.find(configId); | 
 | 356 |     if (pos != mConfigs.end()) { | 
 | 357 |         *outIndex = std::distance(mConfigs.begin(), pos); | 
 | 358 |     } else { | 
 | 359 |         ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, configId); | 
 | 360 |         // Return no error, but the caller needs to check for a negative index | 
 | 361 |         // to detect this case | 
 | 362 |         *outIndex = -1; | 
 | 363 |     } | 
 | 364 |  | 
 | 365 |     return Error::None; | 
 | 366 | } | 
 | 367 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 368 | Error Display::getChangedCompositionTypes( | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 369 |         std::unordered_map<Layer*, Composition>* outTypes) | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 370 | { | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 371 |     std::vector<Hwc2::Layer> layerIds; | 
| Chia-I Wu | cd8d7f0 | 2016-11-16 11:02:31 +0800 | [diff] [blame] | 372 |     std::vector<Hwc2::IComposerClient::Composition> types; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 373 |     auto intError = mComposer.getChangedCompositionTypes( | 
 | 374 |             mId, &layerIds, &types); | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 375 |     uint32_t numElements = layerIds.size(); | 
 | 376 |     auto error = static_cast<Error>(intError); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 377 |     error = static_cast<Error>(intError); | 
 | 378 |     if (error != Error::None) { | 
 | 379 |         return error; | 
 | 380 |     } | 
 | 381 |  | 
 | 382 |     outTypes->clear(); | 
 | 383 |     outTypes->reserve(numElements); | 
 | 384 |     for (uint32_t element = 0; element < numElements; ++element) { | 
 | 385 |         auto layer = getLayerById(layerIds[element]); | 
 | 386 |         if (layer) { | 
 | 387 |             auto type = static_cast<Composition>(types[element]); | 
 | 388 |             ALOGV("getChangedCompositionTypes: adding %" PRIu64 " %s", | 
 | 389 |                     layer->getId(), to_string(type).c_str()); | 
 | 390 |             outTypes->emplace(layer, type); | 
 | 391 |         } else { | 
 | 392 |             ALOGE("getChangedCompositionTypes: invalid layer %" PRIu64 " found" | 
 | 393 |                     " on display %" PRIu64, layerIds[element], mId); | 
 | 394 |         } | 
 | 395 |     } | 
 | 396 |  | 
 | 397 |     return Error::None; | 
 | 398 | } | 
 | 399 |  | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 400 | Error Display::getColorModes(std::vector<ColorMode>* outModes) const | 
| Dan Stoza | 076ac67 | 2016-03-14 10:47:53 -0700 | [diff] [blame] | 401 | { | 
| Peiyong Lin | fd997e0 | 2018-03-28 15:29:00 -0700 | [diff] [blame] | 402 |     auto intError = mComposer.getColorModes(mId, outModes); | 
 | 403 |     return static_cast<Error>(intError); | 
| Dan Stoza | 076ac67 | 2016-03-14 10:47:53 -0700 | [diff] [blame] | 404 | } | 
 | 405 |  | 
| Peiyong Lin | 2c327ac | 2018-04-19 22:06:34 -0700 | [diff] [blame] | 406 | Error Display::getSupportedPerFrameMetadata(int32_t* outSupportedPerFrameMetadata) const | 
 | 407 | { | 
 | 408 |     *outSupportedPerFrameMetadata = 0; | 
 | 409 |     std::vector<Hwc2::PerFrameMetadataKey> tmpKeys; | 
 | 410 |     auto intError = mComposer.getPerFrameMetadataKeys(mId, &tmpKeys); | 
 | 411 |     auto error = static_cast<Error>(intError); | 
 | 412 |     if (error != Error::None) { | 
 | 413 |         return error; | 
 | 414 |     } | 
 | 415 |  | 
 | 416 |     // Check whether a specific metadata type is supported. A metadata type is considered | 
 | 417 |     // supported if and only if all required fields are supported. | 
 | 418 |  | 
 | 419 |     // SMPTE2086 | 
 | 420 |     std::set<Hwc2::PerFrameMetadataKey> keys(tmpKeys.begin(), tmpKeys.end()); | 
 | 421 |     if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X) && | 
 | 422 |         hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y) && | 
 | 423 |         hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X) && | 
 | 424 |         hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y) && | 
 | 425 |         hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X) && | 
 | 426 |         hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y) && | 
 | 427 |         hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_X) && | 
 | 428 |         hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::WHITE_POINT_Y) && | 
 | 429 |         hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_LUMINANCE) && | 
 | 430 |         hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MIN_LUMINANCE)) { | 
 | 431 |         *outSupportedPerFrameMetadata |= HdrMetadata::Type::SMPTE2086; | 
 | 432 |     } | 
 | 433 |     // CTA861_3 | 
 | 434 |     if (hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL) && | 
 | 435 |         hasMetadataKey(keys, Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL)) { | 
 | 436 |         *outSupportedPerFrameMetadata |= HdrMetadata::Type::CTA861_3; | 
 | 437 |     } | 
 | 438 |  | 
 | 439 |     return Error::None; | 
 | 440 | } | 
 | 441 |  | 
| Peiyong Lin | 0e7a791 | 2018-04-05 14:36:36 -0700 | [diff] [blame] | 442 | Error Display::getRenderIntents(ColorMode colorMode, | 
 | 443 |         std::vector<RenderIntent>* outRenderIntents) const | 
 | 444 | { | 
 | 445 |     auto intError = mComposer.getRenderIntents(mId, colorMode, outRenderIntents); | 
 | 446 |     return static_cast<Error>(intError); | 
 | 447 | } | 
 | 448 |  | 
 | 449 | Error Display::getDataspaceSaturationMatrix(Dataspace dataspace, android::mat4* outMatrix) | 
 | 450 | { | 
 | 451 |     auto intError = mComposer.getDataspaceSaturationMatrix(dataspace, outMatrix); | 
 | 452 |     return static_cast<Error>(intError); | 
 | 453 | } | 
 | 454 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 455 | std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const | 
 | 456 | { | 
 | 457 |     std::vector<std::shared_ptr<const Config>> configs; | 
 | 458 |     for (const auto& element : mConfigs) { | 
 | 459 |         configs.emplace_back(element.second); | 
 | 460 |     } | 
 | 461 |     return configs; | 
 | 462 | } | 
 | 463 |  | 
 | 464 | Error Display::getName(std::string* outName) const | 
 | 465 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 466 |     auto intError = mComposer.getDisplayName(mId, outName); | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 467 |     return static_cast<Error>(intError); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 468 | } | 
 | 469 |  | 
 | 470 | Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests, | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 471 |         std::unordered_map<Layer*, LayerRequest>* outLayerRequests) | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 472 | { | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 473 |     uint32_t intDisplayRequests; | 
 | 474 |     std::vector<Hwc2::Layer> layerIds; | 
 | 475 |     std::vector<uint32_t> layerRequests; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 476 |     auto intError = mComposer.getDisplayRequests( | 
 | 477 |             mId, &intDisplayRequests, &layerIds, &layerRequests); | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 478 |     uint32_t numElements = layerIds.size(); | 
 | 479 |     auto error = static_cast<Error>(intError); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 480 |     if (error != Error::None) { | 
 | 481 |         return error; | 
 | 482 |     } | 
 | 483 |  | 
 | 484 |     *outDisplayRequests = static_cast<DisplayRequest>(intDisplayRequests); | 
 | 485 |     outLayerRequests->clear(); | 
 | 486 |     outLayerRequests->reserve(numElements); | 
 | 487 |     for (uint32_t element = 0; element < numElements; ++element) { | 
 | 488 |         auto layer = getLayerById(layerIds[element]); | 
 | 489 |         if (layer) { | 
 | 490 |             auto layerRequest = | 
 | 491 |                     static_cast<LayerRequest>(layerRequests[element]); | 
 | 492 |             outLayerRequests->emplace(layer, layerRequest); | 
 | 493 |         } else { | 
 | 494 |             ALOGE("getRequests: invalid layer %" PRIu64 " found on display %" | 
 | 495 |                     PRIu64, layerIds[element], mId); | 
 | 496 |         } | 
 | 497 |     } | 
 | 498 |  | 
 | 499 |     return Error::None; | 
 | 500 | } | 
 | 501 |  | 
 | 502 | Error Display::getType(DisplayType* outType) const | 
 | 503 | { | 
| Chris Forbes | 016d73c | 2017-04-11 10:04:31 -0700 | [diff] [blame] | 504 |     *outType = mType; | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 505 |     return Error::None; | 
 | 506 | } | 
 | 507 |  | 
 | 508 | Error Display::supportsDoze(bool* outSupport) const | 
 | 509 | { | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 510 |     bool intSupport = false; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 511 |     auto intError = mComposer.getDozeSupport(mId, &intSupport); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 512 |     auto error = static_cast<Error>(intError); | 
 | 513 |     if (error != Error::None) { | 
 | 514 |         return error; | 
 | 515 |     } | 
 | 516 |     *outSupport = static_cast<bool>(intSupport); | 
 | 517 |     return Error::None; | 
 | 518 | } | 
 | 519 |  | 
| Peiyong Lin | 6266589 | 2018-04-16 11:07:44 -0700 | [diff] [blame] | 520 | Error Display::getHdrCapabilities(HdrCapabilities* outCapabilities) const | 
| Dan Stoza | 7d7ae73 | 2016-03-16 12:23:40 -0700 | [diff] [blame] | 521 | { | 
| Dan Stoza | 7d7ae73 | 2016-03-16 12:23:40 -0700 | [diff] [blame] | 522 |     float maxLuminance = -1.0f; | 
 | 523 |     float maxAverageLuminance = -1.0f; | 
 | 524 |     float minLuminance = -1.0f; | 
| Peiyong Lin | 6266589 | 2018-04-16 11:07:44 -0700 | [diff] [blame] | 525 |     std::vector<Hwc2::Hdr> types; | 
 | 526 |     auto intError = mComposer.getHdrCapabilities(mId, &types, | 
| Chia-I Wu | 67e376d | 2016-12-19 11:36:22 +0800 | [diff] [blame] | 527 |             &maxLuminance, &maxAverageLuminance, &minLuminance); | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 528 |     auto error = static_cast<HWC2::Error>(intError); | 
 | 529 |  | 
| Dan Stoza | 7d7ae73 | 2016-03-16 12:23:40 -0700 | [diff] [blame] | 530 |     if (error != Error::None) { | 
 | 531 |         return error; | 
 | 532 |     } | 
 | 533 |  | 
| Peiyong Lin | 6266589 | 2018-04-16 11:07:44 -0700 | [diff] [blame] | 534 |     *outCapabilities = HdrCapabilities(std::move(types), | 
| Dan Stoza | 7d7ae73 | 2016-03-16 12:23:40 -0700 | [diff] [blame] | 535 |             maxLuminance, maxAverageLuminance, minLuminance); | 
 | 536 |     return Error::None; | 
 | 537 | } | 
 | 538 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 539 | Error Display::getReleaseFences( | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 540 |         std::unordered_map<Layer*, sp<Fence>>* outFences) const | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 541 | { | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 542 |     std::vector<Hwc2::Layer> layerIds; | 
 | 543 |     std::vector<int> fenceFds; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 544 |     auto intError = mComposer.getReleaseFences(mId, &layerIds, &fenceFds); | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 545 |     auto error = static_cast<Error>(intError); | 
 | 546 |     uint32_t numElements = layerIds.size(); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 547 |     if (error != Error::None) { | 
 | 548 |         return error; | 
 | 549 |     } | 
 | 550 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 551 |     std::unordered_map<Layer*, sp<Fence>> releaseFences; | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 552 |     releaseFences.reserve(numElements); | 
 | 553 |     for (uint32_t element = 0; element < numElements; ++element) { | 
 | 554 |         auto layer = getLayerById(layerIds[element]); | 
 | 555 |         if (layer) { | 
 | 556 |             sp<Fence> fence(new Fence(fenceFds[element])); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 557 |             releaseFences.emplace(layer, fence); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 558 |         } else { | 
 | 559 |             ALOGE("getReleaseFences: invalid layer %" PRIu64 | 
 | 560 |                     " found on display %" PRIu64, layerIds[element], mId); | 
| Chia-I Wu | 5e74c65 | 2017-05-17 13:43:16 -0700 | [diff] [blame] | 561 |             for (; element < numElements; ++element) { | 
 | 562 |                 close(fenceFds[element]); | 
 | 563 |             } | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 564 |             return Error::BadLayer; | 
 | 565 |         } | 
 | 566 |     } | 
 | 567 |  | 
 | 568 |     *outFences = std::move(releaseFences); | 
 | 569 |     return Error::None; | 
 | 570 | } | 
 | 571 |  | 
| Fabien Sanglard | 11d0fc3 | 2016-12-01 15:43:01 -0800 | [diff] [blame] | 572 | Error Display::present(sp<Fence>* outPresentFence) | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 573 | { | 
| Naseer Ahmed | 847650b | 2016-06-17 11:14:25 -0400 | [diff] [blame] | 574 |     int32_t presentFenceFd = -1; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 575 |     auto intError = mComposer.presentDisplay(mId, &presentFenceFd); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 576 |     auto error = static_cast<Error>(intError); | 
 | 577 |     if (error != Error::None) { | 
 | 578 |         return error; | 
 | 579 |     } | 
 | 580 |  | 
| Fabien Sanglard | 11d0fc3 | 2016-12-01 15:43:01 -0800 | [diff] [blame] | 581 |     *outPresentFence = new Fence(presentFenceFd); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 582 |     return Error::None; | 
 | 583 | } | 
 | 584 |  | 
 | 585 | Error Display::setActiveConfig(const std::shared_ptr<const Config>& config) | 
 | 586 | { | 
 | 587 |     if (config->getDisplayId() != mId) { | 
 | 588 |         ALOGE("setActiveConfig received config %u for the wrong display %" | 
 | 589 |                 PRIu64 " (expected %" PRIu64 ")", config->getId(), | 
 | 590 |                 config->getDisplayId(), mId); | 
 | 591 |         return Error::BadConfig; | 
 | 592 |     } | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 593 |     auto intError = mComposer.setActiveConfig(mId, config->getId()); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 594 |     return static_cast<Error>(intError); | 
 | 595 | } | 
 | 596 |  | 
| Daniel Nicoara | 1f42e3a | 2017-04-10 13:27:32 -0400 | [diff] [blame] | 597 | Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target, | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 598 |         const sp<Fence>& acquireFence, Dataspace dataspace) | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 599 | { | 
| Dan Stoza | 5cf424b | 2016-05-20 14:02:39 -0700 | [diff] [blame] | 600 |     // TODO: Properly encode client target surface damage | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 601 |     int32_t fenceFd = acquireFence->dup(); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 602 |     auto intError = mComposer.setClientTarget(mId, slot, target, | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 603 |             fenceFd, dataspace, std::vector<Hwc2::IComposerClient::Rect>()); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 604 |     return static_cast<Error>(intError); | 
 | 605 | } | 
 | 606 |  | 
| Peiyong Lin | 0e7a791 | 2018-04-05 14:36:36 -0700 | [diff] [blame] | 607 | Error Display::setColorMode(ColorMode mode, RenderIntent renderIntent) | 
| Dan Stoza | 076ac67 | 2016-03-14 10:47:53 -0700 | [diff] [blame] | 608 | { | 
| Michael Wright | 1509a23 | 2018-06-21 02:50:34 +0100 | [diff] [blame] | 609 |     // When the color mode is switched to DISPLAY_P3, we want to boost the GPU frequency | 
 | 610 |     // so that GPU composition can finish in time. When color mode is switched from | 
 | 611 |     // DISPLAY_P3, we want to reset GPU frequency. | 
 | 612 |     const bool expensiveRenderingExpected = (mode == ColorMode::DISPLAY_P3); | 
 | 613 |     mPowerAdvisor.setExpensiveRenderingExpected(mId, expensiveRenderingExpected); | 
 | 614 |  | 
| Peiyong Lin | 0e7a791 | 2018-04-05 14:36:36 -0700 | [diff] [blame] | 615 |     auto intError = mComposer.setColorMode(mId, mode, renderIntent); | 
| Dan Stoza | 076ac67 | 2016-03-14 10:47:53 -0700 | [diff] [blame] | 616 |     return static_cast<Error>(intError); | 
 | 617 | } | 
 | 618 |  | 
| Dan Stoza | 5df2a86 | 2016-03-24 16:19:37 -0700 | [diff] [blame] | 619 | Error Display::setColorTransform(const android::mat4& matrix, | 
 | 620 |         android_color_transform_t hint) | 
 | 621 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 622 |     auto intError = mComposer.setColorTransform(mId, | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 623 |             matrix.asArray(), static_cast<Hwc2::ColorTransform>(hint)); | 
| Dan Stoza | 5df2a86 | 2016-03-24 16:19:37 -0700 | [diff] [blame] | 624 |     return static_cast<Error>(intError); | 
 | 625 | } | 
 | 626 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 627 | Error Display::setOutputBuffer(const sp<GraphicBuffer>& buffer, | 
 | 628 |         const sp<Fence>& releaseFence) | 
 | 629 | { | 
 | 630 |     int32_t fenceFd = releaseFence->dup(); | 
 | 631 |     auto handle = buffer->getNativeBuffer()->handle; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 632 |     auto intError = mComposer.setOutputBuffer(mId, handle, fenceFd); | 
| Dan Stoza | 3862898 | 2016-07-13 15:48:58 -0700 | [diff] [blame] | 633 |     close(fenceFd); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 634 |     return static_cast<Error>(intError); | 
 | 635 | } | 
 | 636 |  | 
 | 637 | Error Display::setPowerMode(PowerMode mode) | 
 | 638 | { | 
| Chia-I Wu | cd8d7f0 | 2016-11-16 11:02:31 +0800 | [diff] [blame] | 639 |     auto intMode = static_cast<Hwc2::IComposerClient::PowerMode>(mode); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 640 |     auto intError = mComposer.setPowerMode(mId, intMode); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 641 |     return static_cast<Error>(intError); | 
 | 642 | } | 
 | 643 |  | 
 | 644 | Error Display::setVsyncEnabled(Vsync enabled) | 
 | 645 | { | 
| Chia-I Wu | cd8d7f0 | 2016-11-16 11:02:31 +0800 | [diff] [blame] | 646 |     auto intEnabled = static_cast<Hwc2::IComposerClient::Vsync>(enabled); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 647 |     auto intError = mComposer.setVsyncEnabled(mId, intEnabled); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 648 |     return static_cast<Error>(intError); | 
 | 649 | } | 
 | 650 |  | 
 | 651 | Error Display::validate(uint32_t* outNumTypes, uint32_t* outNumRequests) | 
 | 652 | { | 
 | 653 |     uint32_t numTypes = 0; | 
 | 654 |     uint32_t numRequests = 0; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 655 |     auto intError = mComposer.validateDisplay(mId, &numTypes, &numRequests); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 656 |     auto error = static_cast<Error>(intError); | 
 | 657 |     if (error != Error::None && error != Error::HasChanges) { | 
 | 658 |         return error; | 
 | 659 |     } | 
 | 660 |  | 
 | 661 |     *outNumTypes = numTypes; | 
 | 662 |     *outNumRequests = numRequests; | 
 | 663 |     return error; | 
 | 664 | } | 
 | 665 |  | 
| Fabien Sanglard | 249c0ae | 2017-06-19 19:22:36 -0700 | [diff] [blame] | 666 | Error Display::presentOrValidate(uint32_t* outNumTypes, uint32_t* outNumRequests, | 
 | 667 |                                  sp<android::Fence>* outPresentFence, uint32_t* state) { | 
 | 668 |  | 
 | 669 |     uint32_t numTypes = 0; | 
 | 670 |     uint32_t numRequests = 0; | 
 | 671 |     int32_t presentFenceFd = -1; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 672 |     auto intError = mComposer.presentOrValidateDisplay( | 
 | 673 |             mId, &numTypes, &numRequests, &presentFenceFd, state); | 
| Fabien Sanglard | 249c0ae | 2017-06-19 19:22:36 -0700 | [diff] [blame] | 674 |     auto error = static_cast<Error>(intError); | 
 | 675 |     if (error != Error::None && error != Error::HasChanges) { | 
 | 676 |         return error; | 
 | 677 |     } | 
 | 678 |  | 
 | 679 |     if (*state == 1) { | 
 | 680 |         *outPresentFence = new Fence(presentFenceFd); | 
 | 681 |     } | 
 | 682 |  | 
 | 683 |     if (*state == 0) { | 
 | 684 |         *outNumTypes = numTypes; | 
 | 685 |         *outNumRequests = numRequests; | 
 | 686 |     } | 
 | 687 |     return error; | 
 | 688 | } | 
| Chia-I Wu | 0c6ce46 | 2017-06-22 10:48:28 -0700 | [diff] [blame] | 689 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 690 | // For use by Device | 
 | 691 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 692 | void Display::setConnected(bool connected) { | 
| Steven Thomas | b6c6ad4 | 2018-01-29 12:22:00 -0800 | [diff] [blame] | 693 |     if (!mIsConnected && connected) { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 694 |         mComposer.setClientTargetSlotCount(mId); | 
| Steven Thomas | b6c6ad4 | 2018-01-29 12:22:00 -0800 | [diff] [blame] | 695 |         if (mType == DisplayType::Physical) { | 
 | 696 |             loadConfigs(); | 
 | 697 |         } | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 698 |     } | 
 | 699 |     mIsConnected = connected; | 
 | 700 | } | 
 | 701 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 702 | int32_t Display::getAttribute(hwc2_config_t configId, Attribute attribute) | 
 | 703 | { | 
 | 704 |     int32_t value = 0; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 705 |     auto intError = mComposer.getDisplayAttribute(mId, configId, | 
| Chia-I Wu | 67e376d | 2016-12-19 11:36:22 +0800 | [diff] [blame] | 706 |             static_cast<Hwc2::IComposerClient::Attribute>(attribute), | 
 | 707 |             &value); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 708 |     auto error = static_cast<Error>(intError); | 
 | 709 |     if (error != Error::None) { | 
 | 710 |         ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId, | 
 | 711 |                 configId, to_string(attribute).c_str(), | 
 | 712 |                 to_string(error).c_str(), intError); | 
 | 713 |         return -1; | 
 | 714 |     } | 
 | 715 |     return value; | 
 | 716 | } | 
 | 717 |  | 
 | 718 | void Display::loadConfig(hwc2_config_t configId) | 
 | 719 | { | 
 | 720 |     ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId); | 
 | 721 |  | 
 | 722 |     auto config = Config::Builder(*this, configId) | 
 | 723 |             .setWidth(getAttribute(configId, Attribute::Width)) | 
 | 724 |             .setHeight(getAttribute(configId, Attribute::Height)) | 
 | 725 |             .setVsyncPeriod(getAttribute(configId, Attribute::VsyncPeriod)) | 
 | 726 |             .setDpiX(getAttribute(configId, Attribute::DpiX)) | 
 | 727 |             .setDpiY(getAttribute(configId, Attribute::DpiY)) | 
 | 728 |             .build(); | 
 | 729 |     mConfigs.emplace(configId, std::move(config)); | 
 | 730 | } | 
 | 731 |  | 
 | 732 | void Display::loadConfigs() | 
 | 733 | { | 
 | 734 |     ALOGV("[%" PRIu64 "] loadConfigs", mId); | 
 | 735 |  | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 736 |     std::vector<Hwc2::Config> configIds; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 737 |     auto intError = mComposer.getDisplayConfigs(mId, &configIds); | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 738 |     auto error = static_cast<Error>(intError); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 739 |     if (error != Error::None) { | 
 | 740 |         ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId, | 
 | 741 |                 to_string(error).c_str(), intError); | 
 | 742 |         return; | 
 | 743 |     } | 
 | 744 |  | 
 | 745 |     for (auto configId : configIds) { | 
 | 746 |         loadConfig(configId); | 
 | 747 |     } | 
 | 748 | } | 
 | 749 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 750 | // Other Display methods | 
 | 751 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 752 | Layer* Display::getLayerById(hwc2_layer_t id) const | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 753 | { | 
 | 754 |     if (mLayers.count(id) == 0) { | 
 | 755 |         return nullptr; | 
 | 756 |     } | 
 | 757 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 758 |     return mLayers.at(id).get(); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 759 | } | 
 | 760 |  | 
 | 761 | // Layer methods | 
 | 762 |  | 
| Courtney Goeltzenleuchter | f9c98e5 | 2018-02-12 07:23:17 -0700 | [diff] [blame] | 763 | Layer::Layer(android::Hwc2::Composer& composer, const std::unordered_set<Capability>& capabilities, | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 764 |              hwc2_display_t displayId, hwc2_layer_t layerId) | 
 | 765 |   : mComposer(composer), | 
 | 766 |     mCapabilities(capabilities), | 
 | 767 |     mDisplayId(displayId), | 
 | 768 |     mId(layerId) | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 769 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 770 |     ALOGV("Created layer %" PRIu64 " on display %" PRIu64, layerId, displayId); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 771 | } | 
 | 772 |  | 
 | 773 | Layer::~Layer() | 
 | 774 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 775 |     auto intError = mComposer.destroyLayer(mDisplayId, mId); | 
 | 776 |     auto error = static_cast<Error>(intError); | 
 | 777 |     ALOGE_IF(error != Error::None, "destroyLayer(%" PRIu64 ", %" PRIu64 ")" | 
 | 778 |             " failed: %s (%d)", mDisplayId, mId, to_string(error).c_str(), | 
 | 779 |             intError); | 
 | 780 |     if (mLayerDestroyedListener) { | 
 | 781 |         mLayerDestroyedListener(this); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 782 |     } | 
 | 783 | } | 
 | 784 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 785 | void Layer::setLayerDestroyedListener(std::function<void(Layer*)> listener) { | 
 | 786 |     LOG_ALWAYS_FATAL_IF(mLayerDestroyedListener && listener, | 
 | 787 |             "Attempt to set layer destroyed listener multiple times"); | 
 | 788 |     mLayerDestroyedListener = listener; | 
 | 789 | } | 
 | 790 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 791 | Error Layer::setCursorPosition(int32_t x, int32_t y) | 
 | 792 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 793 |     auto intError = mComposer.setCursorPosition(mDisplayId, mId, x, y); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 794 |     return static_cast<Error>(intError); | 
 | 795 | } | 
 | 796 |  | 
| Daniel Nicoara | 1f42e3a | 2017-04-10 13:27:32 -0400 | [diff] [blame] | 797 | Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer, | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 798 |         const sp<Fence>& acquireFence) | 
 | 799 | { | 
 | 800 |     int32_t fenceFd = acquireFence->dup(); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 801 |     auto intError = mComposer.setLayerBuffer(mDisplayId, mId, slot, buffer, | 
 | 802 |                                              fenceFd); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 803 |     return static_cast<Error>(intError); | 
 | 804 | } | 
 | 805 |  | 
 | 806 | Error Layer::setSurfaceDamage(const Region& damage) | 
 | 807 | { | 
 | 808 |     // We encode default full-screen damage as INVALID_RECT upstream, but as 0 | 
 | 809 |     // rects for HWC | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 810 |     Hwc2::Error intError = Hwc2::Error::NONE; | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 811 |     if (damage.isRect() && damage.getBounds() == Rect::INVALID_RECT) { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 812 |         intError = mComposer.setLayerSurfaceDamage(mDisplayId, | 
| Chia-I Wu | cd8d7f0 | 2016-11-16 11:02:31 +0800 | [diff] [blame] | 813 |                 mId, std::vector<Hwc2::IComposerClient::Rect>()); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 814 |     } else { | 
 | 815 |         size_t rectCount = 0; | 
 | 816 |         auto rectArray = damage.getArray(&rectCount); | 
 | 817 |  | 
| Chia-I Wu | cd8d7f0 | 2016-11-16 11:02:31 +0800 | [diff] [blame] | 818 |         std::vector<Hwc2::IComposerClient::Rect> hwcRects; | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 819 |         for (size_t rect = 0; rect < rectCount; ++rect) { | 
 | 820 |             hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, | 
 | 821 |                     rectArray[rect].right, rectArray[rect].bottom}); | 
 | 822 |         } | 
 | 823 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 824 |         intError = mComposer.setLayerSurfaceDamage(mDisplayId, mId, hwcRects); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 825 |     } | 
 | 826 |  | 
 | 827 |     return static_cast<Error>(intError); | 
 | 828 | } | 
 | 829 |  | 
 | 830 | Error Layer::setBlendMode(BlendMode mode) | 
 | 831 | { | 
| Chia-I Wu | cd8d7f0 | 2016-11-16 11:02:31 +0800 | [diff] [blame] | 832 |     auto intMode = static_cast<Hwc2::IComposerClient::BlendMode>(mode); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 833 |     auto intError = mComposer.setLayerBlendMode(mDisplayId, mId, intMode); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 834 |     return static_cast<Error>(intError); | 
 | 835 | } | 
 | 836 |  | 
 | 837 | Error Layer::setColor(hwc_color_t color) | 
 | 838 | { | 
| Chia-I Wu | cd8d7f0 | 2016-11-16 11:02:31 +0800 | [diff] [blame] | 839 |     Hwc2::IComposerClient::Color hwcColor{color.r, color.g, color.b, color.a}; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 840 |     auto intError = mComposer.setLayerColor(mDisplayId, mId, hwcColor); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 841 |     return static_cast<Error>(intError); | 
 | 842 | } | 
 | 843 |  | 
 | 844 | Error Layer::setCompositionType(Composition type) | 
 | 845 | { | 
| Chia-I Wu | cd8d7f0 | 2016-11-16 11:02:31 +0800 | [diff] [blame] | 846 |     auto intType = static_cast<Hwc2::IComposerClient::Composition>(type); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 847 |     auto intError = mComposer.setLayerCompositionType( | 
 | 848 |             mDisplayId, mId, intType); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 849 |     return static_cast<Error>(intError); | 
 | 850 | } | 
 | 851 |  | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 852 | Error Layer::setDataspace(Dataspace dataspace) | 
| Dan Stoza | 5df2a86 | 2016-03-24 16:19:37 -0700 | [diff] [blame] | 853 | { | 
| Courtney Goeltzenleuchter | c988ee4 | 2017-05-31 17:56:46 -0600 | [diff] [blame] | 854 |     if (dataspace == mDataSpace) { | 
 | 855 |         return Error::None; | 
 | 856 |     } | 
 | 857 |     mDataSpace = dataspace; | 
| Peiyong Lin | 34beb7a | 2018-03-28 11:57:12 -0700 | [diff] [blame] | 858 |     auto intError = mComposer.setLayerDataspace(mDisplayId, mId, mDataSpace); | 
| Dan Stoza | 5df2a86 | 2016-03-24 16:19:37 -0700 | [diff] [blame] | 859 |     return static_cast<Error>(intError); | 
 | 860 | } | 
 | 861 |  | 
| Peiyong Lin | 2c327ac | 2018-04-19 22:06:34 -0700 | [diff] [blame] | 862 | Error Layer::setPerFrameMetadata(const int32_t supportedPerFrameMetadata, | 
 | 863 |         const android::HdrMetadata& metadata) | 
 | 864 | { | 
| Courtney Goeltzenleuchter | f9c98e5 | 2018-02-12 07:23:17 -0700 | [diff] [blame] | 865 |     if (metadata == mHdrMetadata) { | 
 | 866 |         return Error::None; | 
 | 867 |     } | 
 | 868 |  | 
 | 869 |     mHdrMetadata = metadata; | 
| Peiyong Lin | 2c327ac | 2018-04-19 22:06:34 -0700 | [diff] [blame] | 870 |     int validTypes = mHdrMetadata.validTypes & supportedPerFrameMetadata; | 
 | 871 |     std::vector<Hwc2::PerFrameMetadata> perFrameMetadatas; | 
 | 872 |     if (validTypes & HdrMetadata::SMPTE2086) { | 
 | 873 |         perFrameMetadatas.insert(perFrameMetadatas.end(), | 
 | 874 |                                  {{Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X, | 
 | 875 |                                          mHdrMetadata.smpte2086.displayPrimaryRed.x}, | 
 | 876 |                                    {Hwc2::PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y, | 
 | 877 |                                          mHdrMetadata.smpte2086.displayPrimaryRed.y}, | 
 | 878 |                                    {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X, | 
 | 879 |                                          mHdrMetadata.smpte2086.displayPrimaryGreen.x}, | 
 | 880 |                                    {Hwc2::PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y, | 
 | 881 |                                          mHdrMetadata.smpte2086.displayPrimaryGreen.y}, | 
 | 882 |                                    {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X, | 
 | 883 |                                          mHdrMetadata.smpte2086.displayPrimaryBlue.x}, | 
 | 884 |                                    {Hwc2::PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y, | 
 | 885 |                                          mHdrMetadata.smpte2086.displayPrimaryBlue.y}, | 
 | 886 |                                    {Hwc2::PerFrameMetadataKey::WHITE_POINT_X, | 
 | 887 |                                          mHdrMetadata.smpte2086.whitePoint.x}, | 
 | 888 |                                    {Hwc2::PerFrameMetadataKey::WHITE_POINT_Y, | 
 | 889 |                                          mHdrMetadata.smpte2086.whitePoint.y}, | 
 | 890 |                                    {Hwc2::PerFrameMetadataKey::MAX_LUMINANCE, | 
 | 891 |                                          mHdrMetadata.smpte2086.maxLuminance}, | 
 | 892 |                                    {Hwc2::PerFrameMetadataKey::MIN_LUMINANCE, | 
 | 893 |                                          mHdrMetadata.smpte2086.minLuminance}}); | 
 | 894 |     } | 
 | 895 |  | 
 | 896 |     if (validTypes & HdrMetadata::CTA861_3) { | 
 | 897 |         perFrameMetadatas.insert(perFrameMetadatas.end(), | 
 | 898 |                                  {{Hwc2::PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL, | 
 | 899 |                                          mHdrMetadata.cta8613.maxContentLightLevel}, | 
 | 900 |                                    {Hwc2::PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL, | 
 | 901 |                                          mHdrMetadata.cta8613.maxFrameAverageLightLevel}}); | 
 | 902 |     } | 
 | 903 |  | 
 | 904 |     auto intError = mComposer.setLayerPerFrameMetadata(mDisplayId, mId, perFrameMetadatas); | 
| Courtney Goeltzenleuchter | f9c98e5 | 2018-02-12 07:23:17 -0700 | [diff] [blame] | 905 |     return static_cast<Error>(intError); | 
 | 906 | } | 
 | 907 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 908 | Error Layer::setDisplayFrame(const Rect& frame) | 
 | 909 | { | 
| Chia-I Wu | cd8d7f0 | 2016-11-16 11:02:31 +0800 | [diff] [blame] | 910 |     Hwc2::IComposerClient::Rect hwcRect{frame.left, frame.top, | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 911 |         frame.right, frame.bottom}; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 912 |     auto intError = mComposer.setLayerDisplayFrame(mDisplayId, mId, hwcRect); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 913 |     return static_cast<Error>(intError); | 
 | 914 | } | 
 | 915 |  | 
 | 916 | Error Layer::setPlaneAlpha(float alpha) | 
 | 917 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 918 |     auto intError = mComposer.setLayerPlaneAlpha(mDisplayId, mId, alpha); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 919 |     return static_cast<Error>(intError); | 
 | 920 | } | 
 | 921 |  | 
 | 922 | Error Layer::setSidebandStream(const native_handle_t* stream) | 
 | 923 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 924 |     if (mCapabilities.count(Capability::SidebandStream) == 0) { | 
| Dan Stoza | 09e7a27 | 2016-04-14 12:31:01 -0700 | [diff] [blame] | 925 |         ALOGE("Attempted to call setSidebandStream without checking that the " | 
 | 926 |                 "device supports sideband streams"); | 
 | 927 |         return Error::Unsupported; | 
 | 928 |     } | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 929 |     auto intError = mComposer.setLayerSidebandStream(mDisplayId, mId, stream); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 930 |     return static_cast<Error>(intError); | 
 | 931 | } | 
 | 932 |  | 
 | 933 | Error Layer::setSourceCrop(const FloatRect& crop) | 
 | 934 | { | 
| Chia-I Wu | cd8d7f0 | 2016-11-16 11:02:31 +0800 | [diff] [blame] | 935 |     Hwc2::IComposerClient::FRect hwcRect{ | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 936 |         crop.left, crop.top, crop.right, crop.bottom}; | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 937 |     auto intError = mComposer.setLayerSourceCrop(mDisplayId, mId, hwcRect); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 938 |     return static_cast<Error>(intError); | 
 | 939 | } | 
 | 940 |  | 
 | 941 | Error Layer::setTransform(Transform transform) | 
 | 942 | { | 
| Chia-I Wu | aab99f5 | 2016-10-05 12:59:58 +0800 | [diff] [blame] | 943 |     auto intTransform = static_cast<Hwc2::Transform>(transform); | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 944 |     auto intError = mComposer.setLayerTransform(mDisplayId, mId, intTransform); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 945 |     return static_cast<Error>(intError); | 
 | 946 | } | 
 | 947 |  | 
 | 948 | Error Layer::setVisibleRegion(const Region& region) | 
 | 949 | { | 
 | 950 |     size_t rectCount = 0; | 
 | 951 |     auto rectArray = region.getArray(&rectCount); | 
 | 952 |  | 
| Chia-I Wu | cd8d7f0 | 2016-11-16 11:02:31 +0800 | [diff] [blame] | 953 |     std::vector<Hwc2::IComposerClient::Rect> hwcRects; | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 954 |     for (size_t rect = 0; rect < rectCount; ++rect) { | 
 | 955 |         hwcRects.push_back({rectArray[rect].left, rectArray[rect].top, | 
 | 956 |                 rectArray[rect].right, rectArray[rect].bottom}); | 
 | 957 |     } | 
 | 958 |  | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 959 |     auto intError = mComposer.setLayerVisibleRegion(mDisplayId, mId, hwcRects); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 960 |     return static_cast<Error>(intError); | 
 | 961 | } | 
 | 962 |  | 
 | 963 | Error Layer::setZOrder(uint32_t z) | 
 | 964 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 965 |     auto intError = mComposer.setLayerZOrder(mDisplayId, mId, z); | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 966 |     return static_cast<Error>(intError); | 
 | 967 | } | 
 | 968 |  | 
| Daniel Nicoara | 2f5f8a5 | 2016-12-20 16:11:58 -0500 | [diff] [blame] | 969 | Error Layer::setInfo(uint32_t type, uint32_t appId) | 
 | 970 | { | 
| Steven Thomas | 94e35b9 | 2017-07-26 18:48:28 -0700 | [diff] [blame] | 971 |   auto intError = mComposer.setLayerInfo(mDisplayId, mId, type, appId); | 
| Daniel Nicoara | 2f5f8a5 | 2016-12-20 16:11:58 -0500 | [diff] [blame] | 972 |   return static_cast<Error>(intError); | 
 | 973 | } | 
 | 974 |  | 
| Dan Stoza | 651bf31 | 2015-10-23 17:03:17 -0700 | [diff] [blame] | 975 | } // namespace HWC2 |