Home | History | Annotate | Download | only in base
      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 <Drm.h>
     18 #include <HwcLayer.h>
     19 #include <Hwcomposer.h>
     20 #include <GraphicBuffer.h>
     21 #include <IDisplayDevice.h>
     22 #include <DisplayQuery.h>
     23 #include <PlaneCapabilities.h>
     24 #include <cutils/properties.h>
     25 
     26 
     27 namespace android {
     28 namespace intel {
     29 
     30 inline bool operator==(const hwc_rect_t& x, const hwc_rect_t& y)
     31 {
     32     return (x.top == y.top &&
     33             x.bottom == y.bottom &&
     34             x.left == y.left &&
     35             x.right == y.right);
     36 }
     37 
     38 inline bool operator !=(const hwc_rect_t& x, const hwc_rect_t& y)
     39 {
     40     return !operator==(x, y);
     41 }
     42 
     43 inline bool operator ==(const hwc_frect_t& x, const hwc_frect_t& y)
     44 {
     45     return (x.top == y.top &&
     46             x.bottom == y.bottom &&
     47             x.left == y.left &&
     48             x.right == y.right);
     49 }
     50 
     51 inline bool operator !=(const hwc_frect_t& x, const hwc_frect_t& y)
     52 {
     53     return !operator==(x, y);
     54 }
     55 
     56 HwcLayer::HwcLayer(int index, hwc_layer_1_t *layer)
     57     : mIndex(index),
     58       mZOrder(index + 1),  // 0 is reserved for frame buffer target
     59       mDevice(0),
     60       mLayer(layer),
     61       mPlane(0),
     62       mFormat(DataBuffer::FORMAT_INVALID),
     63       mWidth(0),
     64       mHeight(0),
     65       mUsage(0),
     66       mHandle(0),
     67       mIsProtected(false),
     68       mType(LAYER_FB),
     69       mPriority(0),
     70       mTransform(0),
     71       mStaticCount(0),
     72       mUpdated(false)
     73 {
     74     memset(&mSourceCropf, 0, sizeof(mSourceCropf));
     75     memset(&mDisplayFrame, 0, sizeof(mDisplayFrame));
     76     memset(&mStride, 0, sizeof(mStride));
     77 
     78     mPlaneCandidate = false;
     79     setupAttributes();
     80 
     81 #ifdef HWC_TRACE_FPS
     82     mTraceFps = false;
     83     char prop[PROPERTY_VALUE_MAX];
     84     if (property_get("debug.hwc.fps_trace.enable", prop, "0") > 0) {
     85         mTraceFps = atoi(prop);
     86     }
     87     mLastHandle = NULL;
     88 
     89     if (mTraceFps) {
     90         // holding up to 6 seconds of samples at 60Hz
     91         mFrames.setCapacity(6 * 60);
     92     }
     93 #endif
     94 }
     95 
     96 HwcLayer::~HwcLayer()
     97 {
     98     if (mPlane) {
     99         WTRACE("HwcLayer is not cleaned up");
    100     }
    101 
    102     mLayer = NULL;
    103     mPlane = NULL;
    104 
    105 #ifdef HWC_TRACE_FPS
    106     mFrames.clear();
    107 #endif
    108 }
    109 
    110 bool HwcLayer::attachPlane(DisplayPlane* plane, int device)
    111 {
    112     if (mPlane) {
    113         ETRACE("failed to attach plane, plane exists");
    114         return false;
    115     }
    116 
    117     if (!plane) {
    118         ETRACE("Invalid plane");
    119         return false;
    120     }
    121 
    122     mDevice = device;
    123     //plane->setZOrder(mIndex);
    124     plane->assignToDevice(device);
    125     mPlane = plane;
    126     return true;
    127 }
    128 
    129 DisplayPlane* HwcLayer::detachPlane()
    130 {
    131     // reset plane's z order
    132     if (mPlane)
    133         mPlane->setZOrder(-1);
    134     DisplayPlane *plane = mPlane;
    135     mPlane = 0;
    136     mDevice = 0;
    137     return plane;
    138 }
    139 
    140 void HwcLayer::setType(uint32_t type)
    141 {
    142     if (!mLayer)
    143         return;
    144 
    145     switch (type) {
    146     case LAYER_OVERLAY:
    147     case LAYER_SKIPPED:
    148         mLayer->compositionType = HWC_OVERLAY;
    149         mLayer->hints |= HWC_HINT_CLEAR_FB;
    150         break;
    151     // NOTE: set compositionType to HWC_FRAMEBUFFER here so that we have
    152     // a chance to submit the primary changes to HW.
    153     // Upper layer HWComposer will reset the compositionType automatically.
    154     case LAYER_FB:
    155     case LAYER_FORCE_FB:
    156         mLayer->compositionType = HWC_FRAMEBUFFER;
    157         break;
    158     case LAYER_SIDEBAND:
    159         mLayer->compositionType = HWC_SIDEBAND;
    160         break;
    161     case LAYER_CURSOR_OVERLAY:
    162         mLayer->compositionType = HWC_CURSOR_OVERLAY;
    163         break;
    164     default:
    165         break;
    166     }
    167 
    168     mType = type;
    169 }
    170 
    171 uint32_t HwcLayer::getType() const
    172 {
    173     return mType;
    174 }
    175 
    176 void HwcLayer::setCompositionType(int32_t type)
    177 {
    178     mLayer->compositionType = type;
    179 }
    180 
    181 int32_t HwcLayer::getCompositionType() const
    182 {
    183     return mLayer->compositionType;
    184 }
    185 
    186 int HwcLayer::getIndex() const
    187 {
    188     return mIndex;
    189 }
    190 
    191 int HwcLayer::getZOrder() const
    192 {
    193     return mZOrder;
    194 }
    195 
    196 uint32_t HwcLayer::getFormat() const
    197 {
    198     return mFormat;
    199 }
    200 
    201 uint32_t HwcLayer::getBufferWidth() const
    202 {
    203     return mWidth;
    204 }
    205 
    206 uint32_t HwcLayer::getBufferHeight() const
    207 {
    208     return mHeight;
    209 }
    210 
    211 const stride_t& HwcLayer::getBufferStride() const
    212 {
    213     return mStride;
    214 }
    215 
    216 uint32_t HwcLayer::getUsage() const
    217 {
    218     return mUsage;
    219 }
    220 
    221 buffer_handle_t HwcLayer::getHandle() const
    222 {
    223     return mHandle;
    224 }
    225 
    226 uint32_t HwcLayer::getTransform() const
    227 {
    228     return mTransform;
    229 }
    230 
    231 bool HwcLayer::isProtected() const
    232 {
    233     return mIsProtected;
    234 }
    235 
    236 hwc_layer_1_t* HwcLayer::getLayer() const
    237 {
    238     return mLayer;
    239 }
    240 
    241 DisplayPlane* HwcLayer::getPlane() const
    242 {
    243     return mPlane;
    244 }
    245 
    246 void HwcLayer::setPriority(uint32_t priority)
    247 {
    248     mPriority = priority;
    249 }
    250 
    251 uint32_t HwcLayer::getPriority() const
    252 {
    253     return mPriority;
    254 }
    255 
    256 bool HwcLayer::update(hwc_layer_1_t *layer)
    257 {
    258     // update layer
    259     mLayer = layer;
    260     setupAttributes();
    261 
    262 #ifdef HWC_TRACE_FPS
    263     if (mTraceFps && mLayer && mLayer->compositionType != HWC_FRAMEBUFFER_TARGET ) {
    264         // 1 second = 1000000000 nano seconds
    265         uint64_t now = systemTime(CLOCK_MONOTONIC);
    266         if (mLastHandle != mHandle) {
    267             mLastHandle = mHandle;
    268             mFrames.push(now);
    269         }
    270         // calculate fps in 5-second time window
    271         int frames = mFrames.size();
    272         while (frames && now - mFrames[0] > 5000000000LL) {
    273             mFrames.removeItemsAt(0);
    274             frames--;
    275         }
    276         double fps = 0;
    277         if (frames > 1) {
    278             fps = frames * 1000000000.0/ (now - mFrames[0]);
    279         }
    280         ITRACE("fps of layer %d is %.1f", mIndex, fps);
    281     }
    282 #endif
    283 
    284     // if not a FB layer & a plane was attached update plane's data buffer
    285     if (mPlane) {
    286         mPlane->setPosition(layer->displayFrame.left,
    287                             layer->displayFrame.top,
    288                             layer->displayFrame.right - layer->displayFrame.left,
    289                             layer->displayFrame.bottom - layer->displayFrame.top);
    290         mPlane->setSourceCrop(layer->sourceCropf.left,
    291                               layer->sourceCropf.top,
    292                               layer->sourceCropf.right - layer->sourceCropf.left,
    293                               layer->sourceCropf.bottom - layer->sourceCropf.top);
    294         mPlane->setTransform(layer->transform);
    295         mPlane->setPlaneAlpha(layer->planeAlpha, layer->blending);
    296         bool ret = mPlane->setDataBuffer(layer->handle);
    297         if (ret == true) {
    298             return true;
    299         }
    300         DTRACE("failed to set data buffer, reset handle to 0!!");
    301         mHandle = 0;
    302         if (!mIsProtected) {
    303             // typical case: rotated buffer is not ready or handle is null
    304             return false;
    305         } else {
    306             // protected video has to be rendered using overlay.
    307             // if buffer is not ready overlay will still be attached to this layer
    308             // but rendering needs to be skipped.
    309             WTRACE("ignoring result of data buffer setting for protected video");
    310             return true;
    311         }
    312     }
    313 
    314     return true;
    315 }
    316 
    317 bool HwcLayer::isUpdated()
    318 {
    319     return mUpdated;
    320 }
    321 
    322 uint32_t HwcLayer::getStaticCount()
    323 {
    324     return mStaticCount;
    325 }
    326 
    327 void HwcLayer::postFlip()
    328 {
    329     mUpdated = false;
    330     if (mPlane) {
    331         mPlane->postFlip();
    332 
    333         // flip frame buffer target once in video extended mode to refresh screen,
    334         // then mark type as LAYER_SKIPPED so it will not be flipped again.
    335         // by doing this pipe for primary device can enter idle state
    336         if (mDevice == IDisplayDevice::DEVICE_PRIMARY &&
    337             mType == LAYER_FRAMEBUFFER_TARGET &&
    338             Hwcomposer::getInstance().getDisplayAnalyzer()->isVideoExtModeActive()) {
    339             DTRACE("Skipping frame buffer target...");
    340             mType = LAYER_SKIPPED;
    341         }
    342     }
    343 }
    344 
    345 void HwcLayer::setupAttributes()
    346 {
    347     if ((mLayer->flags & HWC_SKIP_LAYER) ||
    348         mTransform != mLayer->transform ||
    349         mSourceCropf != mLayer->sourceCropf ||
    350         mDisplayFrame != mLayer->displayFrame ||
    351         mHandle != mLayer->handle ||
    352         DisplayQuery::isVideoFormat(mFormat)) {
    353         // TODO: same handle does not mean there is always no update
    354         mUpdated = true;
    355         mStaticCount = 0;
    356     } else {
    357         // protect it from exceeding its max
    358         if (++mStaticCount > 1000)
    359             mStaticCount = LAYER_STATIC_THRESHOLD + 1;
    360     }
    361 
    362     // update handle always as it can become "NULL"
    363     // if the given layer is not ready
    364     mTransform = mLayer->transform;
    365     mSourceCropf = mLayer->sourceCropf;
    366     mDisplayFrame = mLayer->displayFrame;
    367     mHandle = mLayer->handle;
    368 
    369     if (mFormat != DataBuffer::FORMAT_INVALID) {
    370         // other attributes have been set.
    371         return;
    372     }
    373 
    374     if (mLayer->handle == NULL) {
    375         VTRACE("invalid handle");
    376         return;
    377     }
    378 
    379     BufferManager *bm = Hwcomposer::getInstance().getBufferManager();
    380     if (bm == NULL) {
    381         // TODO: this check is redundant
    382         return;
    383     }
    384 
    385     DataBuffer *buffer = bm->lockDataBuffer(mLayer->handle);
    386      if (!buffer) {
    387          ETRACE("failed to get buffer");
    388      } else {
    389         mFormat = buffer->getFormat();
    390         mWidth = buffer->getWidth();
    391         mHeight = buffer->getHeight();
    392         mStride = buffer->getStride();
    393         mPriority = (mSourceCropf.right - mSourceCropf.left) * (mSourceCropf.bottom - mSourceCropf.top);
    394         mPriority <<= LAYER_PRIORITY_SIZE_OFFSET;
    395         mPriority |= mIndex;
    396         GraphicBuffer *gBuffer = (GraphicBuffer*)buffer;
    397         mUsage = gBuffer->getUsage();
    398         mIsProtected = GraphicBuffer::isProtectedBuffer((GraphicBuffer*)buffer);
    399         if (mIsProtected) {
    400             mPriority |= LAYER_PRIORITY_PROTECTED;
    401         } else if (PlaneCapabilities::isFormatSupported(DisplayPlane::PLANE_OVERLAY, this)) {
    402             mPriority |= LAYER_PRIORITY_OVERLAY;
    403         }
    404         bm->unlockDataBuffer(buffer);
    405     }
    406 }
    407 
    408 } // namespace intel
    409 } // namespace android
    410