1 /* 2 * Copyright 2019 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 #ifndef LOG_TAG 20 #warning "HwcHal.h included without LOG_TAG" 21 #endif 22 23 #include <type_traits> 24 25 #include <android/hardware/graphics/composer/2.4/IComposerClient.h> 26 #include <composer-hal/2.4/ComposerHal.h> 27 #include <composer-passthrough/2.3/HwcHal.h> 28 #include <hardware/hwcomposer_defs.h> 29 30 namespace android { 31 namespace hardware { 32 namespace graphics { 33 namespace composer { 34 namespace V2_4 { 35 namespace passthrough { 36 37 namespace detail { 38 39 using common::V1_1::RenderIntent; 40 using common::V1_2::ColorMode; 41 using common::V1_2::Dataspace; 42 using common::V1_2::Hdr; 43 using common::V1_2::PixelFormat; 44 using V2_1::Config; 45 using V2_1::Display; 46 using V2_1::Layer; 47 using V2_4::Error; 48 49 // HwcHalImpl implements V2_*::hal::ComposerHal on top of hwcomposer2 50 template <typename Hal> 51 class HwcHalImpl : public V2_3::passthrough::detail::HwcHalImpl<Hal> { 52 public: registerEventCallback_2_4(hal::ComposerHal::EventCallback_2_4 * callback)53 void registerEventCallback_2_4(hal::ComposerHal::EventCallback_2_4* callback) override { 54 mEventCallback_2_4 = callback; 55 56 BaseType2_1::mDispatch.registerCallback( 57 mDevice, HWC2_CALLBACK_HOTPLUG, this, 58 reinterpret_cast<hwc2_function_pointer_t>(hotplugHook)); 59 BaseType2_1::mDispatch.registerCallback( 60 mDevice, HWC2_CALLBACK_REFRESH, this, 61 reinterpret_cast<hwc2_function_pointer_t>(refreshHook)); 62 BaseType2_1::mDispatch.registerCallback( 63 mDevice, HWC2_CALLBACK_VSYNC_2_4, this, 64 reinterpret_cast<hwc2_function_pointer_t>(vsync_2_4_Hook)); 65 BaseType2_1::mDispatch.registerCallback( 66 mDevice, HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, this, 67 reinterpret_cast<hwc2_function_pointer_t>(vsyncPeriodTimingChangedHook)); 68 BaseType2_1::mDispatch.registerCallback( 69 mDevice, HWC2_CALLBACK_SEAMLESS_POSSIBLE, this, 70 reinterpret_cast<hwc2_function_pointer_t>(seamlessPossibleHook)); 71 } 72 unregisterEventCallback_2_4()73 void unregisterEventCallback_2_4() override { 74 // we assume the callback functions 75 // 76 // - can be unregistered 77 // - can be in-flight 78 // - will never be called afterward 79 // 80 // which is likely incorrect 81 BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_HOTPLUG, this, nullptr); 82 BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_REFRESH, this, nullptr); 83 BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_2_4, this, nullptr); 84 BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_VSYNC_PERIOD_TIMING_CHANGED, 85 this, nullptr); 86 BaseType2_1::mDispatch.registerCallback(mDevice, HWC2_CALLBACK_SEAMLESS_POSSIBLE, this, 87 nullptr); 88 89 mEventCallback_2_4 = nullptr; 90 } 91 getDisplayCapabilities_2_4(Display display,std::vector<IComposerClient::DisplayCapability> * outCapabilities)92 Error getDisplayCapabilities_2_4( 93 Display display, 94 std::vector<IComposerClient::DisplayCapability>* outCapabilities) override { 95 std::vector<V2_3::IComposerClient::DisplayCapability> capabilities; 96 V2_3::Error error_2_3 = BaseType2_3::getDisplayCapabilities(display, &capabilities); 97 Error error = static_cast<Error>(error_2_3); 98 if (error != Error::NONE) { 99 return error; 100 } 101 outCapabilities->clear(); 102 outCapabilities->reserve(capabilities.size()); 103 for (auto capability : capabilities) { 104 outCapabilities->push_back(static_cast<IComposerClient::DisplayCapability>(capability)); 105 } 106 return Error::NONE; 107 } 108 getDisplayConnectionType(Display display,IComposerClient::DisplayConnectionType * outType)109 Error getDisplayConnectionType(Display display, 110 IComposerClient::DisplayConnectionType* outType) override { 111 if (!mDispatch.getDisplayConnectionType) { 112 return Error::UNSUPPORTED; 113 } 114 115 uint32_t type = HWC2_DISPLAY_CONNECTION_TYPE_INTERNAL; 116 int32_t error = mDispatch.getDisplayConnectionType(mDevice, display, &type); 117 *outType = static_cast<IComposerClient::DisplayConnectionType>(type); 118 return static_cast<Error>(error); 119 } 120 getDisplayAttribute_2_4(Display display,Config config,IComposerClient::Attribute attribute,int32_t * outValue)121 Error getDisplayAttribute_2_4(Display display, Config config, 122 IComposerClient::Attribute attribute, 123 int32_t* outValue) override { 124 int32_t err = BaseType2_1::mDispatch.getDisplayAttribute( 125 mDevice, display, config, static_cast<int32_t>(attribute), outValue); 126 if (err != HWC2_ERROR_NONE && *outValue == -1) { 127 // Convert the error from hwcomposer2 to IComposerClient definition 128 return Error::BAD_PARAMETER; 129 } 130 return static_cast<Error>(err); 131 } 132 getDisplayVsyncPeriod(Display display,VsyncPeriodNanos * outVsyncPeriod)133 Error getDisplayVsyncPeriod(Display display, VsyncPeriodNanos* outVsyncPeriod) override { 134 if (!mDispatch.getDisplayVsyncPeriod) { 135 return Error::UNSUPPORTED; 136 } 137 138 int32_t error = mDispatch.getDisplayVsyncPeriod(mDevice, display, outVsyncPeriod); 139 if (error != HWC2_ERROR_NONE) { 140 return static_cast<Error>(error); 141 } 142 return Error::NONE; 143 } 144 setActiveConfigWithConstraints(Display display,Config config,const IComposerClient::VsyncPeriodChangeConstraints & vsyncPeriodChangeConstraints,VsyncPeriodChangeTimeline * timeline)145 Error setActiveConfigWithConstraints( 146 Display display, Config config, 147 const IComposerClient::VsyncPeriodChangeConstraints& vsyncPeriodChangeConstraints, 148 VsyncPeriodChangeTimeline* timeline) override { 149 if (!mDispatch.setActiveConfigWithConstraints) { 150 return Error::UNSUPPORTED; 151 } 152 153 hwc_vsync_period_change_constraints_t vsync_period_change_constraints; 154 vsync_period_change_constraints.desiredTimeNanos = 155 vsyncPeriodChangeConstraints.desiredTimeNanos; 156 vsync_period_change_constraints.seamlessRequired = 157 vsyncPeriodChangeConstraints.seamlessRequired; 158 159 hwc_vsync_period_change_timeline_t out_timeline; 160 int32_t error = mDispatch.setActiveConfigWithConstraints( 161 mDevice, display, config, &vsync_period_change_constraints, &out_timeline); 162 if (error != HWC2_ERROR_NONE) { 163 return static_cast<Error>(error); 164 } 165 timeline->newVsyncAppliedTimeNanos = out_timeline.newVsyncAppliedTimeNanos; 166 timeline->refreshRequired = out_timeline.refreshRequired; 167 timeline->refreshTimeNanos = out_timeline.refreshTimeNanos; 168 return Error::NONE; 169 } 170 setAutoLowLatencyMode(Display display,bool on)171 Error setAutoLowLatencyMode(Display display, bool on) override { 172 if (!mDispatch.setAutoLowLatencyMode) { 173 return Error::UNSUPPORTED; 174 } 175 176 int32_t error = mDispatch.setAutoLowLatencyMode(mDevice, display, on); 177 if (error != HWC2_ERROR_NONE) { 178 return static_cast<Error>(error); 179 } 180 return Error::NONE; 181 } 182 getSupportedContentTypes(Display display,std::vector<IComposerClient::ContentType> * outSupportedContentTypes)183 Error getSupportedContentTypes( 184 Display display, 185 std::vector<IComposerClient::ContentType>* outSupportedContentTypes) override { 186 if (!mDispatch.getSupportedContentTypes) { 187 return Error::UNSUPPORTED; 188 } 189 190 uint32_t count = 0; 191 int32_t error = mDispatch.getSupportedContentTypes(mDevice, display, &count, nullptr); 192 if (error != HWC2_ERROR_NONE) { 193 return static_cast<Error>(error); 194 } 195 196 outSupportedContentTypes->resize(count); 197 198 error = mDispatch.getSupportedContentTypes( 199 mDevice, display, &count, 200 reinterpret_cast<std::underlying_type<IComposerClient::ContentType>::type*>( 201 outSupportedContentTypes->data())); 202 if (error != HWC2_ERROR_NONE) { 203 *outSupportedContentTypes = std::vector<IComposerClient::ContentType>(); 204 return static_cast<Error>(error); 205 } 206 return Error::NONE; 207 } 208 setContentType(Display display,IComposerClient::ContentType contentType)209 Error setContentType(Display display, IComposerClient::ContentType contentType) override { 210 if (!mDispatch.setContentType) { 211 return Error::UNSUPPORTED; 212 } 213 214 int32_t error = 215 mDispatch.setContentType(mDevice, display, static_cast<int32_t>(contentType)); 216 if (error != HWC2_ERROR_NONE) { 217 return static_cast<Error>(error); 218 } 219 return Error::NONE; 220 } 221 validateDisplay_2_4(Display display,std::vector<Layer> * outChangedLayers,std::vector<IComposerClient::Composition> * outCompositionTypes,uint32_t * outDisplayRequestMask,std::vector<Layer> * outRequestedLayers,std::vector<uint32_t> * outRequestMasks,IComposerClient::ClientTargetProperty * outClientTargetProperty)222 Error validateDisplay_2_4( 223 Display display, std::vector<Layer>* outChangedLayers, 224 std::vector<IComposerClient::Composition>* outCompositionTypes, 225 uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers, 226 std::vector<uint32_t>* outRequestMasks, 227 IComposerClient::ClientTargetProperty* outClientTargetProperty) override { 228 auto err = static_cast<Error>(BaseType2_1::validateDisplay( 229 display, outChangedLayers, outCompositionTypes, outDisplayRequestMask, 230 outRequestedLayers, outRequestMasks)); 231 if (err != Error::NONE) { 232 return err; 233 } 234 235 if (mDispatch.getClientTargetProperty) { 236 hwc_client_target_property_t clientTargetProperty; 237 err = static_cast<Error>( 238 mDispatch.getClientTargetProperty(mDevice, display, &clientTargetProperty)); 239 outClientTargetProperty->pixelFormat = 240 static_cast<PixelFormat>(clientTargetProperty.pixelFormat); 241 outClientTargetProperty->dataspace = 242 static_cast<Dataspace>(clientTargetProperty.dataspace); 243 } 244 245 return err; 246 } 247 setLayerGenericMetadata(Display display,Layer layer,const std::string & key,bool mandatory,const std::vector<uint8_t> & value)248 Error setLayerGenericMetadata(Display display, Layer layer, const std::string& key, 249 bool mandatory, const std::vector<uint8_t>& value) override { 250 if (!mDispatch.setLayerGenericMetadata) { 251 return Error::UNSUPPORTED; 252 } 253 254 if (key.size() > std::numeric_limits<uint32_t>::max()) { 255 return Error::BAD_PARAMETER; 256 } 257 258 if (value.size() > std::numeric_limits<uint32_t>::max()) { 259 return Error::BAD_PARAMETER; 260 } 261 262 int32_t error = mDispatch.setLayerGenericMetadata( 263 mDevice, display, layer, static_cast<uint32_t>(key.size()), key.c_str(), mandatory, 264 static_cast<uint32_t>(value.size()), value.data()); 265 return static_cast<Error>(error); 266 } 267 getLayerGenericMetadataKeys(std::vector<IComposerClient::LayerGenericMetadataKey> * outKeys)268 Error getLayerGenericMetadataKeys( 269 std::vector<IComposerClient::LayerGenericMetadataKey>* outKeys) override { 270 if (!mDispatch.getLayerGenericMetadataKey) { 271 return Error::UNSUPPORTED; 272 } 273 274 std::vector<IComposerClient::LayerGenericMetadataKey> keys; 275 276 uint32_t index = 0; 277 uint32_t keyLength = 0; 278 while (true) { 279 mDispatch.getLayerGenericMetadataKey(mDevice, index, &keyLength, nullptr, nullptr); 280 if (keyLength == 0) { 281 break; 282 } 283 284 IComposerClient::LayerGenericMetadataKey key; 285 std::string keyName; 286 keyName.resize(keyLength); 287 mDispatch.getLayerGenericMetadataKey(mDevice, index, &keyLength, keyName.data(), 288 &key.mandatory); 289 key.name = keyName; 290 keys.emplace_back(std::move(key)); 291 292 // Only attempt to load the first 100 keys to avoid an infinite loop 293 // if something goes wrong 294 if (++index > 100) { 295 break; 296 } 297 } 298 299 *outKeys = std::move(keys); 300 return Error::NONE; 301 } 302 303 protected: initDispatch()304 bool initDispatch() override { 305 if (!BaseType2_3::initDispatch()) { 306 return false; 307 } 308 309 if (!BaseType2_1::initDispatch(HWC2_FUNCTION_GET_DISPLAY_VSYNC_PERIOD, 310 &mDispatch.getDisplayVsyncPeriod) || 311 !BaseType2_1::initDispatch(HWC2_FUNCTION_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS, 312 &mDispatch.setActiveConfigWithConstraints)) { 313 return false; 314 } 315 316 this->initOptionalDispatch(HWC2_FUNCTION_GET_DISPLAY_CONNECTION_TYPE, 317 &mDispatch.getDisplayConnectionType); 318 this->initOptionalDispatch(HWC2_FUNCTION_SET_AUTO_LOW_LATENCY_MODE, 319 &mDispatch.setAutoLowLatencyMode); 320 this->initOptionalDispatch(HWC2_FUNCTION_GET_SUPPORTED_CONTENT_TYPES, 321 &mDispatch.getSupportedContentTypes); 322 this->initOptionalDispatch(HWC2_FUNCTION_SET_CONTENT_TYPE, &mDispatch.setContentType); 323 this->initOptionalDispatch(HWC2_FUNCTION_GET_CLIENT_TARGET_PROPERTY, 324 &mDispatch.getClientTargetProperty); 325 this->initOptionalDispatch(HWC2_FUNCTION_SET_LAYER_GENERIC_METADATA, 326 &mDispatch.setLayerGenericMetadata); 327 this->initOptionalDispatch(HWC2_FUNCTION_GET_LAYER_GENERIC_METADATA_KEY, 328 &mDispatch.getLayerGenericMetadataKey); 329 330 return true; 331 } 332 hotplugHook(hwc2_callback_data_t callbackData,hwc2_display_t display,int32_t connected)333 static void hotplugHook(hwc2_callback_data_t callbackData, hwc2_display_t display, 334 int32_t connected) { 335 auto hal = static_cast<HwcHalImpl*>(callbackData); 336 hal->mEventCallback_2_4->onHotplug(display, 337 static_cast<IComposerCallback::Connection>(connected)); 338 } 339 refreshHook(hwc2_callback_data_t callbackData,hwc2_display_t display)340 static void refreshHook(hwc2_callback_data_t callbackData, hwc2_display_t display) { 341 auto hal = static_cast<HwcHalImpl*>(callbackData); 342 hal->mEventCallback_2_4->onRefresh(display); 343 } 344 vsyncHook(hwc2_callback_data_t callbackData,hwc2_display_t display,int64_t timestamp)345 static void vsyncHook(hwc2_callback_data_t callbackData, hwc2_display_t display, 346 int64_t timestamp) { 347 auto hal = static_cast<HwcHalImpl*>(callbackData); 348 hal->mEventCallback_2_4->onVsync(display, timestamp); 349 } 350 vsync_2_4_Hook(hwc2_callback_data_t callbackData,hwc2_display_t display,int64_t timestamp,hwc2_vsync_period_t vsyncPeriodNanos)351 static void vsync_2_4_Hook(hwc2_callback_data_t callbackData, hwc2_display_t display, 352 int64_t timestamp, hwc2_vsync_period_t vsyncPeriodNanos) { 353 auto hal = static_cast<HwcHalImpl*>(callbackData); 354 hal->mEventCallback_2_4->onVsync_2_4(display, timestamp, vsyncPeriodNanos); 355 } 356 vsyncPeriodTimingChangedHook(hwc2_callback_data_t callbackData,hwc2_display_t display,hwc_vsync_period_change_timeline_t * updated_timeline)357 static void vsyncPeriodTimingChangedHook(hwc2_callback_data_t callbackData, 358 hwc2_display_t display, 359 hwc_vsync_period_change_timeline_t* updated_timeline) { 360 auto hal = static_cast<HwcHalImpl*>(callbackData); 361 VsyncPeriodChangeTimeline timeline; 362 timeline.newVsyncAppliedTimeNanos = updated_timeline->newVsyncAppliedTimeNanos; 363 timeline.refreshRequired = updated_timeline->refreshRequired; 364 timeline.refreshTimeNanos = updated_timeline->refreshTimeNanos; 365 hal->mEventCallback_2_4->onVsyncPeriodTimingChanged(display, timeline); 366 } 367 seamlessPossibleHook(hwc2_callback_data_t callbackData,hwc2_display_t display)368 static void seamlessPossibleHook(hwc2_callback_data_t callbackData, hwc2_display_t display) { 369 auto hal = static_cast<HwcHalImpl*>(callbackData); 370 hal->mEventCallback_2_4->onSeamlessPossible(display); 371 } 372 373 private: 374 struct { 375 HWC2_PFN_GET_DISPLAY_CONNECTION_TYPE getDisplayConnectionType; 376 HWC2_PFN_GET_DISPLAY_VSYNC_PERIOD getDisplayVsyncPeriod; 377 HWC2_PFN_SET_ACTIVE_CONFIG_WITH_CONSTRAINTS setActiveConfigWithConstraints; 378 HWC2_PFN_SET_AUTO_LOW_LATENCY_MODE setAutoLowLatencyMode; 379 HWC2_PFN_GET_SUPPORTED_CONTENT_TYPES getSupportedContentTypes; 380 HWC2_PFN_SET_CONTENT_TYPE setContentType; 381 HWC2_PFN_GET_CLIENT_TARGET_PROPERTY getClientTargetProperty; 382 HWC2_PFN_SET_LAYER_GENERIC_METADATA setLayerGenericMetadata; 383 HWC2_PFN_GET_LAYER_GENERIC_METADATA_KEY getLayerGenericMetadataKey; 384 } mDispatch = {}; 385 386 hal::ComposerHal::EventCallback_2_4* mEventCallback_2_4 = nullptr; 387 388 using BaseType2_1 = V2_1::passthrough::detail::HwcHalImpl<Hal>; 389 using BaseType2_3 = V2_3::passthrough::detail::HwcHalImpl<Hal>; 390 using BaseType2_1::mDevice; 391 }; 392 393 } // namespace detail 394 395 using HwcHal = detail::HwcHalImpl<hal::ComposerHal>; 396 397 } // namespace passthrough 398 } // namespace V2_4 399 } // namespace composer 400 } // namespace graphics 401 } // namespace hardware 402 } // namespace android 403