Hwcomposer.cpp revision 6a6081a46a83da606cf21548879b37695adc7e1f
1/*
2 * Copyright © 2012 Intel Corporation
3 * All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 * Authors:
25 *    Jackie Li <yaodong.li@intel.com>
26 *
27 */
28#include <cutils/log.h>
29#include <cutils/atomic.h>
30
31#include <Hwcomposer.h>
32#include <Dump.h>
33
34namespace android {
35namespace intel {
36
37static Log& log = Log::getInstance();
38
39Hwcomposer* Hwcomposer::sInstance(0);
40
41Hwcomposer::Hwcomposer()
42    : mProcs(0),
43      mDrm(0),
44      mPlaneManager(0),
45      mBufferManager(0),
46      mInitialized(false)
47{
48    log.d("Hwcomposer");
49
50    mDisplayDevices.setCapacity(DisplayDevice::DEVICE_COUNT);
51}
52
53Hwcomposer::~Hwcomposer()
54{
55    log.d("~Hwcomposer");
56}
57
58bool Hwcomposer::initCheck() const
59{
60    return mInitialized;
61}
62
63bool Hwcomposer::prepare(size_t numDisplays,
64                          hwc_display_contents_1_t** displays)
65{
66    bool ret = true;
67
68    //Mutex::Autolock _l(mLock);
69
70    log.v("prepare display count %d\n", numDisplays);
71
72    if (!initCheck())
73        return false;
74
75    if (!numDisplays || !displays) {
76        log.e("prepare: invalid parameters");
77        return false;
78    }
79
80    // disable reclaimed planes
81    if (mPlaneManager)
82        mPlaneManager->disableReclaimedPlanes();
83
84    // reclaim all allocated planes if possible
85    for (size_t i = 0; i < numDisplays; i++) {
86        DisplayDevice *device = mDisplayDevices.itemAt(i);
87        if (!device) {
88            log.v("prepare: device %d doesn't exist", i);
89            continue;
90        }
91
92        if (!device->isConnected()) {
93            log.v("prepare: device %d is disconnected", i);
94            continue;
95        }
96
97        device->prePrepare(displays[i]);
98    }
99
100    for (size_t i = 0; i < numDisplays; i++) {
101        DisplayDevice *device = mDisplayDevices.itemAt(i);
102        if (!device) {
103            log.v("prepare: device %d doesn't exist", i);
104            continue;
105        }
106
107        if (!device->isConnected()) {
108            log.v("prepare: device %d is disconnected", i);
109            continue;
110        }
111
112        ret = device->prepare(displays[i]);
113        if (ret == false) {
114            log.e("prepare: failed to do prepare for device %d", i);
115            continue;
116        }
117    }
118
119    return ret;
120}
121
122bool Hwcomposer::commit(size_t numDisplays,
123                         hwc_display_contents_1_t **displays)
124{
125    bool ret = true;
126
127    log.v("commit display count %d\n", numDisplays);
128
129    //Mutex::Autolock _l(mLock);
130
131    if (!initCheck())
132        return false;
133
134    if (!numDisplays || !displays) {
135        log.e("commit: invalid parameters");
136        return false;
137    }
138
139    void *hwContexts = getContexts();
140    int count = 0;
141    if (!hwContexts) {
142        log.e("Hwcomposer::commit: invalid hwContexts");
143        return false;
144    }
145
146    for (size_t i = 0; i < numDisplays; i++) {
147        DisplayDevice *device = mDisplayDevices.itemAt(i);
148        if (!device) {
149            log.v("commit: device %d doesn't exist", i);
150            continue;
151        }
152
153        if (!device->isConnected()) {
154            log.v("commit: device %d is disconnected", i);
155            continue;
156        }
157
158        ret = device->commit(displays[i], hwContexts, count);
159        if (ret == false) {
160            log.e("commit: failed to do commit for device %d", i);
161            continue;
162        }
163    }
164
165    // commit hwContexts to hardware
166    ret = commitContexts(hwContexts, count);
167    if (ret == false) {
168        log.e("Hwcomposer::commit: failed to commit hwContexts");
169        return false;
170    }
171
172    return ret;
173}
174
175bool Hwcomposer::vsyncControl(int disp, int enabled)
176{
177    log.v("vsyncControl: disp %d, enabled %d", disp, enabled);
178
179    if (!initCheck())
180        return false;
181
182    if (disp < 0 || disp >= DisplayDevice::DEVICE_COUNT) {
183        log.e("vsyncControl: invalid disp %d", disp);
184        return false;
185    }
186
187    DisplayDevice *device = mDisplayDevices.itemAt(disp);
188    if (!device) {
189        log.e("vsyncControl: no device found");
190        return false;
191    }
192
193    return device->vsyncControl(enabled);
194}
195
196bool Hwcomposer::blank(int disp, int blank)
197{
198    log.v("blank: disp %d, blank %d", disp, blank);
199
200    if (!initCheck())
201        return false;
202
203    if (disp < 0 || disp >= DisplayDevice::DEVICE_COUNT) {
204        log.e("blank: invalid disp %d", disp);
205        return false;
206    }
207
208    DisplayDevice *device = mDisplayDevices.itemAt(disp);
209    if (!device) {
210        log.e("blank: no device found");
211        return false;
212    }
213
214    return device->blank(blank);
215}
216
217bool Hwcomposer::getDisplayConfigs(int disp,
218                                      uint32_t *configs,
219                                      size_t *numConfigs)
220{
221    log.v("getDisplayConfig");
222
223    if (!initCheck())
224        return false;
225
226    if (disp < 0 || disp >= DisplayDevice::DEVICE_COUNT) {
227        log.e("getDisplayConfigs: invalid disp %d", disp);
228        return false;
229    }
230
231    DisplayDevice *device = mDisplayDevices.itemAt(disp);
232    if (!device) {
233        log.e("getDisplayConfigs: no device %d found", disp);
234        return false;
235    }
236
237    return device->getDisplayConfigs(configs, numConfigs);
238}
239
240bool Hwcomposer::getDisplayAttributes(int disp,
241                                         uint32_t config,
242                                         const uint32_t *attributes,
243                                         int32_t *values)
244{
245    log.v("getDisplayAttributes");
246
247    if (!initCheck())
248        return false;
249
250    if (disp < 0 || disp >= DisplayDevice::DEVICE_COUNT) {
251        log.e("getDisplayAttributes: invalid disp %d", disp);
252        return false;
253    }
254
255    DisplayDevice *device = mDisplayDevices.itemAt(disp);
256    if (!device) {
257        log.e("getDisplayAttributes: no device found");
258        return false;
259    }
260
261    return device->getDisplayAttributes(config, attributes, values);
262}
263
264bool Hwcomposer::compositionComplete(int disp)
265{
266    log.v("compositionComplete");
267
268    if (!initCheck())
269        return false;
270
271    if (disp < 0 || disp >= DisplayDevice::DEVICE_COUNT) {
272        log.e("compositionComplete: invalid disp %d", disp);
273        return false;
274    }
275
276    DisplayDevice *device = mDisplayDevices.itemAt(disp);
277    if (!device) {
278        log.e("compositionComplete: no device found");
279        return false;
280    }
281
282    return device->compositionComplete();
283}
284
285void Hwcomposer::vsync(int disp, int64_t timestamp)
286{
287    //Mutex::Autolock _l(mLock);
288
289    if (!initCheck())
290        return;
291
292    if (mProcs && mProcs->vsync) {
293        log.v("report vsync disp %d timestamp %llu", disp, timestamp);
294        mProcs->vsync(const_cast<hwc_procs_t*>(mProcs), disp, timestamp);
295    }
296}
297
298void Hwcomposer::hotplug(int disp, int connected)
299{
300    //Mutex::Autolock _l(mLock);
301
302    if (!initCheck())
303        return;
304
305    if (mProcs && mProcs->hotplug) {
306        log.v("report hotplug disp %d connected %d", disp, connected);
307        mProcs->hotplug(const_cast<hwc_procs_t*>(mProcs), disp, connected);
308    }
309}
310
311bool Hwcomposer::release()
312{
313    log.d("release");
314
315    if (!initCheck())
316        return false;
317
318    return true;
319}
320
321bool Hwcomposer::dump(char *buff, int buff_len, int *cur_len)
322{
323    log.d("dump");
324
325    if (!initCheck())
326        return false;
327
328    Dump d(buff, buff_len);
329
330    // dump composer status
331    d.append("Intel Hardware Composer state:\n");
332    // dump device status
333    for (size_t i= 0; i < mDisplayDevices.size(); i++) {
334        DisplayDevice *device = mDisplayDevices.itemAt(i);
335        if (device)
336            device->dump(d);
337    }
338
339    // dump plane manager status
340    if (mPlaneManager)
341        mPlaneManager->dump(d);
342
343    return true;
344}
345
346void Hwcomposer::registerProcs(hwc_procs_t const *procs)
347{
348    log.d("registerProcs");
349
350    if (!procs)
351        log.w("registerProcs: procs is NULL");
352
353    mProcs = procs;
354}
355
356bool Hwcomposer::initialize()
357{
358    log.d("initialize");
359
360    // create drm
361    mDrm = new Drm(); //createDrm();
362    if (!mDrm) {
363        log.e("%s: failed to create DRM");
364        return false;
365    }
366
367    // create display plane manager
368    mPlaneManager = createDisplayPlaneManager();
369    if (!mPlaneManager || !mPlaneManager->initialize()) {
370        log.e("initialize: failed to create display plane manager");
371        goto dpm_create_err;
372    }
373
374    // create buffer manager
375    mBufferManager = createBufferManager();
376    if (!mBufferManager || !mBufferManager->initialize()) {
377        log.e("initialize: failed to create buffer manager");
378        goto bm_create_err;
379    }
380
381    // create display device
382    for (int i = 0; i < DisplayDevice::DEVICE_COUNT; i++) {
383        DisplayDevice *device = createDisplayDevice(i, *mPlaneManager);
384        if (!device || !device->initialize()) {
385            log.e("initialize: failed to create device %d", i);
386            continue;
387        }
388        // add this device
389        mDisplayDevices.insertAt(device, i, 1);
390    }
391
392    mInitialized = true;
393    return true;
394device_create_err:
395    for (size_t i = 0; i < mDisplayDevices.size(); i++) {
396        DisplayDevice *device = mDisplayDevices.itemAt(i);
397        delete device;
398    }
399bm_create_err:
400    delete mPlaneManager;
401dpm_create_err:
402    delete mDrm;
403    mInitialized = false;
404    return false;
405}
406
407Drm& Hwcomposer::getDrm()
408{
409    return *mDrm;
410}
411
412DisplayPlaneManager& Hwcomposer::getPlaneManager()
413{
414    return *mPlaneManager;
415}
416
417BufferManager& Hwcomposer::getBufferManager()
418{
419    return *mBufferManager;
420}
421
422} // namespace intel
423} // namespace android
424