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