copybit.cpp revision b16edac51020832b4049b6709df12346b40d20d9
129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Copyright (C) 2008 The Android Open Source Project
329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Copyright (c) 2010 - 2011, Code Aurora Forum. All rights reserved.
429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * you may not use this file except in compliance with the License.
729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * You may obtain a copy of the License at
829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
1029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
1129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Unless required by applicable law or agreed to in writing, software
1229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
1329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * See the License for the specific language governing permissions and
1529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * limitations under the License.
1629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
1729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
1829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
1929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define LOG_TAG "copybit"
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
4529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#if defined(COPYBIT_MSM7K)
4629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define MAX_SCALE_FACTOR    (4)
4729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define MAX_DIMENSION       (4096)
4829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#elif defined(COPYBIT_QSD8K)
4929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define MAX_SCALE_FACTOR    (8)
5029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define MAX_DIMENSION       (2048)
5129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#else
5229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#error "Unsupported MDP version"
5329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#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;
6329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
6429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/**
6629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Common hardware methods
6729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
6829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
7029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        struct hw_device_t** device);
7129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic struct hw_module_methods_t copybit_module_methods = {
7329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedopen:  open_copybit
7429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
7529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
7729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * The COPYBIT Module
7829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
7929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstruct copybit_module_t HAL_MODULE_INFO_SYM = {
8029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedcommon: {
8129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedtag: HARDWARE_MODULE_TAG,
8229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     version_major: 1,
8329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     version_minor: 0,
8429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     id: COPYBIT_HARDWARE_MODULE_ID,
8529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     name: "QCT MSM7K COPYBIT Module",
8629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     author: "Google, Inc.",
8729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     methods: &copybit_module_methods
8829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
8929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
9029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
9129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/******************************************************************************/
9229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
9329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** min of int a, b */
9429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic inline int min(int a, int b) {
9529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return (a<b) ? a : b;
9629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
9729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
9829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** max of int a, b */
9929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic inline int max(int a, int b) {
10029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return (a>b) ? a : b;
10129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
10229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
10329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** scale each parameter by mul/div. Assume div isn't 0 */
10429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic inline void MULDIV(uint32_t *a, uint32_t *b, int mul, int div) {
10529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (mul != div) {
10629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        *a = (mul * *a) / div;
10729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        *b = (mul * *b) / div;
10829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
10929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
11029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
11129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Determine the intersection of lhs & rhs store in out */
11229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void intersect(struct copybit_rect_t *out,
11329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *lhs,
11429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *rhs) {
11529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->l = max(lhs->l, rhs->l);
11629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->t = max(lhs->t, rhs->t);
11729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->r = min(lhs->r, rhs->r);
11829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    out->b = min(lhs->b, rhs->b);
11929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
12029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
12129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** convert COPYBIT_FORMAT to MDP format */
12229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int get_format(int format) {
12329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch (format) {
12429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGB_565:       return MDP_RGB_565;
12529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:     return MDP_RGBX_8888;
12629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGB_888:       return MDP_RGB_888;
12729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:     return MDP_RGBA_8888;
12829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_BGRA_8888:     return MDP_BGRA_8888;
12929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_422_SP:  return MDP_Y_CBCR_H2V1;
13029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:  return MDP_Y_CBCR_H2V2;
13129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_422_SP:  return MDP_Y_CRCB_H2V1;
13229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:  return MDP_Y_CRCB_H2V2;
13329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP_ADRENO: return MDP_Y_CBCR_H2V2_ADRENO;
13429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
13529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return -1;
13629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
13729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
13829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** convert from copybit image to mdp image structure */
13929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void set_image(struct mdp_img *img, const struct copybit_image_t *rhs)
14029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
14129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t* hnd = (private_handle_t*)rhs->handle;
14229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(hnd == NULL){
14329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("copybit: Invalid handle");
14429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return;
14529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
14629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->width      = rhs->w;
14729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->height     = rhs->h;
14829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->format     = get_format(rhs->format);
14929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->offset     = hnd->offset;
15029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    img->memory_id  = hnd->fd;
15129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
15229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** setup rectangles */
15329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void set_rects(struct copybit_context_t *dev,
15429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      struct mdp_blit_req *e,
15529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *dst,
15629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *src,
15729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *scissor,
15829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      uint32_t horiz_padding,
15929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      uint32_t vert_padding) {
16029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t clip;
16129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    intersect(&clip, scissor, dst);
16229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
16329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.x  = clip.l;
16429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.y  = clip.t;
16529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.w  = clip.r - clip.l;
16629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->dst_rect.h  = clip.b - clip.t;
16729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
16829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    uint32_t W, H, delta_x, delta_y;
16929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
17029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_x = (clip.t - dst->t);
17129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_y = (dst->r - clip.r);
17229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.w = (clip.b - clip.t);
17329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.h = (clip.r - clip.l);
17429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        W = dst->b - dst->t;
17529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        H = dst->r - dst->l;
17629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
17729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_x  = (clip.l - dst->l);
17829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delta_y  = (clip.t - dst->t);
17929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.w  = (clip.r - clip.l);
18029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        e->src_rect.h  = (clip.b - clip.t);
18129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        W = dst->r - dst->l;
18229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        H = dst->b - dst->t;
18329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
18429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
18529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    MULDIV(&delta_x, &e->src_rect.w, src->r - src->l, W);
18629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    MULDIV(&delta_y, &e->src_rect.h, src->b - src->t, H);
18729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
18829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->src_rect.x = delta_x + src->l;
18929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    e->src_rect.y = delta_y + src->t;
19029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
19129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_V) {
19229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
19329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
19429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }else{
19529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
19629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
19729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
19829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
19929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (dev->mFlags & COPYBIT_TRANSFORM_FLIP_H) {
20029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (dev->mFlags & COPYBIT_TRANSFORM_ROT_90) {
20129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.y = (src->t + src->b) - (e->src_rect.y + e->src_rect.h);
20229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }else{
20329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            e->src_rect.x = (src->l + src->r) - (e->src_rect.x + e->src_rect.w);
20429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
20529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
20629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
20729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
20829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** setup mdp request */
20929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void set_infos(struct copybit_context_t *dev,
21029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      struct mdp_blit_req *req, int flags)
21129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
21229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->alpha = dev->mAlpha;
21329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->transp_mask = MDP_TRANSP_NOP;
21429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->flags = dev->mFlags | flags;
21529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#if defined(COPYBIT_QSD8K)
21629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    req->flags |= MDP_BLEND_FG_PREMULT;
21729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#endif
21829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
21929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
22029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** copy the bits */
22129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int msm_copybit(struct copybit_context_t *dev, void const *list)
22229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
22329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int err = ioctl(dev->mFD, MSMFB_BLIT,
22429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (struct mdp_blit_req_list const*)list);
22529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ALOGE_IF(err<0, "copyBits failed (%s)", strerror(errno));
22629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (err == 0) {
22729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return 0;
22829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
22929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#if DEBUG_MDP_ERRORS
23029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct mdp_blit_req_list const* l =
23129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            (struct mdp_blit_req_list const*)list;
232b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed        for (unsigned int i=0 ; i<l->count ; i++) {
23329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%d: src={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
23429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  "    dst={w=%d, h=%d, f=%d, rect={%d,%d,%d,%d}}\n"
235b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed                  "    flags=%08x"
23629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  ,
23729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  i,
23829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src.width,
23929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src.height,
24029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src.format,
24129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.x,
24229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.y,
24329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.w,
24429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].src_rect.h,
24529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst.width,
24629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst.height,
24729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst.format,
24829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.x,
24929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.y,
25029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.w,
25129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].dst_rect.h,
25229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  l->req[i].flags
25329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                 );
25429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
25529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#endif
25629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -errno;
25729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
25829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
25929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
26029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*****************************************************************************/
26129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
26229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Set a parameter to value */
26329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int set_parameter_copybit(
26429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
26529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int name,
26629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int value)
26729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
26829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
26929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = 0;
27029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
27129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        switch(name) {
27229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_ROTATION_DEG:
27329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                switch (value) {
27429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 0:
27529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
27629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
27729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 90:
27829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
27929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags |= MDP_ROT_90;
28029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
28129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 180:
28229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
28329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags |= MDP_ROT_180;
28429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
28529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    case 270:
28629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags &= ~0x7;
28729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ctx->mFlags |= MDP_ROT_270;
28829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
28929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    default:
29029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        ALOGE("Invalid value for COPYBIT_ROTATION_DEG");
29129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        status = -EINVAL;
29229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        break;
29329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
29429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
29529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_PLANE_ALPHA:
29629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value < 0)      value = MDP_ALPHA_NOP;
29729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value >= 256)   value = 255;
29829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ctx->mAlpha = value;
29929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
30029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_DITHER:
30129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value == COPYBIT_ENABLE) {
30229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags |= MDP_DITHER;
30329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                } else if (value == COPYBIT_DISABLE) {
30429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags &= ~MDP_DITHER;
30529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
30629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
30729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_BLUR:
30829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (value == COPYBIT_ENABLE) {
30929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags |= MDP_BLUR;
31029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                } else if (value == COPYBIT_DISABLE) {
31129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags &= ~MDP_BLUR;
31229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
31329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
31429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_PREMULTIPLIED_ALPHA:
31529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if(value == COPYBIT_ENABLE) {
31629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags |= MDP_BLEND_FG_PREMULT;
31729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                } else if (value == COPYBIT_DISABLE) {
31829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ctx->mFlags &= ~MDP_BLEND_FG_PREMULT;
31929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
32029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
32129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_TRANSFORM:
32229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ctx->mFlags &= ~0x7;
32329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ctx->mFlags |= value & 0x7;
32429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
32529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            default:
32629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                status = -EINVAL;
32729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
32829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
32929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
33029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = -EINVAL;
33129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
33229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
33329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
33429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
33529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Get a static info value */
33629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int get(struct copybit_device_t *dev, int name)
33729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
33829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
33929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int value;
34029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
34129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        switch(name) {
34229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_MINIFICATION_LIMIT:
34329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = MAX_SCALE_FACTOR;
34429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
34529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_MAGNIFICATION_LIMIT:
34629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = MAX_SCALE_FACTOR;
34729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
34829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_SCALING_FRAC_BITS:
34929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = 32;
35029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
35129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            case COPYBIT_ROTATION_STEP_DEG:
35229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = 90;
35329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                break;
35429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            default:
35529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                value = -EINVAL;
35629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
35729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
35829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        value = -EINVAL;
35929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
36029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return value;
36129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
36229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
36329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** do a stretch blit type operation */
36429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int stretch_copybit(
36529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
36629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *dst,
36729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *src,
36829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t const *dst_rect,
36929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t const *src_rect,
37029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_region_t const *region)
37129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
37229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
37329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = 0;
37429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t *yv12_handle = NULL;
37529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
37629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct {
37729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            uint32_t count;
37829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            struct mdp_blit_req req[12];
37929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        } list;
38029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
38129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (ctx->mAlpha < 255) {
38229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            switch (src->format) {
38329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                // we don't support plane alpha with RGBA formats
38429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                case HAL_PIXEL_FORMAT_RGBA_8888:
38529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                case HAL_PIXEL_FORMAT_BGRA_8888:
38629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                case HAL_PIXEL_FORMAT_RGBA_5551:
38729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                case HAL_PIXEL_FORMAT_RGBA_4444:
38829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ALOGE ("%s : Unsupported Pixel format %d", __FUNCTION__,
38929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                           src->format);
39029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    return -EINVAL;
39129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
39229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
39329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
394b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed        if (src_rect->l < 0 || src_rect->r > (int)src->w ||
395b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed            src_rect->t < 0 || src_rect->b > (int)src->h) {
39629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            // this is always invalid
39729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE ("%s : Invalid source rectangle : src_rect l %d t %d r %d b %d",\
39829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                   __FUNCTION__, src_rect->l, src_rect->t, src_rect->r, src_rect->b);
39929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
40029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return -EINVAL;
40129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
40229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
40329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
40429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE ("%s : Invalid source dimensions w %d h %d", __FUNCTION__, src->w, src->h);
40529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return -EINVAL;
40629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
40729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
40829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
40929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE ("%s : Invalid DST dimensions w %d h %d", __FUNCTION__, dst->w, dst->h);
41029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return -EINVAL;
41129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
41229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
41329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if(src->format ==  HAL_PIXEL_FORMAT_YV12) {
41401d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed            int usage = GRALLOC_USAGE_PRIVATE_MM_HEAP;
41529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (0 == alloc_buffer(&yv12_handle,src->w,src->h,
41629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                  src->format, usage)){
41729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if(0 == convertYV12toYCrCb420SP(src,yv12_handle)){
41829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (const_cast<copybit_image_t *>(src))->format =
41929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        HAL_PIXEL_FORMAT_YCrCb_420_SP;
42029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (const_cast<copybit_image_t *>(src))->handle =
42129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        yv12_handle;
42229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    (const_cast<copybit_image_t *>(src))->base =
42329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        (void *)yv12_handle->base;
42429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
42529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                else{
42629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    ALOGE("Error copybit conversion from yv12 failed");
42729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    if(yv12_handle)
42829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        free_buffer(yv12_handle);
42929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    return -EINVAL;
43029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
43129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
43229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            else{
43329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ALOGE("Error:unable to allocate memeory for yv12 software conversion");
43429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                return -EINVAL;
43529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
43629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
43729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        const uint32_t maxCount = sizeof(list.req)/sizeof(list.req[0]);
43829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        const struct copybit_rect_t bounds = { 0, 0, dst->w, dst->h };
43929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct copybit_rect_t clip;
44029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        list.count = 0;
44129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = 0;
44229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        while ((status == 0) && region->next(region, &clip)) {
44329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            intersect(&clip, &bounds, &clip);
44429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            mdp_blit_req* req = &list.req[list.count];
44529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            int flags = 0;
44629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
44729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            private_handle_t* src_hnd = (private_handle_t*)src->handle;
44829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if(src_hnd != NULL && src_hnd->flags & private_handle_t::PRIV_FLAGS_DO_NOT_FLUSH) {
44929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                flags |=  MDP_BLIT_NON_CACHED;
45029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
45129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
45229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_infos(ctx, req, flags);
45329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_image(&req->dst, dst);
45429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_image(&req->src, src);
45529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            set_rects(ctx, req, dst_rect, src_rect, &clip, src->horiz_padding, src->vert_padding);
45629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
45729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (req->src_rect.w<=0 || req->src_rect.h<=0)
45829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                continue;
45929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
46029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (req->dst_rect.w<=0 || req->dst_rect.h<=0)
46129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                continue;
46229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
46329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (++list.count == maxCount) {
46429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                status = msm_copybit(ctx, &list);
46529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                list.count = 0;
46629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
46729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
46829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if ((status == 0) && list.count) {
46929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            status = msm_copybit(ctx, &list);
47029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
47129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
47229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE ("%s : Invalid COPYBIT context", __FUNCTION__);
47329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = -EINVAL;
47429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
47529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(yv12_handle)
47629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        free_buffer(yv12_handle);
47729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
47829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
47929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
48029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Perform a blit type operation */
48129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int blit_copybit(
48229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
48329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *dst,
48429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *src,
48529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_region_t const *region)
48629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
48729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t dr = { 0, 0, dst->w, dst->h };
48829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t sr = { 0, 0, src->w, src->h };
48929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return stretch_copybit(dev, dst, src, &dr, &sr, region);
49029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
49129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
49229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*****************************************************************************/
49329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
49429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Close the copybit device */
49529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int close_copybit(struct hw_device_t *dev)
49629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
49729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
49829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
49929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        close(ctx->mFD);
50029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        free(ctx);
50129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
50229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
50329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
50429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
50529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Open a new instance of a copybit device using name */
50629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
50729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        struct hw_device_t** device)
50829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
50929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = -EINVAL;
51029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    copybit_context_t *ctx;
51129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx = (copybit_context_t *)malloc(sizeof(copybit_context_t));
51229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    memset(ctx, 0, sizeof(*ctx));
51329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
51429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
51529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.version = 1;
51629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.module = const_cast<hw_module_t*>(module);
51729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.close = close_copybit;
51829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.set_parameter = set_parameter_copybit;
51929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.get = get;
52029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.blit = blit_copybit;
52129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.stretch = stretch_copybit;
52229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->mAlpha = MDP_ALPHA_NOP;
52329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->mFlags = 0;
52429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->mFD = open("/dev/graphics/fb0", O_RDWR, 0);
52529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx->mFD < 0) {
52629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = errno;
52729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("Error opening frame buffer errno=%d (%s)",
52829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed              status, strerror(status));
52929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = -status;
53029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
53129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        struct fb_fix_screeninfo finfo;
53229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (ioctl(ctx->mFD, FBIOGET_FSCREENINFO, &finfo) == 0) {
53329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (strncmp(finfo.id, "msmfb", 5) == 0) {
53429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                /* Success */
53529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                status = 0;
53629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            } else {
53729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ALOGE("Error not msm frame buffer");
53829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                status = -EINVAL;
53929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
54029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        } else {
54129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("Error executing ioctl for screen info");
54229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            status = -errno;
54329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
54429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
54529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
54629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (status == 0) {
54729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        *device = &ctx->device.common;
54829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
54929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        close_copybit(&ctx->device.common);
55029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
55129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
55229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
553