1 /* 2 * Copyright 2016 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 "HwcLoader.h included without LOG_TAG" 21 #endif 22 23 #include <memory> 24 25 #include <composer-hal/2.1/Composer.h> 26 #include <composer-passthrough/2.1/HwcHal.h> 27 #include <hardware/fb.h> 28 #include <hardware/gralloc.h> 29 #include <hardware/hardware.h> 30 #include <hardware/hwcomposer.h> 31 #include <hardware/hwcomposer2.h> 32 #include <hwc2on1adapter/HWC2On1Adapter.h> 33 #include <hwc2onfbadapter/HWC2OnFbAdapter.h> 34 #include <log/log.h> 35 36 namespace android { 37 namespace hardware { 38 namespace graphics { 39 namespace composer { 40 namespace V2_1 { 41 namespace passthrough { 42 43 class HwcLoader { 44 public: load()45 static IComposer* load() { 46 const hw_module_t* module = loadModule(); 47 if (!module) { 48 return nullptr; 49 } 50 51 auto hal = createHalWithAdapter(module); 52 if (!hal) { 53 return nullptr; 54 } 55 56 return createComposer(std::move(hal)); 57 } 58 59 // load hwcomposer2 module loadModule()60 static const hw_module_t* loadModule() { 61 const hw_module_t* module; 62 int error = hw_get_module(HWC_HARDWARE_MODULE_ID, &module); 63 if (error) { 64 ALOGI("falling back to gralloc module"); 65 error = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); 66 } 67 68 if (error) { 69 ALOGE("failed to get hwcomposer or gralloc module"); 70 return nullptr; 71 } 72 73 return module; 74 } 75 76 // create a ComposerHal instance createHal(const hw_module_t * module)77 static std::unique_ptr<hal::ComposerHal> createHal(const hw_module_t* module) { 78 auto hal = std::make_unique<HwcHal>(); 79 return hal->initWithModule(module) ? std::move(hal) : nullptr; 80 } 81 82 // create a ComposerHal instance, insert an adapter if necessary createHalWithAdapter(const hw_module_t * module)83 static std::unique_ptr<hal::ComposerHal> createHalWithAdapter(const hw_module_t* module) { 84 bool adapted; 85 hwc2_device_t* device = openDeviceWithAdapter(module, &adapted); 86 if (!device) { 87 return nullptr; 88 } 89 auto hal = std::make_unique<HwcHal>(); 90 return hal->initWithDevice(std::move(device), !adapted) ? std::move(hal) : nullptr; 91 } 92 93 // create an IComposer instance createComposer(std::unique_ptr<hal::ComposerHal> hal)94 static IComposer* createComposer(std::unique_ptr<hal::ComposerHal> hal) { 95 return hal::Composer::create(std::move(hal)).release(); 96 } 97 98 protected: 99 // open hwcomposer2 device, install an adapter if necessary openDeviceWithAdapter(const hw_module_t * module,bool * outAdapted)100 static hwc2_device_t* openDeviceWithAdapter(const hw_module_t* module, bool* outAdapted) { 101 if (module->id && std::string(module->id) == GRALLOC_HARDWARE_MODULE_ID) { 102 *outAdapted = true; 103 return adaptGrallocModule(module); 104 } 105 106 hw_device_t* device; 107 int error = module->methods->open(module, HWC_HARDWARE_COMPOSER, &device); 108 if (error) { 109 ALOGE("failed to open hwcomposer device: %s", strerror(-error)); 110 return nullptr; 111 } 112 113 int major = (device->version >> 24) & 0xf; 114 if (major != 2) { 115 *outAdapted = true; 116 return adaptHwc1Device(std::move(reinterpret_cast<hwc_composer_device_1*>(device))); 117 } 118 119 *outAdapted = false; 120 return reinterpret_cast<hwc2_device_t*>(device); 121 } 122 123 private: adaptGrallocModule(const hw_module_t * module)124 static hwc2_device_t* adaptGrallocModule(const hw_module_t* module) { 125 framebuffer_device_t* device; 126 int error = framebuffer_open(module, &device); 127 if (error) { 128 ALOGE("failed to open framebuffer device: %s", strerror(-error)); 129 return nullptr; 130 } 131 132 return new HWC2OnFbAdapter(device); 133 } 134 adaptHwc1Device(hwc_composer_device_1 * device)135 static hwc2_device_t* adaptHwc1Device(hwc_composer_device_1* device) { 136 int minor = (device->common.version >> 16) & 0xf; 137 if (minor < 1) { 138 ALOGE("hwcomposer 1.0 is not supported"); 139 device->common.close(&device->common); 140 return nullptr; 141 } 142 143 return new HWC2On1Adapter(device); 144 } 145 }; 146 147 } // namespace passthrough 148 } // namespace V2_1 149 } // namespace composer 150 } // namespace graphics 151 } // namespace hardware 152 } // namespace android 153