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])); }
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; }
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; }