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                 case HAL_PIXEL_FORMAT_RGBA_5551:
    403                 case HAL_PIXEL_FORMAT_RGBA_4444:
    404                     ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__,
    405                            src->format);
    406                     return -EINVAL;
    407             }
    408         }
    409 
    410         if (src_rect->l < 0 || (uint32_t)src_rect->r > src->w ||
    411             src_rect->t < 0 || (uint32_t)src_rect->b > src->h) {
    412             // this is always invalid
    413             ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\
    414                    __FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b);
    415 
    416             return -EINVAL;
    417         }
    418 
    419         if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
    420             ALOGE ("%s : Invalid source dimensions w %d h %d", __FUNCTION__, src->w, src->h);
    421             return -EINVAL;
    422         }
    423 
    424         if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
    425             ALOGE ("%s : Invalid DST dimensions w %d h %d", __FUNCTION__, dst->w, dst->h);
    426             return -EINVAL;
    427         }
    428 
    429         if(src->format ==  HAL_PIXEL_FORMAT_YV12) {
    430             int usage =
    431             GRALLOC_USAGE_PRIVATE_CAMERA_HEAP|GRALLOC_USAGE_PRIVATE_UNCACHED;
    432             if (0 == alloc_buffer(&yv12_handle,src->w,src->h,
    433                                   src->format, usage)){
    434                 if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){
    435                     (const_cast<copybit_image_t *>(src))->format =
    436                         HAL_PIXEL_FORMAT_YCrCb_420_SP;
    437                     (const_cast<copybit_image_t *>(src))->handle =
    438                         yv12_handle;
    439                     (const_cast<copybit_image_t *>(src))->base =
    440                         (void *)yv12_handle->base;
    441                 }
    442                 else{
    443                     ALOGE("Error copybit conversion from yv12 failed");
    444                     if(yv12_handle)
    445                         free_buffer(yv12_handle);
    446                     return -EINVAL;
    447                 }
    448             }
    449             else{
    450                 ALOGE("Error:unable to allocate memeory for yv12 software conversion");
    451                 return -EINVAL;
    452             }
    453         }
    454         const uint32_t maxCount = sizeof(list.req)/sizeof(list.req[0]);
    455         const struct copybit_rect_t bounds = { 0, 0, dst->w, dst->h };
    456         struct copybit_rect_t clip;
    457         list.count = 0;
    458         status = 0;
    459         while ((status == 0) && region->next(region, &clip)) {
    460             intersect(&clip, &bounds, &clip);
    461             mdp_blit_req* req = &list.req[list.count];
    462             int flags = 0;
    463 
    464             private_handle_t* src_hnd = (private_handle_t*)src->handle;
    465             if(src_hnd != NULL && src_hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) {
    466                 flags |=  MDP_BLIT_NON_CACHED;
    467             }
    468 
    469             set_infos(ctx, req, flags);
    470             set_image(&req->dst, dst);
    471             set_image(&req->src, src);
    472             set_rects(ctx, req, dst_rect, src_rect, &clip, src->horiz_padding, src->vert_padding);
    473 
    474             if (req->src_rect.w<=0 || req->src_rect.h<=0)
    475                 continue;
    476 
    477             if (req->dst_rect.w<=0 || req->dst_rect.h<=0)
    478                 continue;
    479 
    480             if (++list.count == maxCount) {
    481                 status = msm_copybit(ctx, &list);
    482                 list.count = 0;
    483             }
    484         }
    485         if ((status == 0) && list.count) {
    486             status = msm_copybit(ctx, &list);
    487         }
    488     } else {
    489         ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__);
    490         status = -EINVAL;
    491     }
    492     if(yv12_handle)
    493         free_buffer(yv12_handle);
    494     return status;
    495 }
    496 
    497 /** Perform a blit type operation */
    498 static int blit_copybit(
    499     struct copybit_device_t *dev,
    500     struct copybit_image_t const *dst,
    501     struct copybit_image_t const *src,
    502     struct copybit_region_t const *region)
    503 {
    504     struct copybit_rect_t dr = { 0, 0, dst->w, dst->h };
    505     struct copybit_rect_t sr = { 0, 0, src->w, src->h };
    506     return stretch_copybit(dev, dst, src, &dr, &sr, region);
    507 }
    508 
    509 static int finish_copybit(struct copybit_device_t *dev)
    510 {
    511     // NOP for MDP copybit
    512 }
    513 
    514 /*****************************************************************************/
    515 
    516 /** Close the copybit device */
    517 static int close_copybit(struct hw_device_t *dev)
    518 {
    519     struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    520     if (ctx) {
    521         close(ctx->mFD);
    522         free(ctx);
    523     }
    524     return 0;
    525 }
    526 
    527 /** Open a new instance of a copybit device using name */
    528 static int open_copybit(const struct hw_module_t* module, const char* name,
    529                         struct hw_device_t** device)
    530 {
    531     int status = -EINVAL;
    532     copybit_context_t *ctx;
    533     ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t));
    534     memset(ctx, 0, sizeof(*ctx));
    535 
    536     ctx->device.common.tag = HARDWARE_DEVICE_TAG;
    537     ctx->device.common.version = 1;
    538     ctx->device.common.module = const_cast<hw_module_t*>(module);
    539     ctx->device.common.close = close_copybit;
    540     ctx->device.set_parameter = set_parameter_copybit;
    541     ctx->device.get = get;
    542     ctx->device.blit = blit_copybit;
    543     ctx->device.stretch = stretch_copybit;
    544     ctx->device.finish = finish_copybit;
    545     ctx->mAlpha = MDP_ALPHA_NOP;
    546     ctx->mFlags = 0;
    547     ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0);
    548     if (ctx->mFD < 0) {
    549         status = errno;
    550         ALOGE("Error opening frame buffer errno=%d (%s)",
    551               status, strerror(status));
    552         status = -status;
    553     } else {
    554         struct fb_fix_screeninfo finfo;
    555         if (ioctl(ctx->mFD, FBIOGET_FSCREENINFO, &finfo) == 0) {
    556             if (strncmp(finfo.id, "msmfb", 5) == 0) {
    557                 /* Success */
    558                 status = 0;
    559             } else {
    560                 ALOGE("Error not msm frame buffer");
    561                 status = -EINVAL;
    562             }
    563         } else {
    564             ALOGE("Error executing ioctl for screen info");
    565             status = -errno;
    566         }
    567     }
    568 
    569     if (status == 0) {
    570         *device = &ctx->device.common;
    571     } else {
    572         close_copybit(&ctx->device.common);
    573     }
    574     return status;
    575 }
    576