Home | History | Annotate | Download | only in libhwcomposer
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  * Copyright (C) 2012-2014, 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 <overlayWriteback.h>
     32 #include <mdp_version.h>
     33 #include "hwc_utils.h"
     34 #include "hwc_fbupdate.h"
     35 #include "hwc_mdpcomp.h"
     36 #include "hwc_dump_layers.h"
     37 #include "external.h"
     38 #include "hwc_copybit.h"
     39 #include "hwc_ad.h"
     40 #include "profiler.h"
     41 #include "hwc_virtual.h"
     42 #ifdef DELTA_PANEL
     43 #include "hwc_delta_panel.h"
     44 #endif
     45 
     46 using namespace qhwc;
     47 using namespace overlay;
     48 #ifdef DELTA_PANEL
     49 using namespace gralloc;
     50 #endif
     51 
     52 #define VSYNC_DEBUG 0
     53 #define POWER_MODE_DEBUG 1
     54 
     55 #ifdef DELTA_PANEL
     56 static bool is_delta_panel = false;
     57 #endif
     58 
     59 static int hwc_device_open(const struct hw_module_t* module,
     60                            const char* name,
     61                            struct hw_device_t** device);
     62 
     63 static struct hw_module_methods_t hwc_module_methods = {
     64     open: hwc_device_open
     65 };
     66 
     67 static void reset_panel(struct hwc_composer_device_1* dev);
     68 
     69 hwc_module_t HAL_MODULE_INFO_SYM = {
     70     common: {
     71         tag: HARDWARE_MODULE_TAG,
     72         version_major: 2,
     73         version_minor: 0,
     74         id: HWC_HARDWARE_MODULE_ID,
     75         name: "Qualcomm Hardware Composer Module",
     76         author: "CodeAurora Forum",
     77         methods: &hwc_module_methods,
     78         dso: 0,
     79         reserved: {0},
     80     }
     81 };
     82 
     83 /* In case of non-hybrid WFD session, we are fooling SF by piggybacking on
     84  * HDMI display ID for virtual. This helper is needed to differentiate their
     85  * paths in HAL.
     86  * TODO: Not needed once we have WFD client working on top of Google API's */
     87 
     88 static int getDpyforExternalDisplay(hwc_context_t *ctx, int dpy) {
     89     if(dpy == HWC_DISPLAY_EXTERNAL && ctx->mVirtualonExtActive)
     90         return HWC_DISPLAY_VIRTUAL;
     91     return dpy;
     92 }
     93 
     94 /*
     95  * Save callback functions registered to HWC
     96  */
     97 static void hwc_registerProcs(struct hwc_composer_device_1* dev,
     98                               hwc_procs_t const* procs)
     99 {
    100     ALOGI("%s", __FUNCTION__);
    101     hwc_context_t* ctx = (hwc_context_t*)(dev);
    102     if(!ctx) {
    103         ALOGE("%s: Invalid context", __FUNCTION__);
    104         return;
    105     }
    106     ctx->proc = procs;
    107 
    108     // Now that we have the functions needed, kick off
    109     // the uevent & vsync threads
    110     init_uevent_thread(ctx);
    111     init_vsync_thread(ctx);
    112 }
    113 
    114 static void setPaddingRound(hwc_context_t *ctx, int numDisplays,
    115                             hwc_display_contents_1_t** displays) {
    116     ctx->isPaddingRound = false;
    117     for(int i = 0; i < numDisplays; i++) {
    118         hwc_display_contents_1_t *list = displays[i];
    119         if (LIKELY(list && list->numHwLayers > 0)) {
    120             if((ctx->mPrevHwLayerCount[i] == 1 or
    121                 ctx->mPrevHwLayerCount[i] == 0) and
    122                (list->numHwLayers > 1)) {
    123                 /* If the previous cycle for dpy 'i' has 0 AppLayers and the
    124                  * current cycle has atleast 1 AppLayer, padding round needs
    125                  * to be invoked in current cycle on all the active displays
    126                  * to free up the resources.
    127                  */
    128                 ctx->isPaddingRound = true;
    129             }
    130             ctx->mPrevHwLayerCount[i] = (int)list->numHwLayers;
    131         } else {
    132             ctx->mPrevHwLayerCount[i] = 0;
    133         }
    134     }
    135 }
    136 
    137 /* Based on certain conditions, isPaddingRound will be set
    138  * to make this function self-contained */
    139 static void setDMAState(hwc_context_t *ctx, int numDisplays,
    140                         hwc_display_contents_1_t** displays) {
    141 
    142     if(ctx->mRotMgr->getNumActiveSessions() == 0)
    143         Overlay::setDMAMode(Overlay::DMA_LINE_MODE);
    144 
    145     for(int dpy = 0; dpy < numDisplays; dpy++) {
    146         hwc_display_contents_1_t *list = displays[dpy];
    147         if (LIKELY(list && list->numHwLayers > 0)) {
    148             for(size_t layerIndex = 0; layerIndex < list->numHwLayers;
    149                                                   layerIndex++) {
    150                 if(list->hwLayers[layerIndex].compositionType !=
    151                                             HWC_FRAMEBUFFER_TARGET)
    152                 {
    153                     hwc_layer_1_t const* layer = &list->hwLayers[layerIndex];
    154                     private_handle_t *hnd = (private_handle_t *)layer->handle;
    155 
    156                     /* If a layer requires rotation, set the DMA state
    157                      * to BLOCK_MODE */
    158 
    159                     if (canUseRotator(ctx, dpy) &&
    160                         has90Transform(layer) && isRotationDoable(ctx, hnd)) {
    161                         if(not ctx->mOverlay->isDMAMultiplexingSupported()) {
    162                             if(ctx->mOverlay->isPipeTypeAttached(
    163                                              overlay::utils::OV_MDP_PIPE_DMA))
    164                                 ctx->isPaddingRound = true;
    165                         }
    166                         Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
    167                     }
    168                 }
    169             }
    170             if(dpy) {
    171                 /* Uncomment the below code for testing purpose.
    172                    Assuming the orientation value is in terms of HAL_TRANSFORM,
    173                    this needs mapping to HAL, if its in different convention */
    174 
    175                 /* char value[PROPERTY_VALUE_MAX];
    176                    property_get("sys.ext_orientation", value, "0");
    177                    ctx->mExtOrientation = atoi(value);*/
    178 
    179                 if(ctx->mExtOrientation || ctx->mBufferMirrorMode) {
    180                     if(ctx->mOverlay->isPipeTypeAttached(
    181                                          overlay::utils::OV_MDP_PIPE_DMA)) {
    182                         ctx->isPaddingRound = true;
    183                     }
    184                     Overlay::setDMAMode(Overlay::DMA_BLOCK_MODE);
    185                 }
    186             }
    187         }
    188     }
    189 }
    190 
    191 static void setNumActiveDisplays(hwc_context_t *ctx, int numDisplays,
    192                             hwc_display_contents_1_t** displays) {
    193 
    194     ctx->numActiveDisplays = 0;
    195     for(int i = 0; i < numDisplays; i++) {
    196         hwc_display_contents_1_t *list = displays[i];
    197         if (LIKELY(list && list->numHwLayers > 0)) {
    198             /* For display devices like SSD and screenrecord, we cannot
    199              * rely on isActive and connected attributes of dpyAttr to
    200              * determine if the displaydevice is active. Hence in case if
    201              * the layer-list is non-null and numHwLayers > 0, we assume
    202              * the display device to be active.
    203              */
    204             ctx->numActiveDisplays += 1;
    205         }
    206     }
    207 }
    208 
    209 static void reset(hwc_context_t *ctx, int numDisplays,
    210                   hwc_display_contents_1_t** displays) {
    211 
    212 
    213     for(int i = 0; i < numDisplays; i++) {
    214         hwc_display_contents_1_t *list = displays[i];
    215         // XXX:SurfaceFlinger no longer guarantees that this
    216         // value is reset on every prepare. However, for the layer
    217         // cache we need to reset it.
    218         // We can probably rethink that later on
    219         if (LIKELY(list && list->numHwLayers > 0)) {
    220             for(size_t j = 0; j < list->numHwLayers; j++) {
    221                 if(list->hwLayers[j].compositionType != HWC_FRAMEBUFFER_TARGET)
    222                     list->hwLayers[j].compositionType = HWC_FRAMEBUFFER;
    223             }
    224 
    225         }
    226 
    227         if(ctx->mMDPComp[i])
    228             ctx->mMDPComp[i]->reset();
    229         if(ctx->mFBUpdate[i])
    230             ctx->mFBUpdate[i]->reset();
    231         if(ctx->mCopyBit[i])
    232             ctx->mCopyBit[i]->reset();
    233         if(ctx->mLayerRotMap[i])
    234             ctx->mLayerRotMap[i]->reset();
    235     }
    236 
    237     ctx->mAD->reset();
    238     if(ctx->mHWCVirtual)
    239         ctx->mHWCVirtual->destroy(ctx, numDisplays, displays);
    240 }
    241 
    242 static void scaleDisplayFrame(hwc_context_t *ctx, int dpy,
    243                             hwc_display_contents_1_t *list) {
    244     uint32_t origXres = ctx->dpyAttr[dpy].xres;
    245     uint32_t origYres = ctx->dpyAttr[dpy].yres;
    246     uint32_t newXres = ctx->dpyAttr[dpy].xres_new;
    247     uint32_t newYres = ctx->dpyAttr[dpy].yres_new;
    248     float xresRatio = (float)origXres / (float)newXres;
    249     float yresRatio = (float)origYres / (float)newYres;
    250     for (size_t i = 0; i < list->numHwLayers; i++) {
    251         hwc_layer_1_t *layer = &list->hwLayers[i];
    252         hwc_rect_t& displayFrame = layer->displayFrame;
    253         hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
    254         uint32_t layerWidth = displayFrame.right - displayFrame.left;
    255         uint32_t layerHeight = displayFrame.bottom - displayFrame.top;
    256         displayFrame.left = (int)(xresRatio * (float)displayFrame.left);
    257         displayFrame.top = (int)(yresRatio * (float)displayFrame.top);
    258         displayFrame.right = (int)((float)displayFrame.left +
    259                                    (float)layerWidth * xresRatio);
    260         displayFrame.bottom = (int)((float)displayFrame.top +
    261                                     (float)layerHeight * yresRatio);
    262     }
    263 }
    264 
    265 static int hwc_prepare_primary(hwc_composer_device_1 *dev,
    266         hwc_display_contents_1_t *list) {
    267     ATRACE_CALL();
    268     hwc_context_t* ctx = (hwc_context_t*)(dev);
    269     const int dpy = HWC_DISPLAY_PRIMARY;
    270     bool fbComp = false;
    271     if (LIKELY(list && list->numHwLayers > 1) &&
    272             ctx->dpyAttr[dpy].isActive) {
    273 
    274         if (ctx->dpyAttr[dpy].customFBSize &&
    275                 list->flags & HWC_GEOMETRY_CHANGED)
    276             scaleDisplayFrame(ctx, dpy, list);
    277 
    278         reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
    279         setListStats(ctx, list, dpy);
    280 
    281         fbComp = (ctx->mMDPComp[dpy]->prepare(ctx, list) < 0);
    282 
    283         if (fbComp) {
    284             const int fbZ = 0;
    285             if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ)) {
    286                 ctx->mOverlay->clear(dpy);
    287                 ctx->mLayerRotMap[dpy]->clear();
    288             }
    289         }
    290 
    291         if (ctx->mMDP.version < qdutils::MDP_V4_0) {
    292             if(ctx->mCopyBit[dpy])
    293                 ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
    294         }
    295         setGPUHint(ctx, list);
    296     }
    297     return 0;
    298 }
    299 
    300 static int hwc_prepare_external(hwc_composer_device_1 *dev,
    301         hwc_display_contents_1_t *list) {
    302     ATRACE_CALL();
    303     hwc_context_t* ctx = (hwc_context_t*)(dev);
    304     const int dpy = HWC_DISPLAY_EXTERNAL;
    305 
    306     if (LIKELY(list && list->numHwLayers > 1) &&
    307             ctx->dpyAttr[dpy].isActive &&
    308             ctx->dpyAttr[dpy].connected) {
    309         reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
    310         if(!ctx->dpyAttr[dpy].isPause) {
    311             ctx->dpyAttr[dpy].isConfiguring = false;
    312             setListStats(ctx, list, dpy);
    313             if(ctx->mMDPComp[dpy]->prepare(ctx, list) < 0) {
    314                 const int fbZ = 0;
    315                 if(not ctx->mFBUpdate[dpy]->prepareAndValidate(ctx, list, fbZ))
    316                 {
    317                     ctx->mOverlay->clear(dpy);
    318                     ctx->mLayerRotMap[dpy]->clear();
    319                 }
    320             }
    321         } else {
    322             /* External Display is in Pause state.
    323              * Mark all application layers as OVERLAY so that
    324              * GPU will not compose.
    325              */
    326             for(size_t i = 0 ;i < (size_t)(list->numHwLayers - 1); i++) {
    327                 hwc_layer_1_t *layer = &list->hwLayers[i];
    328                 layer->compositionType = HWC_OVERLAY;
    329             }
    330         }
    331     }
    332     return 0;
    333 }
    334 
    335 static int hwc_prepare(hwc_composer_device_1 *dev, size_t numDisplays,
    336                        hwc_display_contents_1_t** displays)
    337 {
    338     int ret = 0;
    339     hwc_context_t* ctx = (hwc_context_t*)(dev);
    340 
    341     //Will be unlocked at the end of set
    342     ctx->mDrawLock.lock();
    343 
    344     if (ctx->mPanelResetStatus) {
    345         ALOGW("%s: panel is in bad state. reset the panel", __FUNCTION__);
    346         reset_panel(dev);
    347     }
    348 
    349     setPaddingRound(ctx, (int)numDisplays, displays);
    350     setDMAState(ctx, (int)numDisplays, displays);
    351     setNumActiveDisplays(ctx, (int)numDisplays, displays);
    352     reset(ctx, (int)numDisplays, displays);
    353 
    354     ctx->mOverlay->configBegin();
    355     ctx->mRotMgr->configBegin();
    356     overlay::Writeback::configBegin();
    357 
    358     for (int32_t i = ((int32_t)numDisplays-1); i >=0 ; i--) {
    359         hwc_display_contents_1_t *list = displays[i];
    360         int dpy = getDpyforExternalDisplay(ctx, i);
    361         switch(dpy) {
    362             case HWC_DISPLAY_PRIMARY:
    363                 ret = hwc_prepare_primary(dev, list);
    364                 break;
    365             case HWC_DISPLAY_EXTERNAL:
    366                 ret = hwc_prepare_external(dev, list);
    367                 break;
    368             case HWC_DISPLAY_VIRTUAL:
    369                 if(ctx->mHWCVirtual)
    370                     ret = ctx->mHWCVirtual->prepare(dev, list);
    371                 break;
    372             default:
    373                 ret = -EINVAL;
    374         }
    375     }
    376 
    377     ctx->mOverlay->configDone();
    378     ctx->mRotMgr->configDone();
    379     overlay::Writeback::configDone();
    380 
    381     return ret;
    382 }
    383 
    384 static int hwc_eventControl(struct hwc_composer_device_1* dev, int dpy,
    385                              int event, int enable)
    386 {
    387     ATRACE_CALL();
    388     int ret = 0;
    389     hwc_context_t* ctx = (hwc_context_t*)(dev);
    390     switch(event) {
    391         case HWC_EVENT_VSYNC:
    392             if (ctx->vstate.enable == enable)
    393                 break;
    394             ret = hwc_vsync_control(ctx, dpy, enable);
    395             if(ret == 0)
    396                 ctx->vstate.enable = !!enable;
    397             ALOGD_IF (VSYNC_DEBUG, "VSYNC state changed to %s",
    398                       (enable)?"ENABLED":"DISABLED");
    399             break;
    400 #ifdef QCOM_BSP
    401         case  HWC_EVENT_ORIENTATION:
    402             if(dpy == HWC_DISPLAY_PRIMARY) {
    403                 Locker::Autolock _l(ctx->mDrawLock);
    404                 // store the primary display orientation
    405                 ctx->deviceOrientation = enable;
    406             }
    407             break;
    408 #endif
    409         default:
    410             ret = -EINVAL;
    411     }
    412     return ret;
    413 }
    414 
    415 static int hwc_setPowerMode(struct hwc_composer_device_1* dev, int dpy,
    416         int mode)
    417 {
    418     ATRACE_CALL();
    419     hwc_context_t* ctx = (hwc_context_t*)(dev);
    420     int ret = 0, value = 0;
    421 
    422     Locker::Autolock _l(ctx->mDrawLock);
    423     ALOGV_IF(POWER_MODE_DEBUG, "%s: Setting mode %d on display: %d",
    424             __FUNCTION__, mode, dpy);
    425 
    426     switch(mode) {
    427         case HWC_POWER_MODE_OFF:
    428             // free up all the overlay pipes in use
    429             // when we get a blank for either display
    430             // makes sure that all pipes are freed
    431             ctx->mOverlay->configBegin();
    432             ctx->mOverlay->configDone();
    433             ctx->mRotMgr->clear();
    434             // If VDS is connected, do not clear WB object as it
    435             // will end up detaching IOMMU. This is required
    436             // to send black frame to WFD sink on power suspend.
    437             // Note: With this change, we keep the WriteBack object
    438             // alive on power suspend for AD use case.
    439             value = FB_BLANK_POWERDOWN;
    440             break;
    441         case HWC_POWER_MODE_DOZE:
    442         case HWC_POWER_MODE_DOZE_SUSPEND:
    443             value = FB_BLANK_VSYNC_SUSPEND;
    444             break;
    445         case HWC_POWER_MODE_NORMAL:
    446             value = FB_BLANK_UNBLANK;
    447             break;
    448     }
    449 
    450     ctx->dpyAttr[dpy].lastPowerMode = value;
    451     switch(dpy) {
    452     case HWC_DISPLAY_PRIMARY:
    453         if(ioctl(ctx->dpyAttr[dpy].fd, FBIOBLANK, value) < 0 ) {
    454             ALOGE("%s: ioctl FBIOBLANK failed for Primary with error %s"
    455                     " value %d", __FUNCTION__, strerror(errno), value);
    456             return -errno;
    457         }
    458 
    459         if(mode == HWC_POWER_MODE_NORMAL) {
    460             // Enable HPD here, as during bootup POWER_MODE_NORMAL is set
    461             // when SF is completely initialized
    462             ctx->mExtDisplay->setHPD(1);
    463         }
    464 
    465         ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
    466         //Deliberate fall through since there is no explicit power mode for
    467         //virtual displays.
    468     case HWC_DISPLAY_VIRTUAL:
    469         if(ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected) {
    470             const int dpy = HWC_DISPLAY_VIRTUAL;
    471             if(mode == HWC_POWER_MODE_OFF and
    472                     (not ctx->dpyAttr[dpy].isPause)) {
    473                 if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
    474                     ALOGE("%s: displayCommit failed for virtual", __FUNCTION__);
    475                     ret = -1;
    476                 }
    477             }
    478             ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
    479         }
    480         break;
    481     case HWC_DISPLAY_EXTERNAL:
    482         if(mode == HWC_POWER_MODE_OFF) {
    483             if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
    484                 ALOGE("%s: displayCommit failed for external", __FUNCTION__);
    485                 ret = -1;
    486             }
    487         }
    488         ctx->dpyAttr[dpy].isActive = not(mode == HWC_POWER_MODE_OFF);
    489         break;
    490     default:
    491         return -EINVAL;
    492     }
    493 
    494     ALOGV_IF(POWER_MODE_DEBUG, "%s: Done setting mode %d on display %d",
    495             __FUNCTION__, mode, dpy);
    496     return ret;
    497 }
    498 
    499 static void reset_panel(struct hwc_composer_device_1* dev)
    500 {
    501     int ret = 0;
    502     hwc_context_t* ctx = (hwc_context_t*)(dev);
    503 
    504     if (!ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive) {
    505         ALOGD ("%s : Display OFF - Skip BLANK & UNBLANK", __FUNCTION__);
    506         ctx->mPanelResetStatus = false;
    507         return;
    508     }
    509 
    510     ALOGD("%s: Blanking display", __FUNCTION__);
    511     ret = ioctl(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd, FBIOBLANK,
    512             FB_BLANK_POWERDOWN);
    513     if (ret < 0) {
    514         ALOGE("%s: FBIOBLANK failed to BLANK:  %s", __FUNCTION__,
    515                 strerror(errno));
    516     }
    517 
    518     ALOGD("%s: setting power mode to previous active mode and enabling vsync",
    519             __FUNCTION__);
    520     ret = ioctl(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd, FBIOBLANK,
    521             ctx->dpyAttr[HWC_DISPLAY_PRIMARY].lastPowerMode);
    522     if (ret < 0) {
    523         ALOGE("%s: FBIOBLANK failed to restore mode %d : %s", __FUNCTION__,
    524                 ctx->dpyAttr[HWC_DISPLAY_PRIMARY].lastPowerMode,
    525                 strerror(errno));
    526     }
    527     hwc_vsync_control(ctx, HWC_DISPLAY_PRIMARY, 1);
    528 
    529     ctx->mPanelResetStatus = false;
    530 }
    531 
    532 
    533 static int hwc_query(struct hwc_composer_device_1* dev,
    534                      int param, int* value)
    535 {
    536     hwc_context_t* ctx = (hwc_context_t*)(dev);
    537     int supported = HWC_DISPLAY_PRIMARY_BIT;
    538 
    539     switch (param) {
    540     case HWC_BACKGROUND_LAYER_SUPPORTED:
    541         // Not supported for now
    542         value[0] = 0;
    543         break;
    544     case HWC_DISPLAY_TYPES_SUPPORTED:
    545         if(ctx->mMDP.hasOverlay) {
    546             supported |= HWC_DISPLAY_VIRTUAL_BIT;
    547             if(!(qdutils::MDPVersion::getInstance().is8x26() ||
    548                         qdutils::MDPVersion::getInstance().is8x16() ||
    549                         qdutils::MDPVersion::getInstance().is8x39()))
    550                 supported |= HWC_DISPLAY_EXTERNAL_BIT;
    551         }
    552         value[0] = supported;
    553         break;
    554     case HWC_FORMAT_RB_SWAP:
    555         value[0] = 1;
    556         break;
    557     case HWC_COLOR_FILL:
    558         value[0] = 1;
    559         break;
    560     default:
    561         return -EINVAL;
    562     }
    563     return 0;
    564 
    565 }
    566 
    567 #ifdef DELTA_PANEL
    568 /*
    569  * Return the type of allocator -
    570  * these are used for mapping/unmapping
    571  */
    572 static IMemAlloc* getAllocator(int flags)
    573 {
    574     IMemAlloc* memalloc;
    575     IAllocController* alloc_ctrl = IAllocController::getInstance();
    576     memalloc = alloc_ctrl->getAllocator(flags);
    577     return memalloc;
    578 }
    579 #endif
    580 
    581 static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
    582     ATRACE_CALL();
    583     int ret = 0;
    584     const int dpy = HWC_DISPLAY_PRIMARY;
    585     if (LIKELY(list) && ctx->dpyAttr[dpy].isActive) {
    586         size_t last = list->numHwLayers - 1;
    587         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
    588         int fd = -1; //FenceFD from the Copybit(valid in async mode)
    589         bool copybitDone = false;
    590 
    591         if (ctx->mCopyBit[dpy]) {
    592             if (ctx->mMDP.version < qdutils::MDP_V4_0)
    593                 copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
    594             else
    595                 fd = ctx->mMDPComp[dpy]->drawOverlap(ctx, list);
    596         }
    597 
    598         //TODO We dont check for SKIP flag on this layer because we need PAN
    599         //always. Last layer is always FB
    600         private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
    601 
    602 #ifdef DELTA_PANEL
    603         if(true == is_delta_panel){
    604             sync_wait(fbLayer->acquireFenceFd, 1000);
    605             if(hnd) {
    606                 if(hnd->base) {
    607                     deltaPanelRendering((unsigned char *)hnd->base, DELTA_PANEL_WIDTH,
    608                             DELTA_PANEL_HEIGHT);
    609                     IMemAlloc* memalloc = getAllocator(hnd->flags);
    610                     memalloc->clean_buffer((void*)hnd->base, hnd->size, hnd->offset, hnd->fd,
    611                             CACHE_CLEAN_AND_INVALIDATE);
    612                 }
    613             }
    614         }
    615 #endif
    616 
    617         if(list->numHwLayers > 1)
    618             hwc_sync(ctx, list, dpy, fd);
    619 
    620         // Dump the layers for primary
    621         if(ctx->mHwcDebug[dpy])
    622             ctx->mHwcDebug[dpy]->dumpLayers(list);
    623 
    624         if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
    625             ALOGE("%s: MDPComp draw failed", __FUNCTION__);
    626             ret = -1;
    627         }
    628 
    629         if(copybitDone && ctx->mMDP.version >= qdutils::MDP_V4_0) {
    630             hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
    631         }
    632 
    633         if(isAbcInUse(ctx) == true) {
    634             int index = ctx->listStats[dpy].renderBufIndexforABC;
    635             hwc_layer_1_t *tempLayer = &list->hwLayers[index];
    636             hnd = (private_handle_t *)tempLayer->handle;
    637         }
    638 
    639         if(hnd) {
    640             if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
    641                 ALOGE("%s: FBUpdate draw failed", __FUNCTION__);
    642                 ret = -1;
    643             }
    644         }
    645 
    646         int lSplit = getLeftSplit(ctx, dpy);
    647         qhwc::ovutils::Dim lRoi = qhwc::ovutils::Dim(
    648             ctx->listStats[dpy].lRoi.left,
    649             ctx->listStats[dpy].lRoi.top,
    650             ctx->listStats[dpy].lRoi.right - ctx->listStats[dpy].lRoi.left,
    651             ctx->listStats[dpy].lRoi.bottom - ctx->listStats[dpy].lRoi.top);
    652 
    653         qhwc::ovutils::Dim rRoi = qhwc::ovutils::Dim(
    654             ctx->listStats[dpy].rRoi.left - lSplit,
    655             ctx->listStats[dpy].rRoi.top,
    656             ctx->listStats[dpy].rRoi.right - ctx->listStats[dpy].rRoi.left,
    657             ctx->listStats[dpy].rRoi.bottom - ctx->listStats[dpy].rRoi.top);
    658 
    659         if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, lRoi, rRoi)) {
    660             ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
    661             ret = -1;
    662         }
    663 
    664     }
    665 
    666     closeAcquireFds(list);
    667     return ret;
    668 }
    669 
    670 static int hwc_set_external(hwc_context_t *ctx,
    671                             hwc_display_contents_1_t* list)
    672 {
    673     ATRACE_CALL();
    674     int ret = 0;
    675 
    676     const int dpy = HWC_DISPLAY_EXTERNAL;
    677 
    678 
    679     if (LIKELY(list) && ctx->dpyAttr[dpy].isActive &&
    680         ctx->dpyAttr[dpy].connected &&
    681         !ctx->dpyAttr[dpy].isPause) {
    682         size_t last = list->numHwLayers - 1;
    683         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
    684         int fd = -1; //FenceFD from the Copybit(valid in async mode)
    685         bool copybitDone = false;
    686         if(ctx->mCopyBit[dpy])
    687             copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
    688 
    689         if(list->numHwLayers > 1)
    690             hwc_sync(ctx, list, dpy, fd);
    691 
    692         // Dump the layers for external
    693         if(ctx->mHwcDebug[dpy])
    694             ctx->mHwcDebug[dpy]->dumpLayers(list);
    695 
    696         if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
    697             ALOGE("%s: MDPComp draw failed", __FUNCTION__);
    698             ret = -1;
    699         }
    700 
    701         int extOnlyLayerIndex =
    702                 ctx->listStats[dpy].extOnlyLayerIndex;
    703 
    704         private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
    705         if(extOnlyLayerIndex!= -1) {
    706             hwc_layer_1_t *extLayer = &list->hwLayers[extOnlyLayerIndex];
    707             hnd = (private_handle_t *)extLayer->handle;
    708         } else if(copybitDone) {
    709             hnd = ctx->mCopyBit[dpy]->getCurrentRenderBuffer();
    710         }
    711 
    712         if(hnd && !isYuvBuffer(hnd)) {
    713             if (!ctx->mFBUpdate[dpy]->draw(ctx, hnd)) {
    714                 ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
    715                 ret = -1;
    716             }
    717         }
    718 
    719         if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
    720             ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
    721             ret = -1;
    722         }
    723     }
    724 
    725     closeAcquireFds(list);
    726     return ret;
    727 }
    728 
    729 static int hwc_set(hwc_composer_device_1 *dev,
    730                    size_t numDisplays,
    731                    hwc_display_contents_1_t** displays)
    732 {
    733     int ret = 0;
    734     hwc_context_t* ctx = (hwc_context_t*)(dev);
    735     for (int i = 0; i < (int)numDisplays; i++) {
    736         hwc_display_contents_1_t* list = displays[i];
    737         int dpy = getDpyforExternalDisplay(ctx, i);
    738         switch(dpy) {
    739             case HWC_DISPLAY_PRIMARY:
    740                 ret = hwc_set_primary(ctx, list);
    741                 break;
    742             case HWC_DISPLAY_EXTERNAL:
    743                 ret = hwc_set_external(ctx, list);
    744                 break;
    745             case HWC_DISPLAY_VIRTUAL:
    746                 if(ctx->mHWCVirtual)
    747                     ret = ctx->mHWCVirtual->set(ctx, list);
    748                 break;
    749             default:
    750                 ret = -EINVAL;
    751         }
    752     }
    753     // This is only indicative of how many times SurfaceFlinger posts
    754     // frames to the display.
    755     CALC_FPS();
    756     MDPComp::resetIdleFallBack();
    757     ctx->mVideoTransFlag = false;
    758     //Was locked at the beginning of prepare
    759     ctx->mDrawLock.unlock();
    760     return ret;
    761 }
    762 
    763 int hwc_getDisplayConfigs(struct hwc_composer_device_1* dev, int disp,
    764         uint32_t* configs, size_t* numConfigs) {
    765     int ret = 0;
    766     hwc_context_t* ctx = (hwc_context_t*)(dev);
    767     disp = getDpyforExternalDisplay(ctx, disp);
    768     //Currently we allow only 1 config, reported as config id # 0
    769     //This config is passed in to getDisplayAttributes. Ignored for now.
    770     switch(disp) {
    771         case HWC_DISPLAY_PRIMARY:
    772             if(*numConfigs > 0) {
    773                 configs[0] = 0;
    774                 *numConfigs = 1;
    775             }
    776             ret = 0; //NO_ERROR
    777             break;
    778         case HWC_DISPLAY_EXTERNAL:
    779         case HWC_DISPLAY_VIRTUAL:
    780             ret = -1; //Not connected
    781             if(ctx->dpyAttr[disp].connected) {
    782                 ret = 0; //NO_ERROR
    783                 if(*numConfigs > 0) {
    784                     configs[0] = 0;
    785                     *numConfigs = 1;
    786                 }
    787             }
    788             break;
    789     }
    790     return ret;
    791 }
    792 
    793 int hwc_getDisplayAttributes(struct hwc_composer_device_1* dev, int disp,
    794         uint32_t /*config*/, const uint32_t* attributes, int32_t* values) {
    795 
    796     hwc_context_t* ctx = (hwc_context_t*)(dev);
    797     disp = getDpyforExternalDisplay(ctx, disp);
    798     //If hotpluggable displays(i.e, HDMI, WFD) are inactive return error
    799     if( (disp != HWC_DISPLAY_PRIMARY) && !ctx->dpyAttr[disp].connected) {
    800         return -1;
    801     }
    802 
    803     //From HWComposer
    804     static const uint32_t DISPLAY_ATTRIBUTES[] = {
    805         HWC_DISPLAY_VSYNC_PERIOD,
    806         HWC_DISPLAY_WIDTH,
    807         HWC_DISPLAY_HEIGHT,
    808         HWC_DISPLAY_DPI_X,
    809         HWC_DISPLAY_DPI_Y,
    810         HWC_DISPLAY_NO_ATTRIBUTE,
    811     };
    812 
    813     const size_t NUM_DISPLAY_ATTRIBUTES = (sizeof(DISPLAY_ATTRIBUTES) /
    814             sizeof(DISPLAY_ATTRIBUTES)[0]);
    815 
    816     for (size_t i = 0; i < NUM_DISPLAY_ATTRIBUTES - 1; i++) {
    817         switch (attributes[i]) {
    818         case HWC_DISPLAY_VSYNC_PERIOD:
    819             values[i] = ctx->dpyAttr[disp].vsync_period;
    820             break;
    821         case HWC_DISPLAY_WIDTH:
    822             if (ctx->dpyAttr[disp].customFBSize)
    823                 values[i] = ctx->dpyAttr[disp].xres_new;
    824             else
    825                 values[i] = ctx->dpyAttr[disp].xres;
    826 
    827             ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
    828                     values[i]);
    829             break;
    830         case HWC_DISPLAY_HEIGHT:
    831             if (ctx->dpyAttr[disp].customFBSize)
    832                 values[i] = ctx->dpyAttr[disp].yres_new;
    833             else
    834                 values[i] = ctx->dpyAttr[disp].yres;
    835             ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
    836                     values[i]);
    837             break;
    838         case HWC_DISPLAY_DPI_X:
    839             values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
    840             break;
    841         case HWC_DISPLAY_DPI_Y:
    842             values[i] = (int32_t) (ctx->dpyAttr[disp].ydpi*1000.0);
    843             break;
    844         default:
    845             ALOGE("Unknown display attribute %d",
    846                     attributes[i]);
    847             return -EINVAL;
    848         }
    849     }
    850     return 0;
    851 }
    852 
    853 void hwc_dump(struct hwc_composer_device_1* dev, char *buff, int buff_len)
    854 {
    855     hwc_context_t* ctx = (hwc_context_t*)(dev);
    856     Locker::Autolock _l(ctx->mDrawLock);
    857     android::String8 aBuf("");
    858     dumpsys_log(aBuf, "Qualcomm HWC state:\n");
    859     dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
    860     dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
    861     if(ctx->vstate.fakevsync)
    862         dumpsys_log(aBuf, "  Vsync is being faked!!\n");
    863     for(int dpy = 0; dpy < HWC_NUM_DISPLAY_TYPES; dpy++) {
    864         if(ctx->mMDPComp[dpy])
    865             ctx->mMDPComp[dpy]->dump(aBuf, ctx);
    866     }
    867     char ovDump[2048] = {'\0'};
    868     ctx->mOverlay->getDump(ovDump, 2048);
    869     dumpsys_log(aBuf, ovDump);
    870     ovDump[0] = '\0';
    871     ctx->mRotMgr->getDump(ovDump, 1024);
    872     dumpsys_log(aBuf, ovDump);
    873     ovDump[0] = '\0';
    874     if(Writeback::getDump(ovDump, 1024)) {
    875         dumpsys_log(aBuf, ovDump);
    876         ovDump[0] = '\0';
    877     }
    878     strlcpy(buff, aBuf.string(), buff_len);
    879 }
    880 
    881 int hwc_getActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/) {
    882     //Supports only the default config (0th index) for now
    883     return 0;
    884 }
    885 
    886 int hwc_setActiveConfig(struct hwc_composer_device_1* /*dev*/, int /*disp*/,
    887         int index) {
    888     //Supports only the default config (0th index) for now
    889     return (index == 0) ? index : -EINVAL;
    890 }
    891 
    892 static int hwc_device_close(struct hw_device_t *dev)
    893 {
    894     if(!dev) {
    895         ALOGE("%s: NULL device pointer", __FUNCTION__);
    896         return -1;
    897     }
    898     closeContext((hwc_context_t*)dev);
    899     free(dev);
    900 
    901     return 0;
    902 }
    903 
    904 static int hwc_device_open(const struct hw_module_t* module, const char* name,
    905                            struct hw_device_t** device)
    906 {
    907     int status = -EINVAL;
    908 
    909     if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
    910         struct hwc_context_t *dev;
    911         dev = (hwc_context_t*)malloc(sizeof(*dev));
    912         if(dev == NULL)
    913             return status;
    914         memset(dev, 0, sizeof(*dev));
    915 
    916         //Initialize hwc context
    917         initContext(dev);
    918 
    919         //Setup HWC methods
    920         dev->device.common.tag          = HARDWARE_DEVICE_TAG;
    921         dev->device.common.version      = HWC_DEVICE_API_VERSION_1_4;
    922         dev->device.common.module       = const_cast<hw_module_t*>(module);
    923         dev->device.common.close        = hwc_device_close;
    924         dev->device.prepare             = hwc_prepare;
    925         dev->device.set                 = hwc_set;
    926         dev->device.eventControl        = hwc_eventControl;
    927         dev->device.setPowerMode        = hwc_setPowerMode;
    928         dev->device.query               = hwc_query;
    929         dev->device.registerProcs       = hwc_registerProcs;
    930         dev->device.dump                = hwc_dump;
    931         dev->device.getDisplayConfigs   = hwc_getDisplayConfigs;
    932         dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
    933         dev->device.getActiveConfig     = hwc_getActiveConfig;
    934         dev->device.setActiveConfig     = hwc_setActiveConfig;
    935         *device = &dev->device.common;
    936         status = 0;
    937 
    938 #ifdef DELTA_PANEL
    939         char property[PROPERTY_VALUE_MAX];
    940         if((property_get("ro.hwc.is_delta_panel", property, NULL) > 0) &&
    941            (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
    942             (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
    943             ALOGD("%s: Display is delta panel", __FUNCTION__);
    944             is_delta_panel = true;
    945         }
    946 #endif
    947     }
    948     return status;
    949 }
    950