hwc.cpp revision ce2c4b317470ee8d66333f14fea27c0189197c50
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#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
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#include <utils/Trace.h>
28#include <sys/ioctl.h>
29#include <overlay.h>
30#include <overlayRotator.h>
31#include <mdp_version.h>
32#include "hwc_utils.h"
33#include "hwc_fbupdate.h"
34#include "hwc_mdpcomp.h"
35#include "external.h"
36#include "hwc_copybit.h"
37#include "profiler.h"
38
39using namespace qhwc;
40#define VSYNC_DEBUG 0
41#define BLANK_DEBUG 0
42
43static int hwc_device_open(const struct hw_module_t* module,
44                           const char* name,
45                           struct hw_device_t** device);
46
47static struct hw_module_methods_t hwc_module_methods = {
48    .open = hwc_device_open
49};
50
51hwc_module_t HAL_MODULE_INFO_SYM = {
52    .common = {
53        .tag = HARDWARE_MODULE_TAG,
54        .version_major = 2,
55        .version_minor = 0,
56        .id = HWC_HARDWARE_MODULE_ID,
57        .name = "Qualcomm Hardware Composer Module",
58        .author = "CodeAurora Forum",
59        .methods = &hwc_module_methods,
60        .dso = 0,
61        .reserved = {0},
62    }
63};
64
65/*
66 * Save callback functions registered to HWC
67 */
68static void hwc_registerProcs(struct hwc_composer_device_1* dev,
69                              hwc_procs_t const* procs)
70{
71    ALOGI("%s", __FUNCTION__);
72    hwc_context_t* ctx = (hwc_context_t*)(dev);
73    if(!ctx) {
74        ALOGE("%s: Invalid context", __FUNCTION__);
75        return;
76    }
77    ctx->proc = procs;
78
79    // Now that we have the functions needed, kick off
80    // the uevent & vsync threads
81    init_uevent_thread(ctx);
82    init_vsync_thread(ctx);
83}
84
85//Helper
86static void reset(hwc_context_t *ctx, int numDisplays,
87                  hwc_display_contents_1_t** displays) {
88    memset(ctx->listStats, 0, sizeof(ctx->listStats));
89    for(int i = 0; i < MAX_DISPLAYS; i++) {
90        hwc_display_contents_1_t *list = displays[i];
91        // XXX:SurfaceFlinger no longer guarantees that this
92        // value is reset on every prepare. However, for the layer
93        // cache we need to reset it.
94        // We can probably rethink that later on
95        if (LIKELY(list && list->numHwLayers > 1)) {
96            for(uint32_t j = 0; j < list->numHwLayers; j++) {
97                if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
98                    list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
99            }
100        }
101
102        if(ctx->mFBUpdate[i])
103            ctx->mFBUpdate[i]->reset();
104        if(ctx->mCopyBit[i])
105            ctx->mCopyBit[i]->reset();
106        if(ctx->mLayerRotMap[i])
107            ctx->mLayerRotMap[i]->reset();
108    }
109}
110
111//clear prev layer prop flags and realloc for current frame
112static void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
113    if(ctx->layerProp[dpy]) {
114       delete[] ctx->layerProp[dpy];
115       ctx->layerProp[dpy] = NULL;
116    }
117    ctx->layerProp[dpy] = new LayerProp[numAppLayers];
118}
119
120static int display_commit(hwc_context_t *ctx, int dpy) {
121    int fbFd = ctx->dpyAttr[dpy].fd;
122    if(fbFd == -1) {
123        ALOGE("%s: Invalid FB fd for display: %d", __FUNCTION__, dpy);
124        return -1;
125    }
126
127    struct mdp_display_commit commit_info;
128    memset(&commit_info, 0, sizeof(struct mdp_display_commit));
129    commit_info.flags = MDP_DISPLAY_COMMIT_OVERLAY;
130    if(ioctl(fbFd, MSMFB_DISPLAY_COMMIT, &commit_info) == -1) {
131       ALOGE("%s: MSMFB_DISPLAY_COMMIT for primary failed", __FUNCTION__);
132       return -errno;
133    }
134    return 0;
135}
136
137static int hwc_prepare_primary(hwc_composer_device_1 *dev,
138        hwc_display_contents_1_t *list) {
139    hwc_context_t* ctx = (hwc_context_t*)(dev);
140    const int dpy = HWC_DISPLAY_PRIMARY;
141    if(UNLIKELY(!ctx->mBasePipeSetup))
142        setupBasePipe(ctx);
143    if (LIKELY(list && list->numHwLayers > 1) &&
144            ctx->dpyAttr[dpy].isActive) {
145        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
146        uint32_t last = list->numHwLayers - 1;
147        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
148        if(fbLayer->handle) {
149            setListStats(ctx, list, dpy);
150            int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list);
151            if(fbZOrder >= 0)
152                ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder);
153
154            /* Temporarily commenting out C2D until we support partial
155               copybit composition for mixed mode MDP
156
157            // Use Copybit, when MDP comp fails
158            if((fbZOrder >= 0) && ctx->mCopyBit[dpy])
159                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
160            */
161        }
162    }
163    return 0;
164}
165
166static int hwc_prepare_external(hwc_composer_device_1 *dev,
167        hwc_display_contents_1_t *list, int dpy) {
168    hwc_context_t* ctx = (hwc_context_t*)(dev);
169
170    if (LIKELY(list && list->numHwLayers > 1) &&
171            ctx->dpyAttr[dpy].isActive &&
172            ctx->dpyAttr[dpy].connected) {
173        reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
174        uint32_t last = list->numHwLayers - 1;
175        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
176        if(!ctx->dpyAttr[dpy].isPause) {
177            if(fbLayer->handle) {
178                ctx->mExtDispConfiguring = false;
179                setListStats(ctx, list, dpy);
180                int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list);
181                if(fbZOrder >= 0)
182                    ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder);
183
184                /* Temporarily commenting out C2D until we support partial
185                   copybit composition for mixed mode MDP
186
187                if((fbZOrder >= 0) && ctx->mCopyBit[dpy])
188                    ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
189                */
190            }
191        } else {
192            // External Display is in Pause state.
193            // ToDo:
194            // Mark all application layers as OVERLAY so that
195            // GPU will not compose. This is done for power
196            // optimization
197        }
198    }
199    return 0;
200}
201
202static int hwc_prepare_virtual(hwc_composer_device_1 *dev,
203                               hwc_display_contents_1_t *list, int dpy) {
204    //XXX: Fix when framework support is added
205    return 0;
206}
207
208static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
209                       hwc_display_contents_1_t** displays)
210{
211    int ret = 0;
212    hwc_context_t* ctx = (hwc_context_t*)(dev);
213    Locker::Autolock _l(ctx->mBlankLock);
214    reset(ctx, numDisplays, displays);
215
216    ctx->mOverlay->configBegin();
217    ctx->mRotMgr->configBegin();
218    ctx->mNeedsRotator = false;
219
220    for (int32_t i = numDisplays - 1; i >= 0; i--) {
221        hwc_display_contents_1_t *list = displays[i];
222        switch(i) {
223            case HWC_DISPLAY_PRIMARY:
224                ret = hwc_prepare_primary(dev, list);
225                break;
226            case HWC_DISPLAY_EXTERNAL:
227                ret = hwc_prepare_external(dev, list, i);
228                break;
229            case HWC_DISPLAY_VIRTUAL:
230                ret = hwc_prepare_virtual(dev, list, i);
231                break;
232            default:
233                ret = -EINVAL;
234        }
235    }
236
237    ctx->mOverlay->configDone();
238    ctx->mRotMgr->configDone();
239
240    return ret;
241}
242
243static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
244                             int event, int enable)
245{
246    int ret = 0;
247    hwc_context_t* ctx = (hwc_context_t*)(dev);
248    if(!ctx->dpyAttr[dpy].isActive) {
249        ALOGE("Display is blanked - Cannot %s vsync",
250              enable ? "enable" : "disable");
251        return -EINVAL;
252    }
253
254    switch(event) {
255        case HWC_EVENT_VSYNC:
256            if (ctx->vstate.enable == enable)
257                break;
258            ret = hwc_vsync_control(ctx, dpy, enable);
259            if(ret == 0)
260                ctx->vstate.enable = !!enable;
261            ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
262                      (enable)?"ENABLED":"DISABLED");
263            break;
264        default:
265            ret = -EINVAL;
266    }
267    return ret;
268}
269
270static int hwc_blank(struct hwc_composer_device_1* dev, int dpy, int blank)
271{
272    ATRACE_CALL();
273    hwc_context_t* ctx = (hwc_context_t*)(dev);
274
275    Locker::Autolock _l(ctx->mBlankLock);
276    int ret = 0;
277    ALOGD_IF(BLANK_DEBUG, "%s: %s display: %d", __FUNCTION__,
278          blank==1 ? "Blanking":"Unblanking", dpy);
279    if(blank) {
280        // free up all the overlay pipes in use
281        // when we get a blank for either display
282        // makes sure that all pipes are freed
283        ctx->mOverlay->configBegin();
284        ctx->mOverlay->configDone();
285        ctx->mRotMgr->clear();
286    }
287    switch(dpy) {
288        case HWC_DISPLAY_PRIMARY:
289            if(blank) {
290                ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK,
291                            FB_BLANK_POWERDOWN);
292            } else {
293                ret = ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK,FB_BLANK_UNBLANK);
294            }
295            break;
296        case HWC_DISPLAY_EXTERNAL:
297        case HWC_DISPLAY_VIRTUAL:
298            if(blank) {
299                // call external framebuffer commit on blank,
300                // so that any pipe unsets gets committed
301                if (display_commit(ctx, dpy) < 0) {
302                    ret = -1;
303                    ALOGE("%s:post failed for external display !! ",
304                          __FUNCTION__);
305                }
306            } else {
307            }
308            break;
309        default:
310            return -EINVAL;
311    }
312    // Enable HPD here, as during bootup unblank is called
313    // when SF is completely initialized
314    ctx->mExtDisplay->setHPD(1);
315    if(ret == 0){
316        ctx->dpyAttr[dpy].isActive = !blank;
317    } else {
318        ALOGE("%s: Failed in %s display: %d error:%s", __FUNCTION__,
319              blank==1 ? "blanking":"unblanking", dpy, strerror(errno));
320        return ret;
321    }
322
323    ALOGD_IF(BLANK_DEBUG, "%s: Done %s display: %d", __FUNCTION__,
324          blank==1 ? "blanking":"unblanking", dpy);
325    return 0;
326}
327
328static int hwc_query(struct hwc_composer_device_1* dev,
329                     int param, int* value)
330{
331    hwc_context_t* ctx = (hwc_context_t*)(dev);
332    int supported = HWC_DISPLAY_PRIMARY_BIT;
333
334    switch (param) {
335    case HWC_BACKGROUND_LAYER_SUPPORTED:
336        // Not supported for now
337        value[0] = 0;
338        break;
339    case HWC_DISPLAY_TYPES_SUPPORTED:
340        if(ctx->mMDP.hasOverlay)
341            supported |= HWC_DISPLAY_EXTERNAL_BIT;
342        value[0] = supported;
343        break;
344    default:
345        return -EINVAL;
346    }
347    return 0;
348
349}
350
351
352static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
353    ATRACE_CALL();
354    int ret = 0;
355    const int dpy = HWC_DISPLAY_PRIMARY;
356
357    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
358        uint32_t last = list->numHwLayers - 1;
359        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
360        int fd = -1; //FenceFD from the Copybit(valid in async mode)
361        bool copybitDone = false;
362        if(ctx->mCopyBit[dpy])
363            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
364        if(list->numHwLayers > 1)
365            hwc_sync(ctx, list, dpy, fd);
366
367        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
368            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
369            ret = -1;
370        }
371
372        //TODO We dont check for SKIP flag on this layer because we need PAN
373        //always. Last layer is always FB
374        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
375        if(copybitDone) {
376            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
377        }
378
379        if(hnd) {
380            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
381                ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
382                ret = -1;
383            }
384        }
385
386        if (display_commit(ctx, dpy) < 0) {
387            ALOGE("%s: display commit fail!", __FUNCTION__);
388            return -1;
389        }
390    }
391
392    closeAcquireFds(list);
393    return ret;
394}
395
396static int hwc_set_external(hwc_context_t *ctx,
397                            hwc_display_contents_1_t* list, int dpy)
398{
399    ATRACE_CALL();
400    int ret = 0;
401    Locker::Autolock _l(ctx->mExtSetLock);
402
403    if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
404        !ctx->dpyAttr[dpy].isPause &&
405        ctx->dpyAttr[dpy].connected) {
406        uint32_t last = list->numHwLayers - 1;
407        hwc_layer_1_t *fbLayer = &list->hwLayers[last];
408        int fd = -1; //FenceFD from the Copybit(valid in async mode)
409        bool copybitDone = false;
410        if(ctx->mCopyBit[dpy])
411            copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
412
413        if(list->numHwLayers > 1)
414            hwc_sync(ctx, list, dpy, fd);
415
416        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
417            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
418            ret = -1;
419        }
420
421        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
422        if(copybitDone) {
423            hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
424        }
425
426        if(hnd) {
427            if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
428                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
429                ret = -1;
430            }
431        }
432
433        if (display_commit(ctx, dpy) < 0) {
434            ALOGE("%s: display commit fail!", __FUNCTION__);
435            ret = -1;
436        }
437    }
438
439    closeAcquireFds(list);
440    return ret;
441}
442
443static int hwc_set_virtual(hwc_context_t *ctx,
444                           hwc_display_contents_1_t* list, int dpy)
445{
446    //XXX: Implement set.
447    closeAcquireFds(list);
448    if (list) {
449        // SF assumes HWC waits for the acquire fence and returns a new fence
450        // that signals when we're done. Since we don't wait, and also don't
451        // touch the buffer, we can just handle the acquire fence back to SF
452        // as the retire fence.
453        list->retireFenceFd = list->outbufAcquireFenceFd;
454    }
455    return 0;
456}
457
458
459static int hwc_set(hwc_composer_device_1 *dev,
460                   size_t numDisplays,
461                   hwc_display_contents_1_t** displays)
462{
463    int ret = 0;
464    hwc_context_t* ctx = (hwc_context_t*)(dev);
465    Locker::Autolock _l(ctx->mBlankLock);
466    for (uint32_t i = 0; i < numDisplays; i++) {
467        hwc_display_contents_1_t* list = displays[i];
468        switch(i) {
469            case HWC_DISPLAY_PRIMARY:
470                ret = hwc_set_primary(ctx, list);
471                break;
472            case HWC_DISPLAY_EXTERNAL:
473                ret = hwc_set_external(ctx, list, i);
474                break;
475            case HWC_DISPLAY_VIRTUAL:
476                ret = hwc_set_virtual(ctx, list, i);
477                break;
478            default:
479                ret = -EINVAL;
480        }
481    }
482    // This is only indicative of how many times SurfaceFlinger posts
483    // frames to the display.
484    CALC_FPS();
485    MDPComp::resetIdleFallBack();
486    return ret;
487}
488
489int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
490        uint32_t* configs, size_t* numConfigs) {
491    int ret = 0;
492    hwc_context_t* ctx = (hwc_context_t*)(dev);
493    //in 1.1 there is no way to choose a config, report as config id # 0
494    //This config is passed to getDisplayAttributes. Ignore for now.
495    switch(disp) {
496        case HWC_DISPLAY_PRIMARY:
497            if(*numConfigs > 0) {
498                configs[0] = 0;
499                *numConfigs = 1;
500            }
501            ret = 0; //NO_ERROR
502            break;
503        case HWC_DISPLAY_EXTERNAL:
504            ret = -1; //Not connected
505            if(ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
506                ret = 0; //NO_ERROR
507                if(*numConfigs > 0) {
508                    configs[0] = 0;
509                    *numConfigs = 1;
510                }
511            }
512            break;
513    }
514    return ret;
515}
516
517int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
518        uint32_t config, const uint32_t* attributes, int32_t* values) {
519
520    hwc_context_t* ctx = (hwc_context_t*)(dev);
521    //If hotpluggable displays are inactive return error
522    if(disp == HWC_DISPLAY_EXTERNAL && !ctx->dpyAttr[disp].connected) {
523        return -1;
524    }
525
526    //From HWComposer
527    static const uint32_t DISPLAY_ATTRIBUTES[] = {
528        HWC_DISPLAY_VSYNC_PERIOD,
529        HWC_DISPLAY_WIDTH,
530        HWC_DISPLAY_HEIGHT,
531        HWC_DISPLAY_DPI_X,
532        HWC_DISPLAY_DPI_Y,
533        HWC_DISPLAY_NO_ATTRIBUTE,
534    };
535
536    const int NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
537            sizeof(DISPLAY_ATTRIBUTES)[0]);
538
539    for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
540        switch (attributes[i]) {
541        case HWC_DISPLAY_VSYNC_PERIOD:
542            values[i] = ctx->dpyAttr[disp].vsync_period;
543            break;
544        case HWC_DISPLAY_WIDTH:
545            values[i] = ctx->dpyAttr[disp].xres;
546            ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
547                    ctx->dpyAttr[disp].xres);
548            break;
549        case HWC_DISPLAY_HEIGHT:
550            values[i] = ctx->dpyAttr[disp].yres;
551            ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
552                    ctx->dpyAttr[disp].yres);
553            break;
554        case HWC_DISPLAY_DPI_X:
555            values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
556            break;
557        case HWC_DISPLAY_DPI_Y:
558            values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
559            break;
560        default:
561            ALOGE("Unknown display attribute %d",
562                    attributes[i]);
563            return -EINVAL;
564        }
565    }
566    return 0;
567}
568
569void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
570{
571    hwc_context_t* ctx = (hwc_context_t*)(dev);
572    android::String8 aBuf("");
573    dumpsys_log(aBuf, "Qualcomm HWC state:\n");
574    dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
575    dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
576    for(int dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
577        if(ctx->mMDPComp[dpy])
578            ctx->mMDPComp[dpy]->dump(aBuf);
579    }
580    char ovDump[2048] = {'\0'};
581    ctx->mOverlay->getDump(ovDump, 2048);
582    dumpsys_log(aBuf, ovDump);
583    ovDump[0] = '\0';
584    ctx->mRotMgr->getDump(ovDump, 2048);
585    dumpsys_log(aBuf, ovDump);
586    strlcpy(buff, aBuf.string(), buff_len);
587}
588
589static int hwc_device_close(struct hw_device_t *dev)
590{
591    if(!dev) {
592        ALOGE("%s: NULL device pointer", __FUNCTION__);
593        return -1;
594    }
595    closeContext((hwc_context_t*)dev);
596    free(dev);
597
598    return 0;
599}
600
601static int hwc_device_open(const struct hw_module_t* module, const char* name,
602                           struct hw_device_t** device)
603{
604    int status = -EINVAL;
605
606    if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
607        struct hwc_context_t *dev;
608        dev = (hwc_context_t*)malloc(sizeof(*dev));
609        memset(dev, 0, sizeof(*dev));
610
611        //Initialize hwc context
612        initContext(dev);
613
614        //Setup HWC methods
615        dev->device.common.tag          = HARDWARE_DEVICE_TAG;
616        dev->device.common.version      = HWC_DEVICE_API_VERSION_1_2;
617        dev->device.common.module       = const_cast<hw_module_t*>(module);
618        dev->device.common.close        = hwc_device_close;
619        dev->device.prepare             = hwc_prepare;
620        dev->device.set                 = hwc_set;
621        dev->device.eventControl        = hwc_eventControl;
622        dev->device.blank               = hwc_blank;
623        dev->device.query               = hwc_query;
624        dev->device.registerProcs       = hwc_registerProcs;
625        dev->device.dump                = hwc_dump;
626        dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
627        dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
628        *device = &dev->device.common;
629        status = 0;
630    }
631    return status;
632}
633