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 */
min(int a,int b)95 static inline int min(int a, int b) {
96     return (a<b) ? a : b;
97 }
98 
99 /** max of int a, b */
max(int a,int 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 */
MULDIV(uint32_t * a,uint32_t * b,int mul,int div)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 */
intersect(struct copybit_rect_t * out,const struct copybit_rect_t * lhs,const struct copybit_rect_t * rhs)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 */
get_format(int 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 */
set_image(struct mdp_img * img,const struct copybit_image_t * rhs)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 */
set_rects(struct copybit_context_t * dev,struct mdp_blit_req * e,const struct copybit_rect_t * dst,const struct copybit_rect_t * src,const struct copybit_rect_t * scissor,uint32_t horiz_padding,uint32_t vert_padding)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 */
set_infos(struct copybit_context_t * dev,struct mdp_blit_req * req,int flags)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 */
msm_copybit(struct copybit_context_t * dev,void const * list)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 */
set_parameter_copybit(struct copybit_device_t * dev,int name,int 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 */
get(struct copybit_device_t * dev,int name)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 */
stretch_copybit(struct copybit_device_t * dev,struct copybit_image_t const * dst,struct copybit_image_t const * src,struct copybit_rect_t const * dst_rect,struct copybit_rect_t const * src_rect,struct copybit_region_t const * region)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 */
blit_copybit(struct copybit_device_t * dev,struct copybit_image_t const * dst,struct copybit_image_t const * src,struct copybit_region_t const * region)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 
finish_copybit(struct copybit_device_t * dev)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 */
close_copybit(struct hw_device_t * dev)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 */
open_copybit(const struct hw_module_t * module,const char * name,struct hw_device_t ** device)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