hwc_copybit.cpp revision 4b242336eb6dcb56a6e7e1d8e88791958972a4a8
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
29namespace qhwc {
30
31struct range {
32    int current;
33    int end;
34};
35struct 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
44private:
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
68void CopyBit::reset() {
69    mIsModeOn = false;
70    mCopyBitDraw = false;
71}
72
73bool 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
81bool 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
111unsigned 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
130bool 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_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
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    // We cannot mix copybit layer with layers marked to be drawn on FB
184    if (!useCopybitForYUV && ctx->listStats[dpy].yuvCount)
185        return true;
186
187    // numAppLayers-1, as we iterate till 0th layer index
188    for (int i = ctx->listStats[dpy].numAppLayers-1; i >= 0 ; i--) {
189        private_handle_t *hnd = (private_handle_t *)list->hwLayers[i].handle;
190
191        if ((hnd->bufferType == BUFFER_TYPE_VIDEO && useCopybitForYUV) ||
192            (hnd->bufferType == BUFFER_TYPE_UI && useCopybitForRGB)) {
193            layerProp[i].mFlags |= HWC_COPYBIT;
194            list->hwLayers[i].compositionType = HWC_OVERLAY;
195            mCopyBitDraw = true;
196        } else {
197            // We currently cannot mix copybit layers with layers marked to
198            // be drawn on the framebuffer or that are on the layer cache.
199            mCopyBitDraw = false;
200            //There is no need to reset layer properties here as we return in
201            //draw if mCopyBitDraw is false
202            break;
203        }
204    }
205    return true;
206}
207
208int CopyBit::clear (private_handle_t* hnd, hwc_rect_t& rect)
209{
210    int ret = 0;
211    copybit_rect_t clear_rect = {rect.left, rect.top,
212        rect.right,
213        rect.bottom};
214
215    copybit_image_t buf;
216    buf.w = ALIGN(hnd->width,32);
217    buf.h = hnd->height;
218    buf.format = hnd->format;
219    buf.base = (void *)hnd->base;
220    buf.handle = (native_handle_t *)hnd;
221
222    copybit_device_t *copybit = mEngine;
223    ret = copybit->clear(copybit, &buf, &clear_rect);
224    return ret;
225}
226
227bool CopyBit::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
228                                                        int dpy, int32_t *fd) {
229    // draw layers marked for COPYBIT
230    int retVal = true;
231    int copybitLayerCount = 0;
232    LayerProp *layerProp = ctx->layerProp[dpy];
233
234    if(mCopyBitDraw == false) // there is no layer marked for copybit
235        return false ;
236
237    //render buffer
238    private_handle_t *renderBuffer = getCurrentRenderBuffer();
239    if (!renderBuffer) {
240        ALOGE("%s: Render buffer layer handle is NULL", __FUNCTION__);
241        return false;
242    }
243
244    //Wait for the previous frame to complete before rendering onto it
245    if(mRelFd[0] >=0) {
246        sync_wait(mRelFd[0], 1000);
247        close(mRelFd[0]);
248        mRelFd[0] = -1;
249    }
250
251    if (ctx->mMDP.version >= qdutils::MDP_V4_0) {
252        //Clear the visible region on the render buffer
253        //XXX: Do this only when needed.
254        hwc_rect_t clearRegion;
255        getNonWormholeRegion(list, clearRegion);
256        clear(renderBuffer, clearRegion);
257    }
258    // numAppLayers-1, as we iterate from 0th layer index with HWC_COPYBIT flag
259    for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) {
260        hwc_layer_1_t *layer = &list->hwLayers[i];
261        if(!(layerProp[i].mFlags & HWC_COPYBIT)) {
262            ALOGD_IF(DEBUG_COPYBIT, "%s: Not Marked for copybit", __FUNCTION__);
263            continue;
264        }
265        int ret = -1;
266        if (list->hwLayers[i].acquireFenceFd != -1
267                && ctx->mMDP.version >= qdutils::MDP_V4_0) {
268            // Wait for acquire Fence on the App buffers.
269            ret = sync_wait(list->hwLayers[i].acquireFenceFd, 1000);
270            if(ret < 0) {
271                ALOGE("%s: sync_wait error!! error no = %d err str = %s",
272                                    __FUNCTION__, errno, strerror(errno));
273            }
274            close(list->hwLayers[i].acquireFenceFd);
275            list->hwLayers[i].acquireFenceFd = -1;
276        }
277        retVal = drawLayerUsingCopybit(ctx, &(list->hwLayers[i]),
278                                                    renderBuffer, dpy);
279        copybitLayerCount++;
280        if(retVal < 0) {
281            ALOGE("%s : drawLayerUsingCopybit failed", __FUNCTION__);
282        }
283    }
284
285    if (copybitLayerCount) {
286        copybit_device_t *copybit = getCopyBitDevice();
287        // Async mode
288        copybit->flush_get_fence(copybit, fd);
289    }
290    return true;
291}
292
293int  CopyBit::drawLayerUsingCopybit(hwc_context_t *dev, hwc_layer_1_t *layer,
294                                     private_handle_t *renderBuffer, int dpy)
295{
296    hwc_context_t* ctx = (hwc_context_t*)(dev);
297    int err = 0, acquireFd;
298    if(!ctx) {
299         ALOGE("%s: null context ", __FUNCTION__);
300         return -1;
301    }
302
303    private_handle_t *hnd = (private_handle_t *)layer->handle;
304    if(!hnd) {
305        ALOGE("%s: invalid handle", __FUNCTION__);
306        return -1;
307    }
308
309    private_handle_t *fbHandle = (private_handle_t *)renderBuffer;
310    if(!fbHandle) {
311        ALOGE("%s: Framebuffer handle is NULL", __FUNCTION__);
312        return -1;
313    }
314
315    // Set the copybit source:
316    copybit_image_t src;
317    src.w = hnd->width;
318    src.h = hnd->height;
319    src.format = hnd->format;
320    src.base = (void *)hnd->base;
321    src.handle = (native_handle_t *)layer->handle;
322    src.horiz_padding = src.w - hnd->width;
323    // Initialize vertical padding to zero for now,
324    // this needs to change to accomodate vertical stride
325    // if needed in the future
326    src.vert_padding = 0;
327
328    // Copybit source rect
329    hwc_rect_t sourceCrop = layer->sourceCrop;
330    copybit_rect_t srcRect = {sourceCrop.left, sourceCrop.top,
331                              sourceCrop.right,
332                              sourceCrop.bottom};
333
334    // Copybit destination rect
335    hwc_rect_t displayFrame = layer->displayFrame;
336    copybit_rect_t dstRect = {displayFrame.left, displayFrame.top,
337                              displayFrame.right,
338                              displayFrame.bottom};
339
340    // Copybit dst
341    copybit_image_t dst;
342    dst.w = ALIGN(fbHandle->width,32);
343    dst.h = fbHandle->height;
344    dst.format = fbHandle->format;
345    dst.base = (void *)fbHandle->base;
346    dst.handle = (native_handle_t *)fbHandle;
347
348    copybit_device_t *copybit = mEngine;
349
350    int32_t screen_w        = displayFrame.right - displayFrame.left;
351    int32_t screen_h        = displayFrame.bottom - displayFrame.top;
352    int32_t src_crop_width  = sourceCrop.right - sourceCrop.left;
353    int32_t src_crop_height = sourceCrop.bottom -sourceCrop.top;
354
355    // Copybit dst
356    float copybitsMaxScale =
357                      (float)copybit->get(copybit,COPYBIT_MAGNIFICATION_LIMIT);
358    float copybitsMinScale =
359                       (float)copybit->get(copybit,COPYBIT_MINIFICATION_LIMIT);
360
361    if((layer->transform == HWC_TRANSFORM_ROT_90) ||
362                           (layer->transform == HWC_TRANSFORM_ROT_270)) {
363        //swap screen width and height
364        int tmp = screen_w;
365        screen_w  = screen_h;
366        screen_h = tmp;
367    }
368    private_handle_t *tmpHnd = NULL;
369
370    if(screen_w <=0 || screen_h<=0 ||src_crop_width<=0 || src_crop_height<=0 ) {
371        ALOGE("%s: wrong params for display screen_w=%d src_crop_width=%d \
372        screen_w=%d src_crop_width=%d", __FUNCTION__, screen_w,
373                                src_crop_width,screen_w,src_crop_width);
374        return -1;
375    }
376
377    float dsdx = (float)screen_w/src_crop_width;
378    float dtdy = (float)screen_h/src_crop_height;
379
380    float scaleLimitMax = copybitsMaxScale * copybitsMaxScale;
381    float scaleLimitMin = copybitsMinScale * copybitsMinScale;
382    if(dsdx > scaleLimitMax ||
383        dtdy > scaleLimitMax ||
384        dsdx < 1/scaleLimitMin ||
385        dtdy < 1/scaleLimitMin) {
386        ALOGE("%s: greater than max supported size dsdx=%f dtdy=%f \
387              scaleLimitMax=%f scaleLimitMin=%f", __FUNCTION__,dsdx,dtdy,
388                                          scaleLimitMax,1/scaleLimitMin);
389        return -1;
390    }
391    acquireFd = layer->acquireFenceFd;
392    if(dsdx > copybitsMaxScale ||
393        dtdy > copybitsMaxScale ||
394        dsdx < 1/copybitsMinScale ||
395        dtdy < 1/copybitsMinScale){
396        // The requested scale is out of the range the hardware
397        // can support.
398       ALOGE("%s:%d::Need to scale twice dsdx=%f, dtdy=%f,copybitsMaxScale=%f,\
399                                 copybitsMinScale=%f,screen_w=%d,screen_h=%d \
400                  src_crop_width=%d src_crop_height=%d",__FUNCTION__,__LINE__,
401              dsdx,dtdy,copybitsMaxScale,1/copybitsMinScale,screen_w,screen_h,
402                                              src_crop_width,src_crop_height);
403
404       //Driver makes width and height as even
405       //that may cause wrong calculation of the ratio
406       //in display and crop.Hence we make
407       //crop width and height as even.
408       src_crop_width  = (src_crop_width/2)*2;
409       src_crop_height = (src_crop_height/2)*2;
410
411       int tmp_w =  src_crop_width;
412       int tmp_h =  src_crop_height;
413
414       if (dsdx > copybitsMaxScale || dtdy > copybitsMaxScale ){
415         tmp_w = src_crop_width*copybitsMaxScale;
416         tmp_h = src_crop_height*copybitsMaxScale;
417       }else if (dsdx < 1/copybitsMinScale ||dtdy < 1/copybitsMinScale ){
418         tmp_w = src_crop_width/copybitsMinScale;
419         tmp_h = src_crop_height/copybitsMinScale;
420         tmp_w  = (tmp_w/2)*2;
421         tmp_h = (tmp_h/2)*2;
422       }
423       ALOGE("%s:%d::tmp_w = %d,tmp_h = %d",__FUNCTION__,__LINE__,tmp_w,tmp_h);
424
425       int usage = GRALLOC_USAGE_PRIVATE_IOMMU_HEAP;
426
427       if (0 == alloc_buffer(&tmpHnd, tmp_w, tmp_h, fbHandle->format, usage)){
428            copybit_image_t tmp_dst;
429            copybit_rect_t tmp_rect;
430            tmp_dst.w = tmp_w;
431            tmp_dst.h = tmp_h;
432            tmp_dst.format = tmpHnd->format;
433            tmp_dst.handle = tmpHnd;
434            tmp_dst.horiz_padding = src.horiz_padding;
435            tmp_dst.vert_padding = src.vert_padding;
436            tmp_rect.l = 0;
437            tmp_rect.t = 0;
438            tmp_rect.r = tmp_dst.w;
439            tmp_rect.b = tmp_dst.h;
440            //create one clip region
441            hwc_rect tmp_hwc_rect = {0,0,tmp_rect.r,tmp_rect.b};
442            hwc_region_t tmp_hwc_reg = {1,(hwc_rect_t const*)&tmp_hwc_rect};
443            region_iterator tmp_it(tmp_hwc_reg);
444            copybit->set_parameter(copybit,COPYBIT_TRANSFORM,0);
445            //TODO: once, we are able to read layer alpha, update this
446            copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
447            copybit->set_sync(copybit, acquireFd);
448            err = copybit->stretch(copybit,&tmp_dst, &src, &tmp_rect,
449                                                           &srcRect, &tmp_it);
450            if(err < 0){
451                ALOGE("%s:%d::tmp copybit stretch failed",__FUNCTION__,
452                                                             __LINE__);
453                if(tmpHnd)
454                    free_buffer(tmpHnd);
455                return err;
456            }
457            // use release fence as aquire fd for next stretch
458            if (ctx->mMDP.version < qdutils::MDP_V4_0)
459                copybit->flush_get_fence(copybit, &acquireFd);
460            // copy new src and src rect crop
461            src = tmp_dst;
462            srcRect = tmp_rect;
463      }
464    }
465    // Copybit region
466    hwc_region_t region = layer->visibleRegionScreen;
467    region_iterator copybitRegion(region);
468
469    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_WIDTH,
470                                          renderBuffer->width);
471    copybit->set_parameter(copybit, COPYBIT_FRAMEBUFFER_HEIGHT,
472                                          renderBuffer->height);
473    copybit->set_parameter(copybit, COPYBIT_TRANSFORM,
474                                              layer->transform);
475    //TODO: once, we are able to read layer alpha, update this
476    copybit->set_parameter(copybit, COPYBIT_PLANE_ALPHA, 255);
477    copybit->set_parameter(copybit, COPYBIT_BLEND_MODE,
478                                              layer->blending);
479    copybit->set_parameter(copybit, COPYBIT_DITHER,
480                             (dst.format == HAL_PIXEL_FORMAT_RGB_565)?
481                                             COPYBIT_ENABLE : COPYBIT_DISABLE);
482    copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,
483                                                COPYBIT_ENABLE);
484    copybit->set_sync(copybit, acquireFd);
485    err = copybit->stretch(copybit, &dst, &src, &dstRect, &srcRect,
486                                                   &copybitRegion);
487    copybit->set_parameter(copybit, COPYBIT_BLIT_TO_FRAMEBUFFER,
488                                               COPYBIT_DISABLE);
489
490    if(tmpHnd) {
491        if (ctx->mMDP.version < qdutils::MDP_V4_0){
492            int ret = -1, releaseFd;
493            // we need to wait for the buffer before freeing
494            copybit->flush_get_fence(copybit, &releaseFd);
495            ret = sync_wait(releaseFd, 1000);
496            if(ret < 0) {
497                ALOGE("%s: sync_wait error!! error no = %d err str = %s",
498                    __FUNCTION__, errno, strerror(errno));
499            }
500            close(releaseFd);
501        }
502        free_buffer(tmpHnd);
503    }
504
505    if(err < 0)
506        ALOGE("%s: copybit stretch failed",__FUNCTION__);
507    return err;
508}
509
510void CopyBit::getLayerResolution(const hwc_layer_1_t* layer,
511                                 unsigned int& width, unsigned int& height)
512{
513    hwc_rect_t displayFrame  = layer->displayFrame;
514
515    width = displayFrame.right - displayFrame.left;
516    height = displayFrame.bottom - displayFrame.top;
517}
518
519bool CopyBit::validateParams(hwc_context_t *ctx,
520                                        const hwc_display_contents_1_t *list) {
521    //Validate parameters
522    if (!ctx) {
523        ALOGE("%s:Invalid HWC context", __FUNCTION__);
524        return false;
525    } else if (!list) {
526        ALOGE("%s:Invalid HWC layer list", __FUNCTION__);
527        return false;
528    }
529    return true;
530}
531
532
533int CopyBit::allocRenderBuffers(int w, int h, int f)
534{
535    int ret = 0;
536    for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
537        if (mRenderBuffer[i] == NULL) {
538            ret = alloc_buffer(&mRenderBuffer[i],
539                               w, h, f,
540                               GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
541        }
542        if(ret < 0) {
543            freeRenderBuffers();
544            break;
545        }
546    }
547    return ret;
548}
549
550void CopyBit::freeRenderBuffers()
551{
552    for (int i = 0; i < NUM_RENDER_BUFFERS; i++) {
553        if(mRenderBuffer[i]) {
554            free_buffer(mRenderBuffer[i]);
555            mRenderBuffer[i] = NULL;
556        }
557    }
558}
559
560private_handle_t * CopyBit::getCurrentRenderBuffer() {
561    return mRenderBuffer[mCurRenderBufferIndex];
562}
563
564void CopyBit::setReleaseFd(int fd) {
565    if(mRelFd[0] >=0)
566        close(mRelFd[0]);
567    mRelFd[0] = mRelFd[1];
568    mRelFd[1] = dup(fd);
569}
570
571struct copybit_device_t* CopyBit::getCopyBitDevice() {
572    return mEngine;
573}
574
575CopyBit::CopyBit():mIsModeOn(false), mCopyBitDraw(false),
576    mCurRenderBufferIndex(0){
577    hw_module_t const *module;
578    for (int i = 0; i < NUM_RENDER_BUFFERS; i++)
579        mRenderBuffer[i] = NULL;
580    mRelFd[0] = -1;
581    mRelFd[1] = -1;
582
583    char value[PROPERTY_VALUE_MAX];
584    property_get("debug.hwc.dynThreshold", value, "2");
585    mDynThreshold = atof(value);
586
587    if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
588        if(copybit_open(module, &mEngine) < 0) {
589            ALOGE("FATAL ERROR: copybit open failed.");
590        }
591    } else {
592        ALOGE("FATAL ERROR: copybit hw module not found");
593    }
594}
595
596CopyBit::~CopyBit()
597{
598    freeRenderBuffers();
599    if(mRelFd[0] >=0)
600        close(mRelFd[0]);
601    if(mRelFd[1] >=0)
602        close(mRelFd[1]);
603    if(mEngine)
604    {
605        copybit_close(mEngine);
606        mEngine = NULL;
607    }
608}
609}; //namespace qhwc
610