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