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 <HwcTrace.h>
     17 #include <Hwcomposer.h>
     18 #include <Drm.h>
     19 #include <DisplayPlane.h>
     20 #include <IDisplayDevice.h>
     21 #include <HwcLayerList.h>
     22 #include <tangier/TngDisplayContext.h>
     23 
     24 
     25 namespace android {
     26 namespace intel {
     27 
     28 TngDisplayContext::TngDisplayContext()
     29     : mIMGDisplayDevice(0),
     30       mInitialized(false),
     31       mCount(0)
     32 {
     33     CTRACE();
     34 }
     35 
     36 TngDisplayContext::~TngDisplayContext()
     37 {
     38     WARN_IF_NOT_DEINIT();
     39 }
     40 
     41 bool TngDisplayContext::initialize()
     42 {
     43     CTRACE();
     44 
     45     // open frame buffer device
     46     const hw_device_t *gralloc;
     47     int err = gralloc_open_img(&gralloc);
     48     if (err) {
     49         ETRACE("failed to load gralloc module, error = %d", err);
     50         return false;
     51     }
     52 
     53     // init IMG display device
     54     err = gralloc_get_display_device_img(gralloc, (void **)&mIMGDisplayDevice);
     55     if (err) {
     56         ETRACE("failed to get display device, error = %d", err);
     57         return false;
     58     }
     59 
     60     mCount = 0;
     61     mInitialized = true;
     62     return true;
     63 }
     64 
     65 bool TngDisplayContext::commitBegin(size_t numDisplays, 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         ETRACE("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             ETRACE("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             VTRACE("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 = (unsigned long)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         VTRACE("count %p, handle %#x, trans %#x, blending %#x"
    124               " sourceCrop %f,%f - %fx%f, dst %d,%d - %dx%d, custom %#x",
    125               mCount,
    126               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     VTRACE("count = %d", mCount);
    149 
    150     if (mIMGDisplayDevice && mCount) {
    151         int err = mIMGDisplayDevice->post(mIMGDisplayDevice,
    152                                           mImgLayers,
    153                                           mCount,
    154                                           &releaseFenceFd);
    155         if (err) {
    156             ETRACE("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 (unsigned int 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             VTRACE("handle %#p, acquiredFD %d, releaseFD %d",
    217                  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     DTRACE("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 void TngDisplayContext::deinitialize()
    265 {
    266     mIMGDisplayDevice = 0;
    267 
    268     mCount = 0;
    269     mInitialized = false;
    270 }
    271 
    272 
    273 } // namespace intel
    274 } // namespace android
    275