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