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
21namespace android {
22namespace intel {
23
24Hwcomposer* Hwcomposer::sInstance(0);
25
26Hwcomposer::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
42Hwcomposer::~Hwcomposer()
43{
44    CTRACE();
45    deinitialize();
46}
47
48bool Hwcomposer::initCheck() const
49{
50    return mInitialized;
51}
52
53bool 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
103bool 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
145bool 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
166bool 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
187bool 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
209bool 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
232bool 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
255bool 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
273int 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
291bool 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
309bool 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
321void 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
333void 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
346void 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
356bool Hwcomposer::release()
357{
358    RETURN_FALSE_IF_NOT_INIT();
359
360    return true;
361}
362
363bool 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
389void 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
399bool 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
454void 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
473Drm* Hwcomposer::getDrm()
474{
475    return mDrm;
476}
477
478DisplayPlaneManager* Hwcomposer::getPlaneManager()
479{
480    return mPlaneManager;
481}
482
483BufferManager* Hwcomposer::getBufferManager()
484{
485    return mBufferManager;
486}
487
488IDisplayContext* Hwcomposer::getDisplayContext()
489{
490    return mDisplayContext;
491}
492
493DisplayAnalyzer* Hwcomposer::getDisplayAnalyzer()
494{
495    return mDisplayAnalyzer;
496}
497
498IDisplayDevice* 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
510UeventObserver* Hwcomposer::getUeventObserver()
511{
512    return mUeventObserver;
513}
514
515
516} // namespace intel
517} // namespace android
518