1 /*
2 // Copyright (c) 2014 Intel Corporation 
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 ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
18 
19 #include <hardware/hardware.h>
20 #include <string.h>
21 #include <stdio.h>
22 #include <fcntl.h>
23 #include <errno.h>
24 #include <common/utils/HwcTrace.h>
25 #include <Hwcomposer.h>
26 #include <utils/Trace.h>
27 
28 #define GET_HWC_RETURN_X_IF_NULL(X) \
29     CTRACE(); \
30     Hwcomposer *hwc = static_cast<Hwcomposer*>(dev); \
31     do {\
32         if (!hwc) { \
33             ELOGTRACE("invalid HWC device."); \
34             return X; \
35         } \
36     } while (0)
37 
38 
39 #define GET_HWC_RETURN_ERROR_IF_NULL()        GET_HWC_RETURN_X_IF_NULL(-EINVAL)
40 #define GET_HWC_RETURN_VOID_IF_NULL()         GET_HWC_RETURN_X_IF_NULL()
41 
42 
43 namespace android {
44 namespace intel {
45 
hwc_prepare(struct hwc_composer_device_1 * dev,size_t numDisplays,hwc_display_contents_1_t ** displays)46 static int hwc_prepare(struct hwc_composer_device_1 *dev,
47                           size_t numDisplays,
48                           hwc_display_contents_1_t** displays)
49 {
50     ATRACE_CALL();
51     GET_HWC_RETURN_ERROR_IF_NULL();
52     if (!hwc->prepare(numDisplays, displays)) {
53         ELOGTRACE("failed to prepare");
54         return -EINVAL;
55     }
56     return 0;
57 }
58 
hwc_set(struct hwc_composer_device_1 * dev,size_t numDisplays,hwc_display_contents_1_t ** displays)59 static int hwc_set(struct hwc_composer_device_1 *dev,
60                      size_t numDisplays,
61                      hwc_display_contents_1_t **displays)
62 {
63     ATRACE_CALL();
64     GET_HWC_RETURN_ERROR_IF_NULL();
65     if (!hwc->commit(numDisplays, displays)) {
66         ELOGTRACE("failed to commit");
67         return -EINVAL;
68     }
69     return 0;
70 }
71 
hwc_dump(struct hwc_composer_device_1 * dev,char * buff,int buff_len)72 static void hwc_dump(struct hwc_composer_device_1 *dev,
73                        char *buff,
74                        int buff_len)
75 {
76     GET_HWC_RETURN_VOID_IF_NULL();
77     hwc->dump(buff, buff_len, 0);
78 }
79 
hwc_registerProcs(struct hwc_composer_device_1 * dev,hwc_procs_t const * procs)80 void hwc_registerProcs(struct hwc_composer_device_1 *dev,
81                           hwc_procs_t const *procs)
82 {
83     GET_HWC_RETURN_VOID_IF_NULL();
84     hwc->registerProcs(procs);
85 }
86 
hwc_device_close(struct hw_device_t *)87 static int hwc_device_close(struct hw_device_t * /* dev */)
88 {
89     CTRACE();
90     Hwcomposer::releaseInstance();
91     return 0;
92 }
93 
hwc_query(struct hwc_composer_device_1 *,int what,int *)94 static int hwc_query(struct hwc_composer_device_1 * /* dev */,
95         int what, int* /* value */)
96 {
97     (void) what;
98     ALOGTRACE("what = %d", what);
99     return -EINVAL;
100 }
101 
hwc_eventControl(struct hwc_composer_device_1 * dev,int disp,int event,int enabled)102 static int hwc_eventControl(struct hwc_composer_device_1 *dev,
103                                 int disp,
104                                 int event,
105                                 int enabled)
106 {
107     bool ret;
108     ATRACE_CALL();
109     GET_HWC_RETURN_ERROR_IF_NULL();
110 
111     switch (event) {
112     case HWC_EVENT_VSYNC:
113         ret = hwc->vsyncControl(disp, enabled);
114         if (ret == false) {
115             ELOGTRACE("failed to control vsync");
116             return -EINVAL;
117         }
118         break;
119     default:
120         WLOGTRACE("unsupported event %d", event);
121         break;
122     }
123 
124     return 0;
125 }
126 
hwc_getDisplayConfigs(hwc_composer_device_1_t * dev,int disp,uint32_t * configs,size_t * numConfigs)127 static int hwc_getDisplayConfigs(hwc_composer_device_1_t *dev,
128                                      int disp,
129                                      uint32_t *configs,
130                                      size_t *numConfigs)
131 {
132     ATRACE_CALL();
133     GET_HWC_RETURN_ERROR_IF_NULL();
134     bool ret = hwc->getDisplayConfigs(disp, configs, numConfigs);
135     if (ret == false) {
136         WLOGTRACE("failed to get configs of disp %d", disp);
137         return -EINVAL;
138     }
139 
140     return 0;
141 }
142 
hwc_getDisplayAttributes(hwc_composer_device_1_t * dev,int disp,uint32_t config,const uint32_t * attributes,int32_t * values)143 static int hwc_getDisplayAttributes(hwc_composer_device_1_t *dev,
144                                         int disp,
145                                         uint32_t config,
146                                         const uint32_t *attributes,
147                                         int32_t *values)
148 {
149     ATRACE_CALL();
150     GET_HWC_RETURN_ERROR_IF_NULL();
151     bool ret = hwc->getDisplayAttributes(disp, config, attributes, values);
152     if (ret == false) {
153         WLOGTRACE("failed to get attributes of disp %d", disp);
154         return -EINVAL;
155     }
156 
157     return 0;
158 }
159 
hwc_compositionComplete(hwc_composer_device_1_t * dev,int disp)160 static int hwc_compositionComplete(hwc_composer_device_1_t *dev, int disp)
161 {
162     ATRACE_CALL();
163     GET_HWC_RETURN_ERROR_IF_NULL();
164     bool ret = hwc->compositionComplete(disp);
165     if (ret == false) {
166         ELOGTRACE("failed for disp %d", disp);
167         return -EINVAL;
168     }
169 
170     return 0;
171 }
172 
hwc_setPowerMode(hwc_composer_device_1_t * dev,int disp,int mode)173 static int hwc_setPowerMode(hwc_composer_device_1_t *dev, int disp, int mode)
174 {
175     ATRACE_CALL();
176     GET_HWC_RETURN_ERROR_IF_NULL();
177     bool ret = hwc->setPowerMode(disp, mode);
178     if (ret == false) {
179         WLOGTRACE("failed to set power mode of disp %d", disp);
180         return -EINVAL;
181     }
182 
183     return 0;
184 }
185 
hwc_getActiveConfig(hwc_composer_device_1_t * dev,int disp)186 static int hwc_getActiveConfig(hwc_composer_device_1_t *dev, int disp)
187 {
188     ATRACE_CALL();
189     GET_HWC_RETURN_ERROR_IF_NULL();
190     int ret = hwc->getActiveConfig(disp);
191     if (ret == -1) {
192         WLOGTRACE("failed to get active config of disp %d", disp);
193         return -EINVAL;
194     }
195 
196     return ret;
197 }
198 
hwc_setActiveConfig(hwc_composer_device_1_t * dev,int disp,int index)199 static int hwc_setActiveConfig(hwc_composer_device_1_t *dev, int disp, int index)
200 {
201     ATRACE_CALL();
202     GET_HWC_RETURN_ERROR_IF_NULL();
203     bool ret = hwc->setActiveConfig(disp, index);
204     if (ret == false) {
205         WLOGTRACE("failed to set active config of disp %d", disp);
206         return -EINVAL;
207     }
208 
209     return 0;
210 }
211 
212 // Todo: add hwc_setCursorPositionAsync after supporting patches
213 /*
214 static int hwc_setCursorPositionAsync(hwc_composer_device_1_t *dev, int disp, int x, int y)
215 {
216     ATRACE_CALL();
217     GET_HWC_RETURN_ERROR_IF_NULL();
218     bool ret = hwc->setCursorPositionAsync(disp, x, y);
219     if (ret == false) {
220         WLOGTRACE("failed to set cursor position of disp %d", disp);
221         return -EINVAL;
222     }
223 
224     return 0;
225 }
226 */
227 
228 //------------------------------------------------------------------------------
229 
hwc_device_open(const struct hw_module_t * module,const char * name,struct hw_device_t ** device)230 static int hwc_device_open(const struct hw_module_t* module,
231                               const char* name,
232                               struct hw_device_t** device)
233 {
234     if (!name) {
235         ELOGTRACE("invalid name.");
236         return -EINVAL;
237     }
238 
239     ALOGTRACE("open device %s", name);
240 
241     if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
242         ELOGTRACE("try to open unknown HWComposer %s", name);
243         return -EINVAL;
244     }
245 
246     Hwcomposer& hwc = Hwcomposer::getInstance();
247     // initialize our state here
248     if (hwc.initialize() == false) {
249         ELOGTRACE("failed to intialize HWComposer");
250         Hwcomposer::releaseInstance();
251         return -EINVAL;
252     }
253 
254     // initialize the procs
255     hwc.hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG;
256     hwc.hwc_composer_device_1_t::common.module =
257         const_cast<hw_module_t*>(module);
258     hwc.hwc_composer_device_1_t::common.close = hwc_device_close;
259 
260     hwc.hwc_composer_device_1_t::prepare = hwc_prepare;
261     hwc.hwc_composer_device_1_t::set = hwc_set;
262     hwc.hwc_composer_device_1_t::dump = hwc_dump;
263     hwc.hwc_composer_device_1_t::registerProcs = hwc_registerProcs;
264     hwc.hwc_composer_device_1_t::query = hwc_query;
265 
266     hwc.hwc_composer_device_1_t::eventControl = hwc_eventControl;
267     hwc.hwc_composer_device_1_t::getDisplayConfigs = hwc_getDisplayConfigs;
268     hwc.hwc_composer_device_1_t::getDisplayAttributes = hwc_getDisplayAttributes;
269 
270     // This is used to hack FBO switch flush issue in SurfaceFlinger.
271     hwc.hwc_composer_device_1_t::reserved_proc[0] = (void*)hwc_compositionComplete;
272     hwc.hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_4;
273     hwc.hwc_composer_device_1_t::setPowerMode = hwc_setPowerMode;
274     hwc.hwc_composer_device_1_t::getActiveConfig = hwc_getActiveConfig;
275     hwc.hwc_composer_device_1_t::setActiveConfig = hwc_setActiveConfig;
276     // Todo: add hwc_setCursorPositionAsync after supporting patches
277     hwc.hwc_composer_device_1_t::setCursorPositionAsync = NULL;
278 
279     *device = &hwc.hwc_composer_device_1_t::common;
280 
281     return 0;
282 }
283 
284 } // namespace intel
285 } // namespace android
286 
287 static struct hw_module_methods_t hwc_module_methods = {
288     open: android::intel::hwc_device_open
289 };
290 
291 hwc_module_t HAL_MODULE_INFO_SYM = {
292     common: {
293         tag: HARDWARE_MODULE_TAG,
294         version_major: 1,
295         version_minor: 4,
296         id: HWC_HARDWARE_MODULE_ID,
297         name: "Intel Hardware Composer",
298         author: "Intel",
299         methods: &hwc_module_methods,
300         dso: 0,
301         reserved: { 0 },
302     }
303 };
304