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