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_blank(hwc_composer_device_1_t * dev,int disp,int blank)127 static int hwc_blank(hwc_composer_device_1_t *dev, int disp, int blank)
128 {
129     ATRACE_CALL();
130     GET_HWC_RETURN_ERROR_IF_NULL();
131     bool ret = hwc->blank(disp, blank);
132     if (ret == false) {
133         ELOGTRACE("failed to blank disp %d, blank %d", disp, blank);
134         return -EINVAL;
135     }
136 
137     return 0;
138 }
139 
hwc_getDisplayConfigs(hwc_composer_device_1_t * dev,int disp,uint32_t * configs,size_t * numConfigs)140 static int hwc_getDisplayConfigs(hwc_composer_device_1_t *dev,
141                                      int disp,
142                                      uint32_t *configs,
143                                      size_t *numConfigs)
144 {
145     ATRACE_CALL();
146     GET_HWC_RETURN_ERROR_IF_NULL();
147     bool ret = hwc->getDisplayConfigs(disp, configs, numConfigs);
148     if (ret == false) {
149         WLOGTRACE("failed to get configs of disp %d", disp);
150         return -EINVAL;
151     }
152 
153     return 0;
154 }
155 
hwc_getDisplayAttributes(hwc_composer_device_1_t * dev,int disp,uint32_t config,const uint32_t * attributes,int32_t * values)156 static int hwc_getDisplayAttributes(hwc_composer_device_1_t *dev,
157                                         int disp,
158                                         uint32_t config,
159                                         const uint32_t *attributes,
160                                         int32_t *values)
161 {
162     ATRACE_CALL();
163     GET_HWC_RETURN_ERROR_IF_NULL();
164     bool ret = hwc->getDisplayAttributes(disp, config, attributes, values);
165     if (ret == false) {
166         WLOGTRACE("failed to get attributes of disp %d", disp);
167         return -EINVAL;
168     }
169 
170     return 0;
171 }
172 
hwc_compositionComplete(hwc_composer_device_1_t * dev,int disp)173 static int hwc_compositionComplete(hwc_composer_device_1_t *dev, int disp)
174 {
175     ATRACE_CALL();
176     GET_HWC_RETURN_ERROR_IF_NULL();
177     bool ret = hwc->compositionComplete(disp);
178     if (ret == false) {
179         ELOGTRACE("failed for disp %d", disp);
180         return -EINVAL;
181     }
182 
183     return 0;
184 }
185 
hwc_setPowerMode(hwc_composer_device_1_t * dev,int disp,int mode)186 static int hwc_setPowerMode(hwc_composer_device_1_t *dev, int disp, int mode)
187 {
188     ATRACE_CALL();
189     GET_HWC_RETURN_ERROR_IF_NULL();
190     bool ret = hwc->setPowerMode(disp, mode);
191     if (ret == false) {
192         WLOGTRACE("failed to set power mode of disp %d", disp);
193         return -EINVAL;
194     }
195 
196     return 0;
197 }
198 
hwc_getActiveConfig(hwc_composer_device_1_t * dev,int disp)199 static int hwc_getActiveConfig(hwc_composer_device_1_t *dev, int disp)
200 {
201     ATRACE_CALL();
202     GET_HWC_RETURN_ERROR_IF_NULL();
203     int ret = hwc->getActiveConfig(disp);
204     if (ret == -1) {
205         WLOGTRACE("failed to get active config of disp %d", disp);
206         return -EINVAL;
207     }
208 
209     return ret;
210 }
211 
hwc_setActiveConfig(hwc_composer_device_1_t * dev,int disp,int index)212 static int hwc_setActiveConfig(hwc_composer_device_1_t *dev, int disp, int index)
213 {
214     ATRACE_CALL();
215     GET_HWC_RETURN_ERROR_IF_NULL();
216     bool ret = hwc->setActiveConfig(disp, index);
217     if (ret == false) {
218         WLOGTRACE("failed to set active config of disp %d", disp);
219         return -EINVAL;
220     }
221 
222     return 0;
223 }
224 
hwc_setCursorPositionAsync(hwc_composer_device_1_t * dev,int disp,int x,int y)225 static int hwc_setCursorPositionAsync(hwc_composer_device_1_t *dev, int disp, int x, int y)
226 {
227     ATRACE_CALL();
228     GET_HWC_RETURN_ERROR_IF_NULL();
229     bool ret = hwc->setCursorPositionAsync(disp, x, y);
230     if (ret == false) {
231         WLOGTRACE("failed to set cursor position of disp %d", disp);
232         return -EINVAL;
233     }
234 
235     return 0;
236 }
237 
238 //------------------------------------------------------------------------------
239 
hwc_device_open(const struct hw_module_t * module,const char * name,struct hw_device_t ** device)240 static int hwc_device_open(const struct hw_module_t* module,
241                               const char* name,
242                               struct hw_device_t** device)
243 {
244     if (!name) {
245         ELOGTRACE("invalid name.");
246         return -EINVAL;
247     }
248 
249     ALOGTRACE("open device %s", name);
250 
251     if (strcmp(name, HWC_HARDWARE_COMPOSER) != 0) {
252         ELOGTRACE("try to open unknown HWComposer %s", name);
253         return -EINVAL;
254     }
255 
256     Hwcomposer& hwc = Hwcomposer::getInstance();
257     // initialize our state here
258     if (hwc.initialize() == false) {
259         ELOGTRACE("failed to intialize HWComposer");
260         Hwcomposer::releaseInstance();
261         return -EINVAL;
262     }
263 
264     // initialize the procs
265     hwc.hwc_composer_device_1_t::common.tag = HARDWARE_DEVICE_TAG;
266     hwc.hwc_composer_device_1_t::common.module =
267         const_cast<hw_module_t*>(module);
268     hwc.hwc_composer_device_1_t::common.close = hwc_device_close;
269 
270     hwc.hwc_composer_device_1_t::prepare = hwc_prepare;
271     hwc.hwc_composer_device_1_t::set = hwc_set;
272     hwc.hwc_composer_device_1_t::dump = hwc_dump;
273     hwc.hwc_composer_device_1_t::registerProcs = hwc_registerProcs;
274     hwc.hwc_composer_device_1_t::query = hwc_query;
275 
276     hwc.hwc_composer_device_1_t::eventControl = hwc_eventControl;
277     hwc.hwc_composer_device_1_t::getDisplayConfigs = hwc_getDisplayConfigs;
278     hwc.hwc_composer_device_1_t::getDisplayAttributes = hwc_getDisplayAttributes;
279 
280     // This is used to hack FBO switch flush issue in SurfaceFlinger.
281     hwc.hwc_composer_device_1_t::reserved_proc[0] = (void*)hwc_compositionComplete;
282     hwc.hwc_composer_device_1_t::common.version = HWC_DEVICE_API_VERSION_1_4;
283     hwc.hwc_composer_device_1_t::setPowerMode = hwc_setPowerMode;
284     hwc.hwc_composer_device_1_t::getActiveConfig = hwc_getActiveConfig;
285     hwc.hwc_composer_device_1_t::setActiveConfig = hwc_setActiveConfig;
286     // Todo: add hwc_setCursorPositionAsync after supporting patches
287     hwc.hwc_composer_device_1_t::setCursorPositionAsync = NULL;
288 
289     *device = &hwc.hwc_composer_device_1_t::common;
290 
291     return 0;
292 }
293 
294 } // namespace intel
295 } // namespace android
296 
297 static struct hw_module_methods_t hwc_module_methods = {
298     open: android::intel::hwc_device_open
299 };
300 
301 hwc_module_t HAL_MODULE_INFO_SYM = {
302     common: {
303         tag: HARDWARE_MODULE_TAG,
304         version_major: 1,
305         version_minor: 4,
306         id: HWC_HARDWARE_MODULE_ID,
307         name: "Intel Hardware Composer",
308         author: "Intel",
309         methods: &hwc_module_methods,
310         dso: 0,
311         reserved: { 0 },
312     }
313 };
314