• 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 <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     if (mProcs && mProcs->hotplug) {
338         DLOGTRACE("report hotplug on disp %d, connected %d", disp, connected);
339         mProcs->hotplug(const_cast<hwc_procs_t*>(mProcs), disp, connected);
340         DLOGTRACE("hotplug callback processed and returned!");
341     }
342 
343     mDisplayAnalyzer->postHotplugEvent(connected);
344 }
345 
invalidate()346 void Hwcomposer::invalidate()
347 {
348     RETURN_VOID_IF_NOT_INIT();
349 
350     if (mProcs && mProcs->invalidate) {
351         DLOGTRACE("invalidating screen...");
352         mProcs->invalidate(const_cast<hwc_procs_t*>(mProcs));
353     }
354 }
355 
release()356 bool Hwcomposer::release()
357 {
358     RETURN_FALSE_IF_NOT_INIT();
359 
360     return true;
361 }
362 
dump(char * buff,int buff_len,int *)363 bool Hwcomposer::dump(char *buff, int buff_len, int * /* cur_len */)
364 {
365     RETURN_FALSE_IF_NOT_INIT();
366 
367     Dump d(buff, buff_len);
368 
369     // dump composer status
370     d.append("Hardware Composer state:");
371     // dump device status
372     for (size_t i= 0; i < mDisplayDevices.size(); i++) {
373         IDisplayDevice *device = mDisplayDevices.itemAt(i);
374         if (device)
375             device->dump(d);
376     }
377 
378     // dump plane manager status
379     if (mPlaneManager)
380         mPlaneManager->dump(d);
381 
382     // dump buffer manager status
383     if (mBufferManager)
384         mBufferManager->dump(d);
385 
386     return true;
387 }
388 
registerProcs(hwc_procs_t const * procs)389 void Hwcomposer::registerProcs(hwc_procs_t const *procs)
390 {
391     CTRACE();
392 
393     if (!procs) {
394         WLOGTRACE("procs is NULL");
395     }
396     mProcs = procs;
397 }
398 
initialize()399 bool Hwcomposer::initialize()
400 {
401     CTRACE();
402 
403     // create drm
404     mDrm = new Drm();
405     if (!mDrm || !mDrm->initialize()) {
406         DEINIT_AND_RETURN_FALSE("failed to create DRM");
407     }
408 
409     // create buffer manager
410     mBufferManager = createBufferManager();
411     if (!mBufferManager || !mBufferManager->initialize()) {
412         DEINIT_AND_RETURN_FALSE("failed to create buffer manager");
413     }
414 
415     // create display plane manager
416     mPlaneManager = createDisplayPlaneManager();
417     if (!mPlaneManager || !mPlaneManager->initialize()) {
418         DEINIT_AND_RETURN_FALSE("failed to create display plane manager");
419     }
420 
421     mDisplayContext = createDisplayContext();
422     if (!mDisplayContext || !mDisplayContext->initialize()) {
423         DEINIT_AND_RETURN_FALSE("failed to create display context");
424     }
425 
426     mUeventObserver = new UeventObserver();
427     if (!mUeventObserver || !mUeventObserver->initialize()) {
428         DEINIT_AND_RETURN_FALSE("failed to initialize uevent observer");
429     }
430 
431     // create display device
432     for (int i = 0; i < IDisplayDevice::DEVICE_COUNT; i++) {
433         IDisplayDevice *device = createDisplayDevice(i, *mPlaneManager);
434         if (!device || !device->initialize()) {
435             DEINIT_AND_DELETE_OBJ(device);
436             DEINIT_AND_RETURN_FALSE("failed to create device %d", i);
437         }
438         // add this device
439         mDisplayDevices.insertAt(device, i, 1);
440     }
441 
442     mDisplayAnalyzer = new DisplayAnalyzer();
443     if (!mDisplayAnalyzer || !mDisplayAnalyzer->initialize()) {
444         DEINIT_AND_RETURN_FALSE("failed to initialize display analyzer");
445     }
446 
447     // all initialized, starting uevent observer
448     mUeventObserver->start();
449 
450     mInitialized = true;
451     return true;
452 }
453 
deinitialize()454 void Hwcomposer::deinitialize()
455 {
456     DEINIT_AND_DELETE_OBJ(mDisplayAnalyzer);
457 
458     DEINIT_AND_DELETE_OBJ(mUeventObserver);
459     // destroy display devices
460     for (size_t i = 0; i < mDisplayDevices.size(); i++) {
461         IDisplayDevice *device = mDisplayDevices.itemAt(i);
462         DEINIT_AND_DELETE_OBJ(device);
463     }
464     mDisplayDevices.clear();
465 
466     DEINIT_AND_DELETE_OBJ(mDisplayContext);
467     DEINIT_AND_DELETE_OBJ(mPlaneManager);
468     DEINIT_AND_DELETE_OBJ(mBufferManager);
469     DEINIT_AND_DELETE_OBJ(mDrm);
470     mInitialized = false;
471 }
472 
getDrm()473 Drm* Hwcomposer::getDrm()
474 {
475     return mDrm;
476 }
477 
getPlaneManager()478 DisplayPlaneManager* Hwcomposer::getPlaneManager()
479 {
480     return mPlaneManager;
481 }
482 
getBufferManager()483 BufferManager* Hwcomposer::getBufferManager()
484 {
485     return mBufferManager;
486 }
487 
getDisplayContext()488 IDisplayContext* Hwcomposer::getDisplayContext()
489 {
490     return mDisplayContext;
491 }
492 
getDisplayAnalyzer()493 DisplayAnalyzer* Hwcomposer::getDisplayAnalyzer()
494 {
495     return mDisplayAnalyzer;
496 }
497 
getDisplayDevice(int disp)498 IDisplayDevice* Hwcomposer::getDisplayDevice(int disp)
499 {
500     if (disp < 0 || disp >= IDisplayDevice::DEVICE_COUNT) {
501         ELOGTRACE("invalid disp %d", disp);
502         return NULL;
503     }
504     if (disp >= (int) mDisplayDevices.size()) {
505         return NULL;
506     }
507     return mDisplayDevices.itemAt(disp);
508 }
509 
getUeventObserver()510 UeventObserver* Hwcomposer::getUeventObserver()
511 {
512     return mUeventObserver;
513 }
514 
515 
516 } // namespace intel
517 } // namespace android
518