Home | History | Annotate | Download | only in libhwcomposer
      1 /*
      2  * Copyright (C) 2010 The Android Open Source Project
      3  * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
      4  *
      5  * Not a Contribution, Apache license notifications and license are retained
      6  * for attribution purposes only.
      7  *
      8  * Licensed under the Apache License, Version 2.0 (the "License");
      9  * you may not use this file except in compliance with the License.
     10  * You may obtain a copy of the License at
     11  *
     12  *      http://www.apache.org/licenses/LICENSE-2.0
     13  *
     14  * Unless required by applicable law or agreed to in writing, software
     15  * distributed under the License is distributed on an "AS IS" BASIS,
     16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     17  * See the License for the specific language governing permissions and
     18  * limitations under the License.
     19  */
     20 
     21 #define DEBUG_COPYBIT 0
     22 #include <copybit.h>
     23 #include <utils/Timers.h>
     24 #include <mdp_version.h>
     25 #include "hwc_copybit.h"
     26 #include "comptype.h"
     27 #include "gr.h"
     28 
     29 namespace qhwc {
     30 
     31 struct range {
     32     int current;
     33     int end;
     34 };
     35 struct region_iterator : public copybit_region_t {
     36 
     37     region_iterator(hwc_region_t region) {
     38         mRegion = region;
     39         r.end = region.numRects;
     40         r.current = 0;
     41         this->next = iterate;
     42     }
     43 
     44 private:
     45     static int iterate(copybit_region_t const * self, copybit_rect_t* rect){
     46         if (!self || !rect) {
     47             ALOGE("iterate invalid parameters");
     48             return 0;
     49         }
     50 
     51         region_iterator const* me =
     52                                   static_cast<region_iterator const*>(self);
     53         if (me->r.current != me->r.end) {
     54             rect->l = me->mRegion.rects[me->r.current].left;
     55             rect->t = me->mRegion.rects[me->r.current].top;
     56             rect->r = me->mRegion.rects[me->r.current].right;
     57             rect->b = me->mRegion.rects[me->r.current].bottom;
     58             me->r.current++;
     59             return 1;
     60         }
     61         return 0;
     62     }
     63 
     64     hwc_region_t mRegion;
     65     mutable range r;
     66 };
     67 
     68 void CopyBit::reset() {
     69     mIsModeOn = false;
     70     mCopyBitDraw = false;
     71 }
     72 
     73 bool CopyBit::canUseCopybitForYUV(hwc_context_t *ctx) {
     74     // return true for non-overlay targets
     75     if(ctx->mMDP.hasOverlay && ctx->mMDP.version >= qdutils::MDP_V4_0) {
     76        return false;
     77     }
     78     return true;
     79 }
     80 
     81 bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx,
     82                                         hwc_display_contents_1_t *list,
     83                                         int dpy) {
     84     int compositionType = qdutils::QCCompositionType::
     85                                     getInstance().getCompositionType();
     86 
     87     if (compositionType & qdutils::COMPOSITION_TYPE_DYN) {
     88         // DYN Composition:
     89         // use copybit, if (TotalRGBRenderArea < threashold * FB Area)
     90         // this is done based on perf inputs in ICS
     91         // TODO: Above condition needs to be re-evaluated in JB
     92         int fbWidth =  ctx->dpyAttr[dpy].xres;
     93         int fbHeight =  ctx->dpyAttr[dpy].yres;
     94         unsigned int fbArea = (fbWidth * fbHeight);
     95         unsigned int renderArea = getRGBRenderingArea(list);
     96             ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
     97                                   __FUNCTION__, renderArea, fbArea);
     98         if (renderArea < (mDynThreshold * fbArea)) {
     99             return true;
    100         }
    101     } else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) {
    102       // MDP composition, use COPYBIT always
    103       return true;
    104     } else if ((compositionType & qdutils::COMPOSITION_TYPE_C2D)) {
    105       // C2D composition, use COPYBIT
    106       return true;
    107     }
    108     return false;
    109 }
    110 
    111 unsigned int CopyBit::getRGBRenderingArea
    112                                     (const hwc_display_contents_1_t *list) {
    113     //Calculates total rendering area for RGB layers
    114     unsigned int renderArea = 0;
    115     unsigned int w=0, h=0;
    116     // Skipping last layer since FrameBuffer layer should not affect
    117     // which composition to choose
    118     for (unsigned int i=0; i<list->numHwLayers -1; i++) {
    119          private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
    120          if (hnd) {
    121              if (BUFFER_TYPE_UI == hnd->bufferType) {
    122                  getLayerResolution(&list->hwLayers[i], w, h);
    123                  renderArea += (w*h);
    124              }
    125          }
    126     }
    127     return renderArea;
    128 }
    129 
    130 bool CopyBit::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
    131                                                             int dpy) {
    132 
    133     if(mEngine == NULL) {
    134         // No copybit device found - cannot use copybit
    135         return false;
    136     }
    137     int compositionType = qdutils::QCCompositionType::
    138                                     getInstance().getCompositionType();
    139 
    140     if ((compositionType == qdutils::COMPOSITION_TYPE_GPU) ||
    141         (compositionType == qdutils::COMPOSITION_TYPE_CPU))   {
    142         //GPU/CPU composition, don't change layer composition type
    143         return true;
    144     }
    145 
    146     if(!(validateParams(ctx, list))) {
    147         ALOGE("%s:Invalid Params", __FUNCTION__);
    148         return false;
    149     }
    150 
    151     if(ctx->listStats[dpy].skipCount) {
    152         //GPU will be anyways used
    153         return false;
    154     }
    155 
    156     if (ctx->listStats[dpy].numAppLayers > MAX_NUM_APP_LAYERS) {
    157         // Reached max layers supported by HWC.
    158         return false;
    159     }
    160 
    161     bool useCopybitForYUV = canUseCopybitForYUV(ctx);
    162     bool useCopybitForRGB = canUseCopybitForRGB(ctx, list, dpy);
    163     LayerProp *layerProp = ctx->layerProp[dpy];
    164     size_t fbLayerIndex = ctx->listStats[dpy].fbLayerIndex;
    165     hwc_layer_1_t *fbLayer = &list->hwLayers[fbLayerIndex];
    166     private_handle_t *fbHnd = (private_handle_t *)fbLayer->handle;
    167 
    168 
    169     // Following are MDP3 limitations for which we
    170     // need to fallback to GPU composition:
    171     // 1. HW issues with mdp3 and rotation.
    172     // 2. Plane alpha is not supported by MDP3.
    173     if (qdutils::MDPVersion::getInstance().getMDPVersion() < 400) {
    174         for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
    175             hwc_layer_1_t *layer = (hwc_layer_1_t *) &list->hwLayers[i];
    176             if ((layer->transform & (HAL_TRANSFORM_FLIP_H |
    177                    HAL_TRANSFORM_FLIP_V | HAL_TRANSFORM_ROT_90)) &&
    178                    ((layer->displayFrame.bottom - layer->displayFrame.top) % 16 ||
    179                    (layer->displayFrame.right - layer->displayFrame.left) % 16))
    180                 return true;
    181             if (layer->planeAlpha != 0xFF)
    182                 return true;
    183         }
    184     }
    185 
    186     //Allocate render buffers if they're not allocated
    187     if (useCopybitForYUV || useCopybitForRGB) {
    188         int ret = allocRenderBuffers(fbHnd->width,
    189                                      fbHnd->height,
    190                                      fbHnd->format);
    191         if (ret < 0) {
    192             return false;
    193         } else {
    194             mCurRenderBufferIndex = (mCurRenderBufferIndex + 1) %
    195                 NUM_RENDER_BUFFERS;
    196         }
    197     }
    198 
    199     // We cannot mix copybit layer with layers marked to be drawn on FB
    200     if (!useCopybitForYUV && ctx->listStats[dpy].yuvCount)
    201         return true;
    202 
    203     // numAppLayers-1, as we iterate till 0th layer index
    204     for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
    205         private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
    206 
    207         if ((hnd->bufferType == BUFFER_TYPE_VIDEO && useCopybitForYUV) ||
    208             (hnd->bufferType == BUFFER_TYPE_UI && useCopybitForRGB)) {
    209             layerProp[i].mFlags |= HWC_COPYBIT;
    210             list->hwLayers[i].compositionType = HWC_OVERLAY;
    211             mCopyBitDraw = true;
    212         } else {
    213             // We currently cannot mix copybit layers with layers marked to
    214             // be drawn on the framebuffer or that are on the layer cache.
    215             mCopyBitDraw = false;
    216             //There is no need to reset layer properties here as we return in
    217             //draw if mCopyBitDraw is false
    218             break;
    219         }
    220     }
    221     return true;
    222 }
    223 
    224 int CopyBit::clear (private_handle_t* hnd, hwc_rect_t& rect)
    225 {
    226     int ret = 0;
    227     copybit_rect_t clear_rect = {rect.left, rect.top,
    228         rect.right,
    229         rect.bottom};
    230 
    231     copybit_image_t buf;
    232     buf.w = ALIGN(getWidth(hnd),32);
    233     buf.h = getHeight(hnd);
    234     buf.format = hnd->format;
    235     buf.base = (void *)hnd->base;
    236     buf.handle = (native_handle_t *)hnd;
    237 
    238     copybit_device_t *copybit = mEngine;
    239     ret = copybit->clear(copybit, &buf, &clear_rect);
    240     return ret;
    241 }
    242 
    243 bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
    244                                                         int dpy, int32_t *fd) {
    245     // draw layers marked for COPYBIT
    246     int retVal = true;
    247     int copybitLayerCount = 0;
    248     LayerProp *layerProp = ctx->layerProp[dpy];
    249 
    250     if(mCopyBitDraw == false) // there is no layer marked for copybit
    251         return false ;
    252 
    253     //render buffer
    254     private_handle_t *renderBuffer = getCurrentRenderBuffer();
    255     if (!renderBuffer) {
    256         ALOGE("%s: Render buffer layer handle is NULL", __FUNCTION__);
    257         return false;
    258     }
    259 
    260     //Wait for the previous frame to complete before rendering onto it
    261     if(mRelFd[0] >=0) {
    262         sync_wait(mRelFd[0], 1000);
    263         close(mRelFd[0]);
    264         mRelFd[0] = -1;
    265     }
    266 
    267     if (ctx->mMDP.version >= qdutils::MDP_V4_0) {
    268         //Clear the visible region on the render buffer
    269         //XXX: Do this only when needed.
    270         hwc_rect_t clearRegion;
    271         getNonWormholeRegion(list, clearRegion);
    272         clear(renderBuffer, clearRegion);
    273     }
    274     // numAppLayers-1, as we iterate from 0th layer index with HWC_COPYBIT flag
    275     for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) {
    276         hwc_layer_1_t *layer = &list->hwLayers[i];
    277         if(!(layerProp[i].mFlags & HWC_COPYBIT)) {
    278             ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for copybit", __FUNCTION__);
    279             continue;
    280         }
    281         int ret = -1;
    282         if (list->hwLayers[i].acquireFenceFd != -1
    283                 && ctx->mMDP.version >= qdutils::MDP_V4_0) {
    284             // Wait for acquire Fence on the App buffers.
    285             ret = sync_wait(list->hwLayers[i].acquireFenceFd, 1000);
    286             if(ret < 0) {
    287                 ALOGE("%s: sync_wait error!! error no = %d err str = %s",
    288                                     __FUNCTION__, errno, strerror(errno));
    289             }
    290             close(list->hwLayers[i].acquireFenceFd);
    291             list->hwLayers[i].acquireFenceFd = -1;
    292         }
    293         retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]),
    294                                                     renderBuffer, dpy, !i);
    295         copybitLayerCount++;
    296         if(retVal < 0) {
    297             ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__);
    298         }
    299     }
    300 
    301     if (copybitLayerCount) {
    302         copybit_device_t *copybit = getCopyBitDevice();
    303         // Async mode
    304         copybit->flush_get_fence(copybit, fd);
    305     }
    306     return true;
    307 }
    308 
    309 int  CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
    310                           private_handle_t *renderBuffer, int dpy, bool isFG)
    311 {
    312     hwc_context_t* ctx = (hwc_context_t*)(dev);
    313     int err = 0, acquireFd;
    314     if(!ctx) {
    315          ALOGE("%s: null context ", __FUNCTION__);
    316          return -1;
    317     }
    318 
    319     private_handle_t *hnd = (private_handle_t *)layer->handle;
    320     if(!hnd) {
    321         ALOGE("%s: invalid handle", __FUNCTION__);
    322         return -1;
    323     }
    324 
    325     private_handle_t *fbHandle = (private_handle_t *)renderBuffer;
    326     if(!fbHandle) {
    327         ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
    328         return -1;
    329     }
    330 
    331     // Set the copybit source:
    332     copybit_image_t src;
    333     src.w = getWidth(hnd);
    334     src.h = getHeight(hnd);
    335     src.format = hnd->format;
    336     src.base = (void *)hnd->base;
    337     src.handle = (native_handle_t *)layer->handle;
    338     src.horiz_padding = src.w - getWidth(hnd);
    339     // Initialize vertical padding to zero for now,
    340     // this needs to change to accomodate vertical stride
    341     // if needed in the future
    342     src.vert_padding = 0;
    343 
    344     // Copybit source rect
    345     hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
    346     copybit_rect_t srcRect = {sourceCrop.left, sourceCrop.top,
    347                               sourceCrop.right,
    348                               sourceCrop.bottom};
    349 
    350     // Copybit destination rect
    351     hwc_rect_t displayFrame = layer->displayFrame;
    352     copybit_rect_t dstRect = {displayFrame.left, displayFrame.top,
    353                               displayFrame.right,
    354                               displayFrame.bottom};
    355 
    356     // Copybit dst
    357     copybit_image_t dst;
    358     dst.w = ALIGN(fbHandle->width,32);
    359     dst.h = fbHandle->height;
    360     dst.format = fbHandle->format;
    361     dst.base = (void *)fbHandle->base;
    362     dst.handle = (native_handle_t *)fbHandle;
    363 
    364     copybit_device_t *copybit = mEngine;
    365 
    366     int32_t screen_w        = displayFrame.right - displayFrame.left;
    367     int32_t screen_h        = displayFrame.bottom - displayFrame.top;
    368     int32_t src_crop_width  = sourceCrop.right - sourceCrop.left;
    369     int32_t src_crop_height = sourceCrop.bottom -sourceCrop.top;
    370 
    371     // Copybit dst
    372     float copybitsMaxScale =
    373                       (float)copybit->get(copybit,COPYBIT_MAGNIFICATION_LIMIT);
    374     float copybitsMinScale =
    375                        (float)copybit->get(copybit,COPYBIT_MINIFICATION_LIMIT);
    376 
    377     if((layer->transform == HWC_TRANSFORM_ROT_90) ||
    378                            (layer->transform == HWC_TRANSFORM_ROT_270)) {
    379         //swap screen width and height
    380         int tmp = screen_w;
    381         screen_w  = screen_h;
    382         screen_h = tmp;
    383     }
    384     private_handle_t *tmpHnd = NULL;
    385 
    386     if(screen_w <=0 || screen_h<=0 ||src_crop_width<=0 || src_crop_height<=0 ) {
    387         ALOGE("%s: wrong params for display screen_w=%d src_crop_width=%d \
    388         screen_w=%d src_crop_width=%d", __FUNCTION__, screen_w,
    389                                 src_crop_width,screen_w,src_crop_width);
    390         return -1;
    391     }
    392 
    393     float dsdx = (float)screen_w/src_crop_width;
    394     float dtdy = (float)screen_h/src_crop_height;
    395 
    396     float scaleLimitMax = copybitsMaxScale * copybitsMaxScale;
    397     float scaleLimitMin = copybitsMinScale * copybitsMinScale;
    398     if(dsdx > scaleLimitMax ||
    399         dtdy > scaleLimitMax ||
    400         dsdx < 1/scaleLimitMin ||
    401         dtdy < 1/scaleLimitMin) {
    402         ALOGE("%s: greater than max supported size dsdx=%f dtdy=%f \
    403               scaleLimitMax=%f scaleLimitMin=%f", __FUNCTION__,dsdx,dtdy,
    404                                           scaleLimitMax,1/scaleLimitMin);
    405         return -1;
    406     }
    407     acquireFd = layer->acquireFenceFd;
    408     if(dsdx > copybitsMaxScale ||
    409         dtdy > copybitsMaxScale ||
    410         dsdx < 1/copybitsMinScale ||
    411         dtdy < 1/copybitsMinScale){
    412         // The requested scale is out of the range the hardware
    413         // can support.
    414        ALOGD("%s:%d::Need to scale twice dsdx=%f, dtdy=%f,copybitsMaxScale=%f,\
    415                                  copybitsMinScale=%f,screen_w=%d,screen_h=%d \
    416                   src_crop_width=%d src_crop_height=%d",__FUNCTION__,__LINE__,
    417               dsdx,dtdy,copybitsMaxScale,1/copybitsMinScale,screen_w,screen_h,
    418                                               src_crop_width,src_crop_height);
    419 
    420        //Driver makes width and height as even
    421        //that may cause wrong calculation of the ratio
    422        //in display and crop.Hence we make
    423        //crop width and height as even.
    424        src_crop_width  = (src_crop_width/2)*2;
    425        src_crop_height = (src_crop_height/2)*2;
    426 
    427        int tmp_w =  src_crop_width;
    428        int tmp_h =  src_crop_height;
    429 
    430        if (dsdx > copybitsMaxScale || dtdy > copybitsMaxScale ){
    431          tmp_w = src_crop_width*copybitsMaxScale;
    432          tmp_h = src_crop_height*copybitsMaxScale;
    433        }else if (dsdx < 1/copybitsMinScale ||dtdy < 1/copybitsMinScale ){
    434          tmp_w = src_crop_width/copybitsMinScale;
    435          tmp_h = src_crop_height/copybitsMinScale;
    436          tmp_w  = (tmp_w/2)*2;
    437          tmp_h = (tmp_h/2)*2;
    438        }
    439        ALOGD("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
    440 
    441        int usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
    442        int format = fbHandle->format;
    443 
    444        // We do not want copybit to generate alpha values from nothing
    445        if (format == HAL_PIXEL_FORMAT_RGBA_8888 &&
    446                src.format != HAL_PIXEL_FORMAT_RGBA_8888) {
    447            format = HAL_PIXEL_FORMAT_RGBX_8888;
    448        }
    449        if (0 == alloc_buffer(&tmpHnd, tmp_w, tmp_h, format, usage)){
    450             copybit_image_t tmp_dst;
    451             copybit_rect_t tmp_rect;
    452             tmp_dst.w = tmp_w;
    453             tmp_dst.h = tmp_h;
    454             tmp_dst.format = tmpHnd->format;
    455             tmp_dst.handle = tmpHnd;
    456             tmp_dst.horiz_padding = src.horiz_padding;
    457             tmp_dst.vert_padding = src.vert_padding;
    458             tmp_rect.l = 0;
    459             tmp_rect.t = 0;
    460             tmp_rect.r = tmp_dst.w;
    461             tmp_rect.b = tmp_dst.h;
    462             //create one clip region
    463             hwc_rect tmp_hwc_rect = {0,0,tmp_rect.r,tmp_rect.b};
    464             hwc_region_t tmp_hwc_reg = {1,(hwc_rect_t const*)&tmp_hwc_rect};
    465             region_iterator tmp_it(tmp_hwc_reg);
    466             copybit->set_parameter(copybit,COPYBIT_TRANSFORM,0);
    467             //TODO: once, we are able to read layer alpha, update this
    468             copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
    469             copybit->set_sync(copybit, acquireFd);
    470             err = copybit->stretch(copybit,&tmp_dst, &src, &tmp_rect,
    471                                                            &srcRect, &tmp_it);
    472             if(err < 0){
    473                 ALOGE("%s:%d::tmp copybit stretch failed",__FUNCTION__,
    474                                                              __LINE__);
    475                 if(tmpHnd)
    476                     free_buffer(tmpHnd);
    477                 return err;
    478             }
    479             // use release fence as aquire fd for next stretch
    480             if (ctx->mMDP.version < qdutils::MDP_V4_0) {
    481                 copybit->flush_get_fence(copybit, &acquireFd);
    482                 close(acquireFd);
    483                 acquireFd = -1;
    484             }
    485             // copy new src and src rect crop
    486             src = tmp_dst;
    487             srcRect = tmp_rect;
    488       }
    489     }
    490     // Copybit region
    491     hwc_region_t region = layer->visibleRegionScreen;
    492     region_iterator copybitRegion(region);
    493 
    494     copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
    495                                           renderBuffer->width);
    496     copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
    497                                           renderBuffer->height);
    498     copybit->set_parameter(copybit, COPYBIT_TRANSFORM,
    499                                               layer->transform);
    500     //TODO: once, we are able to read layer alpha, update this
    501     copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
    502     copybit->set_parameter(copybit, COPYBIT_BLEND_MODE,
    503                                               layer->blending);
    504     copybit->set_parameter(copybit, COPYBIT_DITHER,
    505                              (dst.format == HAL_PIXEL_FORMAT_RGB_565)?
    506                                              COPYBIT_ENABLE : COPYBIT_DISABLE);
    507     copybit->set_parameter(copybit, COPYBIT_FG_LAYER, isFG ?
    508                                              COPYBIT_ENABLE : COPYBIT_DISABLE);
    509 
    510     copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,
    511                                                 COPYBIT_ENABLE);
    512     copybit->set_sync(copybit, acquireFd);
    513     err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect,
    514                                                    &copybitRegion);
    515     copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,
    516                                                COPYBIT_DISABLE);
    517 
    518     if(tmpHnd) {
    519         if (ctx->mMDP.version < qdutils::MDP_V4_0){
    520             int ret = -1, releaseFd;
    521             // we need to wait for the buffer before freeing
    522             copybit->flush_get_fence(copybit, &releaseFd);
    523             ret = sync_wait(releaseFd, 1000);
    524             if(ret < 0) {
    525                 ALOGE("%s: sync_wait error!! error no = %d err str = %s",
    526                     __FUNCTION__, errno, strerror(errno));
    527             }
    528             close(releaseFd);
    529         }
    530         free_buffer(tmpHnd);
    531     }
    532 
    533     if(err < 0)
    534         ALOGE("%s: copybit stretch failed",__FUNCTION__);
    535     return err;
    536 }
    537 
    538 void CopyBit::getLayerResolution(const hwc_layer_1_t* layer,
    539                                  unsigned int& width, unsigned int& height)
    540 {
    541     hwc_rect_t displayFrame  = layer->displayFrame;
    542 
    543     width = displayFrame.right - displayFrame.left;
    544     height = displayFrame.bottom - displayFrame.top;
    545 }
    546 
    547 bool CopyBit::validateParams(hwc_context_t *ctx,
    548                                         const hwc_display_contents_1_t *list) {
    549     //Validate parameters
    550     if (!ctx) {
    551         ALOGE("%s:Invalid HWC context", __FUNCTION__);
    552         return false;
    553     } else if (!list) {
    554         ALOGE("%s:Invalid HWC layer list", __FUNCTION__);
    555         return false;
    556     }
    557     return true;
    558 }
    559 
    560 
    561 int CopyBit::allocRenderBuffers(int w, int h, int f)
    562 {
    563     int ret = 0;
    564     for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
    565         if (mRenderBuffer[i] == NULL) {
    566             ret = alloc_buffer(&mRenderBuffer[i],
    567                                w, h, f,
    568                                GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
    569         }
    570         if(ret < 0) {
    571             freeRenderBuffers();
    572             break;
    573         }
    574     }
    575     return ret;
    576 }
    577 
    578 void CopyBit::freeRenderBuffers()
    579 {
    580     for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
    581         if(mRenderBuffer[i]) {
    582             free_buffer(mRenderBuffer[i]);
    583             mRenderBuffer[i] = NULL;
    584         }
    585     }
    586 }
    587 
    588 private_handle_t * CopyBit::getCurrentRenderBuffer() {
    589     return mRenderBuffer[mCurRenderBufferIndex];
    590 }
    591 
    592 void CopyBit::setReleaseFd(int fd) {
    593     if(mRelFd[0] >=0)
    594         close(mRelFd[0]);
    595     mRelFd[0] = mRelFd[1];
    596     mRelFd[1] = dup(fd);
    597 }
    598 
    599 struct copybit_device_t* CopyBit::getCopyBitDevice() {
    600     return mEngine;
    601 }
    602 
    603 CopyBit::CopyBit():mIsModeOn(false), mCopyBitDraw(false),
    604     mCurRenderBufferIndex(0){
    605     hw_module_t const *module;
    606     for (int i = 0; i < NUM_RENDER_BUFFERS; i++)
    607         mRenderBuffer[i] = NULL;
    608     mRelFd[0] = -1;
    609     mRelFd[1] = -1;
    610 
    611     char value[PROPERTY_VALUE_MAX];
    612     property_get("debug.hwc.dynThreshold", value, "2");
    613     mDynThreshold = atof(value);
    614 
    615     if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
    616         if(copybit_open(module, &mEngine) < 0) {
    617             ALOGE("FATAL ERROR: copybit open failed.");
    618         }
    619     } else {
    620         ALOGE("FATAL ERROR: copybit hw module not found");
    621     }
    622 }
    623 
    624 CopyBit::~CopyBit()
    625 {
    626     freeRenderBuffers();
    627     if(mRelFd[0] >=0)
    628         close(mRelFd[0]);
    629     if(mRelFd[1] >=0)
    630         close(mRelFd[1]);
    631     if(mEngine)
    632     {
    633         copybit_close(mEngine);
    634         mEngine = NULL;
    635     }
    636 }
    637 }; //namespace qhwc
    638