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