Home | History | Annotate | Download | only in libhwcomposer
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
      4  *
      5  * Not a Contribution.
      6  *
      7  * Licensed under the Apache License, Version 2.0 (the "License");
      8  * you may not use this file except in compliance with the License.
      9  * You may obtain a copy of the License at
     10  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0
     12  *
     13  * Unless required by applicable law or agreed to in writing, software
     14  * distributed under the License is distributed on an "AS IS" BASIS,
     15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     16  * See the License for the specific language governing permissions and
     17  * limitations under the License.
     18  */
     19 
     20 #define DEBUG_COPYBIT 0
     21 #include <copybit.h>
     22 #include <utils/Timers.h>
     23 #include <mdp_version.h>
     24 #include "hwc_copybit.h"
     25 #include "comptype.h"
     26 #include "gr.h"
     27 #include "cb_utils.h"
     28 #include "cb_swap_rect.h"
     29 #include "math.h"
     30 #include <sync/sync.h>
     31 
     32 using namespace qdutils;
     33 namespace qhwc {
     34 
     35 struct range {
     36     int current;
     37     int end;
     38 };
     39 struct region_iterator : public copybit_region_t {
     40 
     41     region_iterator(hwc_region_t region) {
     42         mRegion = region;
     43         r.end = (int)region.numRects;
     44         r.current = 0;
     45         this->next = iterate;
     46     }
     47 
     48 private:
     49     static int iterate(copybit_region_t const * self, copybit_rect_t* rect){
     50         if (!self || !rect) {
     51             ALOGE("iterate invalid parameters");
     52             return 0;
     53         }
     54 
     55         region_iterator const* me =
     56                                   static_cast<region_iterator const*>(self);
     57         if (me->r.current != me->r.end) {
     58             rect->l = me->mRegion.rects[me->r.current].left;
     59             rect->t = me->mRegion.rects[me->r.current].top;
     60             rect->r = me->mRegion.rects[me->r.current].right;
     61             rect->b = me->mRegion.rects[me->r.current].bottom;
     62             me->r.current++;
     63             return 1;
     64         }
     65         return 0;
     66     }
     67 
     68     hwc_region_t mRegion;
     69     mutable range r;
     70 };
     71 
     72 void CopyBit::reset() {
     73     mIsModeOn = false;
     74     mCopyBitDraw = false;
     75 }
     76 
     77 bool CopyBit::canUseCopybitForYUV(hwc_context_t *ctx) {
     78     // return true for non-overlay targets
     79     if(ctx->mMDP.hasOverlay && ctx->mMDP.version >= qdutils::MDP_V4_0) {
     80        return false;
     81     }
     82     return true;
     83 }
     84 
     85 bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx,
     86                                         hwc_display_contents_1_t *list,
     87                                         int dpy) {
     88     int compositionType = qdutils::QCCompositionType::
     89                                     getInstance().getCompositionType();
     90 
     91     if (compositionType & qdutils::COMPOSITION_TYPE_DYN) {
     92         // DYN Composition:
     93         // use copybit, if (TotalRGBRenderArea < threashold * FB Area)
     94         // this is done based on perf inputs in ICS
     95         // TODO: Above condition needs to be re-evaluated in JB
     96         int fbWidth =  ctx->dpyAttr[dpy].xres;
     97         int fbHeight =  ctx->dpyAttr[dpy].yres;
     98         unsigned int fbArea = (fbWidth * fbHeight);
     99         unsigned int renderArea = getRGBRenderingArea(list);
    100             ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
    101                                   __FUNCTION__, renderArea, fbArea);
    102         if (renderArea < (mDynThreshold * fbArea)) {
    103             return true;
    104         }
    105     } else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) {
    106       // MDP composition, use COPYBIT always
    107       return true;
    108     } else if ((compositionType & qdutils::COMPOSITION_TYPE_C2D)) {
    109       // C2D composition, use COPYBIT
    110       return true;
    111     }
    112     return false;
    113 }
    114 
    115 unsigned int CopyBit::getRGBRenderingArea
    116                                     (const hwc_display_contents_1_t *list) {
    117     //Calculates total rendering area for RGB layers
    118     unsigned int renderArea = 0;
    119     unsigned int w=0, h=0;
    120     // Skipping last layer since FrameBuffer layer should not affect
    121     // which composition to choose
    122     for (unsigned int i=0; i<list->numHwLayers -1; i++) {
    123          private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
    124          if (hnd) {
    125              if (BUFFER_TYPE_UI == hnd->bufferType) {
    126                  getLayerResolution(&list->hwLayers[i], w, h);
    127                  renderArea += (w*h);
    128              }
    129          }
    130     }
    131     return renderArea;
    132 }
    133 
    134 int CopyBit::getLayersChanging(hwc_context_t *ctx,
    135                       hwc_display_contents_1_t *list,
    136                       int dpy){
    137 
    138    int changingLayerIndex = -1;
    139    if(mLayerCache.layerCount != ctx->listStats[dpy].numAppLayers) {
    140         mLayerCache.reset();
    141         mFbCache.reset();
    142         mLayerCache.updateCounts(ctx,list,dpy);
    143         return -1;
    144     }
    145 
    146     int updatingLayerCount = 0;
    147     for (int k = ctx->listStats[dpy].numAppLayers-1; k >= 0 ; k--){
    148        //swap rect will kick in only for single updating layer
    149        if(mLayerCache.hnd[k] != list->hwLayers[k].handle){
    150            updatingLayerCount ++;
    151            if(updatingLayerCount == 1)
    152              changingLayerIndex = k;
    153        }
    154     }
    155     //since we are using more than one framebuffers,we have to
    156     //kick in swap rect only if we are getting continuous same
    157     //dirty rect for same layer at least equal of number of
    158     //framebuffers
    159 
    160     if ( updatingLayerCount ==  1 ) {
    161        hwc_rect_t dirtyRect = list->hwLayers[changingLayerIndex].displayFrame;
    162 #ifdef QCOM_BSP
    163        dirtyRect = list->hwLayers[changingLayerIndex].dirtyRect;
    164 #endif
    165 
    166        for (int k = ctx->listStats[dpy].numAppLayers-1; k >= 0 ; k--){
    167             //disable swap rect for overlapping visible layer(s)
    168             hwc_rect_t displayFrame = list->hwLayers[k].displayFrame;
    169             hwc_rect_t result = getIntersection(displayFrame,dirtyRect);
    170             if((k != changingLayerIndex) && isValidRect(result)){
    171               return -1;
    172            }
    173        }
    174        mFbCache.insertAndUpdateFbCache(dirtyRect);
    175        if(mFbCache.getUnchangedFbDRCount(dirtyRect) <
    176                                              NUM_RENDER_BUFFERS)
    177               changingLayerIndex =  -1;
    178     }else {
    179        mFbCache.reset();
    180        changingLayerIndex =  -1;
    181     }
    182     mLayerCache.updateCounts(ctx,list,dpy);
    183     return changingLayerIndex;
    184 }
    185 
    186 int CopyBit::checkDirtyRect(hwc_context_t *ctx,
    187                            hwc_display_contents_1_t *list,
    188                            int dpy) {
    189 
    190    //dirty rect will enable only if
    191    //1.Only single layer is updating.
    192    //2.No overlapping
    193    //3.No scaling
    194    //4.No video layer
    195    if(mSwapRectEnable == false)
    196       return -1;
    197    int changingLayerIndex =  getLayersChanging(ctx, list, dpy);
    198    //swap rect will kick in only for single updating layer
    199    if(changingLayerIndex == -1){
    200       return -1;
    201    }
    202    if(!needsScaling(&list->hwLayers[changingLayerIndex])){
    203      private_handle_t *hnd =
    204          (private_handle_t *)list->hwLayers[changingLayerIndex].handle;
    205       if( hnd && !isYuvBuffer(hnd))
    206            return  changingLayerIndex;
    207    }
    208    return -1;
    209 }
    210 
    211 bool CopyBit::prepareOverlap(hwc_context_t *ctx,
    212                              hwc_display_contents_1_t *list) {
    213 
    214     if (ctx->mMDP.version < qdutils::MDP_V4_0) {
    215         ALOGE("%s: Invalid request", __FUNCTION__);
    216         return false;
    217     }
    218 
    219     if (mEngine == NULL || !(validateParams(ctx, list))) {
    220         ALOGE("%s: Invalid Params", __FUNCTION__);
    221         return false;
    222     }
    223     PtorInfo* ptorInfo = &(ctx->mPtorInfo);
    224 
    225     // Allocate render buffers if they're not allocated
    226     int alignW = 0, alignH = 0;
    227     int finalW = 0, finalH = 0;
    228     for (int i = 0; i < ptorInfo->count; i++) {
    229         int ovlapIndex = ptorInfo->layerIndex[i];
    230         hwc_rect_t overlap = list->hwLayers[ovlapIndex].displayFrame;
    231         // render buffer width will be the max of two layers
    232         // Align Widht and height to 32, Mdp would be configured
    233         // with Aligned overlap w/h
    234         finalW = max(finalW, ALIGN((overlap.right - overlap.left), 32));
    235         finalH += ALIGN((overlap.bottom - overlap.top), 32);
    236         if(finalH > ALIGN((overlap.bottom - overlap.top), 32)) {
    237             // Calculate the offset for RGBA(4BPP)
    238             ptorInfo->mRenderBuffOffset[i] = finalW *
    239                 (finalH - ALIGN((overlap.bottom - overlap.top), 32)) * 4;
    240             // Calculate the dest top, left will always be zero
    241             ptorInfo->displayFrame[i].top = (finalH -
    242                                 (ALIGN((overlap.bottom - overlap.top), 32)));
    243         }
    244         // calculate the right and bottom values
    245         ptorInfo->displayFrame[i].right =  ptorInfo->displayFrame[i].left +
    246                                             (overlap.right - overlap.left);
    247         ptorInfo->displayFrame[i].bottom = ptorInfo->displayFrame[i].top +
    248                                             (overlap.bottom - overlap.top);
    249     }
    250 
    251     getBufferSizeAndDimensions(finalW, finalH, HAL_PIXEL_FORMAT_RGBA_8888,
    252                                alignW, alignH);
    253 
    254     if ((mAlignedWidth != alignW) || (mAlignedHeight != alignH)) {
    255         // Overlap rect has changed, so free render buffers
    256         freeRenderBuffers();
    257     }
    258 
    259     int ret = allocRenderBuffers(alignW, alignH, HAL_PIXEL_FORMAT_RGBA_8888);
    260 
    261     if (ret < 0) {
    262         ALOGE("%s: Render buffer allocation failed", __FUNCTION__);
    263         return false;
    264     }
    265 
    266     mAlignedWidth = alignW;
    267     mAlignedHeight = alignH;
    268     mCurRenderBufferIndex = (mCurRenderBufferIndex + 1) % NUM_RENDER_BUFFERS;
    269     return true;
    270 }
    271 
    272 bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
    273                                                             int dpy) {
    274 
    275     if(mEngine == NULL) {
    276         // No copybit device found - cannot use copybit
    277         return false;
    278     }
    279     int compositionType = qdutils::QCCompositionType::
    280                                     getInstance().getCompositionType();
    281 
    282     if ((compositionType == qdutils::COMPOSITION_TYPE_GPU) ||
    283         (compositionType == qdutils::COMPOSITION_TYPE_CPU))   {
    284         //GPU/CPU composition, don't change layer composition type
    285         return true;
    286     }
    287 
    288     if(!(validateParams(ctx, list))) {
    289         ALOGE("%s:Invalid Params", __FUNCTION__);
    290         return false;
    291     }
    292 
    293     if(ctx->listStats[dpy].skipCount) {
    294         //GPU will be anyways used
    295         return false;
    296     }
    297 
    298     if (ctx->listStats[dpy].numAppLayers > MAX_NUM_APP_LAYERS) {
    299         // Reached max layers supported by HWC.
    300         return false;
    301     }
    302 
    303     bool useCopybitForYUV = canUseCopybitForYUV(ctx);
    304     bool useCopybitForRGB = canUseCopybitForRGB(ctx, list, dpy);
    305     LayerProp *layerProp = ctx->layerProp[dpy];
    306 
    307     // Following are MDP3 limitations for which we
    308     // need to fallback to GPU composition:
    309     // 1. Plane alpha is not supported by MDP3.
    310     // 2. Scaling is within range
    311     if (qdutils::MDPVersion::getInstance().getMDPVersion() < 400) {
    312         for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
    313             int dst_h, dst_w, src_h, src_w;
    314             float dx, dy;
    315             hwc_layer_1_t *layer = (hwc_layer_1_t *) &list->hwLayers[i];
    316             if (layer->planeAlpha != 0xFF)
    317                 return true;
    318             hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
    319 
    320             if (layer->transform & HAL_TRANSFORM_ROT_90) {
    321                 src_h = sourceCrop.right - sourceCrop.left;
    322                 src_w = sourceCrop.bottom - sourceCrop.top;
    323             } else {
    324                 src_h = sourceCrop.bottom - sourceCrop.top;
    325                 src_w = sourceCrop.right - sourceCrop.left;
    326             }
    327             dst_h = layer->displayFrame.bottom - layer->displayFrame.top;
    328             dst_w = layer->displayFrame.right - layer->displayFrame.left;
    329 
    330             if(src_w <=0 || src_h<=0 ||dst_w<=0 || dst_h<=0 ) {
    331               ALOGE("%s: wrong params for display screen_w=%d \
    332                          src_crop_width=%d screen_h=%d src_crop_height=%d",
    333                          __FUNCTION__, dst_w,src_w,dst_h,src_h);
    334               return false;
    335             }
    336             dx = (float)dst_w/(float)src_w;
    337             dy = (float)dst_h/(float)src_h;
    338 
    339             if (dx > MAX_SCALE_FACTOR || dx < MIN_SCALE_FACTOR)
    340                 return false;
    341 
    342             if (dy > MAX_SCALE_FACTOR || dy < MIN_SCALE_FACTOR)
    343                 return false;
    344         }
    345     }
    346 
    347     //Allocate render buffers if they're not allocated
    348     if (ctx->mMDP.version != qdutils::MDP_V3_0_4 &&
    349             (useCopybitForYUV || useCopybitForRGB)) {
    350         int ret = allocRenderBuffers(mAlignedWidth,
    351                                      mAlignedHeight,
    352                                      HAL_PIXEL_FORMAT_RGBA_8888);
    353         if (ret < 0) {
    354             return false;
    355         } else {
    356             mCurRenderBufferIndex = (mCurRenderBufferIndex + 1) %
    357                 NUM_RENDER_BUFFERS;
    358         }
    359     }
    360 
    361     // We cannot mix copybit layer with layers marked to be drawn on FB
    362     if (!useCopybitForYUV && ctx->listStats[dpy].yuvCount)
    363         return true;
    364 
    365     mCopyBitDraw = false;
    366     if (useCopybitForRGB &&
    367         (useCopybitForYUV || !ctx->listStats[dpy].yuvCount)) {
    368         mCopyBitDraw =  true;
    369         // numAppLayers-1, as we iterate till 0th layer index
    370         // Mark all layers to be drawn by copybit
    371         for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
    372             layerProp[i].mFlags |= HWC_COPYBIT;
    373 #ifdef QCOM_BSP
    374             if (ctx->mMDP.version == qdutils::MDP_V3_0_4)
    375                 list->hwLayers[i].compositionType = HWC_BLIT;
    376             else
    377 #endif
    378                 list->hwLayers[i].compositionType = HWC_OVERLAY;
    379         }
    380     }
    381 
    382     return true;
    383 }
    384 
    385 int CopyBit::clear (private_handle_t* hnd, hwc_rect_t& rect)
    386 {
    387     int ret = 0;
    388     copybit_rect_t clear_rect = {rect.left, rect.top,
    389         rect.right,
    390         rect.bottom};
    391 
    392     copybit_image_t buf;
    393     buf.w = ALIGN(getWidth(hnd),32);
    394     buf.h = getHeight(hnd);
    395     buf.format = hnd->format;
    396     buf.base = (void *)hnd->base;
    397     buf.handle = (native_handle_t *)hnd;
    398 
    399     copybit_device_t *copybit = mEngine;
    400     ret = copybit->clear(copybit, &buf, &clear_rect);
    401     return ret;
    402 }
    403 
    404 bool CopyBit::drawUsingAppBufferComposition(hwc_context_t *ctx,
    405                                       hwc_display_contents_1_t *list,
    406                                       int dpy, int *copybitFd) {
    407      int layerCount = 0;
    408      uint32_t last = (uint32_t)list->numHwLayers - 1;
    409      hwc_layer_1_t *fbLayer = &list->hwLayers[last];
    410      private_handle_t *fbhnd = (private_handle_t *)fbLayer->handle;
    411 
    412     if(ctx->enableABC == false)
    413        return false;
    414 
    415     if(ctx->listStats[dpy].numAppLayers > MAX_LAYERS_FOR_ABC )
    416        return false;
    417 
    418     layerCount = ctx->listStats[dpy].numAppLayers;
    419     //bottom most layer should
    420     //equal to FB
    421     hwc_layer_1_t *tmpLayer = &list->hwLayers[0];
    422     private_handle_t *hnd = (private_handle_t *)tmpLayer->handle;
    423     if(hnd && fbhnd && (hnd->size == fbhnd->size) &&
    424     (hnd->width == fbhnd->width) && (hnd->height == fbhnd->height)){
    425        if(tmpLayer->transform  ||
    426        (!(hnd->format == HAL_PIXEL_FORMAT_RGBA_8888 ||
    427        hnd->format == HAL_PIXEL_FORMAT_RGBX_8888))  ||
    428                    (needsScaling(tmpLayer) == true)) {
    429           return false;
    430        }else {
    431           ctx->listStats[dpy].renderBufIndexforABC = 0;
    432        }
    433     }
    434 
    435     if(ctx->listStats[dpy].renderBufIndexforABC == 0) {
    436        if(layerCount == 1)
    437           return true;
    438 
    439        if(layerCount ==  MAX_LAYERS_FOR_ABC) {
    440           int abcRenderBufIdx = ctx->listStats[dpy].renderBufIndexforABC;
    441           //enable ABC only for non intersecting layers.
    442           hwc_rect_t displayFrame =
    443                   list->hwLayers[abcRenderBufIdx].displayFrame;
    444           for (int i = abcRenderBufIdx + 1; i < layerCount; i++) {
    445              hwc_rect_t tmpDisplayFrame = list->hwLayers[i].displayFrame;
    446              hwc_rect_t result = getIntersection(displayFrame,tmpDisplayFrame);
    447              if (isValidRect(result)) {
    448                 ctx->listStats[dpy].renderBufIndexforABC = -1;
    449                 return false;
    450              }
    451           }
    452           // Pass the Acquire Fence FD to driver for base layer
    453           private_handle_t *renderBuffer =
    454           (private_handle_t *)list->hwLayers[abcRenderBufIdx].handle;
    455           copybit_device_t *copybit = getCopyBitDevice();
    456           if(list->hwLayers[abcRenderBufIdx].acquireFenceFd >=0){
    457              copybit->set_sync(copybit,
    458              list->hwLayers[abcRenderBufIdx].acquireFenceFd);
    459           }
    460           for(int i = abcRenderBufIdx + 1; i < layerCount; i++){
    461              int retVal = drawLayerUsingCopybit(ctx,
    462                &(list->hwLayers[i]),renderBuffer, 0);
    463              if(retVal < 0) {
    464                 ALOGE("%s : Copybit failed", __FUNCTION__);
    465              }
    466           }
    467           // Get Release Fence FD of copybit for the App layer(s)
    468           copybit->flush_get_fence(copybit, copybitFd);
    469           close(list->hwLayers[abcRenderBufIdx].acquireFenceFd);
    470           list->hwLayers[abcRenderBufIdx].acquireFenceFd = -1;
    471           return true;
    472        }
    473     }
    474     return false;
    475 }
    476 
    477 bool  CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
    478                                                           int dpy, int32_t *fd) {
    479     // draw layers marked for COPYBIT
    480     int retVal = true;
    481     int copybitLayerCount = 0;
    482     uint32_t last = 0;
    483     LayerProp *layerProp = ctx->layerProp[dpy];
    484     private_handle_t *renderBuffer;
    485 
    486     if(mCopyBitDraw == false){
    487        mFbCache.reset(); // there is no layer marked for copybit
    488        return false ;
    489     }
    490 
    491     if(drawUsingAppBufferComposition(ctx, list, dpy, fd)) {
    492        return true;
    493     }
    494     //render buffer
    495     if (ctx->mMDP.version == qdutils::MDP_V3_0_4) {
    496         last = (uint32_t)list->numHwLayers - 1;
    497         renderBuffer = (private_handle_t *)list->hwLayers[last].handle;
    498     } else {
    499         renderBuffer = getCurrentRenderBuffer();
    500     }
    501     if (!renderBuffer) {
    502         ALOGE("%s: Render buffer layer handle is NULL", __FUNCTION__);
    503         return false;
    504     }
    505 
    506     if (ctx->mMDP.version >= qdutils::MDP_V4_0) {
    507         //Wait for the previous frame to complete before rendering onto it
    508         if(mRelFd[mCurRenderBufferIndex] >=0) {
    509             sync_wait(mRelFd[mCurRenderBufferIndex], 1000);
    510             close(mRelFd[mCurRenderBufferIndex]);
    511             mRelFd[mCurRenderBufferIndex] = -1;
    512         }
    513     } else {
    514         if(list->hwLayers[last].acquireFenceFd >=0) {
    515             copybit_device_t *copybit = getCopyBitDevice();
    516             copybit->set_sync(copybit, list->hwLayers[last].acquireFenceFd);
    517         }
    518     }
    519 
    520     mDirtyLayerIndex =  checkDirtyRect(ctx, list, dpy);
    521     if( mDirtyLayerIndex != -1){
    522           hwc_layer_1_t *layer = &list->hwLayers[mDirtyLayerIndex];
    523 #ifdef QCOM_BSP
    524           clear(renderBuffer,layer->dirtyRect);
    525 #else
    526           clear(renderBuffer,layer->displayFrame);
    527 #endif
    528     } else {
    529           hwc_rect_t clearRegion = {0,0,0,0};
    530           if(CBUtils::getuiClearRegion(list, clearRegion, layerProp))
    531              clear(renderBuffer, clearRegion);
    532     }
    533 
    534     // numAppLayers-1, as we iterate from 0th layer index with HWC_COPYBIT flag
    535     for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) {
    536         if(!(layerProp[i].mFlags & HWC_COPYBIT)) {
    537             ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for copybit", __FUNCTION__);
    538             continue;
    539         }
    540         //skip non updating layers
    541         if((mDirtyLayerIndex != -1) && (mDirtyLayerIndex != i) )
    542             continue;
    543         int ret = -1;
    544         if (list->hwLayers[i].acquireFenceFd != -1
    545                 && ctx->mMDP.version >= qdutils::MDP_V4_0) {
    546             // Wait for acquire Fence on the App buffers.
    547             ret = sync_wait(list->hwLayers[i].acquireFenceFd, 1000);
    548             if(ret < 0) {
    549                 ALOGE("%s: sync_wait error!! error no = %d err str = %s",
    550                                     __FUNCTION__, errno, strerror(errno));
    551             }
    552             close(list->hwLayers[i].acquireFenceFd);
    553             list->hwLayers[i].acquireFenceFd = -1;
    554         }
    555         retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]),
    556                                           renderBuffer, !i);
    557         copybitLayerCount++;
    558         if(retVal < 0) {
    559             ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__);
    560         }
    561     }
    562 
    563     if (copybitLayerCount) {
    564         copybit_device_t *copybit = getCopyBitDevice();
    565         // Async mode
    566         copybit->flush_get_fence(copybit, fd);
    567         if(ctx->mMDP.version == qdutils::MDP_V3_0_4 &&
    568                 list->hwLayers[last].acquireFenceFd >= 0) {
    569             close(list->hwLayers[last].acquireFenceFd);
    570             list->hwLayers[last].acquireFenceFd = -1;
    571         }
    572     }
    573     return true;
    574 }
    575 
    576 int CopyBit::drawOverlap(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
    577     int fd = -1;
    578     PtorInfo* ptorInfo = &(ctx->mPtorInfo);
    579 
    580     if (ctx->mMDP.version < qdutils::MDP_V4_0) {
    581         ALOGE("%s: Invalid request", __FUNCTION__);
    582         return fd;
    583     }
    584 
    585     private_handle_t *renderBuffer = getCurrentRenderBuffer();
    586 
    587     if (!renderBuffer) {
    588         ALOGE("%s: Render buffer layer handle is NULL", __FUNCTION__);
    589         return fd;
    590     }
    591 
    592     int copybitLayerCount = 0;
    593     for(int j = 0; j < ptorInfo->count; j++) {
    594         int ovlapIndex = ptorInfo->layerIndex[j];
    595         hwc_rect_t overlap = list->hwLayers[ovlapIndex].displayFrame;
    596 
    597         // Draw overlapped content of layers on render buffer
    598         for (int i = 0; i <= ovlapIndex; i++) {
    599             hwc_layer_1_t *layer = &list->hwLayers[i];
    600             if(!isValidRect(getIntersection(layer->displayFrame,
    601                                                overlap))) {
    602                 continue;
    603             }
    604             if ((list->hwLayers[i].acquireFenceFd != -1)) {
    605                 // Wait for acquire fence on the App buffers.
    606                 if(sync_wait(list->hwLayers[i].acquireFenceFd, 1000) < 0) {
    607                     ALOGE("%s: sync_wait error!! error no = %d err str = %s",
    608                           __FUNCTION__, errno, strerror(errno));
    609                 }
    610                 close(list->hwLayers[i].acquireFenceFd);
    611                 list->hwLayers[i].acquireFenceFd = -1;
    612             }
    613 
    614             int retVal = drawRectUsingCopybit(ctx, layer, renderBuffer, overlap,
    615                                                 ptorInfo->displayFrame[j]);
    616             copybitLayerCount++;
    617             if(retVal < 0) {
    618                 ALOGE("%s: drawRectUsingCopybit failed", __FUNCTION__);
    619                 copybitLayerCount = 0;
    620             }
    621         }
    622     }
    623 
    624     if (copybitLayerCount) {
    625         copybit_device_t *copybit = getCopyBitDevice();
    626         copybit->flush_get_fence(copybit, &fd);
    627     }
    628 
    629     ALOGD_IF(DEBUG_COPYBIT, "%s: done! copybitLayerCount = %d", __FUNCTION__,
    630              copybitLayerCount);
    631     return fd;
    632 }
    633 
    634 int CopyBit::drawRectUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
    635                         private_handle_t *renderBuffer, hwc_rect_t overlap,
    636                         hwc_rect_t destRect)
    637 {
    638     hwc_context_t* ctx = (hwc_context_t*)(dev);
    639     if (!ctx) {
    640         ALOGE("%s: null context ", __FUNCTION__);
    641         return -1;
    642     }
    643 
    644     private_handle_t *hnd = (private_handle_t *)layer->handle;
    645     if (!hnd) {
    646         ALOGE("%s: invalid handle", __FUNCTION__);
    647         return -1;
    648     }
    649 
    650     private_handle_t *dstHandle = (private_handle_t *)renderBuffer;
    651     if (!dstHandle) {
    652         ALOGE("%s: RenderBuffer handle is NULL", __FUNCTION__);
    653         return -1;
    654     }
    655 
    656     // Set the Copybit Source
    657     copybit_image_t src;
    658     src.handle = (native_handle_t *)layer->handle;
    659     src.w = hnd->width;
    660     src.h = hnd->height;
    661     src.base = (void *)hnd->base;
    662     src.format = hnd->format;
    663     src.horiz_padding = 0;
    664     src.vert_padding = 0;
    665 
    666 
    667     hwc_rect_t dispFrame = layer->displayFrame;
    668     hwc_rect_t iRect = getIntersection(dispFrame, overlap);
    669     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
    670     qhwc::calculate_crop_rects(crop, dispFrame, iRect,
    671                                layer->transform);
    672 
    673     // Copybit source rect
    674     copybit_rect_t srcRect = {crop.left, crop.top, crop.right,
    675         crop.bottom};
    676 
    677     // Copybit destination rect
    678     copybit_rect_t dstRect = {destRect.left, destRect.top, destRect.right,
    679         destRect.bottom};
    680 
    681     // Copybit dst
    682     copybit_image_t dst;
    683     dst.handle = (native_handle_t *)dstHandle;
    684     dst.w = ALIGN(dstHandle->width, 32);
    685     dst.h = dstHandle->height;
    686     dst.base = (void *)dstHandle->base;
    687     dst.format = dstHandle->format;
    688 
    689     copybit_device_t *copybit = mEngine;
    690 
    691     // Copybit region is the destRect
    692     hwc_rect_t regRect = {dstRect.l,dstRect.t, dstRect.r, dstRect.b};
    693     hwc_region_t region;
    694     region.numRects = 1;
    695     region.rects  = &regRect;
    696     region_iterator copybitRegion(region);
    697     int acquireFd = layer->acquireFenceFd;
    698 
    699     copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
    700                            renderBuffer->width);
    701     copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
    702                            renderBuffer->height);
    703     copybit->set_parameter(copybit, COPYBIT_TRANSFORM, layer->transform);
    704     copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha);
    705     copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending);
    706     copybit->set_parameter(copybit, COPYBIT_DITHER,
    707         (dst.format == HAL_PIXEL_FORMAT_RGB_565) ? COPYBIT_ENABLE :
    708         COPYBIT_DISABLE);
    709     copybit->set_sync(copybit, acquireFd);
    710     int err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect,
    711                                &copybitRegion);
    712 
    713     if (err < 0)
    714         ALOGE("%s: copybit stretch failed",__FUNCTION__);
    715 
    716     return err;
    717 }
    718 
    719 int  CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
    720                           private_handle_t *renderBuffer, bool isFG)
    721 {
    722     hwc_context_t* ctx = (hwc_context_t*)(dev);
    723     int err = 0, acquireFd;
    724     if(!ctx) {
    725          ALOGE("%s: null context ", __FUNCTION__);
    726          return -1;
    727     }
    728 
    729     private_handle_t *hnd = (private_handle_t *)layer->handle;
    730     if(!hnd) {
    731         if (layer->flags & HWC_COLOR_FILL) { // Color layer
    732             return fillColorUsingCopybit(layer, renderBuffer);
    733         }
    734         ALOGE("%s: invalid handle", __FUNCTION__);
    735         return -1;
    736     }
    737 
    738     private_handle_t *fbHandle = (private_handle_t *)renderBuffer;
    739     if(!fbHandle) {
    740         ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
    741         return -1;
    742     }
    743 
    744     // Set the copybit source:
    745     copybit_image_t src;
    746     src.w = getWidth(hnd);
    747     src.h = getHeight(hnd);
    748     src.format = hnd->format;
    749 
    750     // Handle R/B swap
    751     if ((layer->flags & HWC_FORMAT_RB_SWAP)) {
    752         if (src.format == HAL_PIXEL_FORMAT_RGBA_8888) {
    753             src.format = HAL_PIXEL_FORMAT_BGRA_8888;
    754         } else if (src.format == HAL_PIXEL_FORMAT_RGBX_8888) {
    755             src.format = HAL_PIXEL_FORMAT_BGRX_8888;
    756         }
    757     }
    758 
    759     src.base = (void *)hnd->base;
    760     src.handle = (native_handle_t *)layer->handle;
    761     src.horiz_padding = src.w - getWidth(hnd);
    762     // Initialize vertical padding to zero for now,
    763     // this needs to change to accomodate vertical stride
    764     // if needed in the future
    765     src.vert_padding = 0;
    766 
    767     int layerTransform = layer->transform ;
    768     // When flip and rotation(90) are present alter the flip,
    769     // as GPU is doing the flip and rotation in opposite order
    770     // to that of MDP3.0
    771     // For 270 degrees, we get 90 + (H+V) which is same as doing
    772     // flip first and then rotation (H+V) + 90
    773     if (qdutils::MDPVersion::getInstance().getMDPVersion() < 400) {
    774                 if (((layer->transform& HAL_TRANSFORM_FLIP_H) ||
    775                 (layer->transform & HAL_TRANSFORM_FLIP_V)) &&
    776                 (layer->transform &  HAL_TRANSFORM_ROT_90) &&
    777                 !(layer->transform ==  HAL_TRANSFORM_ROT_270)){
    778                       if(layer->transform & HAL_TRANSFORM_FLIP_H){
    779                                  layerTransform ^= HAL_TRANSFORM_FLIP_H;
    780                                  layerTransform |= HAL_TRANSFORM_FLIP_V;
    781                       }
    782                       if(layer->transform & HAL_TRANSFORM_FLIP_V){
    783                                  layerTransform ^= HAL_TRANSFORM_FLIP_V;
    784                                  layerTransform |= HAL_TRANSFORM_FLIP_H;
    785                       }
    786                }
    787     }
    788     // Copybit source rect
    789     hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
    790     copybit_rect_t srcRect = {sourceCrop.left, sourceCrop.top,
    791                               sourceCrop.right,
    792                               sourceCrop.bottom};
    793 
    794     // Copybit destination rect
    795     hwc_rect_t displayFrame = layer->displayFrame;
    796     copybit_rect_t dstRect = {displayFrame.left, displayFrame.top,
    797                               displayFrame.right,
    798                               displayFrame.bottom};
    799 #ifdef QCOM_BSP
    800     //change src and dst with dirtyRect
    801     if(mDirtyLayerIndex != -1) {
    802       srcRect.l = layer->dirtyRect.left;
    803       srcRect.t = layer->dirtyRect.top;
    804       srcRect.r = layer->dirtyRect.right;
    805       srcRect.b = layer->dirtyRect.bottom;
    806       dstRect = srcRect;
    807     }
    808 #endif
    809     // Copybit dst
    810     copybit_image_t dst;
    811     dst.w = ALIGN(fbHandle->width,32);
    812     dst.h = fbHandle->height;
    813     dst.format = fbHandle->format;
    814     dst.base = (void *)fbHandle->base;
    815     dst.handle = (native_handle_t *)fbHandle;
    816 
    817     copybit_device_t *copybit = mEngine;
    818 
    819     int32_t screen_w        = displayFrame.right - displayFrame.left;
    820     int32_t screen_h        = displayFrame.bottom - displayFrame.top;
    821     int32_t src_crop_width  = sourceCrop.right - sourceCrop.left;
    822     int32_t src_crop_height = sourceCrop.bottom -sourceCrop.top;
    823 
    824     // Copybit dst
    825     float copybitsMaxScale =
    826                       (float)copybit->get(copybit,COPYBIT_MAGNIFICATION_LIMIT);
    827     float copybitsMinScale =
    828                        (float)copybit->get(copybit,COPYBIT_MINIFICATION_LIMIT);
    829 
    830     if (layer->transform & HWC_TRANSFORM_ROT_90) {
    831         //swap screen width and height
    832         int tmp = screen_w;
    833         screen_w  = screen_h;
    834         screen_h = tmp;
    835     }
    836     private_handle_t *tmpHnd = NULL;
    837 
    838     if(screen_w <=0 || screen_h<=0 ||src_crop_width<=0 || src_crop_height<=0 ) {
    839         ALOGE("%s: wrong params for display screen_w=%d src_crop_width=%d \
    840         screen_h=%d src_crop_height=%d", __FUNCTION__, screen_w,
    841                                 src_crop_width,screen_h,src_crop_height);
    842         return -1;
    843     }
    844 
    845     float dsdx = (float)screen_w/(float)src_crop_width;
    846     float dtdy = (float)screen_h/(float)src_crop_height;
    847 
    848     float scaleLimitMax = copybitsMaxScale * copybitsMaxScale;
    849     float scaleLimitMin = copybitsMinScale * copybitsMinScale;
    850     if(dsdx > scaleLimitMax ||
    851         dtdy > scaleLimitMax ||
    852         dsdx < 1/scaleLimitMin ||
    853         dtdy < 1/scaleLimitMin) {
    854         ALOGW("%s: greater than max supported size dsdx=%f dtdy=%f \
    855               scaleLimitMax=%f scaleLimitMin=%f", __FUNCTION__,dsdx,dtdy,
    856                                           scaleLimitMax,1/scaleLimitMin);
    857         return -1;
    858     }
    859     acquireFd = layer->acquireFenceFd;
    860     if(dsdx > copybitsMaxScale ||
    861         dtdy > copybitsMaxScale ||
    862         dsdx < 1/copybitsMinScale ||
    863         dtdy < 1/copybitsMinScale){
    864         // The requested scale is out of the range the hardware
    865         // can support.
    866        ALOGD("%s:%d::Need to scale twice dsdx=%f, dtdy=%f,copybitsMaxScale=%f,\
    867                                  copybitsMinScale=%f,screen_w=%d,screen_h=%d \
    868                   src_crop_width=%d src_crop_height=%d",__FUNCTION__,__LINE__,
    869               dsdx,dtdy,copybitsMaxScale,1/copybitsMinScale,screen_w,screen_h,
    870                                               src_crop_width,src_crop_height);
    871 
    872 
    873        int tmp_w =  src_crop_width;
    874        int tmp_h =  src_crop_height;
    875 
    876        if (dsdx > copybitsMaxScale || dtdy > copybitsMaxScale ){
    877          tmp_w = (int)((float)src_crop_width*copybitsMaxScale);
    878          tmp_h = (int)((float)src_crop_height*copybitsMaxScale);
    879        }else if (dsdx < 1/copybitsMinScale ||dtdy < 1/copybitsMinScale ){
    880          // ceil the tmp_w and tmp_h value to maintain proper ratio
    881          // b/w src and dst (should not cross the desired scale limit
    882          // due to float -> int )
    883          tmp_w = (int)ceil((float)src_crop_width/copybitsMinScale);
    884          tmp_h = (int)ceil((float)src_crop_height/copybitsMinScale);
    885        }
    886        ALOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
    887 
    888        int usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
    889        int format = fbHandle->format;
    890 
    891        // We do not want copybit to generate alpha values from nothing
    892        if (format == HAL_PIXEL_FORMAT_RGBA_8888 &&
    893                src.format != HAL_PIXEL_FORMAT_RGBA_8888) {
    894            format = HAL_PIXEL_FORMAT_RGBX_8888;
    895        }
    896        if (0 == alloc_buffer(&tmpHnd, tmp_w, tmp_h, format, usage) && tmpHnd) {
    897             copybit_image_t tmp_dst;
    898             copybit_rect_t tmp_rect;
    899             tmp_dst.w = tmp_w;
    900             tmp_dst.h = tmp_h;
    901             tmp_dst.format = tmpHnd->format;
    902             tmp_dst.handle = tmpHnd;
    903             tmp_dst.horiz_padding = src.horiz_padding;
    904             tmp_dst.vert_padding = src.vert_padding;
    905             tmp_rect.l = 0;
    906             tmp_rect.t = 0;
    907             tmp_rect.r = tmp_dst.w;
    908             tmp_rect.b = tmp_dst.h;
    909             //create one clip region
    910             hwc_rect tmp_hwc_rect = {0,0,tmp_rect.r,tmp_rect.b};
    911             hwc_region_t tmp_hwc_reg = {1,(hwc_rect_t const*)&tmp_hwc_rect};
    912             region_iterator tmp_it(tmp_hwc_reg);
    913             copybit->set_parameter(copybit,COPYBIT_TRANSFORM,0);
    914             //TODO: once, we are able to read layer alpha, update this
    915             copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
    916             copybit->set_sync(copybit, acquireFd);
    917             err = copybit->stretch(copybit,&tmp_dst, &src, &tmp_rect,
    918                                                            &srcRect, &tmp_it);
    919             if(err < 0){
    920                 ALOGE("%s:%d::tmp copybit stretch failed",__FUNCTION__,
    921                                                              __LINE__);
    922                 if(tmpHnd)
    923                     free_buffer(tmpHnd);
    924                 return err;
    925             }
    926             // use release fence as aquire fd for next stretch
    927             if (ctx->mMDP.version < qdutils::MDP_V4_0) {
    928                 copybit->flush_get_fence(copybit, &acquireFd);
    929                 close(acquireFd);
    930                 acquireFd = -1;
    931             }
    932             // copy new src and src rect crop
    933             src = tmp_dst;
    934             srcRect = tmp_rect;
    935       }
    936     }
    937     // Copybit region
    938     hwc_region_t region = layer->visibleRegionScreen;
    939     region_iterator copybitRegion(region);
    940 
    941     copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
    942                                           renderBuffer->width);
    943     copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
    944                                           renderBuffer->height);
    945     copybit->set_parameter(copybit, COPYBIT_TRANSFORM,
    946                                               layerTransform);
    947     //TODO: once, we are able to read layer alpha, update this
    948     copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
    949     copybit->set_parameter(copybit, COPYBIT_BLEND_MODE,
    950                                               layer->blending);
    951     copybit->set_parameter(copybit, COPYBIT_DITHER,
    952                              (dst.format == HAL_PIXEL_FORMAT_RGB_565)?
    953                                              COPYBIT_ENABLE : COPYBIT_DISABLE);
    954     copybit->set_parameter(copybit, COPYBIT_FG_LAYER, isFG ?
    955                                              COPYBIT_ENABLE : COPYBIT_DISABLE);
    956 
    957     copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,
    958                                                 COPYBIT_ENABLE);
    959     copybit->set_sync(copybit, acquireFd);
    960     err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect,
    961                                                    &copybitRegion);
    962     copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,
    963                                                COPYBIT_DISABLE);
    964 
    965     if(tmpHnd) {
    966         if (ctx->mMDP.version < qdutils::MDP_V4_0){
    967             int ret = -1, releaseFd;
    968             // we need to wait for the buffer before freeing
    969             copybit->flush_get_fence(copybit, &releaseFd);
    970             ret = sync_wait(releaseFd, 1000);
    971             if(ret < 0) {
    972                 ALOGE("%s: sync_wait error!! error no = %d err str = %s",
    973                     __FUNCTION__, errno, strerror(errno));
    974             }
    975             close(releaseFd);
    976         }
    977         free_buffer(tmpHnd);
    978     }
    979 
    980     if(err < 0)
    981         ALOGE("%s: copybit stretch failed",__FUNCTION__);
    982     return err;
    983 }
    984 
    985 int CopyBit::fillColorUsingCopybit(hwc_layer_1_t *layer,
    986                           private_handle_t *renderBuffer)
    987 {
    988     if (!renderBuffer) {
    989         ALOGE("%s: Render Buffer is NULL", __FUNCTION__);
    990         return -1;
    991     }
    992 
    993     // Copybit dst
    994     copybit_image_t dst;
    995     dst.w = ALIGN(renderBuffer->width, 32);
    996     dst.h = renderBuffer->height;
    997     dst.format = renderBuffer->format;
    998     dst.base = (void *)renderBuffer->base;
    999     dst.handle = (native_handle_t *)renderBuffer;
   1000 
   1001     // Copybit dst rect
   1002     hwc_rect_t displayFrame = layer->displayFrame;
   1003     copybit_rect_t dstRect = {displayFrame.left, displayFrame.top,
   1004                               displayFrame.right, displayFrame.bottom};
   1005 
   1006     uint32_t color = layer->transform;
   1007     copybit_device_t *copybit = mEngine;
   1008     copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
   1009                            renderBuffer->width);
   1010     copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
   1011                            renderBuffer->height);
   1012     copybit->set_parameter(copybit, COPYBIT_DITHER,
   1013                            (dst.format == HAL_PIXEL_FORMAT_RGB_565) ?
   1014                            COPYBIT_ENABLE : COPYBIT_DISABLE);
   1015     copybit->set_parameter(copybit, COPYBIT_TRANSFORM, 0);
   1016     copybit->set_parameter(copybit, COPYBIT_BLEND_MODE, layer->blending);
   1017     copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, layer->planeAlpha);
   1018     copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,COPYBIT_ENABLE);
   1019     int res = copybit->fill_color(copybit, &dst, &dstRect, color);
   1020     copybit->set_parameter(copybit,COPYBIT_BLIT_TO_FRAMEBUFFER,COPYBIT_DISABLE);
   1021     return res;
   1022 }
   1023 
   1024 void CopyBit::getLayerResolution(const hwc_layer_1_t* layer,
   1025                                  unsigned int& width, unsigned int& height)
   1026 {
   1027     hwc_rect_t displayFrame  = layer->displayFrame;
   1028 
   1029     width = displayFrame.right - displayFrame.left;
   1030     height = displayFrame.bottom - displayFrame.top;
   1031 }
   1032 
   1033 bool CopyBit::validateParams(hwc_context_t *ctx,
   1034                                         const hwc_display_contents_1_t *list) {
   1035     //Validate parameters
   1036     if (!ctx) {
   1037         ALOGE("%s:Invalid HWC context", __FUNCTION__);
   1038         return false;
   1039     } else if (!list) {
   1040         ALOGE("%s:Invalid HWC layer list", __FUNCTION__);
   1041         return false;
   1042     }
   1043     return true;
   1044 }
   1045 
   1046 
   1047 int CopyBit::allocRenderBuffers(int w, int h, int f)
   1048 {
   1049     int ret = 0;
   1050     for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
   1051         if (mRenderBuffer[i] == NULL) {
   1052             ret = alloc_buffer(&mRenderBuffer[i],
   1053                                w, h, f,
   1054                                GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
   1055         }
   1056         if(ret < 0) {
   1057             freeRenderBuffers();
   1058             break;
   1059         }
   1060     }
   1061     return ret;
   1062 }
   1063 
   1064 void CopyBit::freeRenderBuffers()
   1065 {
   1066     for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
   1067         if(mRenderBuffer[i]) {
   1068             //Since we are freeing buffer close the fence if it has a valid one.
   1069             if(mRelFd[i] >= 0) {
   1070                 close(mRelFd[i]);
   1071                 mRelFd[i] = -1;
   1072             }
   1073             free_buffer(mRenderBuffer[i]);
   1074             mRenderBuffer[i] = NULL;
   1075         }
   1076     }
   1077 }
   1078 
   1079 private_handle_t * CopyBit::getCurrentRenderBuffer() {
   1080     return mRenderBuffer[mCurRenderBufferIndex];
   1081 }
   1082 
   1083 void CopyBit::setReleaseFd(int fd) {
   1084     if(mRelFd[mCurRenderBufferIndex] >=0)
   1085         close(mRelFd[mCurRenderBufferIndex]);
   1086     mRelFd[mCurRenderBufferIndex] = dup(fd);
   1087 }
   1088 
   1089 void CopyBit::setReleaseFdSync(int fd) {
   1090     if (mRelFd[mCurRenderBufferIndex] >=0) {
   1091         int ret = -1;
   1092         ret = sync_wait(mRelFd[mCurRenderBufferIndex], 1000);
   1093         if (ret < 0)
   1094             ALOGE("%s: sync_wait error! errno = %d, err str = %s",
   1095                   __FUNCTION__, errno, strerror(errno));
   1096         close(mRelFd[mCurRenderBufferIndex]);
   1097     }
   1098     mRelFd[mCurRenderBufferIndex] = dup(fd);
   1099 }
   1100 
   1101 struct copybit_device_t* CopyBit::getCopyBitDevice() {
   1102     return mEngine;
   1103 }
   1104 
   1105 CopyBit::CopyBit(hwc_context_t *ctx, const int& dpy) :  mEngine(0),
   1106     mIsModeOn(false), mCopyBitDraw(false), mCurRenderBufferIndex(0) {
   1107 
   1108     getBufferSizeAndDimensions(ctx->dpyAttr[dpy].xres,
   1109             ctx->dpyAttr[dpy].yres,
   1110             HAL_PIXEL_FORMAT_RGBA_8888,
   1111             mAlignedWidth,
   1112             mAlignedHeight);
   1113 
   1114     hw_module_t const *module;
   1115     for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
   1116         mRenderBuffer[i] = NULL;
   1117         mRelFd[i] = -1;
   1118     }
   1119 
   1120     char value[PROPERTY_VALUE_MAX];
   1121     property_get("debug.hwc.dynThreshold", value, "2");
   1122     mDynThreshold = atof(value);
   1123 
   1124     property_get("debug.sf.swaprect", value, "0");
   1125     mSwapRectEnable = atoi(value) ? true:false ;
   1126     mDirtyLayerIndex = -1;
   1127     if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
   1128         if(copybit_open(module, &mEngine) < 0) {
   1129             ALOGE("FATAL ERROR: copybit open failed.");
   1130         }
   1131     } else {
   1132         ALOGE("FATAL ERROR: copybit hw module not found");
   1133     }
   1134 }
   1135 
   1136 CopyBit::~CopyBit()
   1137 {
   1138     freeRenderBuffers();
   1139     if(mEngine)
   1140     {
   1141         copybit_close(mEngine);
   1142         mEngine = NULL;
   1143     }
   1144 }
   1145 CopyBit::LayerCache::LayerCache() {
   1146     reset();
   1147 }
   1148 void CopyBit::LayerCache::reset() {
   1149     memset(&hnd, 0, sizeof(hnd));
   1150     layerCount = 0;
   1151 }
   1152 void CopyBit::LayerCache::updateCounts(hwc_context_t *ctx,
   1153               hwc_display_contents_1_t *list, int dpy)
   1154 {
   1155    layerCount = ctx->listStats[dpy].numAppLayers;
   1156    for (int i=0; i<ctx->listStats[dpy].numAppLayers; i++){
   1157       hnd[i] = list->hwLayers[i].handle;
   1158    }
   1159 }
   1160 
   1161 CopyBit::FbCache::FbCache() {
   1162      reset();
   1163 }
   1164 void CopyBit::FbCache::reset() {
   1165      memset(&FbdirtyRect, 0, sizeof(FbdirtyRect));
   1166      FbIndex =0;
   1167 }
   1168 
   1169 void CopyBit::FbCache::insertAndUpdateFbCache(hwc_rect_t dirtyRect) {
   1170    FbIndex =  FbIndex % NUM_RENDER_BUFFERS;
   1171    FbdirtyRect[FbIndex] = dirtyRect;
   1172    FbIndex++;
   1173 }
   1174 
   1175 int CopyBit::FbCache::getUnchangedFbDRCount(hwc_rect_t dirtyRect){
   1176     int sameDirtyCount = 0;
   1177     for (int i = 0 ; i < NUM_RENDER_BUFFERS ; i++ ){
   1178       if( FbdirtyRect[i] == dirtyRect)
   1179            sameDirtyCount++;
   1180    }
   1181    return sameDirtyCount;
   1182 }
   1183 
   1184 }; //namespace qhwc
   1185