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 #include <common/utils/HwcTrace.h>
17 #include <Hwcomposer.h>
18 #include <common/utils/Dump.h>
19 #include <UeventObserver.h>
20
21 namespace android {
22 namespace intel {
23
24 Hwcomposer* Hwcomposer::sInstance(0);
25
Hwcomposer()26 Hwcomposer::Hwcomposer()
27 : mProcs(0),
28 mDrm(0),
29 mPlaneManager(0),
30 mBufferManager(0),
31 mDisplayAnalyzer(0),
32 mDisplayContext(0),
33 mUeventObserver(0),
34 mInitialized(false)
35 {
36 CTRACE();
37
38 mDisplayDevices.setCapacity(IDisplayDevice::DEVICE_COUNT);
39 mDisplayDevices.clear();
40 }
41
~Hwcomposer()42 Hwcomposer::~Hwcomposer()
43 {
44 CTRACE();
45 deinitialize();
46 }
47
initCheck() const48 bool Hwcomposer::initCheck() const
49 {
50 return mInitialized;
51 }
52
prepare(size_t numDisplays,hwc_display_contents_1_t ** displays)53 bool Hwcomposer::prepare(size_t numDisplays,
54 hwc_display_contents_1_t** displays)
55 {
56 bool ret = true;
57
58 RETURN_FALSE_IF_NOT_INIT();
59 ALOGTRACE("display count = %d", numDisplays);
60
61 if (!numDisplays || !displays) {
62 ELOGTRACE("invalid parameters");
63 return false;
64 }
65
66 mDisplayAnalyzer->analyzeContents(numDisplays, displays);
67
68 // disable reclaimed planes
69 mPlaneManager->disableReclaimedPlanes();
70
71 // reclaim all allocated planes if possible
72 for (size_t i = 0; i < numDisplays; i++) {
73 if (i >= mDisplayDevices.size()) {
74 continue;
75 }
76 IDisplayDevice *device = mDisplayDevices.itemAt(i);
77 if (!device) {
78 VLOGTRACE("device %d doesn't exist", i);
79 continue;
80 }
81 device->prePrepare(displays[i]);
82 }
83
84 for (size_t i = 0; i < numDisplays; i++) {
85 if (i >= mDisplayDevices.size()) {
86 continue;
87 }
88 IDisplayDevice *device = mDisplayDevices.itemAt(i);
89 if (!device) {
90 VLOGTRACE("device %d doesn't exist", i);
91 continue;
92 }
93 ret = device->prepare(displays[i]);
94 if (ret == false) {
95 ELOGTRACE("failed to do prepare for device %d", i);
96 continue;
97 }
98 }
99
100 return ret;
101 }
102
commit(size_t numDisplays,hwc_display_contents_1_t ** displays)103 bool Hwcomposer::commit(size_t numDisplays,
104 hwc_display_contents_1_t **displays)
105 {
106 bool ret = true;
107
108 RETURN_FALSE_IF_NOT_INIT();
109 ALOGTRACE("display count = %d", numDisplays);
110
111 if (!numDisplays || !displays) {
112 ELOGTRACE("invalid parameters");
113 return false;
114 }
115
116 mDisplayContext->commitBegin(numDisplays, displays);
117
118 for (size_t i = 0; i < numDisplays; i++) {
119 if (i >= mDisplayDevices.size()) {
120 continue;
121 }
122 IDisplayDevice *device = mDisplayDevices.itemAt(i);
123 if (!device) {
124 VLOGTRACE("device %d doesn't exist", i);
125 continue;
126 }
127
128 if (!device->isConnected()) {
129 VLOGTRACE("device %d is disconnected", i);
130 continue;
131 }
132
133 ret = device->commit(displays[i], mDisplayContext);
134 if (ret == false) {
135 ELOGTRACE("failed to do commit for device %d", i);
136 continue;
137 }
138 }
139
140 mDisplayContext->commitEnd(numDisplays, displays);
141 // return true always
142 return true;
143 }
144
vsyncControl(int disp,int enabled)145 bool Hwcomposer::vsyncControl(int disp, int enabled)
146 {
147 RETURN_FALSE_IF_NOT_INIT();
148 ALOGTRACE("disp = %d, enabled = %d", disp, enabled);
149
150 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
151 ELOGTRACE("invalid disp %d", disp);
152 return false;
153 }
154 if (disp >= (int) mDisplayDevices.size()) {
155 return false;
156 }
157 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
158 if (!device) {
159 ELOGTRACE("no device found");
160 return false;
161 }
162
163 return device->vsyncControl(enabled ? true : false);
164 }
165
blank(int disp,int blank)166 bool Hwcomposer::blank(int disp, int blank)
167 {
168 RETURN_FALSE_IF_NOT_INIT();
169 ALOGTRACE("disp = %d, blank = %d", disp, blank);
170
171 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
172 ELOGTRACE("invalid disp %d", disp);
173 return false;
174 }
175 if (disp >= (int) mDisplayDevices.size()) {
176 return false;
177 }
178 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
179 if (!device) {
180 ELOGTRACE("no device found");
181 return false;
182 }
183
184 return device->blank(blank ? true : false);
185 }
186
getDisplayConfigs(int disp,uint32_t * configs,size_t * numConfigs)187 bool Hwcomposer::getDisplayConfigs(int disp,
188 uint32_t *configs,
189 size_t *numConfigs)
190 {
191 RETURN_FALSE_IF_NOT_INIT();
192
193 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
194 ELOGTRACE("invalid disp %d", disp);
195 return false;
196 }
197 if (disp >= (int) mDisplayDevices.size()) {
198 return false;
199 }
200 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
201 if (!device) {
202 ELOGTRACE("no device %d found", disp);
203 return false;
204 }
205
206 return device->getDisplayConfigs(configs, numConfigs);
207 }
208
getDisplayAttributes(int disp,uint32_t config,const uint32_t * attributes,int32_t * values)209 bool Hwcomposer::getDisplayAttributes(int disp,
210 uint32_t config,
211 const uint32_t *attributes,
212 int32_t *values)
213 {
214 RETURN_FALSE_IF_NOT_INIT();
215
216 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
217 ELOGTRACE("invalid disp %d", disp);
218 return false;
219 }
220 if (disp >= (int) mDisplayDevices.size()) {
221 return false;
222 }
223 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
224 if (!device) {
225 ELOGTRACE("no device found");
226 return false;
227 }
228
229 return device->getDisplayAttributes(config, attributes, values);
230 }
231
compositionComplete(int disp)232 bool Hwcomposer::compositionComplete(int disp)
233 {
234 RETURN_FALSE_IF_NOT_INIT();
235
236 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
237 ELOGTRACE("invalid disp %d", disp);
238 return false;
239 }
240
241 mDisplayContext->compositionComplete();
242 if (disp >= (int) mDisplayDevices.size()) {
243 return false;
244 }
245
246 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
247 if (!device) {
248 ELOGTRACE("no device found");
249 return false;
250 }
251
252 return device->compositionComplete();
253 }
254
setPowerMode(int disp,int mode)255 bool Hwcomposer::setPowerMode(int disp, int mode)
256 {
257 RETURN_FALSE_IF_NOT_INIT();
258
259 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
260 ELOGTRACE("invalid disp %d", disp);
261 return false;
262 }
263
264 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
265 if (!device) {
266 ELOGTRACE("no device found");
267 return false;
268 }
269
270 return device->setPowerMode(mode);
271 }
272
getActiveConfig(int disp)273 int Hwcomposer::getActiveConfig(int disp)
274 {
275 RETURN_NULL_IF_NOT_INIT();
276
277 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
278 ELOGTRACE("invalid disp %d", disp);
279 return -1;
280 }
281
282 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
283 if (!device) {
284 ELOGTRACE("no device found");
285 return -1;
286 }
287
288 return device->getActiveConfig();
289 }
290
setActiveConfig(int disp,int index)291 bool Hwcomposer::setActiveConfig(int disp, int index)
292 {
293 RETURN_FALSE_IF_NOT_INIT();
294
295 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
296 ELOGTRACE("invalid disp %d", disp);
297 return false;
298 }
299
300 IDisplayDevice *device = mDisplayDevices.itemAt(disp);
301 if (!device) {
302 ELOGTRACE("no device found");
303 return false;
304 }
305
306 return device->setActiveConfig(index);
307 }
308
setCursorPositionAsync(int disp,int x,int y)309 bool Hwcomposer::setCursorPositionAsync(int disp, int x, int y)
310 {
311 RETURN_FALSE_IF_NOT_INIT();
312
313 if (disp != HWC_DISPLAY_PRIMARY && disp != HWC_DISPLAY_EXTERNAL) {
314 ELOGTRACE("invalid disp %d", disp);
315 return false;
316 }
317
318 return mDisplayContext->setCursorPosition(disp, x, y);
319 }
320
vsync(int disp,int64_t timestamp)321 void Hwcomposer::vsync(int disp, int64_t timestamp)
322 {
323 RETURN_VOID_IF_NOT_INIT();
324
325 if (mProcs && mProcs->vsync) {
326 VLOGTRACE("report vsync on disp %d, timestamp %llu", disp, timestamp);
327 // workaround to pretend vsync is from primary display
328 // Display will freeze if vsync is from external display.
329 mProcs->vsync(const_cast<hwc_procs_t*>(mProcs), IDisplayDevice::DEVICE_PRIMARY, timestamp);
330 }
331 }
332
hotplug(int disp,bool connected)333 void Hwcomposer::hotplug(__attribute__((unused))int disp, bool connected)
334 {
335 RETURN_VOID_IF_NOT_INIT();
336
337 #ifndef INTEL_SUPPORT_HDMI_PRIMARY
338 if (mProcs && mProcs->hotplug) {
339 DLOGTRACE("report hotplug on disp %d, connected %d", disp, connected);
340 mProcs->hotplug(const_cast<hwc_procs_t*>(mProcs), disp, connected);
341 DLOGTRACE("hotplug callback processed and returned!");
342 }
343 #endif
344
345 mDisplayAnalyzer->postHotplugEvent(connected);
346 }
347
invalidate()348 void Hwcomposer::invalidate()
349 {
350 RETURN_VOID_IF_NOT_INIT();
351
352 if (mProcs && mProcs->invalidate) {
353 DLOGTRACE("invalidating screen...");
354 mProcs->invalidate(const_cast<hwc_procs_t*>(mProcs));
355 }
356 }
357
release()358 bool Hwcomposer::release()
359 {
360 RETURN_FALSE_IF_NOT_INIT();
361
362 return true;
363 }
364
dump(char * buff,int buff_len,int *)365 bool Hwcomposer::dump(char *buff, int buff_len, int * /* cur_len */)
366 {
367 RETURN_FALSE_IF_NOT_INIT();
368
369 Dump d(buff, buff_len);
370
371 // dump composer status
372 d.append("Hardware Composer state:");
373 // dump device status
374 for (size_t i= 0; i < mDisplayDevices.size(); i++) {
375 IDisplayDevice *device = mDisplayDevices.itemAt(i);
376 if (device)
377 device->dump(d);
378 }
379
380 // dump plane manager status
381 if (mPlaneManager)
382 mPlaneManager->dump(d);
383
384 // dump buffer manager status
385 if (mBufferManager)
386 mBufferManager->dump(d);
387
388 return true;
389 }
390
registerProcs(hwc_procs_t const * procs)391 void Hwcomposer::registerProcs(hwc_procs_t const *procs)
392 {
393 CTRACE();
394
395 if (!procs) {
396 WLOGTRACE("procs is NULL");
397 }
398 mProcs = procs;
399 }
400
initialize()401 bool Hwcomposer::initialize()
402 {
403 CTRACE();
404
405 // create drm
406 mDrm = new Drm();
407 if (!mDrm || !mDrm->initialize()) {
408 DEINIT_AND_RETURN_FALSE("failed to create DRM");
409 }
410
411 // create buffer manager
412 mBufferManager = createBufferManager();
413 if (!mBufferManager || !mBufferManager->initialize()) {
414 DEINIT_AND_RETURN_FALSE("failed to create buffer manager");
415 }
416
417 // create display plane manager
418 mPlaneManager = createDisplayPlaneManager();
419 if (!mPlaneManager || !mPlaneManager->initialize()) {
420 DEINIT_AND_RETURN_FALSE("failed to create display plane manager");
421 }
422
423 mDisplayContext = createDisplayContext();
424 if (!mDisplayContext || !mDisplayContext->initialize()) {
425 DEINIT_AND_RETURN_FALSE("failed to create display context");
426 }
427
428 mUeventObserver = new UeventObserver();
429 if (!mUeventObserver || !mUeventObserver->initialize()) {
430 DEINIT_AND_RETURN_FALSE("failed to initialize uevent observer");
431 }
432
433 // create display device
434 for (int i = 0; i < IDisplayDevice::DEVICE_COUNT; i++) {
435 IDisplayDevice *device = createDisplayDevice(i, *mPlaneManager);
436 if (!device || !device->initialize()) {
437 DEINIT_AND_DELETE_OBJ(device);
438 DEINIT_AND_RETURN_FALSE("failed to create device %d", i);
439 }
440 // add this device
441 mDisplayDevices.insertAt(device, i, 1);
442 }
443
444 mDisplayAnalyzer = new DisplayAnalyzer();
445 if (!mDisplayAnalyzer || !mDisplayAnalyzer->initialize()) {
446 DEINIT_AND_RETURN_FALSE("failed to initialize display analyzer");
447 }
448
449 // all initialized, starting uevent observer
450 mUeventObserver->start();
451
452 mInitialized = true;
453 return true;
454 }
455
deinitialize()456 void Hwcomposer::deinitialize()
457 {
458 DEINIT_AND_DELETE_OBJ(mDisplayAnalyzer);
459
460 DEINIT_AND_DELETE_OBJ(mUeventObserver);
461 // destroy display devices
462 for (size_t i = 0; i < mDisplayDevices.size(); i++) {
463 IDisplayDevice *device = mDisplayDevices.itemAt(i);
464 DEINIT_AND_DELETE_OBJ(device);
465 }
466 mDisplayDevices.clear();
467
468 DEINIT_AND_DELETE_OBJ(mDisplayContext);
469 DEINIT_AND_DELETE_OBJ(mPlaneManager);
470 DEINIT_AND_DELETE_OBJ(mBufferManager);
471 DEINIT_AND_DELETE_OBJ(mDrm);
472 mInitialized = false;
473 }
474
getDrm()475 Drm* Hwcomposer::getDrm()
476 {
477 return mDrm;
478 }
479
getPlaneManager()480 DisplayPlaneManager* Hwcomposer::getPlaneManager()
481 {
482 return mPlaneManager;
483 }
484
getBufferManager()485 BufferManager* Hwcomposer::getBufferManager()
486 {
487 return mBufferManager;
488 }
489
getDisplayContext()490 IDisplayContext* Hwcomposer::getDisplayContext()
491 {
492 return mDisplayContext;
493 }
494
getDisplayAnalyzer()495 DisplayAnalyzer* Hwcomposer::getDisplayAnalyzer()
496 {
497 return mDisplayAnalyzer;
498 }
499
getDisplayDevice(int disp)500 IDisplayDevice* Hwcomposer::getDisplayDevice(int disp)
501 {
502 if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
503 ELOGTRACE("invalid disp %d", disp);
504 return NULL;
505 }
506 if (disp >= (int) mDisplayDevices.size()) {
507 return NULL;
508 }
509 return mDisplayDevices.itemAt(disp);
510 }
511
getUeventObserver()512 UeventObserver* Hwcomposer::getUeventObserver()
513 {
514 return mUeventObserver;
515 }
516
517
518 } // namespace intel
519 } // namespace android
520