copybit_c2d.cpp revision 7ec65cb986e25337bf4066437300f6adbfe1e350
1befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*
2befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Copyright (C) 2008 The Android Open Source Project
3728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
4728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R *
5728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R * Not a Contribution, Apache license notifications and license are retained
6728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R * for attribution purposes only.
7befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
8befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
9befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * you may not use this file except in compliance with the License.
10befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * You may obtain a copy of the License at
11befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
12befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
13befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *
14befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Unless required by applicable law or agreed to in writing, software
15befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
16befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * See the License for the specific language governing permissions and
18befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * limitations under the License.
19befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
20befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/log.h>
211cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R#include <sys/resource.h>
221cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R#include <sys/prctl.h>
23befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
24befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <stdint.h>
25befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <string.h>
26befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <unistd.h>
27befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <errno.h>
28befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <fcntl.h>
29befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
30befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <sys/ioctl.h>
31befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <sys/types.h>
32befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <sys/mman.h>
33befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
34befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <linux/msm_kgsl.h>
35befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
36befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <EGL/eglplatform.h>
37befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/native_handle.h>
38befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <cutils/ashmem.h>
39befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <linux/ashmem.h>
40befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <gralloc_priv.h>
41befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
42befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <copybit.h>
43befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <alloc_controller.h>
44befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <memalloc.h>
45befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
46befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include "c2d2.h"
47befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include "software_converter.h"
48befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
49befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <dlfcn.h>
50befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
51befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing gralloc::IMemAlloc;
52befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing gralloc::IonController;
53befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing gralloc::alloc_data;
54befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
55befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
56befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     uint32 surface_bits,
57befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     C2D_SURFACE_TYPE surface_type,
58befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     void *surface_definition );
59befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
60befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id,
61befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     uint32 surface_bits,
62befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     C2D_SURFACE_TYPE surface_type,
63befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     void *surface_definition );
64befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
65befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id,
66befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                   C2D_SURFACE_TYPE surface_type,
67befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                   void *surface_definition,
68befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                   int32 x, int32 y );
69befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
70befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dDraw)( uint32 target_id,
71befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                            uint32 target_config, C2D_RECT *target_scissor,
72befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                            uint32 target_mask_id, uint32 target_color_key,
73befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                            C2D_OBJECT *objects_list, uint32 num_objects );
74befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
75befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dFinish)( uint32 target_id);
76befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
77befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp);
78befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
79befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp );
80befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
81befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
82befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
83728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.RC2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, uint32 len,
84728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                uint32 offset, uint32 flags, void ** gpuaddr);
85befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
86befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
87befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
88728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.RC2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info);
891cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
901cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R/* create a fence fd for the timestamp */
911cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.RC2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
921cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                                                            int32 *fd);
93347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed
94347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer AhmedC2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color,
95347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed                                    C2D_RECT * fill_rect);
96347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed
97befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/******************************************************************************/
98befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
99befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#if defined(COPYBIT_Z180)
100befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#define MAX_SCALE_FACTOR    (4096)
101befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#define MAX_DIMENSION       (4096)
102befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#else
103befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#error "Unsupported HW version"
104befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#endif
105befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
106728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R// The following defines can be changed as required i.e. as we encounter
107728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R// complex use cases.
108ae2425e753369c4940288e280d4e743ca8227c19Sushil Chauhan#define MAX_RGB_SURFACES 32       // Max. RGB layers currently supported per draw
109728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R#define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw
110728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R#define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw
111728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R// +1 for the destination surface. We cannot have multiple destination surfaces.
112728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R#define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1)
113728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R#define NUM_SURFACE_TYPES 3      // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES
114728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R#define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw
115befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
116befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedenum {
117befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    RGB_SURFACE,
118befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    YUV_SURFACE_2_PLANES,
119befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    YUV_SURFACE_3_PLANES
120befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
121befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
122befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedenum eConversionType {
123befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    CONVERT_TO_ANDROID_FORMAT,
124befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    CONVERT_TO_C2D_FORMAT
125befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
126befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
127befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedenum eC2DFlags {
128728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    FLAGS_PREMULTIPLIED_ALPHA  = 1<<0,
129728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    FLAGS_YUV_DESTINATION      = 1<<1,
130728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    FLAGS_TEMP_SRC_DST         = 1<<2
131befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
132befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
133be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmedstatic gralloc::IAllocController* sAlloc = 0;
134befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/******************************************************************************/
135befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
136befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** State information for each device instance */
137befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct copybit_context_t {
138befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t device;
139728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Templates for the various source surfaces. These templates are created
140728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // to avoid the expensive create/destroy C2D Surfaces
141728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES];
142728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES];
143728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES];
144728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects
145728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    C2D_DRIVER_INFO c2d_driver_info;
146befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    void *libc2d2;
147befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    alloc_data temp_src_buffer;
148befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    alloc_data temp_dst_buffer;
149728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces
150728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    unsigned int mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
151728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int blit_rgb_count;         // Total RGB surfaces being blit
152728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being
153728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int blit_yuv_3_plane_count; // Total 3 plane YUV  surfaces being blit
154728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int blit_count;             // Total blit objects.
155728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    unsigned int trg_transform;      /* target transform */
156befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int fb_width;
157befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int fb_height;
158728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int src_global_alpha;
159728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int config_mask;
160728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int dst_surface_type;
161728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    bool is_premultiplied_alpha;
1621cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    void* time_stamp;
163c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr
164c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    void* dst_surface_base; // Stores the dst surface addr
1651cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
1661cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    // used for signaling the wait thread
1671cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    bool wait_timestamp;
1681cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_t wait_thread_id;
1691cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    bool stop_thread;
1701cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_t wait_cleanup_lock;
1711cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_cond_t wait_cleanup_cond;
1721cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
173befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
174befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
175befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct bufferInfo {
176befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int width;
177befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int height;
178befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int format;
179befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
180befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
181befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct yuvPlaneInfo {
182befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int yStride;       //luma stride
183befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int plane1_stride;
184befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int plane2_stride;
185befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int plane1_offset;
186befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int plane2_offset;
187befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
188befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
189befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/**
190befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Common hardware methods
191befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
192befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
193befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
194befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                        struct hw_device_t** device);
195befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
196befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic struct hw_module_methods_t copybit_module_methods = {
197befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedopen:  open_copybit
198befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
199befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
200befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*
201befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * The COPYBIT Module
202befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
203befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct copybit_module_t HAL_MODULE_INFO_SYM = {
204befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedcommon: {
205befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedtag: HARDWARE_MODULE_TAG,
206befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     version_major: 1,
207befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     version_minor: 0,
208befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     id: COPYBIT_HARDWARE_MODULE_ID,
209befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     name: "QCT COPYBIT C2D 2.0 Module",
210befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     author: "Qualcomm",
211befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     methods: &copybit_module_methods
212befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
213befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
214befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
215befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
2161cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R/* thread function which waits on the timeStamp and cleans up the surfaces */
2171cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.Rstatic void* c2d_wait_loop(void* ptr) {
2181cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    copybit_context_t* ctx = (copybit_context_t*)(ptr);
2191cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    char thread_name[64] = "copybitWaitThr";
2201cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
2211cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
2221cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
2231cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    while(ctx->stop_thread == false) {
2241cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        pthread_mutex_lock(&ctx->wait_cleanup_lock);
2251cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        while(ctx->wait_timestamp == false && !ctx->stop_thread) {
2261cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            pthread_cond_wait(&(ctx->wait_cleanup_cond),
2271cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                              &(ctx->wait_cleanup_lock));
2281cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        }
2291cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        if(ctx->wait_timestamp) {
2301cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            if(LINK_c2dWaitTimestamp(ctx->time_stamp)) {
2311cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__);
2321cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            }
2331cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            ctx->wait_timestamp = false;
2341cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            // Unmap any mapped addresses.
2351cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            for (int i = 0; i < MAX_SURFACES; i++) {
2361cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                if (ctx->mapped_gpu_addr[i]) {
2371cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                    LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
2381cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                    ctx->mapped_gpu_addr[i] = 0;
2391cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                }
2401cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            }
2411cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            // Reset the counts after the draw.
2421cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            ctx->blit_rgb_count = 0;
2431cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            ctx->blit_yuv_2_plane_count = 0;
2441cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            ctx->blit_yuv_3_plane_count = 0;
2451cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            ctx->blit_count = 0;
246c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            ctx->dst_surface_mapped = false;
247c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            ctx->dst_surface_base = 0;
2481cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        }
2491cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
2501cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        if(ctx->stop_thread)
2511cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            break;
2521cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    }
2531cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_exit(NULL);
2541cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    return NULL;
2551cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R}
2561cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
2571cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
258befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* convert COPYBIT_FORMAT to C2D format */
259befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_format(int format) {
260befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (format) {
261befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGB_565:        return C2D_COLOR_FORMAT_565_RGB;
262befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
263befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                              C2D_FORMAT_SWAP_RB |
264befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                  C2D_FORMAT_DISABLE_ALPHA;
265befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
266befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                              C2D_FORMAT_SWAP_RB;
267befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_BGRA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
268befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
269befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
270befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
271befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 |
272befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                  C2D_FORMAT_MACROTILED;
273728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        default:                              ALOGE("%s: invalid format (0x%x",
274728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                     __FUNCTION__, format);
275728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                              return -EINVAL;
276befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
277befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return -EINVAL;
278befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
279befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
280befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Get the C2D formats needed for conversion to YUV */
281befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_c2d_format_for_yuv_destination(int halFormat) {
282befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (halFormat) {
283befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // We do not swap the RB when the target is YUV
284befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
285befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                              C2D_FORMAT_DISABLE_ALPHA;
286befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
287728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        // The U and V need to be interchanged when the target is YUV
288befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
289befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21;
290befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
291befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:                              return get_format(halFormat);
292befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
293befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return -EINVAL;
294befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
295befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
296befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* ------------------------------------------------------------------- *//*!
297befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \internal
298befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \brief Get the bpp for a particular color format
299befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \param color format
300befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \return bits per pixel
301befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *//* ------------------------------------------------------------------- */
302befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedint c2diGetBpp(int32 colorformat)
303befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
304befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
305befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int c2dBpp = 0;
306befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
307befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(colorformat&0xFF)
308befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    {
309befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4444_RGBA:
310befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4444_ARGB:
311befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_1555_ARGB:
312befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_565_RGB:
313befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_5551_RGBA:
314befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 16;
315befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
316befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_RGBA:
317befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_ARGB:
318befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 32;
319befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
320befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8_L:
321befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8_A:
322befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 8;
323befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
324befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4_A:
325befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 4;
326befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
327befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_1:
328befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 1;
329befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
330befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
331befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s ERROR", __func__);
332befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
333befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
334befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return c2dBpp;
335befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
336befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
337c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.Rstatic uint32 c2d_get_gpuaddr(copybit_context_t* ctx,
338c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R                              struct private_handle_t *handle, int &mapped_idx)
339befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
340c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    uint32 memtype, *gpuaddr = 0;
341befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_STATUS rc;
342c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    int freeindex = 0;
343c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    bool mapaddr = false;
344befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
345befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!handle)
346befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return 0;
347befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
348befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (handle->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
349befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                         private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP))
350befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memtype = KGSL_USER_MEM_TYPE_PMEM;
351befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)
352befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memtype = KGSL_USER_MEM_TYPE_ASHMEM;
353befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
354befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memtype = KGSL_USER_MEM_TYPE_ION;
355befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    else {
356befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("Invalid handle flags: 0x%x", handle->flags);
357befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return 0;
358befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
359befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
360c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    // Check for a freeindex in the mapped_gpu_addr list
361c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    for (freeindex = 0; freeindex < MAX_SURFACES; freeindex++) {
362c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        if (ctx->mapped_gpu_addr[freeindex] == 0) {
363c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            // free index is available
364c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            // map GPU addr and use this as mapped_idx
365c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            mapaddr = true;
366c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            break;
367728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
368c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    }
369728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
370c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    if(mapaddr) {
371c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size,
372c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R                             handle->offset, memtype, (void**)&gpuaddr);
373c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R
374c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        if (rc == C2D_STATUS_OK) {
375c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            // We have mapped the GPU address inside copybit. We need to unmap
376c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            // this address after the blit. Store this address
377c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            ctx->mapped_gpu_addr[freeindex] = (uint32) gpuaddr;
378c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            mapped_idx = freeindex;
379c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        }
380befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
381c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    return (uint32) gpuaddr;
382befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
383befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
384728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.Rstatic void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx)
385728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R{
386728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (!ctx || (mapped_idx == -1))
387728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return;
388728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
389728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (ctx->mapped_gpu_addr[mapped_idx]) {
390728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]);
391728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->mapped_gpu_addr[mapped_idx] = 0;
392728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
393728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R}
394728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
395befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_supported_rgb_format(int format)
396befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
397befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(format) {
398befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:
399befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:
400befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGB_565:
4017ec65cb986e25337bf4066437300f6adbfe1e350Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888: {
402befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_SUCCESS;
403befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
404befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
405befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
406befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
407befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
408befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
409befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_num_planes(int format)
410befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
411befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(format) {
412befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
413befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
414befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
415befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
416befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return 2;
417befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
418befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YV12: {
419befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return 3;
420befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
421befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
422befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
423befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
424befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
425befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
426befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_supported_yuv_format(int format)
427befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
428befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(format) {
429befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
430befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
431befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
432befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
433befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_SUCCESS;
434befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
435befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
436befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
437befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
438befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
439befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
440befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_valid_destination_format(int format)
441befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
442befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
443befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // C2D does not support NV12Tile as a destination format.
444befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
445befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
446befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return COPYBIT_SUCCESS;
447befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
448befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
449befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int calculate_yuv_offset_and_stride(const bufferInfo& info,
450befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                           yuvPlaneInfo& yuvInfo)
451befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
452befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int width  = info.width;
453befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int height = info.height;
454befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int format = info.format;
455befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
456befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int aligned_height = 0;
457befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int aligned_width = 0, size = 0;
458befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
459befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (format) {
460befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
461befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            /* NV12 Tile buffers have their luma height aligned to 32bytes and width
462befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed             * aligned to 128 bytes. The chroma offset starts at an 8K boundary
463befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed             */
464befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            aligned_height = ALIGN(height, 32);
465befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            aligned_width  = ALIGN(width, 128);
466befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            size = aligned_width * aligned_height;
467befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.plane1_offset = ALIGN(size,8192);
468befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.yStride = aligned_width;
469befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.plane1_stride = aligned_width;
470befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
471befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
472befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
473befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
474befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
475befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            aligned_width = ALIGN(width, 32);
476befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.yStride = aligned_width;
477befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.plane1_stride = aligned_width;
478befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
479befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                // The encoder requires a 2K aligned chroma offset
480befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048);
481befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } else
482befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                yuvInfo.plane1_offset = aligned_width * height;
483befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
484befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
485befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
486befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default: {
487befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
488befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
489befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
490befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return COPYBIT_SUCCESS;
491befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
492befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
493befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** create C2D surface from copybit image */
494728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.Rstatic int set_image(copybit_context_t* ctx, uint32 surfaceId,
495728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                      const struct copybit_image_t *rhs,
496728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                      const eC2DFlags flags, int &mapped_idx)
497befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
498befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
499befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_SURFACE_TYPE surfaceType;
500befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = COPYBIT_SUCCESS;
501728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    uint32 gpuaddr = 0;
502728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int c2d_format;
503728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    mapped_idx = -1;
504befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
505befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (flags & FLAGS_YUV_DESTINATION) {
506728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        c2d_format = get_c2d_format_for_yuv_destination(rhs->format);
507befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
508728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        c2d_format = get_format(rhs->format);
509befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
510befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
511728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if(c2d_format == -EINVAL) {
512befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: invalid format", __FUNCTION__);
513befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
514befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
515befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
516befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(handle == NULL) {
517befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: invalid handle", __func__);
518befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
519befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
520befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
521befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (handle->gpuaddr == 0) {
522728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx);
523728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if(!gpuaddr) {
524befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
525befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
526befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
527728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    } else {
528728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        gpuaddr = handle->gpuaddr;
529befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
530befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
531befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* create C2D surface */
532befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
533befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        /* RGB */
534befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        C2D_RGB_SURFACE_DEF surfaceDef;
535befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
536befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS);
537befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
538728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        surfaceDef.phys = (void*) gpuaddr;
539befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.buffer = (void*) (handle->base);
540befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
541728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        surfaceDef.format = c2d_format |
542befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
543befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.width = rhs->w;
544befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.height = rhs->h;
545befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        int aligned_width = ALIGN(surfaceDef.width,32);
546befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;
547befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
548728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
549728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                  &surfaceDef)) {
550befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__);
551728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_idx);
552befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            status = COPYBIT_FAILURE;
553befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
554befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
555befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        C2D_YUV_SURFACE_DEF surfaceDef;
556befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memset(&surfaceDef, 0, sizeof(surfaceDef));
557befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS);
558728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        surfaceDef.format = c2d_format;
559befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
560befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        bufferInfo info;
561befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.width = rhs->w;
562befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.height = rhs->h;
563befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.format = rhs->format;
564befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
5655aa9f9bebbb02ccfe9b6a4e5a092c8bd324e0e88Naseer Ahmed        yuvPlaneInfo yuvInfo = {0};
566befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = calculate_yuv_offset_and_stride(info, yuvInfo);
567befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(status != COPYBIT_SUCCESS) {
568befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
569728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_idx);
570befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
571befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
572befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.width = rhs->w;
573befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.height = rhs->h;
574befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.plane0 = (void*) (handle->base);
575728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        surfaceDef.phys0 = (void*) (gpuaddr);
576befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride0 = yuvInfo.yStride;
577befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
578befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
579728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset);
580befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride1 = yuvInfo.plane1_stride;
581befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (3 == get_num_planes(rhs->format)) {
582befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset);
583728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset);
584befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            surfaceDef.stride2 = yuvInfo.plane2_stride;
585befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
586befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
587befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
588befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                  &surfaceDef)) {
589befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__);
590728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_idx);
591befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            status = COPYBIT_FAILURE;
592befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
593befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
594befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
595728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_idx);
596befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = COPYBIT_FAILURE;
597befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
598befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
599befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
600befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
601befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
602728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R/** copy the bits */
603728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.Rstatic int msm_copybit(struct copybit_context_t *ctx, unsigned int target)
604befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
605728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (ctx->blit_count == 0) {
606728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return COPYBIT_SUCCESS;
607728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
608befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
609728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < ctx->blit_count; i++)
610befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    {
611728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_list[i].next = &(ctx->blit_list[i+1]);
612befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
613728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_list[ctx->blit_count-1].next = NULL;
6145ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R    uint32_t target_transform = ctx->trg_transform;
6155ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R    if (ctx->c2d_driver_info.capabilities_mask &
6165ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R        C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
6175ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R        // For A3xx - set 0x0 as the transform is set in the config_mask
6185ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R        target_transform = 0x0;
6195ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R    }
6205ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R    if(LINK_c2dDraw(target, target_transform, 0x0, 0, 0, ctx->blit_list,
621728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                    ctx->blit_count)) {
622728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
623728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return COPYBIT_FAILURE;
624befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
625befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return COPYBIT_SUCCESS;
626befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
627befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
628befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
6291cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
6301cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.Rstatic int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd)
6311cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R{
6321cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
6331cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    int status = COPYBIT_FAILURE;
6341cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    if (!ctx)
6351cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        return COPYBIT_FAILURE;
6361cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
6371cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
6381cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
6391cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) {
6401cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__);
6411cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        // unlock the mutex and return failure
6421cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
6431cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        return COPYBIT_FAILURE;
6441cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    }
6451cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp,
6461cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                                                                        fd)) {
6471cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__);
6481cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        status = COPYBIT_FAILURE;
6491cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    }
6501cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    if(status == COPYBIT_SUCCESS) {
6511cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        //signal the wait_thread
6521cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        ctx->wait_timestamp = true;
6531cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        pthread_cond_signal(&ctx->wait_cleanup_cond);
6541cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    }
6551cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
6561cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    return status;
6571cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R}
6581cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
659728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.Rstatic int finish_copybit(struct copybit_device_t *dev)
660befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
661728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
662728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (!ctx)
663728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return COPYBIT_FAILURE;
664befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
665728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R   int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
666befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
667728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R   if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) {
668728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
669728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return COPYBIT_FAILURE;
670befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
671befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
672728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Unmap any mapped addresses.
673728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < MAX_SURFACES; i++) {
674728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (ctx->mapped_gpu_addr[i]) {
675728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
676728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->mapped_gpu_addr[i] = 0;
677befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
678befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
679befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
680728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Reset the counts after the draw.
681728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_rgb_count = 0;
682728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_yuv_2_plane_count = 0;
683728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_yuv_3_plane_count = 0;
684728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_count = 0;
6856bf5ee9ee7e318d1d5011bc26aaa80bfe8bd880bPawan Kumar    ctx->dst_surface_mapped = false;
6866bf5ee9ee7e318d1d5011bc26aaa80bfe8bd880bPawan Kumar    ctx->dst_surface_base = 0;
6876bf5ee9ee7e318d1d5011bc26aaa80bfe8bd880bPawan Kumar
688befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
689befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
690befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
691347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmedstatic int clear_copybit(struct copybit_device_t *dev,
692347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed                         struct copybit_image_t const *buf,
693347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed                         struct copybit_rect_t *rect)
694347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed{
69561218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    int ret = COPYBIT_SUCCESS;
696347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    int flags = FLAGS_PREMULTIPLIED_ALPHA;
697347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    int mapped_dst_idx = -1;
698347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
699347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
70061218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
701c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    if(!ctx->dst_surface_mapped) {
702c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf,
703c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R                        (eC2DFlags)flags, mapped_dst_idx);
704c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        if(ret) {
705c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            ALOGE("%s: set_image error", __FUNCTION__);
706c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            unmap_gpuaddr(ctx, mapped_dst_idx);
707c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            pthread_mutex_unlock(&ctx->wait_cleanup_lock);
708c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            return COPYBIT_FAILURE;
709c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        }
710c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        //clear_copybit is the first call made by HWC for each composition
711c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        //with the dest surface, hence set dst_surface_mapped.
712c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        ctx->dst_surface_mapped = true;
713c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        ctx->dst_surface_base = buf->base;
714c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect);
715347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    }
71661218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
717347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    return ret;
718347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed}
719347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed
720347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed
721befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** setup rectangles */
722befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void set_rects(struct copybit_context_t *ctx,
723befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      C2D_OBJECT *c2dObject,
724befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      const struct copybit_rect_t *dst,
725befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      const struct copybit_rect_t *src,
726befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      const struct copybit_rect_t *scissor)
727befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
728befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Set the target rect.
729befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if((ctx->trg_transform & C2D_TARGET_ROTATE_90) &&
730befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed       (ctx->trg_transform & C2D_TARGET_ROTATE_180)) {
731befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        /* target rotation is 270 */
732befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = (dst->t)<<16;
733befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = ctx->fb_width?(ALIGN(ctx->fb_width,32)- dst->r):dst->r;
734befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
735befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
736befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
737befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) {
738befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
739befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
740befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = (dst->l)<<16;
741befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
742befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
743befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) {
744befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
745befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
746befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = ctx->fb_width?(ALIGN(ctx->fb_width,32) - dst->r):dst->r;
747befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
748befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
749befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
750befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
751befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = (dst->l)<<16;
752befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = (dst->t)<<16;
753befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
754befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
755befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
756befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->config_mask |= C2D_TARGET_RECT_BIT;
757befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
758befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Set the source rect
759befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.x        = (src->l)<<16;
760befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.y        = (src->t)<<16;
761befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.height   = ((src->b) - (src->t))<<16;
762befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.width    = ((src->r) - (src->l))<<16;
763befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->config_mask |= C2D_SOURCE_RECT_BIT;
764befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
765befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Set the scissor rect
766befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.x       = scissor->l;
767befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.y       = scissor->t;
768befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.height  = (scissor->b) - (scissor->t);
769befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.width   = (scissor->r) - (scissor->l);
770befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT;
771befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
772befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
773befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*****************************************************************************/
774befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
775befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Set a parameter to value */
776befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int set_parameter_copybit(
777befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t *dev,
778befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int name,
779befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int value)
780befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
781befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
7821cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    int status = COPYBIT_SUCCESS;
783befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!ctx) {
784befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: null context", __FUNCTION__);
785befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
786befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
787befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
7881cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
789befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(name) {
790befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_PLANE_ALPHA:
791728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        {
792befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (value < 0)      value = 0;
793befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (value >= 256)   value = 255;
794befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
795728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->src_global_alpha = value;
796728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            if (value < 255)
797728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT;
798befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            else
799728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT;
800728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
801728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        break;
802728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        case COPYBIT_BLEND_MODE:
803728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        {
804728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            if (value == COPYBIT_BLENDING_NONE) {
805728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->config_mask |= C2D_ALPHA_BLEND_NONE;
806728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->is_premultiplied_alpha = true;
807728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            } else if (value == COPYBIT_BLENDING_PREMULT) {
808728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->is_premultiplied_alpha = true;
809728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            } else {
810728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE;
811728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            }
812728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
813728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        break;
814befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_TRANSFORM:
815728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        {
816728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unsigned int transform = 0;
817728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            uint32 config_mask = 0;
818728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG;
819728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) {
820728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                transform = C2D_TARGET_ROTATE_180;
821728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180;
822728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) {
823728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                transform = C2D_TARGET_ROTATE_90;
824728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90;
825728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            } else if(value == COPYBIT_TRANSFORM_ROT_90) {
826728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                transform = C2D_TARGET_ROTATE_270;
827728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270;
828728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            } else {
829728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0;
830728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                if(value & COPYBIT_TRANSFORM_FLIP_H) {
831728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                    config_mask |= C2D_MIRROR_H_BIT;
832728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                } else if(value & COPYBIT_TRANSFORM_FLIP_V) {
833728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                    config_mask |= C2D_MIRROR_V_BIT;
834728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                }
835befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            }
836728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
8375ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R            if (ctx->c2d_driver_info.capabilities_mask &
8385ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
8395ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                ctx->config_mask |= config_mask;
8405ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R            } else {
8415ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                // The transform for this surface does not match the current
8425ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                // target transform. Draw all previous surfaces. This will be
8435ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                // changed once we have a new mechanism to send different
8445ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                // target rotations to c2d.
8455ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                finish_copybit(dev);
846728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            }
847728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->trg_transform = transform;
848728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
849728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        break;
850befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_FRAMEBUFFER_WIDTH:
851befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->fb_width = value;
852befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
853befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_FRAMEBUFFER_HEIGHT:
854befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->fb_height = value;
855befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
856728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        case COPYBIT_ROTATION_DEG:
857728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        case COPYBIT_DITHER:
858728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        case COPYBIT_BLUR:
859e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed        case COPYBIT_BLIT_TO_FRAMEBUFFER:
860728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            // Do nothing
861e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed            break;
862befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
863befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
8641cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            status = -EINVAL;
865befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
866befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
8671cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
8681cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    return status;
869befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
870befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
871befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Get a static info value */
872befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get(struct copybit_device_t *dev, int name)
873befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
874befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
875befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int value;
876befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
877befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!ctx) {
878befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: null context error", __FUNCTION__);
879befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
880befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
881befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
882befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(name) {
883befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_MINIFICATION_LIMIT:
884befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = MAX_SCALE_FACTOR;
885befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
886befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_MAGNIFICATION_LIMIT:
887befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = MAX_SCALE_FACTOR;
888befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
889befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_SCALING_FRAC_BITS:
890befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = 32;
891befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
892befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_ROTATION_STEP_DEG:
893befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = 1;
894befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
895befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
896befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
897befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = -EINVAL;
898befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
899befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return value;
900befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
901befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
902befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_alpha(int cformat)
903befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
904befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int alpha = 0;
905befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (cformat & 0xFF) {
906befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_ARGB:
907befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_RGBA:
908befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_5551_RGBA:
909befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4444_ARGB:
910befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            alpha = 1;
911befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
912befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
913befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            alpha = 0;
914befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
915befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
916befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
917befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(alpha && (cformat&C2D_FORMAT_DISABLE_ALPHA))
918befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        alpha = 0;
919befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
920befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return alpha;
921befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
922befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
923befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to check if we need a temporary buffer for the blit.
924befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * This would happen if the requested destination stride and the
925befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * C2D stride do not match. We ignore RGB buffers, since their
926befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * stride is always aligned to 32.
927befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
928befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic bool need_temp_buffer(struct copybit_image_t const *img)
929befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
930befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format))
931befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return false;
932befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
933befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct private_handle_t* handle = (struct private_handle_t*)img->handle;
934befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
935befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // The width parameter in the handle contains the aligned_w. We check if we
936befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // need to convert based on this param. YUV formats have bpp=1, so checking
937befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // if the requested stride is aligned should suffice.
938befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (0 == (handle->width)%32) {
939befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return false;
940befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
941befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
942befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return true;
943befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
944befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
945befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to extract the information from the copybit image and set the corresponding
946befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * values in the bufferInfo struct.
947befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
948befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info)
949befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
950befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    info.width = img->w;
951befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    info.height = img->h;
952befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    info.format = img->format;
953befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
954befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
955befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to get the required size for a particular format, inorder for C2D to perform
956befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * the blit operation.
957befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
958befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic size_t get_size(const bufferInfo& info)
959befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
960befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    size_t size = 0;
961befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int w = info.width;
962befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int h = info.height;
963befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int aligned_w = ALIGN(w, 32);
964befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(info.format) {
965befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
966befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            {
967befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                // Chroma for this format is aligned to 2K.
968befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                size = ALIGN((aligned_w*h), 2048) +
969728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                        ALIGN(aligned_w/2, 32) * (h/2) *2;
970befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                size = ALIGN(size, 4096);
971befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } break;
972befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
973befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
974befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            {
975728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                size = aligned_w * h +
976728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                       ALIGN(aligned_w/2, 32) * (h/2) * 2;
977befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                size = ALIGN(size, 4096);
978befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } break;
979befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default: break;
980befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
981befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return size;
982befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
983befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
984befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to allocate memory for the temporary buffer. This memory is
985befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * allocated from Ashmem. It is the caller's responsibility to free this
986befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * memory.
987befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
988befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_temp_buffer(const bufferInfo& info, alloc_data& data)
989befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
990befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ALOGD("%s E", __FUNCTION__);
991befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Alloc memory from system heap
992befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.base = 0;
993befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.fd = -1;
994befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.offset = 0;
995befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.size = get_size(info);
996befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.align = getpagesize();
997befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.uncached = true;
998befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int allocFlags = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
999befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1000befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (sAlloc == 0) {
1001be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        sAlloc = gralloc::IAllocController::getInstance();
1002befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1003befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1004befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (sAlloc == 0) {
1005befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: sAlloc is still NULL", __FUNCTION__);
1006befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1007befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1008befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1009be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed    int err = sAlloc->allocate(data, allocFlags);
1010befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (0 != err) {
1011befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: allocate failed", __FUNCTION__);
1012befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1013befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1014befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1015befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ALOGD("%s X", __FUNCTION__);
1016befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return err;
1017befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1018befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1019befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to free the temporary allocated memory.*/
1020befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void free_temp_buffer(alloc_data &data)
1021befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1022befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (-1 != data.fd) {
1023be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType);
1024befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memalloc->free_buffer(data.base, data.size, 0, data.fd);
1025befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1026befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1027befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1028befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to perform the software color conversion. Convert the
1029befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * C2D compatible format to the Android compatible format
1030befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
1031befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int copy_image(private_handle_t *src_handle,
1032befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      struct copybit_image_t const *rhs,
1033befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      eConversionType conversionType)
1034befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1035befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (src_handle->fd == -1) {
1036befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: src_handle fd is invalid", __FUNCTION__);
1037befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1038befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1039befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1040befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Copy the info.
1041befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int ret = COPYBIT_SUCCESS;
1042befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(rhs->format) {
1043befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1044befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1045befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1046befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            {
1047befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                if (CONVERT_TO_ANDROID_FORMAT == conversionType) {
1048befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    return convert_yuv_c2d_to_yuv_android(src_handle, rhs);
1049befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                } else {
1050befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    return convert_yuv_android_to_yuv_c2d(src_handle, rhs);
1051befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                }
1052befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1053befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } break;
1054befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default: {
1055befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
1056befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ret = COPYBIT_FAILURE;
1057befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } break;
1058befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1059befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return ret;
1060befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1061befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1062befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void delete_handle(private_handle_t *handle)
1063befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1064befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (handle) {
1065befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete handle;
1066befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        handle = 0;
1067befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1068befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1069728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1070728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.Rstatic bool need_to_execute_draw(struct copybit_context_t* ctx,
1071728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                          eC2DFlags flags)
1072728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R{
1073728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (flags & FLAGS_TEMP_SRC_DST) {
1074728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return true;
1075728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1076728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (flags & FLAGS_YUV_DESTINATION) {
1077728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return true;
1078728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1079728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    return false;
1080728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R}
1081728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1082befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** do a stretch blit type operation */
1083befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int stretch_copybit_internal(
1084befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t *dev,
1085befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *dst,
1086befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *src,
1087befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t const *dst_rect,
1088befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t const *src_rect,
1089befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_region_t const *region,
1090befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    bool enableBlend)
1091befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1092befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1093befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = COPYBIT_SUCCESS;
1094728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int flags = 0;
1095728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int src_surface_type;
1096728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int mapped_src_idx = -1, mapped_dst_idx = -1;
1097728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    C2D_OBJECT_STR src_surface;
1098befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1099befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!ctx) {
1100befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: null context error", __FUNCTION__);
1101befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
1102befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1103befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1104befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
1105befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: src dimension error", __FUNCTION__);
1106befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
1107befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1108befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1109befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
1110728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s : dst dimension error dst w %d h %d",  __FUNCTION__, dst->w,
1111728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                         dst->h);
1112befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
1113befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1114befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1115befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) {
1116728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__,
1117728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                              dst->format);
1118befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1119befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1120befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1121728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int dst_surface_type;
1122befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
1123728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        dst_surface_type = RGB_SURFACE;
1124728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        flags |= FLAGS_PREMULTIPLIED_ALPHA;
1125befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) {
1126befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        int num_planes = get_num_planes(dst->format);
1127728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        flags |= FLAGS_YUV_DESTINATION;
1128befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (num_planes == 2) {
1129728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            dst_surface_type = YUV_SURFACE_2_PLANES;
1130befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } else if (num_planes == 3) {
1131728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            dst_surface_type = YUV_SURFACE_3_PLANES;
1132befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } else {
1133befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x",
1134befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                  __FUNCTION__, dst->format);
1135befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
1136befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1137befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
1138728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__,
1139728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                     dst->format);
1140befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1141befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1142befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1143728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (ctx->blit_rgb_count == MAX_RGB_SURFACES ||
1144728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_yuv_2_plane_count == MAX_YUV_2_PLANE_SURFACES ||
1145728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_yuv_3_plane_count == MAX_YUV_2_PLANE_SURFACES ||
1146728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_count == MAX_BLIT_OBJECT_COUNT ||
1147728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->dst_surface_type != dst_surface_type) {
1148728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        // we have reached the max. limits of our internal structures or
1149728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        // changed the target.
1150728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        // Draw the remaining surfaces. We need to do the finish here since
1151728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        // we need to free up the surface templates.
1152728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        finish_copybit(dev);
1153728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1154728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1155728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->dst_surface_type = dst_surface_type;
1156728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1157728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Update the destination
1158befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    copybit_image_t dst_image;
1159befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    dst_image.w = dst->w;
1160befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    dst_image.h = dst->h;
1161befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    dst_image.format = dst->format;
1162befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    dst_image.handle = dst->handle;
1163befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Check if we need a temp. copy for the destination. We'd need this the destination
1164befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // width is not aligned to 32. This case occurs for YUV formats. RGB formats are
1165befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // aligned to 32.
1166728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    bool need_temp_dst = need_temp_buffer(dst);
1167befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    bufferInfo dst_info;
1168befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    populate_buffer_info(dst, dst_info);
1169befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format,
1170befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                     dst_info.width, dst_info.height);
1171befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (dst_hnd == NULL) {
1172befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: dst_hnd is null", __FUNCTION__);
1173befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1174befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1175728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (need_temp_dst) {
1176befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (get_size(dst_info) != ctx->temp_dst_buffer.size) {
1177befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            free_temp_buffer(ctx->temp_dst_buffer);
1178befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            // Create a temp buffer and set that as the destination.
1179befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) {
1180befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ALOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__);
1181befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                delete_handle(dst_hnd);
1182befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                return COPYBIT_FAILURE;
1183befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            }
1184befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1185befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->fd = ctx->temp_dst_buffer.fd;
1186befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->size = ctx->temp_dst_buffer.size;
1187befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->flags = ctx->temp_dst_buffer.allocType;
1188befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->base = (int)(ctx->temp_dst_buffer.base);
1189befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->offset = ctx->temp_dst_buffer.offset;
1190befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_hnd->gpuaddr = 0;
1191befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        dst_image.handle = dst_hnd;
1192befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1193c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    if(!ctx->dst_surface_mapped) {
1194c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        //map the destination surface to GPU address
1195c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        status = set_image(ctx, ctx->dst[ctx->dst_surface_type], &dst_image,
1196c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R                           (eC2DFlags)flags, mapped_dst_idx);
1197c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        if(status) {
1198c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            ALOGE("%s: dst: set_image error", __FUNCTION__);
1199c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            delete_handle(dst_hnd);
1200c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            unmap_gpuaddr(ctx, mapped_dst_idx);
1201c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            return COPYBIT_FAILURE;
1202c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        }
1203c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        ctx->dst_surface_mapped = true;
1204c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        ctx->dst_surface_base = dst->base;
1205c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    } else if(ctx->dst_surface_mapped && ctx->dst_surface_base != dst->base) {
1206c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        // Destination surface for the operation should be same for multiple
1207c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        // requests, this check is catch if there is any case when the
1208c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        // destination changes
1209c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        ALOGE("%s: a different destination surface!!", __FUNCTION__);
1210befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1211befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1212728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Update the source
1213728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    flags = 0;
1214befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) {
1215728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        src_surface_type = RGB_SURFACE;
1216728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        src_surface = ctx->blit_rgb_object[ctx->blit_rgb_count];
1217befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) {
1218befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        int num_planes = get_num_planes(src->format);
1219befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (num_planes == 2) {
1220728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            src_surface_type = YUV_SURFACE_2_PLANES;
1221728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            src_surface = ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count];
1222befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } else if (num_planes == 3) {
1223728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            src_surface_type = YUV_SURFACE_3_PLANES;
1224728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            src_surface = ctx->blit_yuv_3_plane_object[ctx->blit_yuv_2_plane_count];
1225befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } else {
1226befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: src number of YUV planes is invalid src format = 0x%x",
1227befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                  __FUNCTION__, src->format);
1228befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            delete_handle(dst_hnd);
1229728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_dst_idx);
1230befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return -EINVAL;
1231befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1232befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
1233728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__,
1234728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                        src->format);
1235befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete_handle(dst_hnd);
1236728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_dst_idx);
1237befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
1238befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1239befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1240befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    copybit_image_t src_image;
1241befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    src_image.w = src->w;
1242befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    src_image.h = src->h;
1243befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    src_image.format = src->format;
1244befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    src_image.handle = src->handle;
1245befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1246728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    bool need_temp_src = need_temp_buffer(src);
1247befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    bufferInfo src_info;
1248befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    populate_buffer_info(src, src_info);
1249befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format,
1250728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 src_info.width, src_info.height);
1251befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (NULL == src_hnd) {
1252befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: src_hnd is null", __FUNCTION__);
1253befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete_handle(dst_hnd);
1254728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_dst_idx);
1255befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1256befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1257728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (need_temp_src) {
1258befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (get_size(src_info) != ctx->temp_src_buffer.size) {
1259befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            free_temp_buffer(ctx->temp_src_buffer);
1260befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            // Create a temp buffer and set that as the destination.
1261728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            if (COPYBIT_SUCCESS != get_temp_buffer(src_info,
1262728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                               ctx->temp_src_buffer)) {
1263befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__);
1264befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                delete_handle(dst_hnd);
1265befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                delete_handle(src_hnd);
1266728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                unmap_gpuaddr(ctx, mapped_dst_idx);
1267befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                return COPYBIT_FAILURE;
1268befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            }
1269befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1270befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->fd = ctx->temp_src_buffer.fd;
1271befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->size = ctx->temp_src_buffer.size;
1272befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->flags = ctx->temp_src_buffer.allocType;
1273befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->base = (int)(ctx->temp_src_buffer.base);
1274befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->offset = ctx->temp_src_buffer.offset;
1275befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_hnd->gpuaddr = 0;
1276befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        src_image.handle = src_hnd;
1277befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1278befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // Copy the source.
1279728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = copy_image((private_handle_t *)src->handle, &src_image,
1280728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                CONVERT_TO_C2D_FORMAT);
1281728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (status == COPYBIT_FAILURE) {
1282728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGE("%s:copy_image failed in temp source",__FUNCTION__);
1283728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            delete_handle(dst_hnd);
1284728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            delete_handle(src_hnd);
1285728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_dst_idx);
1286728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            return status;
1287728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
1288befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
12892a0417549a81c49b4826c27edd90e0bae3902233Naseer Ahmed        // Clean the cache
1290be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
1291befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
12922a0417549a81c49b4826c27edd90e0bae3902233Naseer Ahmed                                   src_hnd->offset, src_hnd->fd,
12932a0417549a81c49b4826c27edd90e0bae3902233Naseer Ahmed                                   gralloc::CACHE_CLEAN)) {
1294befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: clean_buffer failed", __FUNCTION__);
1295befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            delete_handle(dst_hnd);
1296befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            delete_handle(src_hnd);
1297728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_dst_idx);
1298befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
1299befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1300befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1301befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1302728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
1303728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
1304728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    status = set_image(ctx, src_surface.surface_id, &src_image,
1305728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                       (eC2DFlags)flags, mapped_src_idx);
1306befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(status) {
1307728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: set_image (src) error", __FUNCTION__);
1308befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete_handle(dst_hnd);
1309befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete_handle(src_hnd);
1310728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_dst_idx);
1311728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_src_idx);
1312befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1313befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1314befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
13154d161e800dd3c5b35f4bd206533375bfc2507780Arun Kumar K.R    src_surface.config_mask = C2D_NO_ANTIALIASING_BIT | ctx->config_mask;
1316728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    src_surface.global_alpha = ctx->src_global_alpha;
1317befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (enableBlend) {
1318728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) {
1319728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
1320728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            if(!(src_surface.global_alpha)) {
1321befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                // src alpha is zero
1322befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                delete_handle(dst_hnd);
1323befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                delete_handle(src_hnd);
1324728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                unmap_gpuaddr(ctx, mapped_dst_idx);
1325728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                unmap_gpuaddr(ctx, mapped_src_idx);
1326728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                return COPYBIT_FAILURE;
1327befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            }
1328befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1329befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
1330728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
1331befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1332befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1333728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (src_surface_type == RGB_SURFACE) {
1334728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_rgb_object[ctx->blit_rgb_count] = src_surface;
1335728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_rgb_count++;
1336728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    } else if (src_surface_type == YUV_SURFACE_2_PLANES) {
1337728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count] = src_surface;
1338728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_yuv_2_plane_count++;
1339728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    } else {
1340728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_yuv_3_plane_object[ctx->blit_yuv_3_plane_count] = src_surface;
1341728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_yuv_3_plane_count++;
1342728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1343befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1344728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    struct copybit_rect_t clip;
1345befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    while ((status == 0) && region->next(region, &clip)) {
1346728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip);
1347728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) {
1348728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGW("Reached end of blit count");
13491cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            finish_copybit(dev);
1350befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
1351728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_list[ctx->blit_count] = src_surface;
1352728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_count++;
1353befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1354befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1355728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Check if we need to perform an early draw-finish.
1356728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0;
1357728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (need_to_execute_draw(ctx, (eC2DFlags)flags))
1358728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    {
1359728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        finish_copybit(dev);
1360befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1361befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1362728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (need_temp_dst) {
1363728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        // copy the temp. destination without the alignment to the actual
1364728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        // destination.
1365728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
1366728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (status == COPYBIT_FAILURE) {
1367728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__);
1368728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            delete_handle(dst_hnd);
1369728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            delete_handle(src_hnd);
1370728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_dst_idx);
1371728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_src_idx);
1372728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            return status;
1373728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
13742a0417549a81c49b4826c27edd90e0bae3902233Naseer Ahmed        // Clean the cache.
1375be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
1376befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
13772a0417549a81c49b4826c27edd90e0bae3902233Naseer Ahmed                               dst_hnd->offset, dst_hnd->fd,
13782a0417549a81c49b4826c27edd90e0bae3902233Naseer Ahmed                               gralloc::CACHE_CLEAN);
1379befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1380befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    delete_handle(dst_hnd);
1381befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    delete_handle(src_hnd);
1382728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1383728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->is_premultiplied_alpha = false;
1384befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->fb_width = 0;
1385befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->fb_height = 0;
1386728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->config_mask = 0;
1387befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
1388befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1389befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1390ac791ef899d93baf8bc2545b2e81f6a71d9bfbc1Terence Hampsonstatic int set_sync_copybit(struct copybit_device_t *dev,
1391ac791ef899d93baf8bc2545b2e81f6a71d9bfbc1Terence Hampson    int acquireFenceFd)
1392ac791ef899d93baf8bc2545b2e81f6a71d9bfbc1Terence Hampson{
1393ac791ef899d93baf8bc2545b2e81f6a71d9bfbc1Terence Hampson    return 0;
1394ac791ef899d93baf8bc2545b2e81f6a71d9bfbc1Terence Hampson}
1395728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1396befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int stretch_copybit(
1397befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t *dev,
1398befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *dst,
1399befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *src,
1400befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t const *dst_rect,
1401befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t const *src_rect,
1402befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_region_t const *region)
1403befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1404befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
14051cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    int status = COPYBIT_SUCCESS;
1406728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    bool needsBlending = (ctx->src_global_alpha != 0);
14071cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
14081cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
1409befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                    region, needsBlending);
14101cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
14111cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    return status;
1412befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1413befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1414befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Perform a blit type operation */
1415befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int blit_copybit(
1416befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t *dev,
1417befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *dst,
1418befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *src,
1419befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_region_t const *region)
1420befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
142161218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    int status = COPYBIT_SUCCESS;
142261218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1423a95531ebf897fcff256840094a6c3e07e3cd578eNaseer Ahmed    struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
1424a95531ebf897fcff256840094a6c3e07e3cd578eNaseer Ahmed    struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
142561218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
142661218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    status = stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false);
142761218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
142861218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    return status;
1429befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1430befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1431befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*****************************************************************************/
1432befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1433728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.Rstatic void clean_up(copybit_context_t* ctx)
1434728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R{
14351cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    void* ret;
1436728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (!ctx)
1437728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return;
1438728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
14391cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    // stop the wait_cleanup_thread
14401cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
14411cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    ctx->stop_thread = true;
14421cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    // Signal waiting thread
14431cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_cond_signal(&ctx->wait_cleanup_cond);
14441cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
14451cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    // waits for the cleanup thread to exit
14461cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_join(ctx->wait_thread_id, &ret);
14471cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_destroy(&ctx->wait_cleanup_lock);
14481cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_cond_destroy (&ctx->wait_cleanup_cond);
14491cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
1450728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < NUM_SURFACE_TYPES; i++) {
1451728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (ctx->dst[i])
1452728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            LINK_c2dDestroySurface(ctx->dst[i]);
1453728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1454728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1455728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < MAX_RGB_SURFACES; i++) {
1456728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (ctx->blit_rgb_object[i].surface_id)
1457728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id);
1458728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1459728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1460728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) {
1461728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (ctx->blit_yuv_2_plane_object[i].surface_id)
1462728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id);
1463728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1464728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1465728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) {
1466728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (ctx->blit_yuv_3_plane_object[i].surface_id)
1467728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id);
1468728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1469728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1470728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (ctx->libc2d2) {
1471728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ::dlclose(ctx->libc2d2);
1472728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGV("dlclose(libc2d2)");
1473728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1474728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1475728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    free(ctx);
1476728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R}
1477728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1478befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Close the copybit device */
1479befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int close_copybit(struct hw_device_t *dev)
1480befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1481befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1482befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (ctx) {
1483befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        free_temp_buffer(ctx->temp_src_buffer);
1484befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        free_temp_buffer(ctx->temp_dst_buffer);
1485befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1486728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    clean_up(ctx);
1487befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return 0;
1488befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1489befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1490befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Open a new instance of a copybit device using name */
1491befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
1492befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                        struct hw_device_t** device)
1493befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1494befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = COPYBIT_SUCCESS;
1495befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_RGB_SURFACE_DEF surfDefinition = {0};
1496befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
1497befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t *ctx;
1498befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    char fbName[64];
1499befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1500befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
1501befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!ctx) {
1502befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: malloc failed", __FUNCTION__);
1503befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1504befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1505befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1506befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* initialize drawstate */
1507befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    memset(ctx, 0, sizeof(*ctx));
1508befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
1509befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!ctx->libc2d2) {
1510befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
1511728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1512728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1513728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1514728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1515befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1516befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2,
1517befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                               "c2dCreateSurface");
1518befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2,
1519befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                               "c2dUpdateSurface");
1520befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2,
1521befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                             "c2dReadSurface");
1522befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw");
1523befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush");
1524befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish");
1525befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2,
1526befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                               "c2dWaitTimestamp");
1527befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2,
1528befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                "c2dDestroySurface");
1529befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2,
1530befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                         "c2dMapAddr");
1531befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2,
1532befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                           "c2dUnMapAddr");
1533728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2,
1534728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                           "c2dGetDriverCapabilities");
15351cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
15361cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                                           "c2dCreateFenceFD");
1537347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2,
1538347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed                                           "c2dFillSurface");
1539befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1540befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
1541728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
1542728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
1543347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD ||
1544347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed        !LINK_c2dFillSurface) {
1545befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: dlsym ERROR", __FUNCTION__);
1546728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1547728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1548728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1549728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1550befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1551befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1552befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
1553befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.version = 1;
1554befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.module = (hw_module_t*)(module);
1555befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.close = close_copybit;
1556befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.set_parameter = set_parameter_copybit;
1557befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.get = get;
1558befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.blit = blit_copybit;
1559ac791ef899d93baf8bc2545b2e81f6a71d9bfbc1Terence Hampson    ctx->device.set_sync = set_sync_copybit;
1560befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.stretch = stretch_copybit;
1561728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->device.finish = finish_copybit;
15621cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    ctx->device.flush_get_fence = flush_get_fence_copybit;
1563347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    ctx->device.clear = clear_copybit;
1564befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1565befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* Create RGB Surface */
1566befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.buffer = (void*)0xdddddddd;
1567befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.phys = (void*)0xdddddddd;
1568befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.stride = 1 * 4;
1569befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.width = 1;
1570befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.height = 1;
1571befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB;
1572befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
1573befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
1574728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
1575728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
1576728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 &surfDefinition)) {
1577728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__);
1578728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->dst[RGB_SURFACE] = 0;
1579728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1580728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1581728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1582728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1583befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1584befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1585728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    unsigned int surface_id = 0;
1586728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < MAX_RGB_SURFACES; i++)
1587728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    {
1588728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
1589befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
1590728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
1591728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
1592728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 &surfDefinition)) {
1593728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i);
1594728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_rgb_object[i].surface_id = 0;
1595728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            status = COPYBIT_FAILURE;
1596728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            break;
1597728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        } else {
1598728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_rgb_object[i].surface_id = surface_id;
1599728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGW("%s i = %d surface_id=%d",  __FUNCTION__, i,
1600728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                          ctx->blit_rgb_object[i].surface_id);
1601728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
1602befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1603befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1604728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (status == COPYBIT_FAILURE) {
1605728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1606728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1607728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1608728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1609728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1610befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1611728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Create 2 plane YUV surfaces
1612728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
1613befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.width = 4;
1614befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.height = 4;
1615befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa;
1616befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa;
1617befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.stride0 = 4;
1618befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1619befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa;
1620befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa;
1621befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.stride1 = 4;
1622728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),
1623befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              C2D_TARGET | C2D_SOURCE,
1624728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1625728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                               C2D_SURFACE_WITH_PHYS |
1626728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                               C2D_SURFACE_WITH_PHYS_DUMMY),
1627befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1628728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
1629728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->dst[YUV_SURFACE_2_PLANES] = 0;
1630728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1631728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1632728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1633728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1634befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1635befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1636728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++)
1637728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    {
1638728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
1639728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1640728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
1641728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
1642befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1643728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGE("%s: create YUV source %d failed", __FUNCTION__, i);
1644728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_yuv_2_plane_object[i].surface_id = 0;
1645728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            status = COPYBIT_FAILURE;
1646728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            break;
1647728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        } else {
1648728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_yuv_2_plane_object[i].surface_id = surface_id;
1649728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGW("%s: 2 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
1650728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                   ctx->blit_yuv_2_plane_object[i].surface_id);
1651728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
1652728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1653728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1654728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (status == COPYBIT_FAILURE) {
1655728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1656728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1657728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1658728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1659befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1660befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1661728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Create YUV 3 plane surfaces
1662befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
1663befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
1664befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
1665befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.stride2 = 4;
1666befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1667728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),
1668befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              C2D_TARGET | C2D_SOURCE,
1669728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1670728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
1671728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
1672befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1673728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
1674728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->dst[YUV_SURFACE_3_PLANES] = 0;
1675728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1676728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1677728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1678728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1679befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1680befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1681728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++)
1682728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    {
1683728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (LINK_c2dCreateSurface(&(surface_id),
1684befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              C2D_TARGET | C2D_SOURCE,
1685728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1686728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
1687728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
1688befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1689728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i);
1690728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_yuv_3_plane_object[i].surface_id = 0;
1691728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            status = COPYBIT_FAILURE;
1692728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            break;
1693728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        } else {
1694728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_yuv_3_plane_object[i].surface_id = surface_id;
1695728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGW("%s: 3 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
1696728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                   ctx->blit_yuv_3_plane_object[i].surface_id);
1697728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
1698befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1699befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1700728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (status == COPYBIT_FAILURE) {
1701728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1702728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1703728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1704728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1705728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1706728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1707728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) {
1708728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R         ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__);
1709728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R         clean_up(ctx);
1710728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R         status = COPYBIT_FAILURE;
1711728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1712728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1713728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1714728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Initialize context variables.
1715728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->trg_transform = C2D_TARGET_ROTATE_0;
1716728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1717befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_src_buffer.fd = -1;
1718befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_src_buffer.base = 0;
1719befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_src_buffer.size = 0;
1720befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1721befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_dst_buffer.fd = -1;
1722befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_dst_buffer.base = 0;
1723befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_dst_buffer.size = 0;
1724befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1725befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->fb_width = 0;
1726befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->fb_height = 0;
1727befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1728728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_rgb_count = 0;
1729728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_yuv_2_plane_count = 0;
1730728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_yuv_3_plane_count = 0;
1731728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_count = 0;
1732befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
17331cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    ctx->wait_timestamp = false;
17341cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    ctx->stop_thread = false;
17351cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL);
17361cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_cond_init(&(ctx->wait_cleanup_cond), NULL);
17371cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    /* Start the wait thread */
17381cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_attr_t attr;
17391cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_attr_init(&attr);
17401cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
17411cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
17421cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop,
17431cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                                                            (void *)ctx);
17441cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_attr_destroy(&attr);
17451cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
1746728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    *device = &ctx->device.common;
1747befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
1748befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1749