• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
region_iteratorqhwc::region_iterator41     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:
iterateqhwc::region_iterator49     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 
reset()72 void CopyBit::reset() {
73     mIsModeOn = false;
74     mCopyBitDraw = false;
75 }
76 
canUseCopybitForYUV(hwc_context_t * ctx)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 
canUseCopybitForRGB(hwc_context_t * ctx,hwc_display_contents_1_t * list,int dpy)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 
getRGBRenderingArea(const hwc_display_contents_1_t * list)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 
getLayersChanging(hwc_context_t * ctx,hwc_display_contents_1_t * list,int dpy)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 
checkDirtyRect(hwc_context_t * ctx,hwc_display_contents_1_t * list,int dpy)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 
prepareOverlap(hwc_context_t * ctx,hwc_display_contents_1_t * list)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 
prepare(hwc_context_t * ctx,hwc_display_contents_1_t * list,int dpy)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 
clear(private_handle_t * hnd,hwc_rect_t & rect)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 
drawUsingAppBufferComposition(hwc_context_t * ctx,hwc_display_contents_1_t * list,int dpy,int * copybitFd)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 
draw(hwc_context_t * ctx,hwc_display_contents_1_t * list,int dpy,int32_t * fd)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 
drawOverlap(hwc_context_t * ctx,hwc_display_contents_1_t * list)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 
drawRectUsingCopybit(hwc_context_t * dev,hwc_layer_1_t * layer,private_handle_t * renderBuffer,hwc_rect_t overlap,hwc_rect_t destRect)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 
drawLayerUsingCopybit(hwc_context_t * dev,hwc_layer_1_t * layer,private_handle_t * renderBuffer,bool isFG)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 
fillColorUsingCopybit(hwc_layer_1_t * layer,private_handle_t * renderBuffer)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 
getLayerResolution(const hwc_layer_1_t * layer,unsigned int & width,unsigned int & height)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 
validateParams(hwc_context_t * ctx,const hwc_display_contents_1_t * list)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 
allocRenderBuffers(int w,int h,int f)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 
freeRenderBuffers()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 
getCurrentRenderBuffer()1079 private_handle_t * CopyBit::getCurrentRenderBuffer() {
1080     return mRenderBuffer[mCurRenderBufferIndex];
1081 }
1082 
setReleaseFd(int fd)1083 void CopyBit::setReleaseFd(int fd) {
1084     if(mRelFd[mCurRenderBufferIndex] >=0)
1085         close(mRelFd[mCurRenderBufferIndex]);
1086     mRelFd[mCurRenderBufferIndex] = dup(fd);
1087 }
1088 
setReleaseFdSync(int fd)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 
getCopyBitDevice()1101 struct copybit_device_t* CopyBit::getCopyBitDevice() {
1102     return mEngine;
1103 }
1104 
CopyBit(hwc_context_t * ctx,const int & dpy)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 
~CopyBit()1136 CopyBit::~CopyBit()
1137 {
1138     freeRenderBuffers();
1139     if(mEngine)
1140     {
1141         copybit_close(mEngine);
1142         mEngine = NULL;
1143     }
1144 }
LayerCache()1145 CopyBit::LayerCache::LayerCache() {
1146     reset();
1147 }
reset()1148 void CopyBit::LayerCache::reset() {
1149     memset(&hnd, 0, sizeof(hnd));
1150     layerCount = 0;
1151 }
updateCounts(hwc_context_t * ctx,hwc_display_contents_1_t * list,int dpy)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 
FbCache()1161 CopyBit::FbCache::FbCache() {
1162      reset();
1163 }
reset()1164 void CopyBit::FbCache::reset() {
1165      memset(&FbdirtyRect, 0, sizeof(FbdirtyRect));
1166      FbIndex =0;
1167 }
1168 
insertAndUpdateFbCache(hwc_rect_t dirtyRect)1169 void CopyBit::FbCache::insertAndUpdateFbCache(hwc_rect_t dirtyRect) {
1170    FbIndex =  FbIndex % NUM_RENDER_BUFFERS;
1171    FbdirtyRect[FbIndex] = dirtyRect;
1172    FbIndex++;
1173 }
1174 
getUnchangedFbDRCount(hwc_rect_t dirtyRect)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