hwc.cpp revision 5a107b4b7124301baf3b9e58089c7621fb9dfc95
1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
4 *
5 * Not a Contribution, Apache license notifications and license are retained
6 * for attribution purposes only.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 *      http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20
21#include <fcntl.h>
22#include <errno.h>
23
24#include <cutils/log.h>
25#include <cutils/atomic.h>
26#include <EGL/egl.h>
27
28#include <overlay.h>
29#include <fb_priv.h>
30#include <mdp_version.h>
31#include "hwc_utils.h"
32#include "hwc_video.h"
33#include "hwc_fbupdate.h"
34#include "hwc_mdpcomp.h"
35#include "external.h"
36#include "hwc_copybit.h"
37
38using namespace qhwc;
39#define VSYNC_DEBUG 0
40
41static int hwc_device_open(const struct hw_module_t* module,
42                           const char* name,
43                           struct hw_device_t** device);
44
45static struct hw_module_methods_t hwc_module_methods = {
46    open: hwc_device_open
47};
48
49hwc_module_t HAL_MODULE_INFO_SYM = {
50    common: {
51        tag: HARDWARE_MODULE_TAG,
52        version_major: 2,
53        version_minor: 0,
54        id: HWC_HARDWARE_MODULE_ID,
55        name: "Qualcomm Hardware Composer Module",
56        author: "CodeAurora Forum",
57        methods: &hwc_module_methods,
58        dso: 0,
59        reserved: {0},
60    }
61};
62
63/*
64 * Save callback functions registered to HWC
65 */
66static void hwc_registerProcs(struct hwc_composer_device_1* dev,
67                              hwc_procs_t const* procs)
68{
69    ALOGI("%s", __FUNCTION__);
70    hwc_context_t* ctx = (hwc_context_t*)(dev);
71    if(!ctx) {
72        ALOGE("%s: Invalid context", __FUNCTION__);
73        return;
74    }
75    ctx->proc = procs;
76
77    // Now that we have the functions needed, kick off
78    // the uevent & vsync threads
79    init_uevent_thread(ctx);
80    init_vsync_thread(ctx);
81}
82
83//Helper
84static void reset(hwc_context_t *ctx, int numDisplays,
85                  hwc_display_contents_1_t** displays) {
86    memset(ctx->listStats, 0, sizeof(ctx->listStats));
87    for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++){
88        hwc_display_contents_1_t *list = displays[i];
89        // XXX:SurfaceFlinger no longer guarantees that this
90        // value is reset on every prepare. However, for the layer
91        // cache we need to reset it.
92        // We can probably rethink that later on
93        if (LIKELY(list && list->numHwLayers > 1)) {
94            for(uint32_t j = 0; j < list->numHwLayers; j++) {
95                if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
96                    list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
97            }
98        }
99
100        if(ctx->mFBUpdate[i])
101            ctx->mFBUpdate[i]->reset();
102
103        if(ctx->mCopyBit[i])
104            ctx->mCopyBit[i]->reset();
105    }
106    VideoOverlay::reset();
107}
108
109//clear prev layer prop flags and realloc for current frame
110static void reset_layer_prop(hwc_context_t* ctx, int dpy) {
111    int layer_count = ctx->listStats[dpy].numAppLayers;
112
113    if(ctx->layerProp[dpy]) {
114       delete[] ctx->layerProp[dpy];
115       ctx->layerProp[dpy] = NULL;
116    }
117
118    if(layer_count) {
119       ctx->layerProp[dpy] = new LayerProp[layer_count];
120    }
121}
122
123static int hwc_prepare_primary(hwc_composer_device_1 *dev,
124        hwc_display_contents_1_t *list) {
125    hwc_context_t* ctx = (hwc_context_t*)(dev);
126    const int dpy = HWC_DISPLAY_PRIMARY;
127    if (LIKELY(list && list->numHwLayers > 1) &&
128        ctx->dpyAttr[dpy].isActive) {
129
130        uint32_t last = list->numHwLayers - 1;
131        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
132        if(fbLayer->handle) {
133            setListStats(ctx, list, dpy);
134            reset_layer_prop(ctx, dpy);
135            int ret = ctx->mMDPComp->prepare(ctx, list);
136            if(!ret) {
137                // IF MDPcomp fails use this route
138                VideoOverlay::prepare(ctx, list, dpy);
139                ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
140            }
141            ctx->mLayerCache[dpy]->updateLayerCache(list);
142            // Use Copybit, when MDP comp fails
143            if(!ret && ctx->mCopyBit[dpy])
144                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
145        }
146    }
147    return 0;
148}
149
150static int hwc_prepare_external(hwc_composer_device_1 *dev,
151        hwc_display_contents_1_t *list) {
152    hwc_context_t* ctx = (hwc_context_t*)(dev);
153    const int dpy = HWC_DISPLAY_EXTERNAL;
154
155    if (LIKELY(list && list->numHwLayers > 1) &&
156        ctx->dpyAttr[dpy].isActive &&
157        ctx->dpyAttr[dpy].connected) {
158
159        uint32_t last = list->numHwLayers - 1;
160        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
161        if(fbLayer->handle) {
162            setListStats(ctx, list, dpy);
163            reset_layer_prop(ctx, dpy);
164            VideoOverlay::prepare(ctx, list, dpy);
165            ctx->mFBUpdate[dpy]->prepare(ctx, fbLayer);
166            ctx->mLayerCache[dpy]->updateLayerCache(list);
167            if(ctx->mCopyBit[dpy])
168                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
169            ctx->mExtDispConfiguring = false;
170        }
171    }
172    return 0;
173}
174
175static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
176                       hwc_display_contents_1_t** displays)
177{
178    int ret = 0;
179    hwc_context_t* ctx = (hwc_context_t*)(dev);
180    Locker::Autolock _l(ctx->mBlankLock);
181    reset(ctx, numDisplays, displays);
182
183    ctx->mOverlay->configBegin();
184
185    for (int32_t i = numDisplays - 1; i >= 0; i--) {
186        hwc_display_contents_1_t *list = displays[i];
187        switch(i) {
188            case HWC_DISPLAY_PRIMARY:
189                ret = hwc_prepare_primary(dev, list);
190                break;
191            case HWC_DISPLAY_EXTERNAL:
192                ret = hwc_prepare_external(dev, list);
193                break;
194            default:
195                ret = -EINVAL;
196        }
197    }
198
199    ctx->mOverlay->configDone();
200    return ret;
201}
202
203static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
204                             int event, int enabled)
205{
206    int ret = 0;
207
208    hwc_context_t* ctx = (hwc_context_t*)(dev);
209    private_module_t* m = reinterpret_cast<private_module_t*>(
210                ctx->mFbDev->common.module);
211    pthread_mutex_lock(&ctx->vstate.lock);
212    switch(event) {
213        case HWC_EVENT_VSYNC:
214            if (ctx->vstate.enable == enabled)
215                break;
216            ctx->vstate.enable = !!enabled;
217            pthread_cond_signal(&ctx->vstate.cond);
218            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
219                      (enabled)?"ENABLED":"DISABLED");
220            break;
221        default:
222            ret = -EINVAL;
223    }
224    pthread_mutex_unlock(&ctx->vstate.lock);
225    return ret;
226}
227
228static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
229{
230    hwc_context_t* ctx = (hwc_context_t*)(dev);
231    private_module_t* m = reinterpret_cast<private_module_t*>(
232        ctx->mFbDev->common.module);
233    Locker::Autolock _l(ctx->mBlankLock);
234    int ret = 0;
235    ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
236    switch(dpy) {
237        case HWC_DISPLAY_PRIMARY:
238            if(blank) {
239                ctx->mOverlay->configBegin();
240                ctx->mOverlay->configDone();
241                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
242            } else {
243                ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
244            }
245            break;
246        case HWC_DISPLAY_EXTERNAL:
247            if(blank) {
248                // External Display post commits the changes to display
249                // Call this on blank, so that any pipe unsets gets committed
250                if (!ctx->mExtDisplay->post()) {
251                    ret = -1;
252                    ALOGE("%s:ctx->mExtDisplay->post fail!! ", __FUNCTION__);
253                }
254            } else {
255            }
256            break;
257        default:
258            return -EINVAL;
259    }
260    // Enable HPD here, as during bootup unblank is called
261    // when SF is completely initialized
262    ctx->mExtDisplay->setHPD(1);
263
264    if(ret < 0) {
265        ALOGE("%s: failed. Dpy=%d, blank=%d : %s",
266                __FUNCTION__, dpy, blank, strerror(errno));
267        return ret;
268    }
269    ALOGD("%s: Done Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
270    ctx->dpyAttr[dpy].isActive = !blank;
271    return 0;
272}
273
274static int hwc_query(struct hwc_composer_device_1* dev,
275                     int param, int* value)
276{
277    hwc_context_t* ctx = (hwc_context_t*)(dev);
278    private_module_t* m = reinterpret_cast<private_module_t*>(
279        ctx->mFbDev->common.module);
280    int supported = HWC_DISPLAY_PRIMARY_BIT;
281
282    switch (param) {
283    case HWC_BACKGROUND_LAYER_SUPPORTED:
284        // Not supported for now
285        value[0] = 0;
286        break;
287    case HWC_VSYNC_PERIOD: //Not used for hwc > 1.1
288        value[0] = m->fps;
289        ALOGI("fps: %d", value[0]);
290        break;
291    case HWC_DISPLAY_TYPES_SUPPORTED:
292        if(ctx->mMDP.hasOverlay)
293            supported |= HWC_DISPLAY_EXTERNAL_BIT;
294        value[0] = supported;
295        break;
296    default:
297        return -EINVAL;
298    }
299    return 0;
300
301}
302
303static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
304    int ret = 0;
305    const int dpy = HWC_DISPLAY_PRIMARY;
306
307    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
308        uint32_t last = list->numHwLayers - 1;
309        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
310        int fd = -1; //FenceFD from the Copybit(valid in async mode)
311        if(ctx->mCopyBit[dpy])
312            ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
313        if(list->numHwLayers > 1)
314            hwc_sync(ctx, list, dpy, fd);
315        if (!VideoOverlay::draw(ctx, list, dpy)) {
316            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
317            ret = -1;
318        }
319        if (!ctx->mMDPComp->draw(ctx, list)) {
320            ALOGE("%s: MDPComp::draw fail!", __FUNCTION__);
321            ret = -1;
322        }
323
324        //TODO We dont check for SKIP flag on this layer because we need PAN
325        //always. Last layer is always FB
326        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
327        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
328            if(!(fbLayer->flags & HWC_SKIP_LAYER) &&
329                (list->numHwLayers > 1)) {
330                if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
331                    ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
332                    ret = -1;
333                }
334            }
335            if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
336                ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
337                return -1;
338            }
339        }
340    }
341    return ret;
342}
343
344static int hwc_set_external(hwc_context_t *ctx,
345        hwc_display_contents_1_t* list) {
346    int ret = 0;
347    const int dpy = HWC_DISPLAY_EXTERNAL;
348
349    Locker::Autolock _l(ctx->mExtSetLock);
350
351    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
352        ctx->dpyAttr[dpy].connected) {
353        uint32_t last = list->numHwLayers - 1;
354        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
355        int fd = -1; //FenceFD from the Copybit(valid in async mode)
356        if(ctx->mCopyBit[dpy])
357            ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
358
359        if(list->numHwLayers > 1)
360            hwc_sync(ctx, list, dpy, fd);
361
362        if (!VideoOverlay::draw(ctx, list, dpy)) {
363            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
364            ret = -1;
365        }
366
367        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
368        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
369                !(fbLayer->flags & HWC_SKIP_LAYER) && hnd &&
370                (list->numHwLayers > 1)) {
371            if (!ctx->mFBUpdate[dpy]->draw(ctx, fbLayer)) {
372                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
373                ret = -1;
374            }
375        }
376        if (!ctx->mExtDisplay->post()) {
377            ALOGE("%s: ctx->mExtDisplay->post fail!", __FUNCTION__);
378            return -1;
379        }
380    }
381    return ret;
382}
383
384static int hwc_set(hwc_composer_device_1 *dev,
385                   size_t numDisplays,
386                   hwc_display_contents_1_t** displays)
387{
388    int ret = 0;
389    hwc_context_t* ctx = (hwc_context_t*)(dev);
390    Locker::Autolock _l(ctx->mBlankLock);
391    for (uint32_t i = 0; i < numDisplays; i++) {
392        hwc_display_contents_1_t* list = displays[i];
393        switch(i) {
394            case HWC_DISPLAY_PRIMARY:
395                ret = hwc_set_primary(ctx, list);
396                break;
397            case HWC_DISPLAY_EXTERNAL:
398                ret = hwc_set_external(ctx, list);
399                break;
400            default:
401                ret = -EINVAL;
402        }
403    }
404    return ret;
405}
406
407int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
408        uint32_t* configs, size_t* numConfigs) {
409    int ret = 0;
410    hwc_context_t* ctx = (hwc_context_t*)(dev);
411    //in 1.1 there is no way to choose a config, report as config id # 0
412    //This config is passed to getDisplayAttributes. Ignore for now.
413    switch(disp) {
414        case HWC_DISPLAY_PRIMARY:
415            if(*numConfigs > 0) {
416                configs[0] = 0;
417                *numConfigs = 1;
418            }
419            ret = 0; //NO_ERROR
420            break;
421        case HWC_DISPLAY_EXTERNAL:
422            ret = -1; //Not connected
423            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
424                ret = 0; //NO_ERROR
425                if(*numConfigs > 0) {
426                    configs[0] = 0;
427                    *numConfigs = 1;
428                }
429            }
430            break;
431    }
432    return ret;
433}
434
435int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
436        uint32_t config, const uint32_t* attributes, int32_t* values) {
437
438    hwc_context_t* ctx = (hwc_context_t*)(dev);
439    //If hotpluggable displays are inactive return error
440    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
441        return -1;
442    }
443
444    //From HWComposer
445    static const uint32_t DISPLAY_ATTRIBUTES[] = {
446        HWC_DISPLAY_VSYNC_PERIOD,
447        HWC_DISPLAY_WIDTH,
448        HWC_DISPLAY_HEIGHT,
449        HWC_DISPLAY_DPI_X,
450        HWC_DISPLAY_DPI_Y,
451        HWC_DISPLAY_NO_ATTRIBUTE,
452    };
453
454    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
455            sizeof(DISPLAY_ATTRIBUTES)[0]);
456
457    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
458        switch (attributes[i]) {
459        case HWC_DISPLAY_VSYNC_PERIOD:
460            values[i] = ctx->dpyAttr[disp].vsync_period;
461            break;
462        case HWC_DISPLAY_WIDTH:
463            values[i] = ctx->dpyAttr[disp].xres;
464            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
465                    ctx->dpyAttr[disp].xres);
466            break;
467        case HWC_DISPLAY_HEIGHT:
468            values[i] = ctx->dpyAttr[disp].yres;
469            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
470                    ctx->dpyAttr[disp].yres);
471            break;
472        case HWC_DISPLAY_DPI_X:
473            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
474            break;
475        case HWC_DISPLAY_DPI_Y:
476            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
477            break;
478        default:
479            ALOGE("Unknown display attribute %d",
480                    attributes[i]);
481            return -EINVAL;
482        }
483    }
484    return 0;
485}
486
487void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
488{
489    hwc_context_t* ctx = (hwc_context_t*)(dev);
490    android::String8 buf("");
491    dumpsys_log(buf, "Qualcomm HWC state:\n");
492    dumpsys_log(buf, "  MDPVersion=%d\n", ctx->mMDP.version);
493    dumpsys_log(buf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
494    ctx->mMDPComp->dump(buf);
495    //XXX: Call Other dump functions
496    strlcpy(buff, buf.string(), buff_len);
497}
498
499static int hwc_device_close(struct hw_device_t *dev)
500{
501    if(!dev) {
502        ALOGE("%s: NULL device pointer", __FUNCTION__);
503        return -1;
504    }
505    closeContext((hwc_context_t*)dev);
506    free(dev);
507
508    return 0;
509}
510
511static int hwc_device_open(const struct hw_module_t* module, const char* name,
512                           struct hw_device_t** device)
513{
514    int status = -EINVAL;
515
516    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
517        struct hwc_context_t *dev;
518        dev = (hwc_context_t*)malloc(sizeof(*dev));
519        memset(dev, 0, sizeof(*dev));
520
521        //Initialize hwc context
522        initContext(dev);
523
524        //Setup HWC methods
525        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
526        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_1;
527        dev->device.common.module       = const_cast<hw_module_t*>(module);
528        dev->device.common.close        = hwc_device_close;
529        dev->device.prepare             = hwc_prepare;
530        dev->device.set                 = hwc_set;
531        dev->device.eventControl        = hwc_eventControl;
532        dev->device.blank               = hwc_blank;
533        dev->device.query               = hwc_query;
534        dev->device.registerProcs       = hwc_registerProcs;
535        dev->device.dump                = hwc_dump;
536        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
537        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
538        *device = &dev->device.common;
539        status = 0;
540    }
541    return status;
542}
543