void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list)
{
    //Video specific stats
    int yuvCount = 0;
    int yuvLayerIndex = -1;
    bool isYuvLayerSkip = false;

    for (size_t i = 0; i < list->numHwLayers; i++) {
        private_handle_t *hnd =
            (private_handle_t *)list->hwLayers[i].handle;

        if (isYuvBuffer(hnd)) {
            yuvCount++;
            yuvLayerIndex = i;
            //Animating
            if (isSkipLayer(&list->hwLayers[i])) {
                isYuvLayerSkip = true;
            }
        } else if (isSkipLayer(&list->hwLayers[i])) { //Popups
            //If video layer is below a skip layer
            if(yuvLayerIndex != -1 && yuvLayerIndex < (ssize_t)i) {
                isYuvLayerSkip = true;
            }
        }
    }

    VideoOverlay::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip);
    CopyBit::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip);

    ctx->numHwLayers = list->numHwLayers;
    return;
}
void VideoOverlay::chooseState(hwc_context_t *ctx, int dpy,
        hwc_layer_1_t *yuvLayer) {
    ALOGD_IF(VIDEO_DEBUG, "%s: old state = %s", __FUNCTION__,
            ovutils::getStateString(sState[dpy]));

    private_handle_t *hnd = NULL;
    if(yuvLayer) {
        hnd = (private_handle_t *)yuvLayer->handle;
    }
    ovutils::eOverlayState newState = ovutils::OV_CLOSED;
    switch(dpy) {
        case HWC_DISPLAY_PRIMARY:
            if(ctx->listStats[dpy].yuvCount == 1) {
                newState = ovutils::OV_2D_VIDEO_ON_PANEL;
                if(isSkipLayer(yuvLayer) && !isSecureBuffer(hnd)) {
                    newState = ovutils::OV_CLOSED;
                }
            }
            break;
        case HWC_DISPLAY_EXTERNAL:
            newState = ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->getState(); //If we are here, external is active
            if(ctx->listStats[dpy].yuvCount == 1) {
                if(!isSkipLayer(yuvLayer) || isSecureBuffer(hnd)) {
                    newState = ovutils::OV_UI_VIDEO_TV;
                }
            }
            break;
        default:
            break;
    }

    sState[dpy] = newState;
    ALOGD_IF(VIDEO_DEBUG, "%s: new chosen state = %s", __FUNCTION__,
            ovutils::getStateString(sState[dpy]));
}
Esempio n. 3
0
void setListStats(hwc_context_t *ctx,
        const hwc_display_contents_1_t *list, int dpy) {

    ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1;
    ctx->listStats[dpy].fbLayerIndex = list->numHwLayers - 1;
    ctx->listStats[dpy].yuvCount = 0;
    ctx->listStats[dpy].yuvIndex = -1;
    ctx->listStats[dpy].skipCount = 0;

    for (size_t i = 0; i < list->numHwLayers; i++) {
        private_handle_t *hnd =
            (private_handle_t *)list->hwLayers[i].handle;

        if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
            continue;
        //We disregard FB being skip for now! so the else if
        } else if (isSkipLayer(&list->hwLayers[i])) {
            ctx->listStats[dpy].skipCount++;
        }

        if (UNLIKELY(isYuvBuffer(hnd))) {
            ctx->listStats[dpy].yuvCount++;
            ctx->listStats[dpy].yuvIndex = i;
        }
    }
}
void setListStats(hwc_context_t *ctx,
        const hwc_display_contents_1_t *list, int dpy) {

    ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1;
    ctx->listStats[dpy].fbLayerIndex = list->numHwLayers - 1;
    ctx->listStats[dpy].skipCount = 0;
    ctx->listStats[dpy].needsAlphaScale = false;
    ctx->listStats[dpy].yuvCount = 0;

    for (size_t i = 0; i < list->numHwLayers; i++) {
        hwc_layer_1_t const* layer = &list->hwLayers[i];
        private_handle_t *hnd = (private_handle_t *)layer->handle;

        //reset stored yuv index
        ctx->listStats[dpy].yuvIndices[i] = -1;

        if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
            continue;
        //We disregard FB being skip for now! so the else if
        } else if (isSkipLayer(&list->hwLayers[i])) {
            ctx->listStats[dpy].skipCount++;
        } else if (UNLIKELY(isYuvBuffer(hnd))) {
            int& yuvCount = ctx->listStats[dpy].yuvCount;
            ctx->listStats[dpy].yuvIndices[yuvCount] = i;
            yuvCount++;
        }

        if(!ctx->listStats[dpy].needsAlphaScale)
            ctx->listStats[dpy].needsAlphaScale = isAlphaScaled(layer);
    }
}
void setListStats(hwc_context_t *ctx,
        const hwc_display_contents_1_t *list, int dpy) {
    const int prevYuvCount = ctx->listStats[dpy].yuvCount;
    ctx->listStats[dpy].numAppLayers = list->numHwLayers - 1;
    ctx->listStats[dpy].fbLayerIndex = list->numHwLayers - 1;
    ctx->listStats[dpy].skipCount = 0;
    ctx->listStats[dpy].needsAlphaScale = false;
    ctx->listStats[dpy].preMultipliedAlpha = false;
    ctx->listStats[dpy].planeAlpha = false;
    ctx->listStats[dpy].yuvCount = 0;

    //reset yuv indices
    memset(ctx->listStats[dpy].yuvIndices, -1, MAX_NUM_APP_LAYERS);

    for (size_t i = 0; i < (list->numHwLayers - 1); i++) {
        hwc_layer_1_t const* layer = &list->hwLayers[i];
        private_handle_t *hnd = (private_handle_t *)layer->handle;

        // continue if i reaches MAX_NUM_APP_LAYERS
        if(i >= MAX_NUM_APP_LAYERS)
            continue;

        if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
            continue;
        //We disregard FB being skip for now! so the else if
        } else if (isSkipLayer(&list->hwLayers[i])) {
            ctx->listStats[dpy].skipCount++;
        } else if (UNLIKELY(isYuvBuffer(hnd))) {
            int& yuvCount = ctx->listStats[dpy].yuvCount;
            ctx->listStats[dpy].yuvIndices[yuvCount] = i;
            yuvCount++;

            if(layer->transform & HWC_TRANSFORM_ROT_90)
                ctx->mNeedsRotator = true;
        }
        if(layer->blending == HWC_BLENDING_PREMULT)
            ctx->listStats[dpy].preMultipliedAlpha = true;
        if(layer->planeAlpha < 0xFF)
            ctx->listStats[dpy].planeAlpha = true;
        if(!ctx->listStats[dpy].needsAlphaScale)
            ctx->listStats[dpy].needsAlphaScale = isAlphaScaled(layer);
    }

    //The marking of video begin/end is useful on some targets where we need
    //to have a padding round to be able to shift pipes across mixers.
    if(prevYuvCount != ctx->listStats[dpy].yuvCount) {
        ctx->mVideoTransFlag = true;
    }

    if (dpy == HWC_DISPLAY_PRIMARY)
        configurePPD(ctx, ctx->listStats[dpy].yuvCount);
}
bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list) {

    int compositionType =
        qdutils::QCCompositionType::getInstance().getCompositionType();

    if ((compositionType & qdutils::COMPOSITION_TYPE_GPU) ||
        (compositionType & qdutils::COMPOSITION_TYPE_CPU))   {
        //GPU/CPU composition, don't change layer composition type
        return true;
    }

    bool useCopybitForYUV = canUseCopybitForYUV(ctx);
    bool useCopybitForRGB = canUseCopybitForRGB(ctx, list);

    if(!(validateParams(ctx, list))) {
       ALOGE("%s:Invalid Params", __FUNCTION__);
       return false;
    }
    sCopyBitDraw = false;
    for (int i=list->numHwLayers-1; i >= 0 ; i--) {
        private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;

        if (isSkipLayer(&list->hwLayers[i])) {
            return true;
        } else if (hnd->bufferType == BUFFER_TYPE_VIDEO) {
          //YUV layer, check, if copybit can be used
          if (useCopybitForYUV) {
              list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
              sCopyBitDraw = true;
          }
       } else if (hnd->bufferType == BUFFER_TYPE_UI) {
          //RGB layer, check, if copybit can be used
          if (useCopybitForRGB) {
              list->hwLayers[i].compositionType = HWC_USE_COPYBIT;
              sCopyBitDraw = true;
          }
       }
    }
    return true;
}
Esempio n. 7
0
void getLayerStats(hwc_context_t *ctx, const hwc_layer_list_t *list)
{
    //Video specific stats
    int yuvCount = 0;
    int yuvLayerIndex = -1;
    int pipLayerIndex = -1; //2nd video in pip scenario
    bool isYuvLayerSkip = false;
    int skipCount = 0;
    int ccLayerIndex = -1; //closed caption
    int extLayerIndex = -1; //ext-only or block except closed caption
    int extCount = 0; //ext-only except closed caption
    bool isExtBlockPresent = false; //is BLOCK layer present
    bool yuvSecure = false;

    for (size_t i = 0; i < list->numHwLayers; i++) {
        private_handle_t *hnd =
            (private_handle_t *)list->hwLayers[i].handle;

        if (UNLIKELY(isYuvBuffer(hnd))) {
            yuvCount++;
            if(yuvCount==1) {
                //Set the primary video to the video layer in
                //lower z-order
                yuvLayerIndex = i;
            }
            if(yuvCount == 2) {
                //In case of two videos, set the pipLayerIndex to the
                //second video
                pipLayerIndex = i;
            }
            yuvSecure = isSecureBuffer(hnd);
            //Animating
            //Do not mark as SKIP if it is secure buffer
            if (isSkipLayer(&list->hwLayers[i]) && !yuvSecure) {
                isYuvLayerSkip = true;
            }
        } else if(UNLIKELY(isExtCC(hnd))) {
            ccLayerIndex = i;
        } else if(UNLIKELY(isExtBlock(hnd))) {
            extCount++;
            extLayerIndex = i;
            isExtBlockPresent = true;
        } else if(UNLIKELY(isExtOnly(hnd))) {
            extCount++;
            //If BLOCK layer present, dont cache index, display BLOCK only.
            if(isExtBlockPresent == false) extLayerIndex = i;
        } else if (isSkipLayer(&list->hwLayers[i])) { //Popups
            skipCount++;
        }
    }

    VideoOverlay::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip,
                           ccLayerIndex);
    VideoPIP::setStats(yuvCount, yuvLayerIndex, isYuvLayerSkip,
                       pipLayerIndex);
    ExtOnly::setStats(extCount, extLayerIndex, isExtBlockPresent);
    CopyBit::setStats(skipCount);
    MDPComp::setStats(skipCount);

    ctx->numHwLayers = list->numHwLayers;
    return;
}