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