copybit_c2d.cpp revision e2cb361a1ac1df575a6316b691f49b6bad177a2e
1befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*
2befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Copyright (C) 2008 The Android Open Source Project
3befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
4befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
5befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
6befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * you may not use this file except in compliance with the License.
7befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * You may obtain a copy of the License at
8befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
9befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
10befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
11befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Unless required by applicable law or agreed to in writing, software
12befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
13befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * See the License for the specific language governing permissions and
15befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * limitations under the License.
16befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
17befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
18befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#define LOG_TAG "copybit_c2d"
19befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
20befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/log.h>
21befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
22befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <stdint.h>
23befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <string.h>
24befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <unistd.h>
25befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <errno.h>
26befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <fcntl.h>
27befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
28befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <sys/ioctl.h>
29befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <sys/types.h>
30befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <sys/mman.h>
31befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
32befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <linux/msm_kgsl.h>
33befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
34befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <EGL/eglplatform.h>
35befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/native_handle.h>
36befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/ashmem.h>
37befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <linux/ashmem.h>
38befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <gralloc_priv.h>
39befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
40befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <copybit.h>
41befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <alloc_controller.h>
42befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <memalloc.h>
43befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
44befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include "c2d2.h"
45befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include "software_converter.h"
46befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
47befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <dlfcn.h>
48befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
49befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing gralloc::IMemAlloc;
50befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing gralloc::IonController;
51befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing gralloc::alloc_data;
52befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
53befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
54befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     uint32 surface_bits,
55befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     C2D_SURFACE_TYPE surface_type,
56befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     void *surface_definition );
57befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
58befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id,
59befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     uint32 surface_bits,
60befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     C2D_SURFACE_TYPE surface_type,
61befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     void *surface_definition );
62befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
63befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id,
64befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                   C2D_SURFACE_TYPE surface_type,
65befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                   void *surface_definition,
66befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                   int32 x, int32 y );
67befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
68befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dDraw)( uint32 target_id,
69befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                            uint32 target_config, C2D_RECT *target_scissor,
70befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                            uint32 target_mask_id, uint32 target_color_key,
71befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                            C2D_OBJECT *objects_list, uint32 num_objects );
72befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
73befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dFinish)( uint32 target_id);
74befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
75befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp);
76befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
77befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp );
78befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
79befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
80befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
81befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, uint32 len, uint32 offset, uint32 flags, void ** gpuaddr);
82befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
83befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
84befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
85befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/******************************************************************************/
86befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
87befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#if defined(COPYBIT_Z180)
88befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#define MAX_SCALE_FACTOR    (4096)
89befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#define MAX_DIMENSION       (4096)
90befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#else
91befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#error "Unsupported HW version"
92befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#endif
93befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
94befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#define NUM_SURFACES 3
95befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
96befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedenum {
97befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    RGB_SURFACE,
98befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    YUV_SURFACE_2_PLANES,
99befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    YUV_SURFACE_3_PLANES
100befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
101befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
102befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedenum eConversionType {
103befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    CONVERT_TO_ANDROID_FORMAT,
104befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    CONVERT_TO_C2D_FORMAT
105befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
106befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
107befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedenum eC2DFlags {
108befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    FLAGS_PREMULTIPLIED_ALPHA = 1<<0,
109befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    FLAGS_YUV_DESTINATION     = 1<<1
110befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
111befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
112be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmedstatic gralloc::IAllocController* sAlloc = 0;
113befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/******************************************************************************/
114befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
115befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** State information for each device instance */
116befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct copybit_context_t {
117befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t device;
118befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    unsigned int src[NUM_SURFACES];  /* src surfaces */
119befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    unsigned int dst[NUM_SURFACES];  /* dst surfaces */
120befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    unsigned int trg_transform;      /* target transform */
121befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_OBJECT blitState;
122befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    void *libc2d2;
123befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    alloc_data temp_src_buffer;
124befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    alloc_data temp_dst_buffer;
125befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int fb_width;
126befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int fb_height;
127befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    bool isPremultipliedAlpha;
128e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed    bool mBlitToFB;
129befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
130befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
131befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct blitlist{
132befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    uint32_t count;
133befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_OBJECT blitObjects[12];
134befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
135befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
136befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct bufferInfo {
137befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int width;
138befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int height;
139befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int format;
140befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
141befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
142befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct yuvPlaneInfo {
143befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int yStride;       //luma stride
144befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int plane1_stride;
145befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int plane2_stride;
146befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int plane1_offset;
147befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int plane2_offset;
148befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
149befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
150befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/**
151befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Common hardware methods
152befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
153befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
154befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
155befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                        struct hw_device_t** device);
156befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
157befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic struct hw_module_methods_t copybit_module_methods = {
158befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedopen:  open_copybit
159befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
160befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
161befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*
162befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * The COPYBIT Module
163befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
164befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct copybit_module_t HAL_MODULE_INFO_SYM = {
165befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedcommon: {
166befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedtag: HARDWARE_MODULE_TAG,
167befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     version_major: 1,
168befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     version_minor: 0,
169befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     id: COPYBIT_HARDWARE_MODULE_ID,
170befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     name: "QCT COPYBIT C2D 2.0 Module",
171befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     author: "Qualcomm",
172befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     methods: &copybit_module_methods
173befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
174befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
175befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
176befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
177befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* convert COPYBIT_FORMAT to C2D format */
178befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_format(int format) {
179befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (format) {
180befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGB_565:        return C2D_COLOR_FORMAT_565_RGB;
181befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
182befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                              C2D_FORMAT_SWAP_RB |
183befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                  C2D_FORMAT_DISABLE_ALPHA;
184befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
185befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                              C2D_FORMAT_SWAP_RB;
186befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_BGRA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
187befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_5551:      return C2D_COLOR_FORMAT_5551_RGBA;
188befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_4444:      return C2D_COLOR_FORMAT_4444_RGBA;
189befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
190befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
191befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
192befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 |
193befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                  C2D_FORMAT_MACROTILED;
194befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:                              ALOGE("%s: invalid format (0x%x", __FUNCTION__, format); return -EINVAL;
195befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
196befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return -EINVAL;
197befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
198befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
199befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Get the C2D formats needed for conversion to YUV */
200befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_c2d_format_for_yuv_destination(int halFormat) {
201befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (halFormat) {
202befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // We do not swap the RB when the target is YUV
203befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
204befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                              C2D_FORMAT_DISABLE_ALPHA;
205befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
206befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                              // The U and V need to be interchanged when the target is YUV
207befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
208befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21;
209befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
210befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:                              return get_format(halFormat);
211befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
212befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return -EINVAL;
213befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
214befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
215befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* ------------------------------------------------------------------- *//*!
216befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \internal
217befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \brief Get the bpp for a particular color format
218befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \param color format
219befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \return bits per pixel
220befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *//* ------------------------------------------------------------------- */
221befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedint c2diGetBpp(int32 colorformat)
222befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
223befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
224befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int c2dBpp = 0;
225befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
226befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(colorformat&0xFF)
227befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    {
228befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4444_RGBA:
229befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4444_ARGB:
230befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_1555_ARGB:
231befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_565_RGB:
232befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_5551_RGBA:
233befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 16;
234befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
235befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_RGBA:
236befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_ARGB:
237befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 32;
238befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
239befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8_L:
240befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8_A:
241befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 8;
242befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
243befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4_A:
244befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 4;
245befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
246befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_1:
247befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 1;
248befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
249befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
250befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s ERROR", __func__);
251befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
252befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
253befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return c2dBpp;
254befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
255befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
256befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic uint32 c2d_get_gpuaddr( struct private_handle_t *handle)
257befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
258befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    uint32 memtype, *gpuaddr;
259befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_STATUS rc;
260befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
261befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!handle)
262befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return 0;
263befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
264befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (handle->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
265befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                         private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP))
266befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memtype = KGSL_USER_MEM_TYPE_PMEM;
267befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)
268befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memtype = KGSL_USER_MEM_TYPE_ASHMEM;
269befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
270befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memtype = KGSL_USER_MEM_TYPE_ION;
271befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    else {
272befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("Invalid handle flags: 0x%x", handle->flags);
273befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return 0;
274befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
275befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
276befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size, handle->offset, memtype, (void**)&gpuaddr);
277befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (rc == C2D_STATUS_OK) {
278befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return (uint32) gpuaddr;
279befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
280befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return 0;
281befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
282befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
283befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_supported_rgb_format(int format)
284befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
285befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(format) {
286befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:
287befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:
288befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGB_565:
289befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_BGRA_8888:
290befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_5551:
291befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_4444: {
292befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_SUCCESS;
293befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
294befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
295befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
296befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
297befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
298befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
299befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_num_planes(int format)
300befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
301befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(format) {
302befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
303befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
304befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
305befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
306befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return 2;
307befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
308befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YV12: {
309befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return 3;
310befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
311befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
312befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
313befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
314befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
315befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
316befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_supported_yuv_format(int format)
317befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
318befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(format) {
319befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
320befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
321befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
322befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
323befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_SUCCESS;
324befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
325befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
326befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
327befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
328befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
329befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
330befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_valid_destination_format(int format)
331befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
332befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
333befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // C2D does not support NV12Tile as a destination format.
334befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
335befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
336befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return COPYBIT_SUCCESS;
337befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
338befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
339befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int calculate_yuv_offset_and_stride(const bufferInfo& info,
340befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                           yuvPlaneInfo& yuvInfo)
341befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
342befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int width  = info.width;
343befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int height = info.height;
344befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int format = info.format;
345befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
346befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int aligned_height = 0;
347befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int aligned_width = 0, size = 0;
348befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
349befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (format) {
350befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
351befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            /* NV12 Tile buffers have their luma height aligned to 32bytes and width
352befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed             * aligned to 128 bytes. The chroma offset starts at an 8K boundary
353befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed             */
354befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            aligned_height = ALIGN(height, 32);
355befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            aligned_width  = ALIGN(width, 128);
356befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            size = aligned_width * aligned_height;
357befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.plane1_offset = ALIGN(size,8192);
358befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.yStride = aligned_width;
359befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.plane1_stride = aligned_width;
360befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
361befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
362befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
363befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
364befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
365befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            aligned_width = ALIGN(width, 32);
366befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.yStride = aligned_width;
367befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.plane1_stride = aligned_width;
368befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
369befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                // The encoder requires a 2K aligned chroma offset
370befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048);
371befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } else
372befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                yuvInfo.plane1_offset = aligned_width * height;
373befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
374befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
375befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
376befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default: {
377befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
378befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
379befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
380befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return COPYBIT_SUCCESS;
381befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
382befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
383befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** create C2D surface from copybit image */
384befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int set_image( uint32 surfaceId, const struct copybit_image_t *rhs,
385befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      int *cformat, uint32_t *mapped, const eC2DFlags flags)
386befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
387befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
388befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_SURFACE_TYPE surfaceType;
389befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = COPYBIT_SUCCESS;
390befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
391befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (flags & FLAGS_YUV_DESTINATION) {
392befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        *cformat = get_c2d_format_for_yuv_destination(rhs->format);
393befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
394befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        *cformat = get_format(rhs->format);
395befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
396befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
397befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(*cformat == -EINVAL) {
398befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: invalid format", __FUNCTION__);
399befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
400befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
401befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
402befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(handle == NULL) {
403befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: invalid handle", __func__);
404befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
405befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
406befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
407befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (handle->gpuaddr == 0) {
408befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        handle->gpuaddr = c2d_get_gpuaddr(handle);
409befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(!handle->gpuaddr) {
410befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
411befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
412befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
413befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        *mapped = 1;
414befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
415befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
416befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* create C2D surface */
417befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
418befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        /* RGB */
419befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        C2D_RGB_SURFACE_DEF surfaceDef;
420befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
421befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS);
422befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
423befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.phys = (void*) handle->gpuaddr;
424befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.buffer = (void*) (handle->base);
425befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
426befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.format = *cformat |
427befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
428befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.width = rhs->w;
429befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.height = rhs->h;
430befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        int aligned_width = ALIGN(surfaceDef.width,32);
431befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;
432befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
433befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType, &surfaceDef)) {
434befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__);
435befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            goto error;
436befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            status = COPYBIT_FAILURE;
437befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
438befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
439befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        C2D_YUV_SURFACE_DEF surfaceDef;
440befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memset(&surfaceDef, 0, sizeof(surfaceDef));
441befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS);
442befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.format = *cformat;
443befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
444befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        bufferInfo info;
445befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.width = rhs->w;
446befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.height = rhs->h;
447befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.format = rhs->format;
448befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
4495aa9f9bebbb02ccfe9b6a4e5a092c8bd324e0e88Naseer Ahmed        yuvPlaneInfo yuvInfo = {0};
450befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = calculate_yuv_offset_and_stride(info, yuvInfo);
451befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(status != COPYBIT_SUCCESS) {
452befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
453befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            goto error;
454befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
455befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
456befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.width = rhs->w;
457befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.height = rhs->h;
458befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.plane0 = (void*) (handle->base);
459befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.phys0 = (void*) (handle->gpuaddr);
460befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride0 = yuvInfo.yStride;
461befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
462befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
463befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.phys1 = (void*) (handle->gpuaddr + yuvInfo.plane1_offset);
464befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride1 = yuvInfo.plane1_stride;
465befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (3 == get_num_planes(rhs->format)) {
466befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset);
467befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            surfaceDef.phys2 = (void*) (handle->gpuaddr + yuvInfo.plane2_offset);
468befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            surfaceDef.stride2 = yuvInfo.plane2_stride;
469befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
470befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
471befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
472befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                  &surfaceDef)) {
473befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__);
474befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            goto error;
475befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            status = COPYBIT_FAILURE;
476befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
477befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
478befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
479befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        goto error;
480befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = COPYBIT_FAILURE;
481befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
482befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
483befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
484befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
485befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmederror:
486befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(*mapped == 1) {
487befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
488befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        handle->gpuaddr = 0;
489befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        *mapped = 0;
490befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
491befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
492befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
493befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
494befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int set_src_image( uint32 *surfaceId, const struct copybit_image_t *rhs,
495befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                          int *cformat, uint32 *mapped)
496befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
497befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
498befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *cformat  = get_format(rhs->format);
499befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_SURFACE_TYPE surfaceType;
500befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    uint32 gpuaddr = (uint32)handle->gpuaddr;
501befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = COPYBIT_SUCCESS;
502befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
503befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (handle->gpuaddr == 0)
504befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    {
505befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        handle->gpuaddr = c2d_get_gpuaddr( handle);
506befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(!handle->gpuaddr)
507befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
508befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
509befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        *mapped = 1;
510befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
511befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
512befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* create C2D surface */
513befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
514befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        /* RGB */
515befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        C2D_RGB_SURFACE_DEF surfaceDef;
516befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY);
517befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
518befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.phys = (void*) handle->gpuaddr;
519befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.buffer = (void*) (handle->base);
520befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.buffer = (void*) (handle->base + handle->offset);
521befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
522befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.format = get_format(rhs->format);
523befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.width = rhs->w;
524befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.height = rhs->h;
525befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride = ALIGN(((surfaceDef.width * c2diGetBpp(surfaceDef.format))>>3), 32);
526befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
527befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(LINK_c2dCreateSurface( surfaceId, C2D_TARGET, surfaceType,(void*)&surfaceDef)) {
528befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: LINK_c2dCreateSurface error", __FUNCTION__);
529befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            status = COPYBIT_FAILURE;
530befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            goto error;
531befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
532befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if(is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
533befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        /* YUV */
534befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        C2D_YUV_SURFACE_DEF surfaceDef;
535befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        int offset = 0;
536befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        int yStride = 0;
537befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        int uvStride = 0;
538befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memset(&surfaceDef, 0, sizeof(surfaceDef));
539befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
540befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY);
541befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.format = get_format(rhs->format);
542befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        bufferInfo info;
543befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.width = rhs->w;
544befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.height = rhs->h;
545befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.format = rhs->format;
546befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
547befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        yuvPlaneInfo yuvInfo;
548befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = calculate_yuv_offset_and_stride(info, yuvInfo);
549befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(status != COPYBIT_SUCCESS) {
550befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
551befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            goto error;
552befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
553befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
554befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.width = rhs->w;
555befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.height = rhs->h;
556befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.plane0 = (void*) (handle->base);
557befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.phys0 = (void*) handle->gpuaddr;
558befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride0 = yuvInfo.yStride;
559befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
560befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
561befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.phys1 = (void*) (handle->gpuaddr + yuvInfo.plane1_offset);
562befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride1 = yuvInfo.plane1_stride;
563befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
564befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(LINK_c2dCreateSurface( surfaceId, C2D_TARGET | C2D_SOURCE, surfaceType,
565befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                  (void*)&surfaceDef)) {
566befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: YUV surface LINK_c2dCreateSurface error", __func__);
567befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            status = COPYBIT_FAILURE;
568befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            goto error;
569befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
570befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
571befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: Invalid format 0x%x", __FUNCTION__, rhs->format);
572befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = COPYBIT_FAILURE;
573befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
574befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
575befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return COPYBIT_SUCCESS;
576befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
577befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmederror:
578befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(*mapped == 1) {
579befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
580befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        handle->gpuaddr = 0;
581befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        *mapped = 0;
582befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
583befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
584befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
585befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
586befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedvoid unset_image( uint32 surfaceId, const struct copybit_image_t *rhs,
587befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                  uint32 mmapped)
588befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
589befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
590befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
591befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (mmapped && handle->gpuaddr) {
592befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // Unmap this gpuaddr
593befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
594befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        handle->gpuaddr = 0;
595befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
596befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
597befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
598befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int blit_to_target( uint32 surfaceId, const struct copybit_image_t *rhs)
599befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
600befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
601befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    uint32 cformat  = get_format(rhs->format);
602befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_SURFACE_TYPE surfaceType;
603befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    uint32 memoryMapped = 0;
604befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = COPYBIT_SUCCESS;
605befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
606befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!handle->gpuaddr) {
607befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        handle->gpuaddr = c2d_get_gpuaddr(handle);
608befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(!handle->gpuaddr)
609befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
610befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
611befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memoryMapped = 1;
612befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
613befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
614befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* create C2D surface */
615befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
616befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(cformat) {
617befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        /* RGB */
618befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        C2D_RGB_SURFACE_DEF surfaceDef;
619befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memset(&surfaceDef, 0, sizeof(surfaceDef));
620befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
621befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.buffer = (void*) handle->base;
622befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.phys = (void*) handle->gpuaddr;
623befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
624befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceType = C2D_SURFACE_RGB_HOST;
625befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.format = get_format(rhs->format);
626befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.width = rhs->w;
627befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.height = rhs->h;
628befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride = ALIGN(((surfaceDef.width * c2diGetBpp(surfaceDef.format))>>3), 32);
629befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
630befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(LINK_c2dReadSurface(surfaceId, surfaceType, (void*)&surfaceDef, 0, 0)) {
631befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: LINK_c2dReadSurface ERROR", __func__);
632befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            status = COPYBIT_FAILURE;
633befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            goto done;
634befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
635befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
636befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    else {
637befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        /* YUV */
638befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        /* TODO */
639befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
640befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
641befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmeddone:
642befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (memoryMapped) {
643befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        LINK_c2dUnMapAddr( (void*) handle->gpuaddr);
644befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        handle->gpuaddr = 0;
645befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
646befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
647befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
648befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
649befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** setup rectangles */
650befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void set_rects(struct copybit_context_t *ctx,
651befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      C2D_OBJECT *c2dObject,
652befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      const struct copybit_rect_t *dst,
653befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      const struct copybit_rect_t *src,
654befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      const struct copybit_rect_t *scissor)
655befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
656befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Set the target rect.
657befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if((ctx->trg_transform & C2D_TARGET_ROTATE_90) &&
658befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed       (ctx->trg_transform & C2D_TARGET_ROTATE_180)) {
659befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        /* target rotation is 270 */
660befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = (dst->t)<<16;
661befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = ctx->fb_width?(ALIGN(ctx->fb_width,32)- dst->r):dst->r;
662befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
663befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
664befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
665befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) {
666befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
667befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
668befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = (dst->l)<<16;
669befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
670befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
671befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) {
672befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
673befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
674befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = ctx->fb_width?(ALIGN(ctx->fb_width,32) - dst->r):dst->r;
675befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
676befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
677befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
678befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
679befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = (dst->l)<<16;
680befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = (dst->t)<<16;
681befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
682befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
683befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
684befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->config_mask |= C2D_TARGET_RECT_BIT;
685befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
686befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Set the source rect
687befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.x        = (src->l)<<16;
688befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.y        = (src->t)<<16;
689befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.height   = ((src->b) - (src->t))<<16;
690befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.width    = ((src->r) - (src->l))<<16;
691befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->config_mask |= C2D_SOURCE_RECT_BIT;
692befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
693befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Set the scissor rect
694befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.x       = scissor->l;
695befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.y       = scissor->t;
696befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.height  = (scissor->b) - (scissor->t);
697befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.width   = (scissor->r) - (scissor->l);
698befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT;
699befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
700befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
701befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** copy the bits */
702befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int msm_copybit(struct copybit_context_t *dev, blitlist *list, uint32 target)
703befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
7045aa9f9bebbb02ccfe9b6a4e5a092c8bd324e0e88Naseer Ahmed    unsigned int objects;
705befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
706befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    for(objects = 0; objects < list->count; objects++) {
707befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        list->blitObjects[objects].next = &(list->blitObjects[objects+1]);
708befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
709befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
710befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(LINK_c2dDraw(target,dev->trg_transform, 0x0, 0, 0, list->blitObjects,
711befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    list->count)) {
712befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
713befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
714befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
715befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
716befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return COPYBIT_SUCCESS;
717befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
718befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
719befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*****************************************************************************/
720befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
721befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Set a parameter to value */
722befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int set_parameter_copybit(
723befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t *dev,
724befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int name,
725befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int value)
726befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
727befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
728befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!ctx) {
729befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: null context", __FUNCTION__);
730befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
731befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
732befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
733befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(name) {
734befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_ROTATION_DEG:
735befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->blitState.rotation = value<<16;
736befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            /* SRC rotation */
737befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if(!value)
738befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ctx->blitState.config_mask &=~C2D_ROTATE_BIT;;
739befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
740befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_PLANE_ALPHA:
741befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (value < 0)      value = 0;
742befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (value >= 256)   value = 255;
743befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
744befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->blitState.global_alpha = value;
745befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
746befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if(ctx->blitState.global_alpha<255)
747befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ctx->blitState.config_mask |= C2D_GLOBAL_ALPHA_BIT;
748befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            else
749befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ctx->blitState.config_mask &=~C2D_GLOBAL_ALPHA_BIT;
750befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
751befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_DITHER:
752befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            /* TODO */
753befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
754befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_BLUR:
755befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            /* TODO */
756befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
757befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_TRANSFORM:
758befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->blitState.config_mask &=~C2D_ROTATE_BIT;
759befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->blitState.config_mask &=~C2D_MIRROR_H_BIT;
760befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->blitState.config_mask &=~C2D_MIRROR_V_BIT;
761befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->trg_transform = C2D_TARGET_ROTATE_0;
762befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
763befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if((value&0x7) == COPYBIT_TRANSFORM_ROT_180)
764befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ctx->trg_transform = C2D_TARGET_ROTATE_180;
765befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            else if((value&0x7) == COPYBIT_TRANSFORM_ROT_270)
766befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ctx->trg_transform = C2D_TARGET_ROTATE_90;
767befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            else {
768befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                if(value&COPYBIT_TRANSFORM_FLIP_H)
769befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    ctx->blitState.config_mask |= C2D_MIRROR_H_BIT;
770befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                if(value&COPYBIT_TRANSFORM_FLIP_V)
771befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    ctx->blitState.config_mask |= C2D_MIRROR_V_BIT;
772befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                if(value&COPYBIT_TRANSFORM_ROT_90)
773befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    ctx->trg_transform = C2D_TARGET_ROTATE_270;
774befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            }
775befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
776befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_PREMULTIPLIED_ALPHA:
777befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            (value == COPYBIT_ENABLE) ? ctx->isPremultipliedAlpha = true :
778befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ctx->isPremultipliedAlpha = false;
779befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
780befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_FRAMEBUFFER_WIDTH:
781befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->fb_width = value;
782befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
783befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_FRAMEBUFFER_HEIGHT:
784befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->fb_height = value;
785befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
786e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed        case COPYBIT_BLIT_TO_FRAMEBUFFER:
787e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed            if (COPYBIT_ENABLE == value) {
788e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed                ctx->mBlitToFB = value;
789e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed            } else if (COPYBIT_DISABLE == value) {
790e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed                ctx->mBlitToFB = value;
791e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed            } else {
792e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed              ALOGE ("%s:Invalid input for COPYBIT_BLIT_TO_FRAMEBUFFER : %d",
793e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed                                                         __FUNCTION__, value);
794e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed            }
795e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed            break;
796befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
797befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
798befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return -EINVAL;
799befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
800befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
801befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
802befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return COPYBIT_SUCCESS;
803befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
804befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
805befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Get a static info value */
806befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get(struct copybit_device_t *dev, int name)
807befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
808befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
809befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int value;
810befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
811befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!ctx) {
812befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: null context error", __FUNCTION__);
813befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
814befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
815befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
816befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(name) {
817befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_MINIFICATION_LIMIT:
818befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = MAX_SCALE_FACTOR;
819befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
820befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_MAGNIFICATION_LIMIT:
821befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = MAX_SCALE_FACTOR;
822befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
823befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_SCALING_FRAC_BITS:
824befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = 32;
825befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
826befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_ROTATION_STEP_DEG:
827befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = 1;
828befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
829befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
830befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
831befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = -EINVAL;
832befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
833befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return value;
834befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
835befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
836befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_alpha(int cformat)
837befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
838befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int alpha = 0;
839befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (cformat & 0xFF) {
840befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_ARGB:
841befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_RGBA:
842befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_5551_RGBA:
843befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4444_ARGB:
844befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            alpha = 1;
845befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
846befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
847befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            alpha = 0;
848befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
849befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
850befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
851befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(alpha && (cformat&C2D_FORMAT_DISABLE_ALPHA))
852befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        alpha = 0;
853befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
854befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return alpha;
855befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
856befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
857befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to check if we need a temporary buffer for the blit.
858befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * This would happen if the requested destination stride and the
859befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * C2D stride do not match. We ignore RGB buffers, since their
860befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * stride is always aligned to 32.
861befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
862befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic bool need_temp_buffer(struct copybit_image_t const *img)
863befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
864befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format))
865befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return false;
866befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
867befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct private_handle_t* handle = (struct private_handle_t*)img->handle;
868befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
869befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // The width parameter in the handle contains the aligned_w. We check if we
870befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // need to convert based on this param. YUV formats have bpp=1, so checking
871befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // if the requested stride is aligned should suffice.
872befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (0 == (handle->width)%32) {
873befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return false;
874befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
875befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
876befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return true;
877befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
878befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
879befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to extract the information from the copybit image and set the corresponding
880befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * values in the bufferInfo struct.
881befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
882befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info)
883befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
884befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    info.width = img->w;
885befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    info.height = img->h;
886befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    info.format = img->format;
887befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
888befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
889befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to get the required size for a particular format, inorder for C2D to perform
890befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * the blit operation.
891befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
892befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic size_t get_size(const bufferInfo& info)
893befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
894befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    size_t size = 0;
895befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int w = info.width;
896befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int h = info.height;
897befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int aligned_w = ALIGN(w, 32);
898befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(info.format) {
899befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
900befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            {
901befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                // Chroma for this format is aligned to 2K.
902befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                size = ALIGN((aligned_w*h), 2048) +
903befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    ALIGN(w/2, 32) * h/2 *2;
904befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                size = ALIGN(size, 4096);
905befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } break;
906befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
907befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
908befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            {
909befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                size = aligned_w*h +
910befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    ALIGN(w/2, 32) * h/2 *2;
911befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                size = ALIGN(size, 4096);
912befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } break;
913befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default: break;
914befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
915befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return size;
916befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
917befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
918befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to allocate memory for the temporary buffer. This memory is
919befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * allocated from Ashmem. It is the caller's responsibility to free this
920befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * memory.
921befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
922befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_temp_buffer(const bufferInfo& info, alloc_data& data)
923befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
924befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ALOGD("%s E", __FUNCTION__);
925befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Alloc memory from system heap
926befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.base = 0;
927befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.fd = -1;
928befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.offset = 0;
929befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.size = get_size(info);
930befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.align = getpagesize();
931befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.uncached = true;
932befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int allocFlags = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
933befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
934befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (sAlloc == 0) {
935be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        sAlloc = gralloc::IAllocController::getInstance();
936befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
937befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
938befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (sAlloc == 0) {
939befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: sAlloc is still NULL", __FUNCTION__);
940befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
941befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
942befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
943be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed    int err = sAlloc->allocate(data, allocFlags);
944befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (0 != err) {
945befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: allocate failed", __FUNCTION__);
946befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
947befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
948befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
949befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ALOGD("%s X", __FUNCTION__);
950befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return err;
951befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
952befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
953befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to free the temporary allocated memory.*/
954befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void free_temp_buffer(alloc_data &data)
955befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
956befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (-1 != data.fd) {
957be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType);
958befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memalloc->free_buffer(data.base, data.size, 0, data.fd);
959befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
960befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
961befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
962befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to perform the software color conversion. Convert the
963befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * C2D compatible format to the Android compatible format
964befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
965befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int copy_image(private_handle_t *src_handle,
966befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      struct copybit_image_t const *rhs,
967befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      eConversionType conversionType)
968befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
969befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (src_handle->fd == -1) {
970befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: src_handle fd is invalid", __FUNCTION__);
971befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
972befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
973befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
974befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Copy the info.
975befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int ret = COPYBIT_SUCCESS;
976befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(rhs->format) {
977befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
978befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
979befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
980befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            {
981befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                if (CONVERT_TO_ANDROID_FORMAT == conversionType) {
982befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    return convert_yuv_c2d_to_yuv_android(src_handle, rhs);
983befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                } else {
984befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    return convert_yuv_android_to_yuv_c2d(src_handle, rhs);
985befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                }
986befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
987befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } break;
988befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default: {
989befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
990befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ret = COPYBIT_FAILURE;
991befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } break;
992befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
993befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return ret;
994befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
995befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
996befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void delete_handle(private_handle_t *handle)
997befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
998befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (handle) {
999befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete handle;
1000befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        handle = 0;
1001befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1002befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1003befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** do a stretch blit type operation */
1004befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int stretch_copybit_internal(
1005befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t *dev,
1006befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *dst,
1007befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *src,
1008befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t const *dst_rect,
1009befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t const *src_rect,
1010befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_region_t const *region,
1011befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    bool enableBlend)
1012befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1013befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1014befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = COPYBIT_SUCCESS;
1015befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    uint32 maxCount;
1016befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    uint32 src_mapped = 0, trg_mapped = 0;
1017befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    blitlist list;
1018befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_OBJECT *req;
1019befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    memset(&list, 0, sizeof(list));
1020befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int cformat;
1021befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2d_ts_handle timestamp;
1022befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    uint32 src_surface_index = 0, dst_surface_index = 0;
1023befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1024befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!ctx) {
1025befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: null context error", __FUNCTION__);
1026befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
1027befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1028befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1029befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
1030befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: src dimension error", __FUNCTION__);
1031befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
1032befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1033befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1034befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
1035befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s : dst dimension error dst w %d h %d",  __FUNCTION__, dst->w, dst->h);
1036befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
1037befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1038befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1039befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    maxCount = sizeof(list.blitObjects)/sizeof(C2D_OBJECT);
1040befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1041befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t clip;
1042befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    list.count = 0;
1043befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1044befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) {
1045befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__, dst->format);
1046befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1047befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1048befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1049befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    bool isYUVDestination = false;
1050befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
1051befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_surface_index = RGB_SURFACE;
1052befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) {
1053befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        isYUVDestination = true;
1054befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        int num_planes = get_num_planes(dst->format);
1055befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (num_planes == 2) {
1056befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            dst_surface_index = YUV_SURFACE_2_PLANES;
1057befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } else if (num_planes == 3) {
1058befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            dst_surface_index = YUV_SURFACE_3_PLANES;
1059befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } else {
1060befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x",
1061befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                  __FUNCTION__, dst->format);
1062befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
1063befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1064befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
1065befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__, dst->format);
1066befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1067befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1068befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1069befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    copybit_image_t dst_image;
1070befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    dst_image.w = dst->w;
1071befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    dst_image.h = dst->h;
1072befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    dst_image.format = dst->format;
1073befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    dst_image.handle = dst->handle;
1074befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Check if we need a temp. copy for the destination. We'd need this the destination
1075befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // width is not aligned to 32. This case occurs for YUV formats. RGB formats are
1076befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // aligned to 32.
1077befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    bool needTempDestination = need_temp_buffer(dst);
1078befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    bufferInfo dst_info;
1079befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    populate_buffer_info(dst, dst_info);
1080befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format,
1081befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                     dst_info.width, dst_info.height);
1082befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (dst_hnd == NULL) {
1083befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: dst_hnd is null", __FUNCTION__);
1084befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1085befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1086befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (needTempDestination) {
1087befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (get_size(dst_info) != ctx->temp_dst_buffer.size) {
1088befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            free_temp_buffer(ctx->temp_dst_buffer);
1089befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            // Create a temp buffer and set that as the destination.
1090befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) {
1091befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ALOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__);
1092befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                delete_handle(dst_hnd);
1093befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                return COPYBIT_FAILURE;
1094befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            }
1095befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1096befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->fd = ctx->temp_dst_buffer.fd;
1097befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->size = ctx->temp_dst_buffer.size;
1098befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->flags = ctx->temp_dst_buffer.allocType;
1099befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->base = (int)(ctx->temp_dst_buffer.base);
1100befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->offset = ctx->temp_dst_buffer.offset;
1101befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->gpuaddr = 0;
1102befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_image.handle = dst_hnd;
1103befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1104befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1105befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int flags = 0;
1106befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    flags |= (ctx->isPremultipliedAlpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
1107befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    flags |= (isYUVDestination) ? FLAGS_YUV_DESTINATION : 0;
1108befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1109befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    status = set_image( ctx->dst[dst_surface_index], &dst_image,
1110befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                        &cformat, &trg_mapped, (eC2DFlags)flags);
1111befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(status) {
1112befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: dst: set_image error", __FUNCTION__);
1113befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete_handle(dst_hnd);
1114befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1115befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1116befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1117befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) {
1118befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_surface_index = RGB_SURFACE;
1119befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) {
1120befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        int num_planes = get_num_planes(src->format);
1121befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (num_planes == 2) {
1122befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            src_surface_index = YUV_SURFACE_2_PLANES;
1123befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } else if (num_planes == 3) {
1124befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            src_surface_index = YUV_SURFACE_3_PLANES;
1125befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } else {
1126befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: src number of YUV planes is invalid src format = 0x%x",
1127befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                  __FUNCTION__, src->format);
1128befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            delete_handle(dst_hnd);
1129befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return -EINVAL;
1130befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1131befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
1132befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__, src->format);
1133befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete_handle(dst_hnd);
1134befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
1135befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1136befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1137befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    copybit_image_t src_image;
1138befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    src_image.w = src->w;
1139befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    src_image.h = src->h;
1140befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    src_image.format = src->format;
1141befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    src_image.handle = src->handle;
1142befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1143befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    bool needTempSource = need_temp_buffer(src);
1144befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    bufferInfo src_info;
1145befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    populate_buffer_info(src, src_info);
1146befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format,
1147befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                     src_info.width, src_info.height);
1148befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (NULL == src_hnd) {
1149befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: src_hnd is null", __FUNCTION__);
1150befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete_handle(dst_hnd);
1151befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1152befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1153befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (needTempSource) {
1154befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (get_size(src_info) != ctx->temp_src_buffer.size) {
1155befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            free_temp_buffer(ctx->temp_src_buffer);
1156befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            // Create a temp buffer and set that as the destination.
1157befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (COPYBIT_SUCCESS != get_temp_buffer(src_info, ctx->temp_src_buffer)) {
1158befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__);
1159befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                delete_handle(dst_hnd);
1160befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                delete_handle(src_hnd);
1161befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                return COPYBIT_FAILURE;
1162befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            }
1163befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1164befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->fd = ctx->temp_src_buffer.fd;
1165befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->size = ctx->temp_src_buffer.size;
1166befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->flags = ctx->temp_src_buffer.allocType;
1167befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->base = (int)(ctx->temp_src_buffer.base);
1168befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->offset = ctx->temp_src_buffer.offset;
1169befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->gpuaddr = 0;
1170befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_image.handle = src_hnd;
1171befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1172befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // Copy the source.
1173befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        copy_image((private_handle_t *)src->handle, &src_image, CONVERT_TO_C2D_FORMAT);
1174befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1175befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // Flush the cache
1176be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
1177befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
1178befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                   src_hnd->offset, src_hnd->fd)) {
1179befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: clean_buffer failed", __FUNCTION__);
1180befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            delete_handle(dst_hnd);
1181befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            delete_handle(src_hnd);
1182befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
1183befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1184befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1185befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1186befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    status = set_image( ctx->src[src_surface_index], &src_image,
1187befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                        &cformat, &src_mapped, (eC2DFlags)flags);
1188befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(status) {
1189befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: set_src_image error", __FUNCTION__);
1190befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete_handle(dst_hnd);
1191befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete_handle(src_hnd);
1192befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1193befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1194befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1195befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (enableBlend) {
1196befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(ctx->blitState.config_mask & C2D_GLOBAL_ALPHA_BIT) {
1197befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->blitState.config_mask &= ~C2D_ALPHA_BLEND_NONE;
1198befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if(!(ctx->blitState.global_alpha)) {
1199befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                // src alpha is zero
1200befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                unset_image( ctx->src[src_surface_index],
1201befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                             &src_image, src_mapped);
1202befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                unset_image( ctx->dst[dst_surface_index],
1203befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                             &dst_image, trg_mapped);
1204befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                delete_handle(dst_hnd);
1205befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                delete_handle(src_hnd);
1206befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                return status;
1207befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            }
1208befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } else {
1209befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if(is_alpha(cformat))
1210befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ctx->blitState.config_mask &= ~C2D_ALPHA_BLEND_NONE;
1211befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            else
1212befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ctx->blitState.config_mask |= C2D_ALPHA_BLEND_NONE;
1213befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1214befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
1215befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ctx->blitState.config_mask |= C2D_ALPHA_BLEND_NONE;
1216befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1217befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1218befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->blitState.surface_id = ctx->src[src_surface_index];
1219befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1220befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    while ((status == 0) && region->next(region, &clip)) {
1221befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        req = &(list.blitObjects[list.count]);
1222befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memcpy(req,&ctx->blitState,sizeof(C2D_OBJECT));
1223befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1224befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        set_rects(ctx, req, dst_rect, src_rect, &clip);
1225befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1226befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (++list.count == maxCount) {
1227befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            status = msm_copybit(ctx, &list, ctx->dst[dst_surface_index]);
1228befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            list.count = 0;
1229befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1230befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1231befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if ((status == 0) && list.count) {
1232befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = msm_copybit(ctx, &list, ctx->dst[dst_surface_index]);
1233befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1234befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1235befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(LINK_c2dFinish(ctx->dst[dst_surface_index])) {
1236befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
1237befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1238befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1239befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    unset_image( ctx->src[src_surface_index], &src_image,
1240befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                 src_mapped);
1241befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    unset_image( ctx->dst[dst_surface_index], &dst_image,
1242befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                 trg_mapped);
1243befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (needTempDestination) {
1244befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // copy the temp. destination without the alignment to the actual destination.
1245befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
1246befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // Invalidate the cache.
1247be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
1248befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
1249befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                               dst_hnd->offset, dst_hnd->fd);
1250befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1251befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    delete_handle(dst_hnd);
1252befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    delete_handle(src_hnd);
1253befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->isPremultipliedAlpha = false;
1254befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->fb_width = 0;
1255befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->fb_height = 0;
1256befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
1257befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1258befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1259befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int stretch_copybit(
1260befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t *dev,
1261befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *dst,
1262befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *src,
1263befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t const *dst_rect,
1264befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t const *src_rect,
1265befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_region_t const *region)
1266befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1267befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1268befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    bool needsBlending = (ctx->blitState.global_alpha != 0);
1269befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
1270befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                    region, needsBlending);
1271befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1272befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1273befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Perform a blit type operation */
1274befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int blit_copybit(
1275befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t *dev,
1276befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *dst,
1277befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *src,
1278befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_region_t const *region)
1279befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1280befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t dr = { 0, 0, dst->w, dst->h };
1281befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t sr = { 0, 0, src->w, src->h };
1282befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false);
1283befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1284befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1285befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*****************************************************************************/
1286befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1287befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Close the copybit device */
1288befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int close_copybit(struct hw_device_t *dev)
1289befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1290befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1291befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (ctx) {
1292befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        for(int i = 0; i <NUM_SURFACES; i++) {
1293befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            LINK_c2dDestroySurface(ctx->dst[i]);
1294befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            LINK_c2dDestroySurface(ctx->src[i]);
1295befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1296befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1297befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (ctx->libc2d2) {
1298befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ::dlclose(ctx->libc2d2);
1299befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGV("dlclose(libc2d2)");
1300befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1301befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1302befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        free_temp_buffer(ctx->temp_src_buffer);
1303befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        free_temp_buffer(ctx->temp_dst_buffer);
1304befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        free(ctx);
1305befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1306befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1307befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return 0;
1308befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1309befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1310befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Open a new instance of a copybit device using name */
1311befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
1312befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                        struct hw_device_t** device)
1313befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1314befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = COPYBIT_SUCCESS;
1315befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_RGB_SURFACE_DEF surfDefinition = {0};
1316befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
1317befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t *ctx;
1318befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    char fbName[64];
1319befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1320befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
1321befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!ctx) {
1322befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: malloc failed", __FUNCTION__);
1323befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1324befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1325befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1326befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* initialize drawstate */
1327befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    memset(ctx, 0, sizeof(*ctx));
1328befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1329befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    for (int i=0; i< NUM_SURFACES; i++) {
1330befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ctx->dst[i] = -1;
1331befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ctx->src[i] = -1;
1332befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1333befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1334befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
1335befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!ctx->libc2d2) {
1336befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
1337befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        goto error;
1338befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1339befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2,
1340befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                               "c2dCreateSurface");
1341befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2,
1342befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                               "c2dUpdateSurface");
1343befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2,
1344befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                             "c2dReadSurface");
1345befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw");
1346befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush");
1347befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish");
1348befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2,
1349befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                               "c2dWaitTimestamp");
1350befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2,
1351befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                "c2dDestroySurface");
1352befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2,
1353befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                         "c2dMapAddr");
1354befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2,
1355befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                           "c2dUnMapAddr");
1356befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1357befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
1358befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp || !LINK_c2dFinish
1359befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        || !LINK_c2dDestroySurface) {
1360befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: dlsym ERROR", __FUNCTION__);
1361befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        goto error;
1362befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1363befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1364befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
1365befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.version = 1;
1366befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.module = (hw_module_t*)(module);
1367befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.close = close_copybit;
1368befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.set_parameter = set_parameter_copybit;
1369befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.get = get;
1370befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.blit = blit_copybit;
1371befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.stretch = stretch_copybit;
1372befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->blitState.config_mask = C2D_NO_BILINEAR_BIT | C2D_NO_ANTIALIASING_BIT;
1373befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->trg_transform = C2D_TARGET_ROTATE_0;
1374befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1375befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* Create RGB Surface */
1376befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.buffer = (void*)0xdddddddd;
1377befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.phys = (void*)0xdddddddd;
1378befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.stride = 1 * 4;
1379befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.width = 1;
1380befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.height = 1;
1381befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB;
1382befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
1383befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
1384befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                 C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY ), &surfDefinition)) {
1385befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: create ctx->dst[RGB_SURFACE] failed", __FUNCTION__);
1386befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ctx->dst[RGB_SURFACE] = -1;
1387befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        goto error;
1388befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1389befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1390befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1391befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (LINK_c2dCreateSurface(&(ctx->src[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
1392befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
1393befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                 C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY), &surfDefinition)) {
1394befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: create ctx->src[RGB_SURFACE] failed", __FUNCTION__);
1395befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ctx->src[RGB_SURFACE] = -1;
1396befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        goto error;
1397befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1398befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1399befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* Create YUV source surface */
1400befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
1401befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1402befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.width = 4;
1403befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.height = 4;
1404befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa;
1405befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa;
1406befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.stride0 = 4;
1407befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1408befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa;
1409befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa;
1410befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.stride1 = 4;
1411befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1412befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (LINK_c2dCreateSurface(&(ctx->src[YUV_SURFACE_2_PLANES]),
1413befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              C2D_TARGET | C2D_SOURCE,
1414befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST|C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY),
1415befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1416befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: create ctx->src[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
1417befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ctx->src[YUV_SURFACE_2_PLANES] = -1;
1418befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        goto error;
1419befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1420befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1421befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),
1422befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              C2D_TARGET | C2D_SOURCE,
1423befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY),
1424befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1425befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
1426befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ctx->dst[YUV_SURFACE_2_PLANES] = -1;
1427befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        goto error;
1428befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1429befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1430befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
1431befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
1432befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
1433befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.stride2 = 4;
1434befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1435befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (LINK_c2dCreateSurface(&(ctx->src[YUV_SURFACE_3_PLANES]),
1436befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              C2D_TARGET | C2D_SOURCE,
1437befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY),
1438befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1439befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: create ctx->src[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
1440befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ctx->src[YUV_SURFACE_3_PLANES] = -1;
1441befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        goto error;
1442befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1443befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1444befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),
1445befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              C2D_TARGET | C2D_SOURCE,
1446befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS | C2D_SURFACE_WITH_PHYS_DUMMY),
1447befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1448befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
1449befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ctx->dst[YUV_SURFACE_3_PLANES] = -1;
1450befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        goto error;
1451befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1452befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1453befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_src_buffer.fd = -1;
1454befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_src_buffer.base = 0;
1455befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_src_buffer.size = 0;
1456befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1457befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_dst_buffer.fd = -1;
1458befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_dst_buffer.base = 0;
1459befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_dst_buffer.size = 0;
1460befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1461befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->fb_width = 0;
1462befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->fb_height = 0;
1463befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->isPremultipliedAlpha = false;
1464befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1465befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *device = &ctx->device.common;
1466befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
1467befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1468befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmederror:
1469befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    for (int i = 0; i<NUM_SURFACES; i++) {
1470befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (-1 != (ctx->src[i])) {
1471befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            LINK_c2dDestroySurface(ctx->src[i]);
1472befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->src[i] = -1;
1473befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1474befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (-1 != (ctx->dst[i])) {
1475befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            LINK_c2dDestroySurface(ctx->dst[i]);
1476befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->dst[i] = -1;
1477befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1478befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1479befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (ctx->libc2d2)
1480befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ::dlclose(ctx->libc2d2);
1481befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (ctx)
1482befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        free(ctx);
1483befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    status = COPYBIT_FAILURE;
1484befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *device = NULL;
1485befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1486befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
1487befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1488