Home | History | Annotate | Download | only in libcopybit
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  * Copyright (c) 2010 - 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 #include <cutils/log.h>
     22 
     23 #include <linux/msm_mdp.h>
     24 #include <linux/fb.h>
     25 
     26 #include <stdint.h>
     27 #include <string.h>
     28 #include <unistd.h>
     29 #include <errno.h>
     30 #include <fcntl.h>
     31 
     32 #include <sys/ioctl.h>
     33 #include <sys/types.h>
     34 #include <sys/mman.h>
     35 
     36 #include <copybit.h>
     37 
     38 #include "gralloc_priv.h"
     39 #include "software_converter.h"
     40 
     41 #define DEBUG_MDP_ERRORS 1
     42 
     43 /******************************************************************************/
     44 
     45 #if defined(COPYBIT_MSM7K)
     46 #define MAX_SCALE_FACTOR    (4)
     47 #define MAX_DIMENSION       (4096)
     48 #elif defined(COPYBIT_QSD8K)
     49 #define MAX_SCALE_FACTOR    (8)
     50 #define MAX_DIMENSION       (2048)
     51 #else
     52 #error "Unsupported MDP version"
     53 #endif
     54 
     55 /******************************************************************************/
     56 
     57 /** State information for each device instance */
     58 struct copybit_context_t {
     59     struct copybit_device_t device;
     60     int     mFD;
     61     uint8_t mAlpha;
     62     int     mFlags;
     63     bool    mBlitToFB;
     64 };
     65 
     66 /**
     67  * Common hardware methods
     68  */
     69 
     70 static int open_copybit(const struct hw_module_t* module, const char* name,
     71                         struct hw_device_t** device);
     72 
     73 static struct hw_module_methods_t copybit_module_methods = {
     74 open:  open_copybit
     75 };
     76 
     77 /*
     78  * The COPYBIT Module
     79  */
     80 struct copybit_module_t HAL_MODULE_INFO_SYM = {
     81 common: {
     82 tag: HARDWARE_MODULE_TAG,
     83      version_major: 1,
     84      version_minor: 0,
     85      id: COPYBIT_HARDWARE_MODULE_ID,
     86      name: "QCT MSM7K COPYBIT Module",
     87      author: "Google, Inc.",
     88      methods: &copybit_module_methods
     89         }
     90 };
     91 
     92 /******************************************************************************/
     93 
     94 /** min of int a, b */
     95 static inline int min(int a, int b) {
     96     return (a<b) ? a : b;
     97 }
     98 
     99 /** max of int a, b */
    100 static inline int max(int a, int b) {
    101     return (a>b) ? a : b;
    102 }
    103 
    104 /** scale each parameter by mul/div. Assume div isn't 0 */
    105 static inline void MULDIV(uint32_t *a, uint32_t *b, int mul, int div) {
    106     if (mul != div) {
    107         *a = (mul * *a) / div;
    108         *b = (mul * *b) / div;
    109     }
    110 }
    111 
    112 /** Determine the intersection of lhs & rhs store in out */
    113 static void intersect(struct copybit_rect_t *out,
    114                       const struct copybit_rect_t *lhs,
    115                       const struct copybit_rect_t *rhs) {
    116     out->l = max(lhs->l, rhs->l);
    117     out->t = max(lhs->t, rhs->t);
    118     out->r = min(lhs->r, rhs->r);
    119     out->b = min(lhs->b, rhs->b);
    120 }
    121 
    122 /** convert COPYBIT_FORMAT to MDP format */
    123 static int get_format(int format) {
    124     switch (format) {
    125         case HAL_PIXEL_FORMAT_RGB_565:       return MDP_RGB_565;
    126         case HAL_PIXEL_FORMAT_RGBX_8888:     return MDP_RGBX_8888;
    127         case HAL_PIXEL_FORMAT_RGB_888:       return MDP_RGB_888;
    128         case HAL_PIXEL_FORMAT_RGBA_8888:     return MDP_RGBA_8888;
    129         case HAL_PIXEL_FORMAT_BGRA_8888:     return MDP_BGRA_8888;
    130         case HAL_PIXEL_FORMAT_YCrCb_422_SP:  return MDP_Y_CBCR_H2V1;
    131         case HAL_PIXEL_FORMAT_YCrCb_420_SP:  return MDP_Y_CBCR_H2V2;
    132         case HAL_PIXEL_FORMAT_YCbCr_422_SP:  return MDP_Y_CRCB_H2V1;
    133         case HAL_PIXEL_FORMAT_YCbCr_420_SP:  return MDP_Y_CRCB_H2V2;
    134         case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO;
    135         case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2;
    136     }
    137     return -1;
    138 }
    139 
    140 /** convert from copybit image to mdp image structure */
    141 static void set_image(struct mdp_img *img, const struct copybit_image_t *rhs)
    142 {
    143     private_handle_t* hnd = (private_handle_t*)rhs->handle;
    144     if(hnd == NULL){
    145         ALOGE("copybit: Invalid handle");
    146         return;
    147     }
    148     img->width      = rhs->w;
    149     img->height     = rhs->h;
    150     img->format     = get_format(rhs->format);
    151     img->offset     = hnd->offset;
    152     img->memory_id  = hnd->fd;
    153 }
    154 /** setup rectangles */
    155 static void set_rects(struct copybit_context_t *dev,
    156                       struct mdp_blit_req *e,
    157                       const struct copybit_rect_t *dst,
    158                       const struct copybit_rect_t *src,
    159                       const struct copybit_rect_t *scissor,
    160                       uint32_t horiz_padding,
    161                       uint32_t vert_padding) {
    162     struct copybit_rect_t clip;
    163     intersect(&clip, scissor, dst);
    164 
    165     e->dst_rect.x  = clip.l;
    166     e->dst_rect.y  = clip.t;
    167     e->dst_rect.w  = clip.r - clip.l;
    168     e->dst_rect.h  = clip.b - clip.t;
    169 
    170     uint32_t W, H, delta_x, delta_y;
    171     if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
    172         delta_x = (clip.t - dst->t);
    173         delta_y = (dst->r - clip.r);
    174         e->src_rect.w = (clip.b - clip.t);
    175         e->src_rect.h = (clip.r - clip.l);
    176         W = dst->b - dst->t;
    177         H = dst->r - dst->l;
    178     } else {
    179         delta_x  = (clip.l - dst->l);
    180         delta_y  = (clip.t - dst->t);
    181         e->src_rect.w  = (clip.r - clip.l);
    182         e->src_rect.h  = (clip.b - clip.t);
    183         W = dst->r - dst->l;
    184         H = dst->b - dst->t;
    185     }
    186 
    187     MULDIV(&delta_x, &e->src_rect.w, src->r - src->l, W);
    188     MULDIV(&delta_y, &e->src_rect.h, src->b - src->t, H);
    189 
    190     e->src_rect.x = delta_x + src->l;
    191     e->src_rect.y = delta_y + src->t;
    192 
    193     if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_V) {
    194         if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
    195             e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
    196         }else{
    197             e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
    198         }
    199     }
    200 
    201     if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_H) {
    202         if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
    203             e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
    204         }else{
    205             e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
    206         }
    207     }
    208 }
    209 
    210 /** setup mdp request */
    211 static void set_infos(struct copybit_context_t *dev,
    212                       struct mdp_blit_req *req, int flags)
    213 {
    214     req->alpha = dev->mAlpha;
    215     req->transp_mask = MDP_TRANSP_NOP;
    216     req->flags = dev->mFlags | flags;
    217     // check if we are blitting to f/b
    218     if (COPYBIT_ENABLE == dev->mBlitToFB) {
    219         req->flags |= MDP_MEMORY_ID_TYPE_FB;
    220     }
    221 #if defined(COPYBIT_QSD8K)
    222     req->flags |= MDP_BLEND_FG_PREMULT;
    223 #endif
    224 }
    225 
    226 /** copy the bits */
    227 static int msm_copybit(struct copybit_context_t *dev, void const *list)
    228 {
    229     int err = ioctl(dev->mFD, MSMFB_BLIT,
    230                     (struct mdp_blit_req_list const*)list);
    231     ALOGE_IF(err<0, "copyBits failed (%s)", strerror(errno));
    232     if (err == 0) {
    233         return 0;
    234     } else {
    235 #if DEBUG_MDP_ERRORS
    236         struct mdp_blit_req_list const* l =
    237             (struct mdp_blit_req_list const*)list;
    238         for (unsigned int i=0 ; i<l->count ; i++) {
    239             ALOGE("%d: src={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
    240                   "    dst={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
    241                   "    flags=%08x"
    242                   ,
    243                   i,
    244                   l->req[i].src.width,
    245                   l->req[i].src.height,
    246                   l->req[i].src.format,
    247                   l->req[i].src_rect.x,
    248                   l->req[i].src_rect.y,
    249                   l->req[i].src_rect.w,
    250                   l->req[i].src_rect.h,
    251                   l->req[i].dst.width,
    252                   l->req[i].dst.height,
    253                   l->req[i].dst.format,
    254                   l->req[i].dst_rect.x,
    255                   l->req[i].dst_rect.y,
    256                   l->req[i].dst_rect.w,
    257                   l->req[i].dst_rect.h,
    258                   l->req[i].flags
    259                  );
    260         }
    261 #endif
    262         return -errno;
    263     }
    264 }
    265 
    266 /*****************************************************************************/
    267 
    268 /** Set a parameter to value */
    269 static int set_parameter_copybit(
    270     struct copybit_device_t *dev,
    271     int name,
    272     int value)
    273 {
    274     struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    275     int status = 0;
    276     if (ctx) {
    277         switch(name) {
    278             case COPYBIT_ROTATION_DEG:
    279                 switch (value) {
    280                     case 0:
    281                         ctx->mFlags &= ~0x7;
    282                         break;
    283                     case 90:
    284                         ctx->mFlags &= ~0x7;
    285                         ctx->mFlags |= MDP_ROT_90;
    286                         break;
    287                     case 180:
    288                         ctx->mFlags &= ~0x7;
    289                         ctx->mFlags |= MDP_ROT_180;
    290                         break;
    291                     case 270:
    292                         ctx->mFlags &= ~0x7;
    293                         ctx->mFlags |= MDP_ROT_270;
    294                         break;
    295                     default:
    296                         ALOGE("Invalid value for COPYBIT_ROTATION_DEG");
    297                         status = -EINVAL;
    298                         break;
    299                 }
    300                 break;
    301             case COPYBIT_PLANE_ALPHA:
    302                 if (value < 0)      value = MDP_ALPHA_NOP;
    303                 if (value >= 256)   value = 255;
    304                 ctx->mAlpha = value;
    305                 break;
    306             case COPYBIT_DITHER:
    307                 if (value == COPYBIT_ENABLE) {
    308                     ctx->mFlags |= MDP_DITHER;
    309                 } else if (value == COPYBIT_DISABLE) {
    310                     ctx->mFlags &= ~MDP_DITHER;
    311                 }
    312                 break;
    313             case COPYBIT_BLUR:
    314                 if (value == COPYBIT_ENABLE) {
    315                     ctx->mFlags |= MDP_BLUR;
    316                 } else if (value == COPYBIT_DISABLE) {
    317                     ctx->mFlags &= ~MDP_BLUR;
    318                 }
    319                 break;
    320             case COPYBIT_BLEND_MODE:
    321                 if(value == COPYBIT_BLENDING_PREMULT) {
    322                     ctx->mFlags |= MDP_BLEND_FG_PREMULT;
    323                 } else {
    324                     ctx->mFlags &= ~MDP_BLEND_FG_PREMULT;
    325                 }
    326                 break;
    327             case COPYBIT_TRANSFORM:
    328                 ctx->mFlags &= ~0x7;
    329                 ctx->mFlags |= value & 0x7;
    330                 break;
    331             case COPYBIT_BLIT_TO_FRAMEBUFFER:
    332                 if (COPYBIT_ENABLE == value) {
    333                     ctx->mBlitToFB = value;
    334                 } else if (COPYBIT_DISABLE == value) {
    335                     ctx->mBlitToFB = value;
    336                 } else {
    337                     ALOGE ("%s:Invalid input for COPYBIT_BLIT_TO_FRAMEBUFFER : %d",
    338                             __FUNCTION__, value);
    339                 }
    340                 break;
    341             default:
    342                 status = -EINVAL;
    343                 break;
    344         }
    345     } else {
    346         status = -EINVAL;
    347     }
    348     return status;
    349 }
    350 
    351 /** Get a static info value */
    352 static int get(struct copybit_device_t *dev, int name)
    353 {
    354     struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    355     int value;
    356     if (ctx) {
    357         switch(name) {
    358             case COPYBIT_MINIFICATION_LIMIT:
    359                 value = MAX_SCALE_FACTOR;
    360                 break;
    361             case COPYBIT_MAGNIFICATION_LIMIT:
    362                 value = MAX_SCALE_FACTOR;
    363                 break;
    364             case COPYBIT_SCALING_FRAC_BITS:
    365                 value = 32;
    366                 break;
    367             case COPYBIT_ROTATION_STEP_DEG:
    368                 value = 90;
    369                 break;
    370             default:
    371                 value = -EINVAL;
    372         }
    373     } else {
    374         value = -EINVAL;
    375     }
    376     return value;
    377 }
    378 
    379 /** do a stretch blit type operation */
    380 static int stretch_copybit(
    381     struct copybit_device_t *dev,
    382     struct copybit_image_t const *dst,
    383     struct copybit_image_t const *src,
    384     struct copybit_rect_t const *dst_rect,
    385     struct copybit_rect_t const *src_rect,
    386     struct copybit_region_t const *region)
    387 {
    388     struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    389     int status = 0;
    390     private_handle_t *yv12_handle = NULL;
    391     if (ctx) {
    392         struct {
    393             uint32_t count;
    394             struct mdp_blit_req req[12];
    395         } list;
    396 
    397         if (ctx->mAlpha < 255) {
    398             switch (src->format) {
    399                 // we don't support plane alpha with RGBA formats
    400                 case HAL_PIXEL_FORMAT_RGBA_8888:
    401                 case HAL_PIXEL_FORMAT_BGRA_8888:
    402                     ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__,
    403                            src->format);
    404                     return -EINVAL;
    405             }
    406         }
    407 
    408         if (src_rect->l < 0 || (uint32_t)src_rect->r > src->w ||
    409             src_rect->t < 0 || (uint32_t)src_rect->b > src->h) {
    410             // this is always invalid
    411             ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\
    412                    __FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b);
    413 
    414             return -EINVAL;
    415         }
    416 
    417         if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
    418             ALOGE ("%s : Invalid source dimensions w %d h %d", __FUNCTION__, src->w, src->h);
    419             return -EINVAL;
    420         }
    421 
    422         if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
    423             ALOGE ("%s : Invalid DST dimensions w %d h %d", __FUNCTION__, dst->w, dst->h);
    424             return -EINVAL;
    425         }
    426 
    427         if(src->format ==  HAL_PIXEL_FORMAT_YV12) {
    428             int usage =
    429             GRALLOC_USAGE_PRIVATE_CAMERA_HEAP|GRALLOC_USAGE_PRIVATE_UNCACHED;
    430             if (0 == alloc_buffer(&yv12_handle,src->w,src->h,
    431                                   src->format, usage)){
    432                 if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){
    433                     (const_cast<copybit_image_t *>(src))->format =
    434                         HAL_PIXEL_FORMAT_YCrCb_420_SP;
    435                     (const_cast<copybit_image_t *>(src))->handle =
    436                         yv12_handle;
    437                     (const_cast<copybit_image_t *>(src))->base =
    438                         (void *)yv12_handle->base;
    439                 }
    440                 else{
    441                     ALOGE("Error copybit conversion from yv12 failed");
    442                     if(yv12_handle)
    443                         free_buffer(yv12_handle);
    444                     return -EINVAL;
    445                 }
    446             }
    447             else{
    448                 ALOGE("Error:unable to allocate memeory for yv12 software conversion");
    449                 return -EINVAL;
    450             }
    451         }
    452         const uint32_t maxCount = sizeof(list.req)/sizeof(list.req[0]);
    453         const struct copybit_rect_t bounds = { 0, 0, dst->w, dst->h };
    454         struct copybit_rect_t clip;
    455         list.count = 0;
    456         status = 0;
    457         while ((status == 0) && region->next(region, &clip)) {
    458             intersect(&clip, &bounds, &clip);
    459             mdp_blit_req* req = &list.req[list.count];
    460             int flags = 0;
    461 
    462             private_handle_t* src_hnd = (private_handle_t*)src->handle;
    463             if(src_hnd != NULL && src_hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) {
    464                 flags |=  MDP_BLIT_NON_CACHED;
    465             }
    466 
    467             set_infos(ctx, req, flags);
    468             set_image(&req->dst, dst);
    469             set_image(&req->src, src);
    470             set_rects(ctx, req, dst_rect, src_rect, &clip, src->horiz_padding, src->vert_padding);
    471 
    472             if (req->src_rect.w<=0 || req->src_rect.h<=0)
    473                 continue;
    474 
    475             if (req->dst_rect.w<=0 || req->dst_rect.h<=0)
    476                 continue;
    477 
    478             if (++list.count == maxCount) {
    479                 status = msm_copybit(ctx, &list);
    480                 list.count = 0;
    481             }
    482         }
    483         if ((status == 0) && list.count) {
    484             status = msm_copybit(ctx, &list);
    485         }
    486     } else {
    487         ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__);
    488         status = -EINVAL;
    489     }
    490     if(yv12_handle)
    491         free_buffer(yv12_handle);
    492     return status;
    493 }
    494 
    495 /** Perform a blit type operation */
    496 static int blit_copybit(
    497     struct copybit_device_t *dev,
    498     struct copybit_image_t const *dst,
    499     struct copybit_image_t const *src,
    500     struct copybit_region_t const *region)
    501 {
    502     struct copybit_rect_t dr = { 0, 0, dst->w, dst->h };
    503     struct copybit_rect_t sr = { 0, 0, src->w, src->h };
    504     return stretch_copybit(dev, dst, src, &dr, &sr, region);
    505 }
    506 
    507 static int finish_copybit(struct copybit_device_t *dev)
    508 {
    509     // NOP for MDP copybit
    510 }
    511 
    512 /*****************************************************************************/
    513 
    514 /** Close the copybit device */
    515 static int close_copybit(struct hw_device_t *dev)
    516 {
    517     struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    518     if (ctx) {
    519         close(ctx->mFD);
    520         free(ctx);
    521     }
    522     return 0;
    523 }
    524 
    525 /** Open a new instance of a copybit device using name */
    526 static int open_copybit(const struct hw_module_t* module, const char* name,
    527                         struct hw_device_t** device)
    528 {
    529     int status = -EINVAL;
    530     copybit_context_t *ctx;
    531     ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t));
    532     memset(ctx, 0, sizeof(*ctx));
    533 
    534     ctx->device.common.tag = HARDWARE_DEVICE_TAG;
    535     ctx->device.common.version = 1;
    536     ctx->device.common.module = const_cast<hw_module_t*>(module);
    537     ctx->device.common.close = close_copybit;
    538     ctx->device.set_parameter = set_parameter_copybit;
    539     ctx->device.get = get;
    540     ctx->device.blit = blit_copybit;
    541     ctx->device.stretch = stretch_copybit;
    542     ctx->device.finish = finish_copybit;
    543     ctx->mAlpha = MDP_ALPHA_NOP;
    544     ctx->mFlags = 0;
    545     ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0);
    546     if (ctx->mFD < 0) {
    547         status = errno;
    548         ALOGE("Error opening frame buffer errno=%d (%s)",
    549               status, strerror(status));
    550         status = -status;
    551     } else {
    552         struct fb_fix_screeninfo finfo;
    553         if (ioctl(ctx->mFD, FBIOGET_FSCREENINFO, &finfo) == 0) {
    554             if (strncmp(finfo.id, "msmfb", 5) == 0) {
    555                 /* Success */
    556                 status = 0;
    557             } else {
    558                 ALOGE("Error not msm frame buffer");
    559                 status = -EINVAL;
    560             }
    561         } else {
    562             ALOGE("Error executing ioctl for screen info");
    563             status = -errno;
    564         }
    565     }
    566 
    567     if (status == 0) {
    568         *device = &ctx->device.common;
    569     } else {
    570         close_copybit(&ctx->device.common);
    571     }
    572     return status;
    573 }
    574