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