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 36namespace android { 37namespace hardware { 38namespace graphics { 39namespace composer { 40namespace V2_1 { 41namespace passthrough { 42 43class HwcLoader { 44 public: 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 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 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 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 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 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: 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 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