Home | History | Annotate | Download | only in tangier
      1 /*
      2 // Copyright(c)2014 IntelCorporation
      3 //
      4 // LicensedundertheApacheLicense,Version2.0(the"License");
      5 // youmaynotusethisfileexceptincompliancewiththeLicense.
      6 // YoumayobtainacopyoftheLicenseat
      7 //
      8 // http://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unlessrequiredbyapplicablelaworagreedtoinwriting,software
     11 // distributedundertheLicenseisdistributedonan"ASIS"BASIS,
     12 // WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.
     13 // SeetheLicenseforthespecificlanguagegoverningpermissionsand
     14 // limitationsundertheLicense.
     15 */
     16 #include <common/utils/HwcTrace.h>
     17 #include <common/base/Drm.h>
     18 #include <Hwcomposer.h>
     19 #include <DisplayPlane.h>
     20 #include <IDisplayDevice.h>
     21 #include <common/base/HwcLayerList.h>
     22 #include <ips/tangier/TngDisplayContext.h>
     23 
     24 namespace android {
     25 namespace intel {
     26 
     27 TngDisplayContext::TngDisplayContext()
     28     : mIMGDisplayDevice(0),
     29       mInitialized(false),
     30       mCount(0)
     31 {
     32     CTRACE();
     33 }
     34 
     35 TngDisplayContext::~TngDisplayContext()
     36 {
     37     WARN_IF_NOT_DEINIT();
     38 }
     39 
     40 bool TngDisplayContext::initialize()
     41 {
     42     CTRACE();
     43 
     44     // open frame buffer device
     45     gralloc_module_t const* module;
     46     int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
     47     if (err) {
     48         ELOGTRACE("failed to load gralloc module, error = %d", err);
     49         return false;
     50     }
     51 
     52     // init IMG display device
     53     err = module->perform(module, GRALLOC_MODULE_GET_DISPLAY_DEVICE_IMG, (void **)&mIMGDisplayDevice);
     54     if (err) {
     55         ELOGTRACE("failed to get display device, error = %d", err);
     56         return false;
     57     }
     58 
     59     mCount = 0;
     60     mInitialized = true;
     61     return true;
     62 }
     63 
     64 bool TngDisplayContext::commitBegin(size_t /* numDisplays */,
     65         hwc_display_contents_1_t ** /* displays */)
     66 {
     67     RETURN_FALSE_IF_NOT_INIT();
     68     mCount = 0;
     69     return true;
     70 }
     71 
     72 bool TngDisplayContext::commitContents(hwc_display_contents_1_t *display, HwcLayerList *layerList)
     73 {
     74     bool ret;
     75 
     76     RETURN_FALSE_IF_NOT_INIT();
     77 
     78     if (!display || !layerList) {
     79         ELOGTRACE("invalid parameters");
     80         return false;
     81     }
     82 
     83     IMG_hwc_layer_t *imgLayerList = (IMG_hwc_layer_t*)mImgLayers;
     84 
     85     for (size_t i = 0; i < display->numHwLayers; i++) {
     86         if (mCount >= MAXIMUM_LAYER_NUMBER) {
     87             ELOGTRACE("layer count exceeds the limit");
     88             return false;
     89         }
     90 
     91         // check layer parameters
     92         if (!display->hwLayers[i].handle) {
     93             continue;
     94         }
     95 
     96         DisplayPlane* plane = layerList->getPlane(i);
     97         if (!plane) {
     98             continue;
     99         }
    100 
    101         ret = plane->flip(NULL);
    102         if (ret == false) {
    103             VLOGTRACE("failed to flip plane %d", i);
    104             continue;
    105         }
    106 
    107         IMG_hwc_layer_t *imgLayer = &imgLayerList[mCount++];
    108         // update IMG layer
    109         imgLayer->psLayer = &display->hwLayers[i];
    110         imgLayer->custom = (uint32_t)plane->getContext();
    111         struct intel_dc_plane_ctx *ctx =
    112             (struct intel_dc_plane_ctx *)imgLayer->custom;
    113         // update z order
    114         Hwcomposer& hwc = Hwcomposer::getInstance();
    115         DisplayPlaneManager *pm = hwc.getPlaneManager();
    116         void *config = pm->getZOrderConfig();
    117         if (config) {
    118             memcpy(&ctx->zorder, config, sizeof(ctx->zorder));
    119         } else {
    120             memset(&ctx->zorder, 0, sizeof(ctx->zorder));
    121         }
    122 
    123         VLOGTRACE("count %d, handle %#x, trans %#x, blending %#x"
    124               " sourceCrop %f,%f - %fx%f, dst %d,%d - %dx%d, custom %#x",
    125               mCount,
    126               (uint32_t)imgLayer->psLayer->handle,
    127               imgLayer->psLayer->transform,
    128               imgLayer->psLayer->blending,
    129               imgLayer->psLayer->sourceCropf.left,
    130               imgLayer->psLayer->sourceCropf.top,
    131               imgLayer->psLayer->sourceCropf.right - imgLayer->psLayer->sourceCropf.left,
    132               imgLayer->psLayer->sourceCropf.bottom - imgLayer->psLayer->sourceCropf.top,
    133               imgLayer->psLayer->displayFrame.left,
    134               imgLayer->psLayer->displayFrame.top,
    135               imgLayer->psLayer->displayFrame.right - imgLayer->psLayer->displayFrame.left,
    136               imgLayer->psLayer->displayFrame.bottom - imgLayer->psLayer->displayFrame.top,
    137               imgLayer->custom);
    138     }
    139 
    140     layerList->postFlip();
    141     return true;
    142 }
    143 
    144 bool TngDisplayContext::commitEnd(size_t numDisplays, hwc_display_contents_1_t **displays)
    145 {
    146     int releaseFenceFd = -1;
    147 
    148     VLOGTRACE("count = %d", mCount);
    149 
    150     if (mIMGDisplayDevice && mCount) {
    151         int err = mIMGDisplayDevice->post(mIMGDisplayDevice,
    152                                           mImgLayers,
    153                                           mCount,
    154                                           &releaseFenceFd);
    155         if (err) {
    156             ELOGTRACE("post failed, err = %d", err);
    157             return false;
    158         }
    159     }
    160 
    161     // close acquire fence
    162     for (size_t i = 0; i < numDisplays; i++) {
    163         // Wait and close HWC_OVERLAY typed layer's acquire fence
    164         hwc_display_contents_1_t* display = displays[i];
    165         if (!display) {
    166             continue;
    167         }
    168 
    169         for (size_t j = 0; j < display->numHwLayers-1; j++) {
    170             hwc_layer_1_t& layer = display->hwLayers[j];
    171             if (layer.compositionType == HWC_OVERLAY) {
    172                 if (layer.acquireFenceFd != -1) {
    173                     // sync_wait(layer.acquireFenceFd, 16ms);
    174                     close(layer.acquireFenceFd);
    175                     layer.acquireFenceFd = -1;
    176                 }
    177             }
    178         }
    179 
    180         // Wait and close framebuffer target layer's acquire fence
    181         hwc_layer_1_t& fbt = display->hwLayers[display->numHwLayers-1];
    182         if (fbt.acquireFenceFd != -1) {
    183             // sync_wait(fbt.acquireFencdFd, 16ms);
    184             close(fbt.acquireFenceFd);
    185             fbt.acquireFenceFd = -1;
    186         }
    187 
    188         // Wait and close outbuf's acquire fence
    189         if (display->outbufAcquireFenceFd != -1) {
    190             // sync_wait(display->outbufAcquireFenceFd, 16ms);
    191             close(display->outbufAcquireFenceFd);
    192             display->outbufAcquireFenceFd = -1;
    193         }
    194     }
    195 
    196     // update release fence and retire fence
    197     if (mCount > 0) {
    198         // For physical displays, dup the releaseFenceFd only for
    199         // HWC layers which successfully flipped to display planes
    200         IMG_hwc_layer_t *imgLayerList = (IMG_hwc_layer_t*)mImgLayers;
    201 
    202         for (size_t i = 0; i < mCount; i++) {
    203             IMG_hwc_layer_t *imgLayer = &imgLayerList[i];
    204             imgLayer->psLayer->releaseFenceFd =
    205                 (releaseFenceFd != -1) ? dup(releaseFenceFd) : -1;
    206         }
    207     }
    208 
    209     for (size_t i = 0; i < numDisplays; i++) {
    210         if (!displays[i]) {
    211             continue;
    212         }
    213 
    214         // log for layer fence status
    215         for (size_t j = 0; j < displays[i]->numHwLayers; j++) {
    216             VLOGTRACE("handle %#x, acquiredFD %d, releaseFD %d",
    217                  (uint32_t)displays[i]->hwLayers[j].handle,
    218                  displays[i]->hwLayers[j].acquireFenceFd,
    219                  displays[i]->hwLayers[j].releaseFenceFd);
    220         }
    221 
    222         // retireFence is used for SurfaceFlinger to do DispSync;
    223         // dup releaseFenceFd for physical displays and ignore virtual
    224         // display; we don't distinguish between release and retire, and all
    225         // physical displays are using a single releaseFence; for virtual
    226         // display, fencing is handled by the VirtualDisplay class
    227         if (i < IDisplayDevice::DEVICE_VIRTUAL) {
    228             displays[i]->retireFenceFd =
    229                 (releaseFenceFd != -1) ? dup(releaseFenceFd) : -1;
    230         }
    231     }
    232 
    233     // close original release fence fd
    234     if (releaseFenceFd != -1) {
    235         close(releaseFenceFd);
    236     }
    237     return true;
    238 }
    239 
    240 bool TngDisplayContext::compositionComplete()
    241 {
    242     return true;
    243 }
    244 
    245 bool TngDisplayContext::setCursorPosition(int disp, int x, int y)
    246 {
    247     DLOGTRACE("setCursorPosition");
    248     struct intel_dc_cursor_ctx ctx;
    249     memset(&ctx, 0, sizeof(ctx));
    250     ctx.pipe = disp;
    251     if (x < 0) {
    252         ctx.pos |= 1 << 15;
    253         x = -x;
    254     }
    255     if (y < 0) {
    256         ctx.pos |= 1 << 31;
    257         y = -y;
    258     }
    259     ctx.pos |= (y & 0xfff) << 16 | (x & 0xfff);
    260     Drm *drm = Hwcomposer::getInstance().getDrm();
    261     return drm->writeIoctl(DRM_PSB_UPDATE_CURSOR_POS, &ctx, sizeof(ctx));
    262 }
    263 
    264 
    265 void TngDisplayContext::deinitialize()
    266 {
    267     mIMGDisplayDevice = 0;
    268 
    269     mCount = 0;
    270     mInitialized = false;
    271 }
    272 
    273 
    274 } // namespace intel
    275 } // namespace android
    276