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