129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Copyright (C) 2008 The Android Open Source Project
39ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R * Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved.
49ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R *
59ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R * Not a Contribution, Apache license notifications and license are retained
69ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R * for attribution purposes only.
729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * you may not use this file except in compliance with the License.
1029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * You may obtain a copy of the License at
1129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
1229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
1329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
1429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Unless required by applicable law or agreed to in writing, software
1529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
1629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * See the License for the specific language governing permissions and
1829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * limitations under the License.
1929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
2029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <cutils/log.h>
2229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <linux/msm_mdp.h>
2429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <linux/fb.h>
2529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <stdint.h>
2729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <string.h>
2829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <unistd.h>
2929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <errno.h>
3029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <fcntl.h>
3129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <sys/ioctl.h>
3329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <sys/types.h>
3429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <sys/mman.h>
3529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <copybit.h>
3729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "gralloc_priv.h"
3929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "software_converter.h"
4029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define DEBUG_MDP_ERRORS 1
4229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/******************************************************************************/
4429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
45513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava#if defined(COPYBIT_MSM7K)
4629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define MAX_SCALE_FACTOR    (4)
4729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define MAX_DIMENSION       (4096)
48513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava#elif defined(COPYBIT_QSD8K)
49513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava#define MAX_SCALE_FACTOR    (8)
50513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava#define MAX_DIMENSION       (2048)
51513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava#else
52513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava#error "Unsupported MDP version"
53513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava#endif
5429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/******************************************************************************/
5629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** State information for each device instance */
5829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstruct copybit_context_t {
5929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t device;
6029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int     mFD;
6129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    uint8_t mAlpha;
6229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int     mFlags;
6331da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed    bool    mBlitToFB;
6429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
6529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/**
6729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Common hardware methods
6829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
6929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
7129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        struct hw_device_t** device);
7229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic struct hw_module_methods_t copybit_module_methods = {
7429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedopen:  open_copybit
7529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
7629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
7829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * The COPYBIT Module
7929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
8029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstruct copybit_module_t HAL_MODULE_INFO_SYM = {
8129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedcommon: {
8229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedtag: HARDWARE_MODULE_TAG,
8329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     version_major: 1,
8429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     version_minor: 0,
8529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     id: COPYBIT_HARDWARE_MODULE_ID,
8629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     name: "QCT MSM7K COPYBIT Module",
8729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     author: "Google, Inc.",
8829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     methods: &copybit_module_methods
8929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
9029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
9129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
9229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/******************************************************************************/
9329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
9429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** min of int a, b */
9529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic inline int min(int a, int b) {
9629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return (a<b) ? a : b;
9729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
9829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
9929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** max of int a, b */
10029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic inline int max(int a, int b) {
10129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return (a>b) ? a : b;
10229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
10329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
10429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** scale each parameter by mul/div. Assume div isn't 0 */
10529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic inline void MULDIV(uint32_t *a, uint32_t *b, int mul, int div) {
10629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (mul != div) {
10729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        *a = (mul * *a) / div;
10829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        *b = (mul * *b) / div;
10929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
11029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
11129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
11229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Determine the intersection of lhs & rhs store in out */
11329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void intersect(struct copybit_rect_t *out,
11429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *lhs,
11529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *rhs) {
11629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->l = max(lhs->l, rhs->l);
11729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->t = max(lhs->t, rhs->t);
11829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->r = min(lhs->r, rhs->r);
11929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->b = min(lhs->b, rhs->b);
12029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
12129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
12229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** convert COPYBIT_FORMAT to MDP format */
12329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int get_format(int format) {
12429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch (format) {
12529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGB_565:       return MDP_RGB_565;
12629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:     return MDP_RGBX_8888;
12729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGB_888:       return MDP_RGB_888;
12829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:     return MDP_RGBA_8888;
12929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_BGRA_8888:     return MDP_BGRA_8888;
13029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_422_SP:  return MDP_Y_CBCR_H2V1;
13129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:  return MDP_Y_CBCR_H2V2;
13229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_422_SP:  return MDP_Y_CRCB_H2V1;
13329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:  return MDP_Y_CRCB_H2V2;
13429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO;
1359ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: return MDP_Y_CBCR_H2V2;
13629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
13729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return -1;
13829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
13929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
14029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** convert from copybit image to mdp image structure */
14129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void set_image(struct mdp_img *img, const struct copybit_image_t *rhs)
14229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
14329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t* hnd = (private_handle_t*)rhs->handle;
14429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(hnd == NULL){
14529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("copybit: Invalid handle");
14629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return;
14729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
14829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->width      = rhs->w;
14929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->height     = rhs->h;
15029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->format     = get_format(rhs->format);
15129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->offset     = hnd->offset;
15229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->memory_id  = hnd->fd;
15329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
15429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** setup rectangles */
15529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void set_rects(struct copybit_context_t *dev,
15629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      struct mdp_blit_req *e,
15729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *dst,
15829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *src,
15929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *scissor,
16029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      uint32_t horiz_padding,
16129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      uint32_t vert_padding) {
16229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t clip;
16329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    intersect(&clip, scissor, dst);
16429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
16529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.x  = clip.l;
16629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.y  = clip.t;
16729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.w  = clip.r - clip.l;
16829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.h  = clip.b - clip.t;
16929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
17029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    uint32_t W, H, delta_x, delta_y;
17129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
17229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_x = (clip.t - dst->t);
17329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_y = (dst->r - clip.r);
17429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.w = (clip.b - clip.t);
17529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.h = (clip.r - clip.l);
17629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        W = dst->b - dst->t;
17729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        H = dst->r - dst->l;
17829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
17929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_x  = (clip.l - dst->l);
18029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_y  = (clip.t - dst->t);
18129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.w  = (clip.r - clip.l);
18229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.h  = (clip.b - clip.t);
18329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        W = dst->r - dst->l;
18429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        H = dst->b - dst->t;
18529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
18629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
18729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    MULDIV(&delta_x, &e->src_rect.w, src->r - src->l, W);
18829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    MULDIV(&delta_y, &e->src_rect.h, src->b - src->t, H);
18929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
19029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->src_rect.x = delta_x + src->l;
19129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->src_rect.y = delta_y + src->t;
19229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
19329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_V) {
19429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
19529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
19629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }else{
19729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
19829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
19929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
20029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
20129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_H) {
20229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
20329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
20429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }else{
20529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
20629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
20729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
20829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
20929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
21029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** setup mdp request */
21129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void set_infos(struct copybit_context_t *dev,
21229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      struct mdp_blit_req *req, int flags)
21329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
21429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->alpha = dev->mAlpha;
21529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->transp_mask = MDP_TRANSP_NOP;
21629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->flags = dev->mFlags | flags;
21731da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed    // check if we are blitting to f/b
21831da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed    if (COPYBIT_ENABLE == dev->mBlitToFB) {
21931da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed        req->flags |= MDP_MEMORY_ID_TYPE_FB;
22031da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed    }
22129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#if defined(COPYBIT_QSD8K)
22229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->flags |= MDP_BLEND_FG_PREMULT;
22329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#endif
22429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
22529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
22629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** copy the bits */
22729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int msm_copybit(struct copybit_context_t *dev, void const *list)
22829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
22929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int err = ioctl(dev->mFD, MSMFB_BLIT,
23029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (struct mdp_blit_req_list const*)list);
23129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ALOGE_IF(err<0, "copyBits failed (%s)", strerror(errno));
23229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (err == 0) {
23329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return 0;
23429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
23529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#if DEBUG_MDP_ERRORS
23629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct mdp_blit_req_list const* l =
23729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            (struct mdp_blit_req_list const*)list;
238b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed        for (unsigned int i=0 ; i<l->count ; i++) {
23929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%d: src={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
24029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  "    dst={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
241b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed                  "    flags=%08x"
24229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  ,
24329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  i,
24429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src.width,
24529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src.height,
24629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src.format,
24729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.x,
24829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.y,
24929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.w,
25029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.h,
25129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst.width,
25229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst.height,
25329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst.format,
25429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.x,
25529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.y,
25629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.w,
25729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.h,
25829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].flags
25929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                 );
26029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
26129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#endif
26229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -errno;
26329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
26429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
26529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
26629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*****************************************************************************/
26729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
26829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Set a parameter to value */
26929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int set_parameter_copybit(
27029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
27129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int name,
27229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int value)
27329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
27429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
27529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = 0;
27629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
27729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        switch(name) {
27829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_ROTATION_DEG:
27929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                switch (value) {
28029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 0:
28129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
28229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
28329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 90:
28429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
28529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags |= MDP_ROT_90;
28629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
28729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 180:
28829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
28929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags |= MDP_ROT_180;
29029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
29129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 270:
29229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
29329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags |= MDP_ROT_270;
29429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
29529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    default:
29629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ALOGE("Invalid value for COPYBIT_ROTATION_DEG");
29729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        status = -EINVAL;
29829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
29929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
30029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
30129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_PLANE_ALPHA:
30229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value < 0)      value = MDP_ALPHA_NOP;
30329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value >= 256)   value = 255;
30429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ctx->mAlpha = value;
30529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
30629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_DITHER:
30729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value == COPYBIT_ENABLE) {
30829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags |= MDP_DITHER;
30929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                } else if (value == COPYBIT_DISABLE) {
31029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags &= ~MDP_DITHER;
31129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
31229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
31329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_BLUR:
31429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value == COPYBIT_ENABLE) {
31529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags |= MDP_BLUR;
31629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                } else if (value == COPYBIT_DISABLE) {
31729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags &= ~MDP_BLUR;
31829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
31929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
3209ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            case COPYBIT_BLEND_MODE:
3219ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                if(value == COPYBIT_BLENDING_PREMULT) {
32229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags |= MDP_BLEND_FG_PREMULT;
3239ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                } else {
32429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags &= ~MDP_BLEND_FG_PREMULT;
32529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
32629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
32729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_TRANSFORM:
32829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ctx->mFlags &= ~0x7;
32929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ctx->mFlags |= value & 0x7;
33029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
33131da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed            case COPYBIT_BLIT_TO_FRAMEBUFFER:
33231da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                if (COPYBIT_ENABLE == value) {
33331da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                    ctx->mBlitToFB = value;
33431da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                } else if (COPYBIT_DISABLE == value) {
33531da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                    ctx->mBlitToFB = value;
33631da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                } else {
33731da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                    ALOGE ("%s:Invalid input for COPYBIT_BLIT_TO_FRAMEBUFFER : %d",
33831da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                            __FUNCTION__, value);
33931da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                }
34031da0b1f44d5ff8f95be2b440df3cdd8c5c396d4Naseer Ahmed                break;
34129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            default:
34229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                status = -EINVAL;
34329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
34429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
34529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
34629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = -EINVAL;
34729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
34829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
34929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
35029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
35129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Get a static info value */
35229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int get(struct copybit_device_t *dev, int name)
35329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
35429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
35529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int value;
35629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
35729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        switch(name) {
35829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_MINIFICATION_LIMIT:
35929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = MAX_SCALE_FACTOR;
36029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
36129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_MAGNIFICATION_LIMIT:
36229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = MAX_SCALE_FACTOR;
36329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
36429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_SCALING_FRAC_BITS:
36529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = 32;
36629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
36729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_ROTATION_STEP_DEG:
36829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = 90;
36929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
37029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            default:
37129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = -EINVAL;
37229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
37329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
37429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        value = -EINVAL;
37529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
37629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return value;
37729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
37829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
37929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** do a stretch blit type operation */
38029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int stretch_copybit(
38129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
38229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *dst,
38329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *src,
38429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t const *dst_rect,
38529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t const *src_rect,
38629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_region_t const *region)
38729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
38829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
38929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = 0;
39029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t *yv12_handle = NULL;
39129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
39229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct {
39329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            uint32_t count;
39429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            struct mdp_blit_req req[12];
39529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        } list;
39629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
39729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (ctx->mAlpha < 255) {
39829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            switch (src->format) {
39929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                // we don't support plane alpha with RGBA formats
40029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                case HAL_PIXEL_FORMAT_RGBA_8888:
40129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                case HAL_PIXEL_FORMAT_BGRA_8888:
40229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__,
40329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           src->format);
40429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    return -EINVAL;
40529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
40629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
40729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4089ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (src_rect->l < 0 || (uint32_t)src_rect->r > src->w ||
4099ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            src_rect->t < 0 || (uint32_t)src_rect->b > src->h) {
41029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            // this is always invalid
41129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\
41229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                   __FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b);
41329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
41429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return -EINVAL;
41529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
41629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
41729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
41829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE ("%s : Invalid source dimensions w %d h %d", __FUNCTION__, src->w, src->h);
41929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return -EINVAL;
42029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
42129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
42229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
42329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE ("%s : Invalid DST dimensions w %d h %d", __FUNCTION__, dst->w, dst->h);
42429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return -EINVAL;
42529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
42629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
42729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if(src->format ==  HAL_PIXEL_FORMAT_YV12) {
4289ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            int usage =
429513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava            GRALLOC_USAGE_PRIVATE_CAMERA_HEAP|GRALLOC_USAGE_PRIVATE_UNCACHED;
43029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (0 == alloc_buffer(&yv12_handle,src->w,src->h,
43129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                  src->format, usage)){
43229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){
43329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (const_cast<copybit_image_t *>(src))->format =
43429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        HAL_PIXEL_FORMAT_YCrCb_420_SP;
43529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (const_cast<copybit_image_t *>(src))->handle =
43629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        yv12_handle;
43729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (const_cast<copybit_image_t *>(src))->base =
43829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        (void *)yv12_handle->base;
43929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
44029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                else{
44129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ALOGE("Error copybit conversion from yv12 failed");
44229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    if(yv12_handle)
44329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        free_buffer(yv12_handle);
44429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    return -EINVAL;
44529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
44629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
44729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            else{
44829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ALOGE("Error:unable to allocate memeory for yv12 software conversion");
44929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                return -EINVAL;
45029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
45129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
45229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        const uint32_t maxCount = sizeof(list.req)/sizeof(list.req[0]);
45329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        const struct copybit_rect_t bounds = { 0, 0, dst->w, dst->h };
45429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct copybit_rect_t clip;
45529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        list.count = 0;
45629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = 0;
45729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        while ((status == 0) && region->next(region, &clip)) {
45829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            intersect(&clip, &bounds, &clip);
45929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            mdp_blit_req* req = &list.req[list.count];
46029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            int flags = 0;
46129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
46229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            private_handle_t* src_hnd = (private_handle_t*)src->handle;
46329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if(src_hnd != NULL && src_hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) {
46429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                flags |=  MDP_BLIT_NON_CACHED;
46529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
46629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
46729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_infos(ctx, req, flags);
46829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_image(&req->dst, dst);
46929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_image(&req->src, src);
47029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_rects(ctx, req, dst_rect, src_rect, &clip, src->horiz_padding, src->vert_padding);
47129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
47229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (req->src_rect.w<=0 || req->src_rect.h<=0)
47329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                continue;
47429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
47529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (req->dst_rect.w<=0 || req->dst_rect.h<=0)
47629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                continue;
47729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
47829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (++list.count == maxCount) {
47929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                status = msm_copybit(ctx, &list);
48029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                list.count = 0;
48129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
48229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
48329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if ((status == 0) && list.count) {
48429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            status = msm_copybit(ctx, &list);
48529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
48629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
48729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__);
48829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = -EINVAL;
48929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
49029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(yv12_handle)
49129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        free_buffer(yv12_handle);
49229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
49329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
49429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
49529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Perform a blit type operation */
49629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int blit_copybit(
49729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
49829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *dst,
49929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *src,
50029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_region_t const *region)
50129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
50229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t dr = { 0, 0, dst->w, dst->h };
50329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t sr = { 0, 0, src->w, src->h };
50429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return stretch_copybit(dev, dst, src, &dr, &sr, region);
50529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
50629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5079ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.Rstatic int finish_copybit(struct copybit_device_t *dev)
5089ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R{
5099ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // NOP for MDP copybit
5109ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R}
5119ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
51229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*****************************************************************************/
51329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
51429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Close the copybit device */
51529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int close_copybit(struct hw_device_t *dev)
51629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
51729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
51829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
51929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        close(ctx->mFD);
52029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        free(ctx);
52129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
52229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
52329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
52429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
52529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Open a new instance of a copybit device using name */
52629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
52729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        struct hw_device_t** device)
52829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
52929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = -EINVAL;
53029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    copybit_context_t *ctx;
53129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t));
53229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    memset(ctx, 0, sizeof(*ctx));
53329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
53429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
53529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.version = 1;
53629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.module = const_cast<hw_module_t*>(module);
53729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.close = close_copybit;
53829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.set_parameter = set_parameter_copybit;
53929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.get = get;
54029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.blit = blit_copybit;
54129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.stretch = stretch_copybit;
5429ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->device.finish = finish_copybit;
54329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->mAlpha = MDP_ALPHA_NOP;
54429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->mFlags = 0;
54529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0);
54629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx->mFD < 0) {
54729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = errno;
54829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("Error opening frame buffer errno=%d (%s)",
54929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed              status, strerror(status));
55029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = -status;
55129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
552513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        struct fb_fix_screeninfo finfo;
553513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        if (ioctl(ctx->mFD, FBIOGET_FSCREENINFO, &finfo) == 0) {
554513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava            if (strncmp(finfo.id, "msmfb", 5) == 0) {
555513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava                /* Success */
556513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava                status = 0;
557513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava            } else {
558513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava                ALOGE("Error not msm frame buffer");
559513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava                status = -EINVAL;
560513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava            }
561513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        } else {
562513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava            ALOGE("Error executing ioctl for screen info");
563513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava            status = -errno;
564513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        }
565513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava    }
566513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava
567513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava    if (status == 0) {
56829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        *device = &ctx->device.common;
569513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava    } else {
570513ddc2124abf90c63af41999201f0d2031af0c8Vineeta Srivastava        close_copybit(&ctx->device.common);
57129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
57229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
57329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
574