• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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