diff options
Diffstat (limited to 'msm8909/libhwcomposer/hwc_copybit.cpp')
-rw-r--r-- | msm8909/libhwcomposer/hwc_copybit.cpp | 1382 |
1 files changed, 0 insertions, 1382 deletions
diff --git a/msm8909/libhwcomposer/hwc_copybit.cpp b/msm8909/libhwcomposer/hwc_copybit.cpp deleted file mode 100644 index 4b70b130..00000000 --- a/msm8909/libhwcomposer/hwc_copybit.cpp +++ /dev/null @@ -1,1382 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * Copyright (C) 2012-2016, The Linux Foundation. All rights reserved. - * - * Not a Contribution. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define DEBUG_COPYBIT 0 -#include <copybit.h> -#include <utils/Timers.h> -#include <mdp_version.h> -#include "hwc_copybit.h" -#include "comptype.h" -#include "gr.h" -#include "cb_utils.h" -#include "cb_swap_rect.h" -#include "math.h" -#include "sync/sync.h" - -using namespace qdutils; -namespace qhwc { - -struct range { - int current; - int end; -}; -struct region_iterator : public copybit_region_t { - - region_iterator(hwc_region_t region) { - mRegion = region; - r.end = (int)region.numRects; - r.current = 0; - this->next = iterate; - } - -private: - static int iterate(copybit_region_t const * self, copybit_rect_t* rect){ - if (!self || !rect) { - ALOGE("iterate invalid parameters"); - return 0; - } - - region_iterator const* me = - static_cast<region_iterator const*>(self); - if (me->r.current != me->r.end) { - rect->l = me->mRegion.rects[me->r.current].left; - rect->t = me->mRegion.rects[me->r.current].top; - rect->r = me->mRegion.rects[me->r.current].right; - rect->b = me->mRegion.rects[me->r.current].bottom; - me->r.current++; - return 1; - } - return 0; - } - - hwc_region_t mRegion; - mutable range r; -}; - -void CopyBit::reset() { - mIsModeOn = false; - mCopyBitDraw = false; -} - -bool CopyBit::canUseCopybitForYUV(hwc_context_t *ctx) { - // return true for non-overlay targets - if(ctx->mMDP.hasOverlay && ctx->mMDP.version >= qdutils::MDP_V4_0) { - return false; - } - return true; -} - -bool CopyBit::isSmartBlitPossible(const hwc_display_contents_1_t *list){ - if(list->numHwLayers > 2) { - hwc_rect_t displayFrame0 = {0, 0, 0, 0}; - hwc_rect_t displayFrame1 = {0, 0, 0, 0}; - int layer0_transform = 0; - int layer1_transform = 0; - int isYuvLayer0 = 0; - int isYuvLayer1 = 0; - for (unsigned int i=0; i<list->numHwLayers -1; i++) { - hwc_rect_t displayFrame = list->hwLayers[i].displayFrame; - if (mSwapRect) - displayFrame = getIntersection(mDirtyRect, - list->hwLayers[i].displayFrame); - if (isValidRect(displayFrame) && !isValidRect(displayFrame0)) { - displayFrame0 = displayFrame; - private_handle_t *hnd =(private_handle_t *)list->hwLayers[i].handle; - isYuvLayer0 = isYuvBuffer(hnd); - layer0_transform = list->hwLayers[i].transform; - } else if(isValidRect(displayFrame)) { - displayFrame1 = displayFrame; - layer1_transform = list->hwLayers[i].transform; - private_handle_t *hnd =(private_handle_t *)list->hwLayers[i].handle; - isYuvLayer1 = isYuvBuffer(hnd); - break; - } - } - /* - * smart blit enable only if - * 1. Both layers should have same ROI. - * 2. Both layers can't be video layer. - * 3. Should not be any rotation for base RGB layer. - * 4. In case of base layer as video, next above RGB layer - * should not contains any rotation. - */ - if((displayFrame0 == displayFrame1) && not (isYuvLayer1 && isYuvLayer0)) { - if (isYuvLayer0) { - if (not layer1_transform) { - ALOGD_IF(DEBUG_COPYBIT,"%s:Smart Bilt Possible",__FUNCTION__); - return true; - } - } else if (not layer0_transform) { - ALOGD_IF(DEBUG_COPYBIT,"%s:Smart Bilt Possible",__FUNCTION__); - return true; - } - } - } - return false; -} - -bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx, - hwc_display_contents_1_t *list, - int dpy) { - int compositionType = qdutils::QCCompositionType:: - getInstance().getCompositionType(); - - if (compositionType & qdutils::COMPOSITION_TYPE_DYN) { - // DYN Composition: - // use copybit, if (TotalRGBRenderArea < threashold * FB Area) - // this is done based on perf inputs in ICS - // TODO: Above condition needs to be re-evaluated in JB - int fbWidth = ctx->dpyAttr[dpy].xres; - int fbHeight = ctx->dpyAttr[dpy].yres; - unsigned int fbArea = (fbWidth * fbHeight); - unsigned int renderArea = getRGBRenderingArea(ctx, list); - ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u", - __FUNCTION__, renderArea, fbArea); - double dynThreshold = mDynThreshold; - if(not isSmartBlitPossible(list)) - dynThreshold -= 1; - - if (renderArea < (dynThreshold * fbArea)) { - return true; - } - } else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) { - // MDP composition, use COPYBIT always - return true; - } else if ((compositionType & qdutils::COMPOSITION_TYPE_C2D)) { - // C2D composition, use COPYBIT - return true; - } - return false; -} - -unsigned int CopyBit::getRGBRenderingArea (const hwc_context_t *ctx, - const hwc_display_contents_1_t *list) { - //Calculates total rendering area for RGB layers - unsigned int renderArea = 0; - unsigned int w=0, h=0; - // Skipping last layer since FrameBuffer layer should not affect - // which composition to choose - for (unsigned int i=0; i<list->numHwLayers -1; i++) { - private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle; - if (hnd) { - if (BUFFER_TYPE_UI == hnd->bufferType && !ctx->copybitDrop[i]) { - getLayerResolution(&list->hwLayers[i], w, h); - renderArea += (w*h); - } - } - } - return renderArea; -} - -bool CopyBit::isLayerChanging(hwc_context_t *ctx, - hwc_display_contents_1_t *list, int k) { - if((mLayerCache.hnd[k] != list->hwLayers[k].handle) || - (mLayerCache.drop[k] != ctx->copybitDrop[k]) || - (mLayerCache.displayFrame[k].left != - list->hwLayers[k].displayFrame.left) || - (mLayerCache.displayFrame[k].top != - list->hwLayers[k].displayFrame.top) || - (mLayerCache.displayFrame[k].right != - list->hwLayers[k].displayFrame.right) || - (mLayerCache.displayFrame[k].bottom != - list->hwLayers[k].displayFrame.bottom)) { - return 1; - } - return 0; -} - -bool CopyBit::prepareSwapRect(hwc_context_t *ctx, - hwc_display_contents_1_t *list, - int dpy) { - bool canUseSwapRect = 0; - hwc_rect_t dirtyRect = {0, 0, 0, 0}; - hwc_rect_t displayRect = {0, 0, 0, 0}; - hwc_rect fullFrame = (struct hwc_rect) {0, 0,(int)ctx->dpyAttr[dpy].xres, - (int)ctx->dpyAttr[dpy].yres}; - if((mLayerCache.layerCount != ctx->listStats[dpy].numAppLayers) || - list->flags & HWC_GEOMETRY_CHANGED || not mSwapRectEnable) { - mLayerCache.reset(); - mFbCache.reset(); - mLayerCache.updateCounts(ctx,list,dpy); - mDirtyRect = displayRect; - return 0; - } - - int updatingLayerCount = 0; - for (int k = ctx->listStats[dpy].numAppLayers-1; k >= 0 ; k--){ - //swap rect will kick in only for single updating layer - if(isLayerChanging(ctx, list, k)) { - updatingLayerCount ++; - hwc_layer_1_t layer = list->hwLayers[k]; - canUseSwapRect = 1; -#ifdef QTI_BSP - dirtyRect = getUnion(dirtyRect, calculateDirtyRect(&layer,fullFrame)); -#else - (void)fullFrame; -#endif - displayRect = getUnion(displayRect, layer.displayFrame); - } - } - //since we are using more than one framebuffers,we have to - //kick in swap rect only if we are getting continuous same - //dirty rect for same layer at least equal of number of - //framebuffers - - if (canUseSwapRect || updatingLayerCount == 0) { - if (updatingLayerCount == 0) { - dirtyRect.left = INVALID_DIMENSION; - dirtyRect.top = INVALID_DIMENSION; - dirtyRect.right = INVALID_DIMENSION; - dirtyRect.bottom = INVALID_DIMENSION; - canUseSwapRect = 1; - } - - for (int k = ctx->listStats[dpy].numAppLayers-1; k >= 0 ; k--) { - //disable swap rect in case of scaling and video . - private_handle_t *hnd =(private_handle_t *)list->hwLayers[k].handle; - if(needsScaling(&list->hwLayers[k])||( hnd && isYuvBuffer(hnd)) || - (list->hwLayers[k].transform & HAL_TRANSFORM_ROT_90)) { - mFbCache.reset(); - displayRect.bottom = 0; - displayRect.top = 0; - displayRect.right = 0; - displayRect.bottom = 0; - mDirtyRect = displayRect; - return 0; - } - } - - if(mFbCache.getUnchangedFbDRCount(dirtyRect, displayRect) < - NUM_RENDER_BUFFERS) { - mFbCache.insertAndUpdateFbCache(dirtyRect, displayRect); - canUseSwapRect = 0; - displayRect.bottom = 0; - displayRect.top = 0; - displayRect.right = 0; - displayRect.bottom = 0; - } - } else { - mFbCache.reset(); - canUseSwapRect = 0; - displayRect.bottom = 0; - displayRect.top = 0; - displayRect.right = 0; - displayRect.bottom = 0; - - } - mDirtyRect = displayRect; - mLayerCache.updateCounts(ctx,list,dpy); - return canUseSwapRect; -} - -bool CopyBit::prepareOverlap(hwc_context_t *ctx, - hwc_display_contents_1_t *list) { - - if (ctx->mMDP.version < qdutils::MDP_V4_0) { - ALOGE("%s: Invalid request", __FUNCTION__); - return false; - } - - if (mEngine == NULL || !(validateParams(ctx, list))) { - ALOGE("%s: Invalid Params", __FUNCTION__); - return false; - } - PtorInfo* ptorInfo = &(ctx->mPtorInfo); - - // Allocate render buffers if they're not allocated - int alignW = 0, alignH = 0; - int finalW = 0, finalH = 0; - for (int i = 0; i < ptorInfo->count; i++) { - int ovlapIndex = ptorInfo->layerIndex[i]; - hwc_rect_t overlap = list->hwLayers[ovlapIndex].displayFrame; - // render buffer width will be the max of two layers - // Align Widht and height to 32, Mdp would be configured - // with Aligned overlap w/h - finalW = max(finalW, ALIGN((overlap.right - overlap.left), 32)); - finalH += ALIGN((overlap.bottom - overlap.top), 32); - if(finalH > ALIGN((overlap.bottom - overlap.top), 32)) { - // Calculate the dest top, left will always be zero - ptorInfo->displayFrame[i].top = (finalH - - (ALIGN((overlap.bottom - overlap.top), 32))); - } - // calculate the right and bottom values - ptorInfo->displayFrame[i].right = ptorInfo->displayFrame[i].left + - (overlap.right - overlap.left); - ptorInfo->displayFrame[i].bottom = ptorInfo->displayFrame[i].top + - (overlap.bottom - overlap.top); - } - - getBufferSizeAndDimensions(finalW, finalH, HAL_PIXEL_FORMAT_RGBA_8888, - alignW, alignH); - - if ((mAlignedWidth != alignW) || (mAlignedHeight != alignH)) { - // Overlap rect has changed, so free render buffers - freeRenderBuffers(); - } - - int ret = allocRenderBuffers(alignW, alignH, HAL_PIXEL_FORMAT_RGBA_8888); - - if (ret < 0) { - ALOGE("%s: Render buffer allocation failed", __FUNCTION__); - return false; - } - - mAlignedWidth = alignW; - mAlignedHeight = alignH; - mCurRenderBufferIndex = (mCurRenderBufferIndex + 1) % NUM_RENDER_BUFFERS; - return true; -} - -bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list, - int dpy) { - - if(mEngine == NULL) { - // No copybit device found - cannot use copybit - return false; - } - - if(ctx->mThermalBurstMode) { - ALOGD_IF (DEBUG_COPYBIT, "%s:Copybit failed," - "Running in Thermal Burst mode",__FUNCTION__); - return false; - } - - 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; - } - - if(!(validateParams(ctx, list))) { - ALOGE("%s:Invalid Params", __FUNCTION__); - return false; - } - - if(ctx->listStats[dpy].skipCount) { - //GPU will be anyways used - return false; - } - - if (ctx->listStats[dpy].numAppLayers > MAX_NUM_APP_LAYERS) { - // Reached max layers supported by HWC. - return false; - } - - int last = (uint32_t)list->numHwLayers - 1; - mDirtyRect = list->hwLayers[last].displayFrame; - mSwapRect = prepareSwapRect(ctx, list, dpy); - ALOGD_IF (DEBUG_COPYBIT, "%s: mSwapRect: %d mDirtyRect: [%d, %d, %d, %d]", - __FUNCTION__, mSwapRect, mDirtyRect.left, - mDirtyRect.top, mDirtyRect.right, mDirtyRect.bottom); - - bool useCopybitForYUV = canUseCopybitForYUV(ctx); - bool useCopybitForRGB = canUseCopybitForRGB(ctx, list, dpy); - LayerProp *layerProp = ctx->layerProp[dpy]; - - // Following are MDP3 limitations for which we - // need to fallback to GPU composition: - // 1. Plane alpha is not supported by MDP3. - // 2. Scaling is within range - if (qdutils::MDPVersion::getInstance().getMDPVersion() < 400) { - for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) { - int dst_h, dst_w, src_h, src_w; - float dx, dy; - if(ctx->copybitDrop[i]) { - continue; - } - hwc_layer_1_t *layer = (hwc_layer_1_t *) &list->hwLayers[i]; - if (layer->planeAlpha != 0xFF) - return true; - - if (layer->transform) { - ALOGD_IF (DEBUG_COPYBIT, "%s: Do GPU comp Transform : %d", - __FUNCTION__, layer->transform); - return true; - } - hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf); - - if (has90Transform(layer)) { - src_h = sourceCrop.right - sourceCrop.left; - src_w = sourceCrop.bottom - sourceCrop.top; - } else { - src_h = sourceCrop.bottom - sourceCrop.top; - src_w = sourceCrop.right - sourceCrop.left; - } - dst_h = layer->displayFrame.bottom - layer->displayFrame.top; - dst_w = layer->displayFrame.right - layer->displayFrame.left; - - if(src_w <=0 || src_h<=0 ||dst_w<=0 || dst_h<=0 ) { - ALOGE("%s: wrong params for display screen_w=%d \ - src_crop_width=%d screen_h=%d src_crop_height=%d", - __FUNCTION__, dst_w,src_w,dst_h,src_h); - return false; - } - dx = (float)dst_w/(float)src_w; - dy = (float)dst_h/(float)src_h; - - float scale_factor_max = MAX_SCALE_FACTOR; - float scale_factor_min = MIN_SCALE_FACTOR; - - if (isAlphaPresent(layer)) { - scale_factor_max = MAX_SCALE_FACTOR/4; - scale_factor_min = MIN_SCALE_FACTOR*4; - } - - if (dx > scale_factor_max || dx < scale_factor_min) - return false; - - if (dy > scale_factor_max || dy < scale_factor_min) - return false; - } - } - - //Allocate render buffers if they're not allocated - if ((ctx->mMDP.version != qdutils::MDP_V3_0_4 && -#ifdef SUPPORT_BLIT_TO_FB - ctx->mMDP.version == qdutils::MDP_V3_0_5 -#else - ctx->mMDP.version != qdutils::MDP_V3_0_5 -#endif - ) && (useCopybitForYUV || useCopybitForRGB)) { - int ret = allocRenderBuffers(mAlignedWidth, - mAlignedHeight, - HAL_PIXEL_FORMAT_RGBA_8888); - if (ret < 0) { - return false; - } else { - mCurRenderBufferIndex = (mCurRenderBufferIndex + 1) % - NUM_RENDER_BUFFERS; - } - } - - // We cannot mix copybit layer with layers marked to be drawn on FB - if (!useCopybitForYUV && ctx->listStats[dpy].yuvCount) - return true; - - mCopyBitDraw = false; - if (useCopybitForRGB && - (useCopybitForYUV || !ctx->listStats[dpy].yuvCount)) { - mCopyBitDraw = true; - // numAppLayers-1, as we iterate till 0th layer index - // Mark all layers to be drawn by copybit - for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) { - layerProp[i].mFlags |= HWC_COPYBIT; -#ifdef QTI_BSP - if (ctx->mMDP.version == qdutils::MDP_V3_0_4 || - ctx->mMDP.version == qdutils::MDP_V3_0_5) - list->hwLayers[i].compositionType = HWC_BLIT; - else -#endif - list->hwLayers[i].compositionType = HWC_OVERLAY; - } - } - - return true; -} - -int CopyBit::clear (private_handle_t* hnd, hwc_rect_t& rect) -{ - int ret = 0; - copybit_rect_t clear_rect = {rect.left, rect.top, - rect.right, - rect.bottom}; - - copybit_image_t buf; - buf.w = ALIGN(getWidth(hnd),32); - buf.h = getHeight(hnd); - buf.format = hnd->format; - buf.base = (void *)hnd->base; - buf.handle = (native_handle_t *)hnd; - - copybit_device_t *copybit = mEngine; - ret = copybit->clear(copybit, &buf, &clear_rect); - return ret; -} - -bool CopyBit::drawUsingAppBufferComposition(hwc_context_t *ctx, - hwc_display_contents_1_t *list, - int dpy, int *copybitFd) { - int layerCount = 0; - uint32_t last = (uint32_t)list->numHwLayers - 1; - hwc_layer_1_t *fbLayer = &list->hwLayers[last]; - private_handle_t *fbhnd = (private_handle_t *)fbLayer->handle; - - if(ctx->enableABC == false) - return false; - - if(ctx->listStats[dpy].numAppLayers > MAX_LAYERS_FOR_ABC ) - return false; - - layerCount = ctx->listStats[dpy].numAppLayers; - //bottom most layer should - //equal to FB - hwc_layer_1_t *tmpLayer = &list->hwLayers[0]; - private_handle_t *hnd = (private_handle_t *)tmpLayer->handle; - if(hnd && fbhnd && (hnd->size == fbhnd->size) && - (hnd->width == fbhnd->width) && (hnd->height == fbhnd->height)){ - if(tmpLayer->transform || - (list->flags & HWC_GEOMETRY_CHANGED) || - (!(hnd->format == HAL_PIXEL_FORMAT_RGBA_8888 || - hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)) || - (needsScaling(tmpLayer) == true)) { - return false; - }else { - ctx->listStats[dpy].renderBufIndexforABC = 0; - } - } - - if(ctx->listStats[dpy].renderBufIndexforABC == 0) { - if(layerCount == 1) - return true; - - if(layerCount == MAX_LAYERS_FOR_ABC) { - int abcRenderBufIdx = ctx->listStats[dpy].renderBufIndexforABC; - //enable ABC only for non intersecting layers. - hwc_rect_t displayFrame = - list->hwLayers[abcRenderBufIdx].displayFrame; - for (int i = abcRenderBufIdx + 1; i < layerCount; i++) { - hwc_rect_t tmpDisplayFrame = list->hwLayers[i].displayFrame; - hwc_rect_t result = getIntersection(displayFrame,tmpDisplayFrame); - if (isValidRect(result)) { - ctx->listStats[dpy].renderBufIndexforABC = -1; - return false; - } - } - // Pass the Acquire Fence FD to driver for base layer - private_handle_t *renderBuffer = - (private_handle_t *)list->hwLayers[abcRenderBufIdx].handle; - copybit_device_t *copybit = getCopyBitDevice(); - if(list->hwLayers[abcRenderBufIdx].acquireFenceFd >=0){ - copybit->set_sync(copybit, - list->hwLayers[abcRenderBufIdx].acquireFenceFd); - } - for(int i = abcRenderBufIdx + 1; i < layerCount; i++){ - mSwapRect = 0; - int retVal = drawLayerUsingCopybit(ctx, - &(list->hwLayers[i]),renderBuffer, 0); - if(retVal < 0) { - ALOGE("%s : Copybit failed", __FUNCTION__); - } - } - // Get Release Fence FD of copybit for the App layer(s) - copybit->flush_get_fence(copybit, copybitFd); - close(list->hwLayers[last].acquireFenceFd); - list->hwLayers[last].acquireFenceFd = -1; - return true; - } - } - return false; -} - -bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list, - int dpy, int32_t *fd) { - // draw layers marked for COPYBIT - int retVal = true; - int copybitLayerCount = 0; - uint32_t last = 0; - LayerProp *layerProp = ctx->layerProp[dpy]; - private_handle_t *renderBuffer; - - if(mCopyBitDraw == false){ - mFbCache.reset(); // there is no layer marked for copybit - return false ; - } - - if(drawUsingAppBufferComposition(ctx, list, dpy, fd)) { - mFbCache.reset(); - return true; - } - //render buffer - if (ctx->mMDP.version == qdutils::MDP_V3_0_4 || -#ifdef SUPPORT_BLIT_TO_FB - ctx->mMDP.version != qdutils::MDP_V3_0_5 -#else - ctx->mMDP.version == qdutils::MDP_V3_0_5 -#endif - ) { - last = (uint32_t)list->numHwLayers - 1; - renderBuffer = (private_handle_t *)list->hwLayers[last].handle; - } else { - renderBuffer = getCurrentRenderBuffer(); - } - if (!renderBuffer) { - ALOGE("%s: Render buffer layer handle is NULL", __FUNCTION__); - return false; - } - - if ((ctx->mMDP.version >= qdutils::MDP_V4_0) -#ifdef SUPPORT_BLIT_TO_FB - || (ctx->mMDP.version == qdutils::MDP_V3_0_5) -#endif - ) { - //Wait for the previous frame to complete before rendering onto it - if(mRelFd[mCurRenderBufferIndex] >=0) { - sync_wait(mRelFd[mCurRenderBufferIndex], 1000); - close(mRelFd[mCurRenderBufferIndex]); - mRelFd[mCurRenderBufferIndex] = -1; - } - } else { - if(list->hwLayers[last].acquireFenceFd >=0) { - copybit_device_t *copybit = getCopyBitDevice(); - copybit->set_sync(copybit, list->hwLayers[last].acquireFenceFd); - } - } - - //if swap rect on and not getting valid dirtyRect - //means calling only commit without any draw. Hence avoid - //clear call as well. - if (not mSwapRect || isValidRect(mDirtyRect)) { - if (not CBUtils::uiClearRegion(list, ctx->mMDP.version, layerProp, - mDirtyRect, mEngine, renderBuffer)){ - mSwapRect = 0; - } - } - - // numAppLayers-1, as we iterate from 0th layer index with HWC_COPYBIT flag - for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) { - if(!(layerProp[i].mFlags & HWC_COPYBIT)) { - ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for copybit", __FUNCTION__); - continue; - } - if(ctx->copybitDrop[i]) { - continue; - } - int ret = -1; - if (list->hwLayers[i].acquireFenceFd != -1 - && ctx->mMDP.version >= qdutils::MDP_V4_0) { - // Wait for acquire Fence on the App buffers. - ret = sync_wait(list->hwLayers[i].acquireFenceFd, 1000); - if(ret < 0) { - ALOGE("%s: sync_wait error!! error no = %d err str = %s", - __FUNCTION__, errno, strerror(errno)); - } - close(list->hwLayers[i].acquireFenceFd); - list->hwLayers[i].acquireFenceFd = -1; - } - retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]), - renderBuffer, !i); - copybitLayerCount++; - if(retVal < 0) { - ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__); - } - } - - if (copybitLayerCount) { - copybit_device_t *copybit = getCopyBitDevice(); - // Async mode - copybit->flush_get_fence(copybit, fd); - if((ctx->mMDP.version == qdutils::MDP_V3_0_4 || -#ifdef SUPPORT_BLIT_TO_FB - ctx->mMDP.version != qdutils::MDP_V3_0_5 -#else - ctx->mMDP.version == qdutils::MDP_V3_0_5 -#endif - ) && list->hwLayers[last].acquireFenceFd >= 0) { - close(list->hwLayers[last].acquireFenceFd); - list->hwLayers[last].acquireFenceFd = -1; - } - } - return true; -} - -int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list) { - int fd = -1; - PtorInfo* ptorInfo = &(ctx->mPtorInfo); - - if (ctx->mMDP.version < qdutils::MDP_V4_0) { - ALOGE("%s: Invalid request", __FUNCTION__); - return fd; - } - - private_handle_t *renderBuffer = getCurrentRenderBuffer(); - - if (!renderBuffer) { - ALOGE("%s: Render buffer layer handle is NULL", __FUNCTION__); - return fd; - } - - //Clear the transparent or left out region on the render buffer - LayerProp *layerProp = ctx->layerProp[0]; - hwc_rect_t clearRegion = {0, 0, 0, 0}; - CBUtils::uiClearRegion(list, ctx->mMDP.version, layerProp, clearRegion, - mEngine, renderBuffer); - - int copybitLayerCount = 0; - for(int j = 0; j < ptorInfo->count; j++) { - int ovlapIndex = ptorInfo->layerIndex[j]; - hwc_rect_t overlap = list->hwLayers[ovlapIndex].displayFrame; - if(j) { - /** - * It's possible that 2 PTOR layers might have overlapping. - * In such case, remove the intersection(again if peripheral) - * from the lower PTOR layer to avoid overlapping. - * If intersection is not on peripheral then compromise - * by reducing number of PTOR layers. - **/ - int prevOvlapIndex = ptorInfo->layerIndex[0]; - hwc_rect_t prevOvlap = list->hwLayers[prevOvlapIndex].displayFrame; - hwc_rect_t commonRect = getIntersection(prevOvlap, overlap); - if(isValidRect(commonRect)) { - overlap = deductRect(overlap, commonRect); - } - } - - // Draw overlapped content of layers on render buffer - for (int i = 0; i <= ovlapIndex; i++) { - hwc_layer_1_t *layer = &list->hwLayers[i]; - if(!isValidRect(getIntersection(layer->displayFrame, - overlap))) { - continue; - } - if ((list->hwLayers[i].acquireFenceFd != -1)) { - // Wait for acquire fence on the App buffers. - if(sync_wait(list->hwLayers[i].acquireFenceFd, 1000) < 0) { - ALOGE("%s: sync_wait error!! error no = %d err str = %s", - __FUNCTION__, errno, strerror(errno)); - } - close(list->hwLayers[i].acquireFenceFd); - list->hwLayers[i].acquireFenceFd = -1; - } - /* - * Find the intersection of layer display frame with PTOR layer - * with respect to screen co-ordinates - * - * Calculated the destination rect by transforming the overlapping - * region of layer display frame with respect to PTOR display frame - * - * Transform the destination rect on to render buffer - * */ - hwc_rect_t destRect = getIntersection(overlap, layer->displayFrame); - destRect.left = destRect.left - overlap.left + - ptorInfo->displayFrame[j].left; - destRect.right = destRect.right- overlap.left + - ptorInfo->displayFrame[j].left; - destRect.top = destRect.top - overlap.top + - ptorInfo->displayFrame[j].top; - destRect.bottom = destRect.bottom - overlap.top + - ptorInfo->displayFrame[j].top; - - int retVal = drawRectUsingCopybit(ctx, layer, renderBuffer, - overlap, destRect); - copybitLayerCount++; - if(retVal < 0) { - ALOGE("%s: drawRectUsingCopybit failed", __FUNCTION__); - copybitLayerCount = 0; - } - } - } - - if (copybitLayerCount) { - copybit_device_t *copybit = getCopyBitDevice(); - copybit->flush_get_fence(copybit, &fd); - } - - ALOGD_IF(DEBUG_COPYBIT, "%s: done! copybitLayerCount = %d", __FUNCTION__, - copybitLayerCount); - return fd; -} - -int CopyBit::drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer, - private_handle_t *renderBuffer, hwc_rect_t overlap, - hwc_rect_t destRect) -{ - hwc_context_t* ctx = (hwc_context_t*)(dev); - if (!ctx) { - ALOGE("%s: null context ", __FUNCTION__); - return -1; - } - - private_handle_t *hnd = (private_handle_t *)layer->handle; - if (!hnd) { - ALOGE("%s: invalid handle", __FUNCTION__); - return -1; - } - - private_handle_t *dstHandle = (private_handle_t *)renderBuffer; - if (!dstHandle) { - ALOGE("%s: RenderBuffer handle is NULL", __FUNCTION__); - return -1; - } - - // Set the Copybit Source - copybit_image_t src; - src.handle = (native_handle_t *)layer->handle; - src.w = hnd->width; - src.h = hnd->height; - src.base = (void *)hnd->base; - src.format = hnd->format; - src.horiz_padding = 0; - src.vert_padding = 0; - - - hwc_rect_t dispFrame = layer->displayFrame; - hwc_rect_t iRect = getIntersection(dispFrame, overlap); - hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf); - qhwc::calculate_crop_rects(crop, dispFrame, iRect, - layer->transform); - - // Copybit source rect - copybit_rect_t srcRect = {crop.left, crop.top, crop.right, - crop.bottom}; - - // Copybit destination rect - copybit_rect_t dstRect = {destRect.left, destRect.top, destRect.right, - destRect.bottom}; - - // Copybit dst - copybit_image_t dst; - dst.handle = (native_handle_t *)dstHandle; - dst.w = ALIGN(dstHandle->width, 32); - dst.h = dstHandle->height; - dst.base = (void *)dstHandle->base; - dst.format = dstHandle->format; - - copybit_device_t *copybit = mEngine; - - // Copybit region is the destRect - hwc_rect_t regRect = {dstRect.l,dstRect.t, dstRect.r, dstRect.b}; - hwc_region_t region; - region.numRects = 1; - region.rects = ®Rect; - region_iterator copybitRegion(region); - int acquireFd = layer->acquireFenceFd; - - copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH, - renderBuffer->width); - copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT, - renderBuffer->height); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, layer->transform); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha); - copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending); - copybit->set_parameter(copybit, COPYBIT_DITHER, - (dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE : - COPYBIT_DISABLE); - copybit->set_sync(copybit, acquireFd); - int err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect, - ©bitRegion); - - if (err < 0) - ALOGE("%s: copybit stretch failed",__FUNCTION__); - - return err; -} - -int CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer, - private_handle_t *renderBuffer, bool isFG) -{ - hwc_context_t* ctx = (hwc_context_t*)(dev); - int err = 0, acquireFd; - if(!ctx) { - ALOGE("%s: null context ", __FUNCTION__); - return -1; - } - - private_handle_t *hnd = (private_handle_t *)layer->handle; - if(!hnd) { - if (layer->flags & HWC_COLOR_FILL) { // Color layer - return fillColorUsingCopybit(layer, renderBuffer); - } - ALOGE("%s: invalid handle", __FUNCTION__); - return -1; - } - - private_handle_t *fbHandle = (private_handle_t *)renderBuffer; - if(!fbHandle) { - ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__); - return -1; - } - uint32_t dynamic_fps = 0; -#ifdef DYNAMIC_FPS - MetaData_t *mdata = hnd ? (MetaData_t *)hnd->base_metadata : NULL; - if (mdata && (mdata->operation & UPDATE_REFRESH_RATE)) { - dynamic_fps = roundOff(mdata->refreshrate); - } -#endif - // Set the copybit source: - copybit_image_t src; - src.w = getWidth(hnd); - src.h = getHeight(hnd); - src.format = hnd->format; - - // Handle R/B swap - if ((layer->flags & HWC_FORMAT_RB_SWAP)) { - if (src.format == HAL_PIXEL_FORMAT_RGBA_8888) { - src.format = HAL_PIXEL_FORMAT_BGRA_8888; - } else if (src.format == HAL_PIXEL_FORMAT_RGBX_8888) { - src.format = HAL_PIXEL_FORMAT_BGRX_8888; - } - } - - src.base = (void *)hnd->base; - src.handle = (native_handle_t *)layer->handle; - src.horiz_padding = src.w - getWidth(hnd); - // Initialize vertical padding to zero for now, - // this needs to change to accomodate vertical stride - // if needed in the future - src.vert_padding = 0; - - int layerTransform = layer->transform ; - // When flip and rotation(90) are present alter the flip, - // as GPU is doing the flip and rotation in opposite order - // to that of MDP3.0 - // For 270 degrees, we get 90 + (H+V) which is same as doing - // flip first and then rotation (H+V) + 90 - if (qdutils::MDPVersion::getInstance().getMDPVersion() < 400) { - if (((layer->transform& HAL_TRANSFORM_FLIP_H) || - (layer->transform & HAL_TRANSFORM_FLIP_V)) && - (layer->transform & HAL_TRANSFORM_ROT_90) && - !(layer->transform == HAL_TRANSFORM_ROT_270)){ - if(layer->transform & HAL_TRANSFORM_FLIP_H){ - layerTransform ^= HAL_TRANSFORM_FLIP_H; - layerTransform |= HAL_TRANSFORM_FLIP_V; - } - if(layer->transform & HAL_TRANSFORM_FLIP_V){ - layerTransform ^= HAL_TRANSFORM_FLIP_V; - layerTransform |= HAL_TRANSFORM_FLIP_H; - } - } - } - // Copybit source rect - hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf); - copybit_rect_t srcRect = {sourceCrop.left, sourceCrop.top, - sourceCrop.right, - sourceCrop.bottom}; - - // Copybit destination rect - hwc_rect_t displayFrame = layer->displayFrame; - copybit_rect_t dstRect = {displayFrame.left, displayFrame.top, - displayFrame.right, - displayFrame.bottom}; -#ifdef QTI_BSP - //change src and dst with dirtyRect - if(mSwapRect) { - hwc_rect_t result = getIntersection(displayFrame, mDirtyRect); - if(!isValidRect(result)) - return true; - dstRect.l = result.left; - dstRect.t = result.top; - dstRect.r = result.right; - dstRect.b = result.bottom; - - srcRect.l += (result.left - displayFrame.left); - srcRect.t += (result.top - displayFrame.top); - srcRect.r -= (displayFrame.right - result.right); - srcRect.b -= (displayFrame.bottom - result.bottom); - } -#endif - // Copybit dst - copybit_image_t dst; - dst.w = ALIGN(fbHandle->width,32); - dst.h = fbHandle->height; - dst.format = fbHandle->format; - dst.base = (void *)fbHandle->base; - dst.handle = (native_handle_t *)fbHandle; - - copybit_device_t *copybit = mEngine; - - int32_t screen_w = displayFrame.right - displayFrame.left; - int32_t screen_h = displayFrame.bottom - displayFrame.top; - int32_t src_crop_width = sourceCrop.right - sourceCrop.left; - int32_t src_crop_height = sourceCrop.bottom -sourceCrop.top; - - // Copybit dst - float copybitsMaxScale = - (float)copybit->get(copybit,COPYBIT_MAGNIFICATION_LIMIT); - float copybitsMinScale = - (float)copybit->get(copybit,COPYBIT_MINIFICATION_LIMIT); - - if (layer->transform & HWC_TRANSFORM_ROT_90) { - //swap screen width and height - int tmp = screen_w; - screen_w = screen_h; - screen_h = tmp; - } - private_handle_t *tmpHnd = NULL; - - if(screen_w <=0 || screen_h<=0 ||src_crop_width<=0 || src_crop_height<=0 ) { - ALOGE("%s: wrong params for display screen_w=%d src_crop_width=%d \ - screen_h=%d src_crop_height=%d", __FUNCTION__, screen_w, - src_crop_width,screen_h,src_crop_height); - return -1; - } - - float dsdx = (float)screen_w/(float)src_crop_width; - float dtdy = (float)screen_h/(float)src_crop_height; - - float scaleLimitMax = copybitsMaxScale * copybitsMaxScale; - float scaleLimitMin = copybitsMinScale * copybitsMinScale; - if(dsdx > scaleLimitMax || - dtdy > scaleLimitMax || - dsdx < 1/scaleLimitMin || - dtdy < 1/scaleLimitMin) { - ALOGW("%s: greater than max supported size dsdx=%f dtdy=%f \ - scaleLimitMax=%f scaleLimitMin=%f", __FUNCTION__,dsdx,dtdy, - scaleLimitMax,1/scaleLimitMin); - return -1; - } - acquireFd = layer->acquireFenceFd; - if(dsdx > copybitsMaxScale || - dtdy > copybitsMaxScale || - dsdx < 1/copybitsMinScale || - dtdy < 1/copybitsMinScale){ - // The requested scale is out of the range the hardware - // can support. - ALOGD("%s:%d::Need to scale twice dsdx=%f, dtdy=%f,copybitsMaxScale=%f,\ - copybitsMinScale=%f,screen_w=%d,screen_h=%d \ - src_crop_width=%d src_crop_height=%d",__FUNCTION__,__LINE__, - dsdx,dtdy,copybitsMaxScale,1/copybitsMinScale,screen_w,screen_h, - src_crop_width,src_crop_height); - - - int tmp_w = src_crop_width; - int tmp_h = src_crop_height; - - if (dsdx > copybitsMaxScale) - tmp_w = (int)((float)src_crop_width*copybitsMaxScale); - if (dtdy > copybitsMaxScale) - tmp_h = (int)((float)src_crop_height*copybitsMaxScale); - // ceil the tmp_w and tmp_h value to maintain proper ratio - // b/w src and dst (should not cross the desired scale limit - // due to float -> int ) - if (dsdx < 1/copybitsMinScale) - tmp_w = (int)ceil((float)src_crop_width/copybitsMinScale); - if (dtdy < 1/copybitsMinScale) - tmp_h = (int)ceil((float)src_crop_height/copybitsMinScale); - - ALOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h); - - int usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP; - int format = fbHandle->format; - - // We do not want copybit to generate alpha values from nothing - if (format == HAL_PIXEL_FORMAT_RGBA_8888 && - src.format != HAL_PIXEL_FORMAT_RGBA_8888) { - format = HAL_PIXEL_FORMAT_RGBX_8888; - } - if (0 == alloc_buffer(&tmpHnd, tmp_w, tmp_h, format, usage) && tmpHnd) { - copybit_image_t tmp_dst; - copybit_rect_t tmp_rect; - tmp_dst.w = tmp_w; - tmp_dst.h = tmp_h; - tmp_dst.format = tmpHnd->format; - tmp_dst.handle = tmpHnd; - tmp_dst.horiz_padding = src.horiz_padding; - tmp_dst.vert_padding = src.vert_padding; - tmp_rect.l = 0; - tmp_rect.t = 0; - tmp_rect.r = tmp_dst.w; - tmp_rect.b = tmp_dst.h; - //create one clip region - hwc_rect tmp_hwc_rect = {0,0,tmp_rect.r,tmp_rect.b}; - hwc_region_t tmp_hwc_reg = {1,(hwc_rect_t const*)&tmp_hwc_rect}; - region_iterator tmp_it(tmp_hwc_reg); - copybit->set_parameter(copybit,COPYBIT_TRANSFORM,0); - //TODO: once, we are able to read layer alpha, update this - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255); - copybit->set_sync(copybit, acquireFd); - err = copybit->stretch(copybit,&tmp_dst, &src, &tmp_rect, - &srcRect, &tmp_it); - if(err < 0){ - ALOGE("%s:%d::tmp copybit stretch failed",__FUNCTION__, - __LINE__); - if(tmpHnd) - free_buffer(tmpHnd); - return err; - } - // use release fence as aquire fd for next stretch - if (ctx->mMDP.version < qdutils::MDP_V4_0) { - copybit->flush_get_fence(copybit, &acquireFd); - close(acquireFd); - acquireFd = -1; - } - // copy new src and src rect crop - src = tmp_dst; - srcRect = tmp_rect; - } - } - // Copybit region - hwc_region_t region = layer->visibleRegionScreen; - //Do not use visible regions in case of scaling - if (region.numRects > 1) { - if (needsScaling(layer)) { - region.numRects = 1; - region.rects = &layer->displayFrame; - } - } - - region_iterator copybitRegion(region); - - copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH, - renderBuffer->width); - copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT, - renderBuffer->height); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, - layerTransform); - //TODO: once, we are able to read layer alpha, update this - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255); - copybit->set_parameter(copybit, COPYBIT_DYNAMIC_FPS, dynamic_fps); - copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, - layer->blending); - copybit->set_parameter(copybit, COPYBIT_DITHER, - (dst.format == HAL_PIXEL_FORMAT_RGB_565)? - COPYBIT_ENABLE : COPYBIT_DISABLE); - copybit->set_parameter(copybit, COPYBIT_FG_LAYER, - (layer->blending == HWC_BLENDING_NONE || isFG ) ? - COPYBIT_ENABLE : COPYBIT_DISABLE); - - copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER, - COPYBIT_ENABLE); - copybit->set_sync(copybit, acquireFd); - err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect, - ©bitRegion); - copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER, - COPYBIT_DISABLE); - - if(tmpHnd) { - if (ctx->mMDP.version < qdutils::MDP_V4_0){ - int ret = -1, releaseFd; - // we need to wait for the buffer before freeing - copybit->flush_get_fence(copybit, &releaseFd); - ret = sync_wait(releaseFd, 1000); - if(ret < 0) { - ALOGE("%s: sync_wait error!! error no = %d err str = %s", - __FUNCTION__, errno, strerror(errno)); - } - close(releaseFd); - } - free_buffer(tmpHnd); - } - - if(err < 0) - ALOGE("%s: copybit stretch failed",__FUNCTION__); - return err; -} - -int CopyBit::fillColorUsingCopybit(hwc_layer_1_t *layer, - private_handle_t *renderBuffer) -{ - if (!renderBuffer) { - ALOGE("%s: Render Buffer is NULL", __FUNCTION__); - return -1; - } - - // Copybit dst - copybit_image_t dst; - dst.w = ALIGN(renderBuffer->width, 32); - dst.h = renderBuffer->height; - dst.format = renderBuffer->format; - dst.base = (void *)renderBuffer->base; - dst.handle = (native_handle_t *)renderBuffer; - - // Copybit dst rect - hwc_rect_t displayFrame = layer->displayFrame; - copybit_rect_t dstRect = {displayFrame.left, displayFrame.top, - displayFrame.right, displayFrame.bottom}; - - uint32_t color = layer->transform; - copybit_device_t *copybit = mEngine; - copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH, - renderBuffer->width); - copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT, - renderBuffer->height); - copybit->set_parameter(copybit, COPYBIT_DITHER, - (dst.format == HAL_PIXEL_FORMAT_RGB_565) ? - COPYBIT_ENABLE : COPYBIT_DISABLE); - copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0); - copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending); - copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha); - copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,COPYBIT_ENABLE); - int res = copybit->fill_color(copybit, &dst, &dstRect, color); - copybit->set_parameter(copybit,COPYBIT_BLIT_TO_FRAMEBUFFER,COPYBIT_DISABLE); - return res; -} - -void CopyBit::getLayerResolution(const hwc_layer_1_t* layer, - unsigned int& width, unsigned int& height) -{ - hwc_rect_t result = layer->displayFrame; - if (mSwapRect) - result = getIntersection(mDirtyRect, result); - - width = result.right - result.left; - height = result.bottom - result.top; -} - -bool CopyBit::validateParams(hwc_context_t *ctx, - const hwc_display_contents_1_t *list) { - //Validate parameters - if (!ctx) { - ALOGE("%s:Invalid HWC context", __FUNCTION__); - return false; - } else if (!list) { - ALOGE("%s:Invalid HWC layer list", __FUNCTION__); - return false; - } - return true; -} - - -int CopyBit::allocRenderBuffers(int w, int h, int f) -{ - int ret = 0; - for (int i = 0; i < NUM_RENDER_BUFFERS; i++) { - if (mRenderBuffer[i] == NULL) { - ret = alloc_buffer(&mRenderBuffer[i], - w, h, f, - GRALLOC_USAGE_PRIVATE_IOMMU_HEAP); - } - if(ret < 0) { - freeRenderBuffers(); - break; - } - } - return ret; -} - -void CopyBit::freeRenderBuffers() -{ - for (int i = 0; i < NUM_RENDER_BUFFERS; i++) { - if(mRenderBuffer[i]) { - //Since we are freeing buffer close the fence if it has a valid one. - if(mRelFd[i] >= 0) { - close(mRelFd[i]); - mRelFd[i] = -1; - } - free_buffer(mRenderBuffer[i]); - mRenderBuffer[i] = NULL; - } - } -} - -private_handle_t * CopyBit::getCurrentRenderBuffer() { - return mRenderBuffer[mCurRenderBufferIndex]; -} - -void CopyBit::setReleaseFd(int fd) { - if(mRelFd[mCurRenderBufferIndex] >=0) - close(mRelFd[mCurRenderBufferIndex]); - mRelFd[mCurRenderBufferIndex] = dup(fd); -} - -void CopyBit::setReleaseFdSync(int fd) { - if (mRelFd[mCurRenderBufferIndex] >=0) { - int ret = -1; - ret = sync_wait(mRelFd[mCurRenderBufferIndex], 1000); - if (ret < 0) - ALOGE("%s: sync_wait error! errno = %d, err str = %s", - __FUNCTION__, errno, strerror(errno)); - close(mRelFd[mCurRenderBufferIndex]); - } - mRelFd[mCurRenderBufferIndex] = dup(fd); -} - -struct copybit_device_t* CopyBit::getCopyBitDevice() { - return mEngine; -} - -CopyBit::CopyBit(hwc_context_t *ctx, const int& dpy) : mEngine(0), - mIsModeOn(false), mCopyBitDraw(false), mCurRenderBufferIndex(0) { - - getBufferSizeAndDimensions(ctx->dpyAttr[dpy].xres, - ctx->dpyAttr[dpy].yres, - HAL_PIXEL_FORMAT_RGBA_8888, - mAlignedWidth, - mAlignedHeight); - - hw_module_t const *module; - for (int i = 0; i < NUM_RENDER_BUFFERS; i++) { - mRenderBuffer[i] = NULL; - mRelFd[i] = -1; - } - - char value[PROPERTY_VALUE_MAX]; - property_get("debug.hwc.dynThreshold", value, "2"); - mDynThreshold = atof(value); - - property_get("debug.sf.swaprect", value, "0"); - mSwapRectEnable = atoi(value) ? true:false ; - mSwapRect = 0; - if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) { - if(copybit_open(module, &mEngine) < 0) { - ALOGE("FATAL ERROR: copybit open failed."); - } - } else { - ALOGE("FATAL ERROR: copybit hw module not found"); - } -} - -CopyBit::~CopyBit() -{ - freeRenderBuffers(); - if(mEngine) - { - copybit_close(mEngine); - mEngine = NULL; - } -} -CopyBit::LayerCache::LayerCache() { - reset(); -} -void CopyBit::LayerCache::reset() { - memset(&hnd, 0, sizeof(hnd)); - layerCount = 0; -} -void CopyBit::LayerCache::updateCounts(hwc_context_t *ctx, - hwc_display_contents_1_t *list, int dpy) -{ - layerCount = ctx->listStats[dpy].numAppLayers; - for (int i=0; i<ctx->listStats[dpy].numAppLayers; i++){ - hnd[i] = list->hwLayers[i].handle; - displayFrame[i] = list->hwLayers[i].displayFrame; - drop[i] = ctx->copybitDrop[i]; - } -} - -CopyBit::FbCache::FbCache() { - reset(); -} -void CopyBit::FbCache::reset() { - memset(&FbdirtyRect, 0, sizeof(FbdirtyRect)); - memset(&FbdisplayRect, 0, sizeof(FbdisplayRect)); - FbIndex =0; -} - -void CopyBit::FbCache::insertAndUpdateFbCache(hwc_rect_t dirtyRect, - hwc_rect_t displayRect) { - FbIndex = FbIndex % NUM_RENDER_BUFFERS; - FbdirtyRect[FbIndex] = dirtyRect; - FbdisplayRect[FbIndex] = displayRect; - FbIndex++; -} - -int CopyBit::FbCache::getUnchangedFbDRCount(hwc_rect_t dirtyRect, - hwc_rect_t displayRect){ - int sameDirtyCount = 0; - for (int i = 0 ; i < NUM_RENDER_BUFFERS ; i++ ){ - if( FbdirtyRect[i] == dirtyRect && - FbdisplayRect[i] == displayRect) - sameDirtyCount++; - } - return sameDirtyCount; -} - -}; //namespace qhwc |