1befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*
2befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Copyright (C) 2008 The Android Open Source Project
346f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu * Copyright (c) 2010-2014, 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 <gralloc_priv.h>
39befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
40befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <copybit.h>
41befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <alloc_controller.h>
42befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <memalloc.h>
43befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
44befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include "c2d2.h"
45befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include "software_converter.h"
46befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
47befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#include <dlfcn.h>
48befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
49befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing gralloc::IMemAlloc;
50befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing gralloc::IonController;
51befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedusing gralloc::alloc_data;
52befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
53befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
54befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     uint32 surface_bits,
55befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     C2D_SURFACE_TYPE surface_type,
56befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     void *surface_definition );
57befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
58befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id,
59befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     uint32 surface_bits,
60befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     C2D_SURFACE_TYPE surface_type,
61befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                     void *surface_definition );
62befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
63befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id,
64befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                   C2D_SURFACE_TYPE surface_type,
65befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                   void *surface_definition,
66befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                   int32 x, int32 y );
67befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
68befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dDraw)( uint32 target_id,
69befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                            uint32 target_config, C2D_RECT *target_scissor,
70befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                            uint32 target_mask_id, uint32 target_color_key,
71befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                            C2D_OBJECT *objects_list, uint32 num_objects );
72befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
73befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dFinish)( uint32 target_id);
74befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
75befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp);
76befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
77befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp );
78befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
79befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
80befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
8146f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena PachipulusuC2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, size_t len,
8246f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu                                size_t offset, uint32 flags, void ** gpuaddr);
83befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
84befc466069680cb8a65b1f22ad44723d949128c8Naseer AhmedC2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
85befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
86728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.RC2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info);
871cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
881cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R/* create a fence fd for the timestamp */
891cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.RC2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
901cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                                                            int32 *fd);
91347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed
92347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer AhmedC2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color,
93347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed                                    C2D_RECT * fill_rect);
94347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed
95befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/******************************************************************************/
96befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
97befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#if defined(COPYBIT_Z180)
98befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#define MAX_SCALE_FACTOR    (4096)
99befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#define MAX_DIMENSION       (4096)
100befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#else
101befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#error "Unsupported HW version"
102befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed#endif
103befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
104728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R// The following defines can be changed as required i.e. as we encounter
105728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R// complex use cases.
106ae2425e753369c4940288e280d4e743ca8227c19Sushil Chauhan#define MAX_RGB_SURFACES 32       // Max. RGB layers currently supported per draw
107728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R#define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw
108728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R#define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw
109728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R// +1 for the destination surface. We cannot have multiple destination surfaces.
110728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R#define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1)
111728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R#define NUM_SURFACE_TYPES 3      // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES
112728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R#define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw
113befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
114befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedenum {
115befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    RGB_SURFACE,
116befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    YUV_SURFACE_2_PLANES,
117befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    YUV_SURFACE_3_PLANES
118befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
119befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
120befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedenum eConversionType {
121befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    CONVERT_TO_ANDROID_FORMAT,
122befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    CONVERT_TO_C2D_FORMAT
123befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
124befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
125befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedenum eC2DFlags {
126728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    FLAGS_PREMULTIPLIED_ALPHA  = 1<<0,
127728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    FLAGS_YUV_DESTINATION      = 1<<1,
128728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    FLAGS_TEMP_SRC_DST         = 1<<2
129befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
130befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
131be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmedstatic gralloc::IAllocController* sAlloc = 0;
132befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/******************************************************************************/
133befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
134befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** State information for each device instance */
135befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct copybit_context_t {
136befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t device;
137728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Templates for the various source surfaces. These templates are created
138728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // to avoid the expensive create/destroy C2D Surfaces
139728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES];
140728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES];
141728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES];
142728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects
143728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    C2D_DRIVER_INFO c2d_driver_info;
144befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    void *libc2d2;
145befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    alloc_data temp_src_buffer;
146befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    alloc_data temp_dst_buffer;
147728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces
14846f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    uintptr_t mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
149728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int blit_rgb_count;         // Total RGB surfaces being blit
150728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being
151728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int blit_yuv_3_plane_count; // Total 3 plane YUV  surfaces being blit
152728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int blit_count;             // Total blit objects.
153728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    unsigned int trg_transform;      /* target transform */
154befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int fb_width;
155befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int fb_height;
156728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int src_global_alpha;
157728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int config_mask;
158728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int dst_surface_type;
159728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    bool is_premultiplied_alpha;
1601cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    void* time_stamp;
161c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr
162c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    void* dst_surface_base; // Stores the dst surface addr
1631cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
1641cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    // used for signaling the wait thread
1651cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    bool wait_timestamp;
1661cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_t wait_thread_id;
1671cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    bool stop_thread;
1681cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_t wait_cleanup_lock;
1691cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_cond_t wait_cleanup_cond;
1701cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
171befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
172befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
173befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct bufferInfo {
174befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int width;
175befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int height;
176befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int format;
177befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
178befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
179befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct yuvPlaneInfo {
180befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int yStride;       //luma stride
181befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int plane1_stride;
182befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int plane2_stride;
18346f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    size_t plane1_offset;
18446f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    size_t plane2_offset;
185befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
186befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
187befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/**
188befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * Common hardware methods
189befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
190befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
191befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
192befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                        struct hw_device_t** device);
193befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
194befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic struct hw_module_methods_t copybit_module_methods = {
195befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedopen:  open_copybit
196befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
197befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
198befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*
199befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * The COPYBIT Module
200befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
201befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstruct copybit_module_t HAL_MODULE_INFO_SYM = {
202befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedcommon: {
203befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedtag: HARDWARE_MODULE_TAG,
204befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     version_major: 1,
205befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     version_minor: 0,
206befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     id: COPYBIT_HARDWARE_MODULE_ID,
207befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     name: "QCT COPYBIT C2D 2.0 Module",
208befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     author: "Qualcomm",
209befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed     methods: &copybit_module_methods
210befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
211befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed};
212befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
213befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
2141cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R/* thread function which waits on the timeStamp and cleans up the surfaces */
2151cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.Rstatic void* c2d_wait_loop(void* ptr) {
2161cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    copybit_context_t* ctx = (copybit_context_t*)(ptr);
2171cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    char thread_name[64] = "copybitWaitThr";
2181cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
2191cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
2201cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
2211cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    while(ctx->stop_thread == false) {
2221cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        pthread_mutex_lock(&ctx->wait_cleanup_lock);
2231cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        while(ctx->wait_timestamp == false && !ctx->stop_thread) {
2241cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            pthread_cond_wait(&(ctx->wait_cleanup_cond),
2251cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                              &(ctx->wait_cleanup_lock));
2261cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        }
2271cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        if(ctx->wait_timestamp) {
2281cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            if(LINK_c2dWaitTimestamp(ctx->time_stamp)) {
2291cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__);
2301cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            }
2311cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            ctx->wait_timestamp = false;
2321cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            // Unmap any mapped addresses.
2331cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            for (int i = 0; i < MAX_SURFACES; i++) {
2341cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                if (ctx->mapped_gpu_addr[i]) {
2351cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                    LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
2361cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                    ctx->mapped_gpu_addr[i] = 0;
2371cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                }
2381cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            }
2391cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            // Reset the counts after the draw.
2401cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            ctx->blit_rgb_count = 0;
2411cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            ctx->blit_yuv_2_plane_count = 0;
2421cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            ctx->blit_yuv_3_plane_count = 0;
2431cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            ctx->blit_count = 0;
244c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            ctx->dst_surface_mapped = false;
245c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            ctx->dst_surface_base = 0;
2461cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        }
2471cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
2481cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        if(ctx->stop_thread)
2491cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            break;
2501cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    }
2511cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_exit(NULL);
2521cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    return NULL;
2531cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R}
2541cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
2551cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
256befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* convert COPYBIT_FORMAT to C2D format */
257befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_format(int format) {
258befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (format) {
259befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGB_565:        return C2D_COLOR_FORMAT_565_RGB;
260befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
261befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                              C2D_FORMAT_SWAP_RB |
262befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                  C2D_FORMAT_DISABLE_ALPHA;
263befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
264befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                              C2D_FORMAT_SWAP_RB;
265befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_BGRA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
266befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
267befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
268befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
269befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 |
270befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                  C2D_FORMAT_MACROTILED;
271728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        default:                              ALOGE("%s: invalid format (0x%x",
272728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                     __FUNCTION__, format);
273728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                              return -EINVAL;
274befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
275befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return -EINVAL;
276befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
277befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
278befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Get the C2D formats needed for conversion to YUV */
279befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_c2d_format_for_yuv_destination(int halFormat) {
280befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (halFormat) {
281befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // We do not swap the RB when the target is YUV
282befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
283befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                              C2D_FORMAT_DISABLE_ALPHA;
284befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
285728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        // The U and V need to be interchanged when the target is YUV
286befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
287befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21;
288befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
289befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:                              return get_format(halFormat);
290befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
291befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return -EINVAL;
292befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
293befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
294befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* ------------------------------------------------------------------- *//*!
295befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \internal
296befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \brief Get the bpp for a particular color format
297befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \param color format
298befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * \return bits per pixel
299befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed *//* ------------------------------------------------------------------- */
300befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedint c2diGetBpp(int32 colorformat)
301befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
302befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
303befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int c2dBpp = 0;
304befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
305befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(colorformat&0xFF)
306befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    {
307befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4444_RGBA:
308befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4444_ARGB:
309befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_1555_ARGB:
310befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_565_RGB:
311befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_5551_RGBA:
312befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 16;
313befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
314befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_RGBA:
315befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_ARGB:
316befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 32;
317befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
318befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8_L:
319befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8_A:
320befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 8;
321befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
322befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4_A:
323befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 4;
324befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
325befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_1:
326befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            c2dBpp = 1;
327befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
328befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
329befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s ERROR", __func__);
330befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
331befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
332befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return c2dBpp;
333befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
334befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
33546f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusustatic size_t c2d_get_gpuaddr(copybit_context_t* ctx,
336c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R                              struct private_handle_t *handle, int &mapped_idx)
337befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
33846f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    uint32 memtype;
33946f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    size_t *gpuaddr = 0;
340befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_STATUS rc;
341c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    int freeindex = 0;
342c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    bool mapaddr = false;
343befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
344befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!handle)
345befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return 0;
346befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
347befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (handle->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
348befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                         private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP))
349befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memtype = KGSL_USER_MEM_TYPE_PMEM;
350befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)
351befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memtype = KGSL_USER_MEM_TYPE_ASHMEM;
352befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
353befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memtype = KGSL_USER_MEM_TYPE_ION;
354befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    else {
355befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("Invalid handle flags: 0x%x", handle->flags);
356befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return 0;
357befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
358befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
359c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    // Check for a freeindex in the mapped_gpu_addr list
360c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    for (freeindex = 0; freeindex < MAX_SURFACES; freeindex++) {
361c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        if (ctx->mapped_gpu_addr[freeindex] == 0) {
362c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            // free index is available
363c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            // map GPU addr and use this as mapped_idx
364c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            mapaddr = true;
365c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            break;
366728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
367c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    }
368728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
369c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    if(mapaddr) {
370c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size,
371c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R                             handle->offset, memtype, (void**)&gpuaddr);
372c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R
373c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        if (rc == C2D_STATUS_OK) {
374c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            // We have mapped the GPU address inside copybit. We need to unmap
375c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            // this address after the blit. Store this address
37646f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu            ctx->mapped_gpu_addr[freeindex] = (size_t)gpuaddr;
377c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            mapped_idx = freeindex;
378c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        }
379befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
38046f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    return (size_t)gpuaddr;
381befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
382befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
383728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.Rstatic void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx)
384728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R{
385728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (!ctx || (mapped_idx == -1))
386728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return;
387728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
388728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (ctx->mapped_gpu_addr[mapped_idx]) {
389728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]);
390728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->mapped_gpu_addr[mapped_idx] = 0;
391728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
392728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R}
393728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
394befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_supported_rgb_format(int format)
395befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
396befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(format) {
397befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:
398befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:
399befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_RGB_565:
4007ec65cb986e25337bf4066437300f6adbfe1e350Mathias Agopian        case HAL_PIXEL_FORMAT_BGRA_8888: {
401befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_SUCCESS;
402befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
403befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
404befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
405befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
406befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
407befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
408befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_num_planes(int format)
409befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
410befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(format) {
411befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
412befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
413befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
414befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
415befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return 2;
416befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
417befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YV12: {
418befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return 3;
419befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
420befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
421befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
422befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
423befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
424befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
425befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_supported_yuv_format(int format)
426befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
427befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(format) {
428befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
429befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
430befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
431befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
432befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_SUCCESS;
433befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
434befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
435befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
436befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
437befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
438befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
439befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_valid_destination_format(int format)
440befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
441befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
442befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        // C2D does not support NV12Tile as a destination format.
443befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
444befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
445befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return COPYBIT_SUCCESS;
446befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
447befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
448befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int calculate_yuv_offset_and_stride(const bufferInfo& info,
449befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                           yuvPlaneInfo& yuvInfo)
450befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
451befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int width  = info.width;
452befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int height = info.height;
453befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int format = info.format;
454befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
455befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int aligned_height = 0;
456befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int aligned_width = 0, size = 0;
457befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
458befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (format) {
459befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
460befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            /* NV12 Tile buffers have their luma height aligned to 32bytes and width
461befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed             * aligned to 128 bytes. The chroma offset starts at an 8K boundary
462befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed             */
463befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            aligned_height = ALIGN(height, 32);
464befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            aligned_width  = ALIGN(width, 128);
465befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            size = aligned_width * aligned_height;
466befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.plane1_offset = ALIGN(size,8192);
467befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.yStride = aligned_width;
468befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.plane1_stride = aligned_width;
469befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
470befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
471befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
472befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
473befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
474befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            aligned_width = ALIGN(width, 32);
475befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.yStride = aligned_width;
476befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            yuvInfo.plane1_stride = aligned_width;
477befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
478befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                // The encoder requires a 2K aligned chroma offset
479befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048);
480befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } else
481befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                yuvInfo.plane1_offset = aligned_width * height;
482befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
483befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
484befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
485befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default: {
486befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
487befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
488befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
489befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return COPYBIT_SUCCESS;
490befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
491befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
492befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** create C2D surface from copybit image */
493728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.Rstatic int set_image(copybit_context_t* ctx, uint32 surfaceId,
494728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                      const struct copybit_image_t *rhs,
495728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                      const eC2DFlags flags, int &mapped_idx)
496befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
497befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
498befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_SURFACE_TYPE surfaceType;
499befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = COPYBIT_SUCCESS;
50046f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    uintptr_t gpuaddr = 0;
501728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    int c2d_format;
502728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    mapped_idx = -1;
503befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
504befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (flags & FLAGS_YUV_DESTINATION) {
505728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        c2d_format = get_c2d_format_for_yuv_destination(rhs->format);
506befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
507728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        c2d_format = get_format(rhs->format);
508befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
509befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
510728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if(c2d_format == -EINVAL) {
511befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: invalid format", __FUNCTION__);
512befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
513befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
514befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
515befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(handle == NULL) {
516befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: invalid handle", __func__);
517befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
518befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
519befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
520befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (handle->gpuaddr == 0) {
521728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx);
522728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if(!gpuaddr) {
523befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
524befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            return COPYBIT_FAILURE;
525befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
526728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    } else {
527728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        gpuaddr = handle->gpuaddr;
528befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
529befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
530befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* create C2D surface */
531befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
532befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        /* RGB */
533befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        C2D_RGB_SURFACE_DEF surfaceDef;
534befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
535befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS);
536befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
537728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        surfaceDef.phys = (void*) gpuaddr;
538befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.buffer = (void*) (handle->base);
539befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
540728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        surfaceDef.format = c2d_format |
541befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
542befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.width = rhs->w;
543befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.height = rhs->h;
54446f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu        int aligned_width = ALIGN((int)surfaceDef.width,32);
545befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;
546befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
547728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
548728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                  &surfaceDef)) {
549befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__);
550728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_idx);
551befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            status = COPYBIT_FAILURE;
552befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
553befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
554befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        C2D_YUV_SURFACE_DEF surfaceDef;
555befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memset(&surfaceDef, 0, sizeof(surfaceDef));
556befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS);
557728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        surfaceDef.format = c2d_format;
558befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
559befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        bufferInfo info;
560befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.width = rhs->w;
561befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.height = rhs->h;
562befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        info.format = rhs->format;
563befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
5645aa9f9bebbb02ccfe9b6a4e5a092c8bd324e0e88Naseer Ahmed        yuvPlaneInfo yuvInfo = {0};
565befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = calculate_yuv_offset_and_stride(info, yuvInfo);
566befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(status != COPYBIT_SUCCESS) {
567befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
568728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_idx);
569befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
570befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
571befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.width = rhs->w;
572befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.height = rhs->h;
573befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.plane0 = (void*) (handle->base);
574728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        surfaceDef.phys0 = (void*) (gpuaddr);
575befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride0 = yuvInfo.yStride;
576befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
577befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
578728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset);
579befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        surfaceDef.stride1 = yuvInfo.plane1_stride;
580befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if (3 == get_num_planes(rhs->format)) {
581befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset);
582728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset);
583befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            surfaceDef.stride2 = yuvInfo.plane2_stride;
584befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
585befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
586befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
587befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                  &surfaceDef)) {
588befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__);
589728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_idx);
590befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            status = COPYBIT_FAILURE;
591befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
592befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
593befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
594728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_idx);
595befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        status = COPYBIT_FAILURE;
596befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
597befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
598befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
599befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
600befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
601728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R/** copy the bits */
602728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.Rstatic int msm_copybit(struct copybit_context_t *ctx, unsigned int target)
603befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
604728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (ctx->blit_count == 0) {
605728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return COPYBIT_SUCCESS;
606728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
607befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
608728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < ctx->blit_count; i++)
609befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    {
610728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->blit_list[i].next = &(ctx->blit_list[i+1]);
611befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
612728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_list[ctx->blit_count-1].next = NULL;
6135ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R    uint32_t target_transform = ctx->trg_transform;
6145ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R    if (ctx->c2d_driver_info.capabilities_mask &
6155ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R        C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
6165ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R        // For A3xx - set 0x0 as the transform is set in the config_mask
6175ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R        target_transform = 0x0;
6185ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R    }
6195ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R    if(LINK_c2dDraw(target, target_transform, 0x0, 0, 0, ctx->blit_list,
620728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                    ctx->blit_count)) {
621728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
622728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return COPYBIT_FAILURE;
623befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
624befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return COPYBIT_SUCCESS;
625befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
626befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
627befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
6281cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
6291cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.Rstatic int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd)
6301cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R{
6311cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
6321cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    int status = COPYBIT_FAILURE;
6331cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    if (!ctx)
6341cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        return COPYBIT_FAILURE;
6351cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
6361cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
6371cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
6381cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) {
6391cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__);
6401cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        // unlock the mutex and return failure
6411cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
6421cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        return COPYBIT_FAILURE;
6431cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    }
6441cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp,
6451cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                                                                        fd)) {
6461cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__);
6471cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        status = COPYBIT_FAILURE;
6481cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    }
6491cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    if(status == COPYBIT_SUCCESS) {
6501cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        //signal the wait_thread
6511cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        ctx->wait_timestamp = true;
6521cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R        pthread_cond_signal(&ctx->wait_cleanup_cond);
6531cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    }
6541cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
6551cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    return status;
6561cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R}
6571cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
658728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.Rstatic int finish_copybit(struct copybit_device_t *dev)
659befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
660728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
661728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (!ctx)
662728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return COPYBIT_FAILURE;
663befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
664728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R   int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
665befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
666728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R   if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) {
667728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
668728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return COPYBIT_FAILURE;
669befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
670befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
671728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Unmap any mapped addresses.
672728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < MAX_SURFACES; i++) {
673728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (ctx->mapped_gpu_addr[i]) {
674728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
675728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->mapped_gpu_addr[i] = 0;
676befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        }
677befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
678befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
679728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Reset the counts after the draw.
680728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_rgb_count = 0;
681728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_yuv_2_plane_count = 0;
682728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_yuv_3_plane_count = 0;
683728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_count = 0;
6846bf5ee9ee7e318d1d5011bc26aaa80bfe8bd880bPawan Kumar    ctx->dst_surface_mapped = false;
6856bf5ee9ee7e318d1d5011bc26aaa80bfe8bd880bPawan Kumar    ctx->dst_surface_base = 0;
6866bf5ee9ee7e318d1d5011bc26aaa80bfe8bd880bPawan Kumar
687befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
688befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
689befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
690347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmedstatic int clear_copybit(struct copybit_device_t *dev,
691347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed                         struct copybit_image_t const *buf,
692347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed                         struct copybit_rect_t *rect)
693347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed{
69461218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    int ret = COPYBIT_SUCCESS;
695347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    int flags = FLAGS_PREMULTIPLIED_ALPHA;
696347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    int mapped_dst_idx = -1;
697347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
698347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
69961218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
700c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R    if(!ctx->dst_surface_mapped) {
701c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf,
702c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R                        (eC2DFlags)flags, mapped_dst_idx);
703c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        if(ret) {
704c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            ALOGE("%s: set_image error", __FUNCTION__);
705c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            unmap_gpuaddr(ctx, mapped_dst_idx);
706c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            pthread_mutex_unlock(&ctx->wait_cleanup_lock);
707c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R            return COPYBIT_FAILURE;
708c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        }
709c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        //clear_copybit is the first call made by HWC for each composition
710c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        //with the dest surface, hence set dst_surface_mapped.
711c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        ctx->dst_surface_mapped = true;
712c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        ctx->dst_surface_base = buf->base;
713c8d5e1eb3d576d1e54ce6280bb3bddaca6c7c2bdArun Kumar K.R        ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect);
714347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    }
71561218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
716347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    return ret;
717347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed}
718347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed
719347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed
720befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** setup rectangles */
721befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void set_rects(struct copybit_context_t *ctx,
722befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      C2D_OBJECT *c2dObject,
723befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      const struct copybit_rect_t *dst,
724befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      const struct copybit_rect_t *src,
725befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      const struct copybit_rect_t *scissor)
726befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
727befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Set the target rect.
728befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if((ctx->trg_transform & C2D_TARGET_ROTATE_90) &&
729befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed       (ctx->trg_transform & C2D_TARGET_ROTATE_180)) {
730befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        /* target rotation is 270 */
731befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = (dst->t)<<16;
73246f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu        c2dObject->target_rect.y        = ctx->fb_width?
73346f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu                (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;
74646f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu        c2dObject->target_rect.x        = ctx->fb_width?
74746f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu                (ALIGN(ctx->fb_width,32) - dst->r):dst->r;
748befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
749befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
750befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
751befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    } else {
752befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.x        = (dst->l)<<16;
753befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.y        = (dst->t)<<16;
754befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
755befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
756befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
757befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->config_mask |= C2D_TARGET_RECT_BIT;
758befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
759befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Set the source rect
760befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.x        = (src->l)<<16;
761befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.y        = (src->t)<<16;
762befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.height   = ((src->b) - (src->t))<<16;
763befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->source_rect.width    = ((src->r) - (src->l))<<16;
764befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->config_mask |= C2D_SOURCE_RECT_BIT;
765befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
766befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Set the scissor rect
767befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.x       = scissor->l;
768befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.y       = scissor->t;
769befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.height  = (scissor->b) - (scissor->t);
770befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->scissor_rect.width   = (scissor->r) - (scissor->l);
771befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT;
772befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
773befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
774befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*****************************************************************************/
775befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
776befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Set a parameter to value */
777befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int set_parameter_copybit(
778befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t *dev,
779befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int name,
780befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int value)
781befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
782befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
7831cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    int status = COPYBIT_SUCCESS;
784befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!ctx) {
785befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: null context", __FUNCTION__);
786befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
787befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
788befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
7891cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
790befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(name) {
791befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_PLANE_ALPHA:
792728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        {
793befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (value < 0)      value = 0;
794befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            if (value >= 256)   value = 255;
795befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
796728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->src_global_alpha = value;
797728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            if (value < 255)
798728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT;
799befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            else
800728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT;
801728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
802728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        break;
803728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        case COPYBIT_BLEND_MODE:
804728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        {
805728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            if (value == COPYBIT_BLENDING_NONE) {
806728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->config_mask |= C2D_ALPHA_BLEND_NONE;
807728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->is_premultiplied_alpha = true;
808728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            } else if (value == COPYBIT_BLENDING_PREMULT) {
809728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->is_premultiplied_alpha = true;
810728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            } else {
811728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE;
812728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            }
813728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
814728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        break;
815befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_TRANSFORM:
816728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        {
817728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            unsigned int transform = 0;
818728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            uint32 config_mask = 0;
819728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG;
820728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) {
821728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                transform = C2D_TARGET_ROTATE_180;
822728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180;
823728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) {
824728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                transform = C2D_TARGET_ROTATE_90;
825728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90;
826728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            } else if(value == COPYBIT_TRANSFORM_ROT_90) {
827728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                transform = C2D_TARGET_ROTATE_270;
828728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270;
829728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            } else {
830728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0;
831728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                if(value & COPYBIT_TRANSFORM_FLIP_H) {
832728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                    config_mask |= C2D_MIRROR_H_BIT;
833728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                } else if(value & COPYBIT_TRANSFORM_FLIP_V) {
834728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                    config_mask |= C2D_MIRROR_V_BIT;
835728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                }
836befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            }
837728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
8385ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R            if (ctx->c2d_driver_info.capabilities_mask &
8395ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
8405ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                ctx->config_mask |= config_mask;
8415ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R            } else {
8425ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                // The transform for this surface does not match the current
8435ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                // target transform. Draw all previous surfaces. This will be
8445ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                // changed once we have a new mechanism to send different
8455ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                // target rotations to c2d.
8465ac5b81b6124110c21edd3164a83fbfaece83910Arun Kumar K.R                finish_copybit(dev);
847728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            }
848728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->trg_transform = transform;
849728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
850728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        break;
851befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_FRAMEBUFFER_WIDTH:
852befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->fb_width = value;
853befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
854befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_FRAMEBUFFER_HEIGHT:
855befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ctx->fb_height = value;
856befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
857728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        case COPYBIT_ROTATION_DEG:
858728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        case COPYBIT_DITHER:
859728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        case COPYBIT_BLUR:
860e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed        case COPYBIT_BLIT_TO_FRAMEBUFFER:
861728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            // Do nothing
862e2cb361a1ac1df575a6316b691f49b6bad177a2eNaseer Ahmed            break;
863befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
864befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
8651cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R            status = -EINVAL;
866befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
867befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
8681cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
8691cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    return status;
870befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
871befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
872befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Get a static info value */
873befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get(struct copybit_device_t *dev, int name)
874befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
875befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
876befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int value;
877befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
878befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!ctx) {
879befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: null context error", __FUNCTION__);
880befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return -EINVAL;
881befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
882befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
883befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(name) {
884befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_MINIFICATION_LIMIT:
885befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = MAX_SCALE_FACTOR;
886befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
887befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_MAGNIFICATION_LIMIT:
888befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = MAX_SCALE_FACTOR;
889befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
890befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_SCALING_FRAC_BITS:
891befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = 32;
892befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
893befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case COPYBIT_ROTATION_STEP_DEG:
894befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = 1;
895befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
896befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
897befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
898befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            value = -EINVAL;
899befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
900befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return value;
901befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
902befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
903befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int is_alpha(int cformat)
904befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
905befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int alpha = 0;
906befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch (cformat & 0xFF) {
907befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_ARGB:
908befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_8888_RGBA:
909befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_5551_RGBA:
910befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case C2D_COLOR_FORMAT_4444_ARGB:
911befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            alpha = 1;
912befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
913befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default:
914befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            alpha = 0;
915befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            break;
916befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
917befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
918befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(alpha && (cformat&C2D_FORMAT_DISABLE_ALPHA))
919befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        alpha = 0;
920befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
921befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return alpha;
922befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
923befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
924befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to check if we need a temporary buffer for the blit.
925befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * This would happen if the requested destination stride and the
926befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * C2D stride do not match. We ignore RGB buffers, since their
927befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * stride is always aligned to 32.
928befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
929befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic bool need_temp_buffer(struct copybit_image_t const *img)
930befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
931befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format))
932befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return false;
933befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
934befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct private_handle_t* handle = (struct private_handle_t*)img->handle;
935befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
936befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // The width parameter in the handle contains the aligned_w. We check if we
937befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // need to convert based on this param. YUV formats have bpp=1, so checking
938befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // if the requested stride is aligned should suffice.
939befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (0 == (handle->width)%32) {
940befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return false;
941befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
942befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
943befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return true;
944befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
945befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
946befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to extract the information from the copybit image and set the corresponding
947befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * values in the bufferInfo struct.
948befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
949befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info)
950befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
951befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    info.width = img->w;
952befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    info.height = img->h;
953befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    info.format = img->format;
954befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
955befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
956befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to get the required size for a particular format, inorder for C2D to perform
957befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * the blit operation.
958befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
959befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic size_t get_size(const bufferInfo& info)
960befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
96146f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    int size = 0;
962befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int w = info.width;
963befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int h = info.height;
964befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int aligned_w = ALIGN(w, 32);
965befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(info.format) {
966befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
967befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            {
968befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                // Chroma for this format is aligned to 2K.
969befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                size = ALIGN((aligned_w*h), 2048) +
970728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                        ALIGN(aligned_w/2, 32) * (h/2) *2;
971befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                size = ALIGN(size, 4096);
972befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } break;
973befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
974befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
975befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            {
976728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                size = aligned_w * h +
977728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                       ALIGN(aligned_w/2, 32) * (h/2) * 2;
978befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                size = ALIGN(size, 4096);
979befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } break;
980befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default: break;
981befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
982befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return size;
983befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
984befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
985befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to allocate memory for the temporary buffer. This memory is
986befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * allocated from Ashmem. It is the caller's responsibility to free this
987befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * memory.
988befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
989befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int get_temp_buffer(const bufferInfo& info, alloc_data& data)
990befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
991befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ALOGD("%s E", __FUNCTION__);
992befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Alloc memory from system heap
993befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.base = 0;
994befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.fd = -1;
995befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.offset = 0;
996befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.size = get_size(info);
997befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.align = getpagesize();
998befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    data.uncached = true;
999befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int allocFlags = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
1000befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1001befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (sAlloc == 0) {
1002be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        sAlloc = gralloc::IAllocController::getInstance();
1003befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1004befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1005befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (sAlloc == 0) {
1006befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: sAlloc is still NULL", __FUNCTION__);
1007befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1008befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1009befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1010be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed    int err = sAlloc->allocate(data, allocFlags);
1011befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (0 != err) {
1012befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: allocate failed", __FUNCTION__);
1013befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1014befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1015befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1016befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ALOGD("%s X", __FUNCTION__);
1017befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return err;
1018befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1019befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1020befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to free the temporary allocated memory.*/
1021befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void free_temp_buffer(alloc_data &data)
1022befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1023befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (-1 != data.fd) {
1024be2e1bb9057c8d0666de057743eeb898c78f34b0Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType);
1025befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        memalloc->free_buffer(data.base, data.size, 0, data.fd);
1026befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1027befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1028befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1029befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/* Function to perform the software color conversion. Convert the
1030befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed * C2D compatible format to the Android compatible format
1031befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed */
1032befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int copy_image(private_handle_t *src_handle,
1033befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      struct copybit_image_t const *rhs,
1034befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                      eConversionType conversionType)
1035befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1036befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (src_handle->fd == -1) {
1037befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: src_handle fd is invalid", __FUNCTION__);
1038befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1039befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1040befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1041befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    // Copy the info.
1042befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int ret = COPYBIT_SUCCESS;
1043befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    switch(rhs->format) {
1044befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1045befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1046befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1047befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            {
1048befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                if (CONVERT_TO_ANDROID_FORMAT == conversionType) {
1049befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    return convert_yuv_c2d_to_yuv_android(src_handle, rhs);
1050befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                } else {
1051befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                    return convert_yuv_android_to_yuv_c2d(src_handle, rhs);
1052befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                }
1053befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1054befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            } break;
1055befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        default: {
1056befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
1057befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed            ret = COPYBIT_FAILURE;
1058befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        } break;
1059befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1060befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return ret;
1061befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1062befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1063befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic void delete_handle(private_handle_t *handle)
1064befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1065befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (handle) {
1066befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        delete handle;
1067befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        handle = 0;
1068befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1069befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1070728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
107146f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusustatic bool need_to_execute_draw(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;
118846f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu        dst_hnd->base = (uintptr_t)(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;
127346f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu        src_hnd->base = (uintptr_t)(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;
135746f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    if (need_to_execute_draw((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,
139146f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    int /*acquireFenceFd*/)
1392ac791ef899d93baf8bc2545b2e81f6a71d9bfbc1Terence Hampson{
139346f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    if(!dev)
139446f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu        return -EINVAL;
139546f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu
1396ac791ef899d93baf8bc2545b2e81f6a71d9bfbc1Terence Hampson    return 0;
1397ac791ef899d93baf8bc2545b2e81f6a71d9bfbc1Terence Hampson}
1398728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1399befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int stretch_copybit(
1400befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t *dev,
1401befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *dst,
1402befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *src,
1403befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t const *dst_rect,
1404befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_rect_t const *src_rect,
1405befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_region_t const *region)
1406befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1407befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
14081cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    int status = COPYBIT_SUCCESS;
1409728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    bool needsBlending = (ctx->src_global_alpha != 0);
14101cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
14111cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
1412befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                    region, needsBlending);
14131cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
14141cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    return status;
1415befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1416befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1417befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Perform a blit type operation */
1418befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int blit_copybit(
1419befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_device_t *dev,
1420befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *dst,
1421befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_image_t const *src,
1422befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_region_t const *region)
1423befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
142461218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    int status = COPYBIT_SUCCESS;
142561218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1426a95531ebf897fcff256840094a6c3e07e3cd578eNaseer Ahmed    struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
1427a95531ebf897fcff256840094a6c3e07e3cd578eNaseer Ahmed    struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
142861218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
142961218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    status = stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false);
143061218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
143161218d1716f5a55cebe31da2ad8a8d805e2df81aArun Kumar K.R    return status;
1432befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1433befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1434905042d4ea8c4c736ea248b694d93ef2f59866d5Sushil Chauhan/** Fill the rect on dst with RGBA color **/
1435905042d4ea8c4c736ea248b694d93ef2f59866d5Sushil Chauhanstatic int fill_color(struct copybit_device_t *dev,
1436905042d4ea8c4c736ea248b694d93ef2f59866d5Sushil Chauhan                      struct copybit_image_t const *dst,
1437905042d4ea8c4c736ea248b694d93ef2f59866d5Sushil Chauhan                      struct copybit_rect_t const *rect,
143846f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu                      uint32_t /*color*/)
1439905042d4ea8c4c736ea248b694d93ef2f59866d5Sushil Chauhan{
1440905042d4ea8c4c736ea248b694d93ef2f59866d5Sushil Chauhan    // TODO: Implement once c2d driver supports color fill
144146f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    if(!dev || !dst || !rect)
144246f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu       return -EINVAL;
144346f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu
1444905042d4ea8c4c736ea248b694d93ef2f59866d5Sushil Chauhan    return -EINVAL;
1445905042d4ea8c4c736ea248b694d93ef2f59866d5Sushil Chauhan}
1446905042d4ea8c4c736ea248b694d93ef2f59866d5Sushil Chauhan
1447befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/*****************************************************************************/
1448befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1449728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.Rstatic void clean_up(copybit_context_t* ctx)
1450728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R{
14511cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    void* ret;
1452728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (!ctx)
1453728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return;
1454728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
14551cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    // stop the wait_cleanup_thread
14561cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
14571cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    ctx->stop_thread = true;
14581cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    // Signal waiting thread
14591cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_cond_signal(&ctx->wait_cleanup_cond);
14601cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
14611cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    // waits for the cleanup thread to exit
14621cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_join(ctx->wait_thread_id, &ret);
14631cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_destroy(&ctx->wait_cleanup_lock);
14641cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_cond_destroy (&ctx->wait_cleanup_cond);
14651cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
1466728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < NUM_SURFACE_TYPES; i++) {
1467728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (ctx->dst[i])
1468728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            LINK_c2dDestroySurface(ctx->dst[i]);
1469728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1470728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1471728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < MAX_RGB_SURFACES; i++) {
1472728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (ctx->blit_rgb_object[i].surface_id)
1473728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id);
1474728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1475728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1476728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) {
1477728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (ctx->blit_yuv_2_plane_object[i].surface_id)
1478728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id);
1479728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1480728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1481728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) {
1482728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (ctx->blit_yuv_3_plane_object[i].surface_id)
1483728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id);
1484728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1485728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1486728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (ctx->libc2d2) {
1487728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ::dlclose(ctx->libc2d2);
1488728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGV("dlclose(libc2d2)");
1489728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1490728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1491728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    free(ctx);
1492728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R}
1493728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1494befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Close the copybit device */
1495befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int close_copybit(struct hw_device_t *dev)
1496befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1497befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1498befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (ctx) {
1499befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        free_temp_buffer(ctx->temp_src_buffer);
1500befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        free_temp_buffer(ctx->temp_dst_buffer);
1501befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1502728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    clean_up(ctx);
1503befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return 0;
1504befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1505befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1506befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed/** Open a new instance of a copybit device using name */
1507befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
1508befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                        struct hw_device_t** device)
1509befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed{
1510befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    int status = COPYBIT_SUCCESS;
151146f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
151246f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu        return COPYBIT_FAILURE;
151346f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu    }
151446f5ca8de60939f8ee16f63ba244b46e1353bab8Praveena Pachipulusu
1515befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_RGB_SURFACE_DEF surfDefinition = {0};
1516befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
1517befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    struct copybit_context_t *ctx;
1518befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1519befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
1520befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if(!ctx) {
1521befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: malloc failed", __FUNCTION__);
1522befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        return COPYBIT_FAILURE;
1523befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1524befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1525befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* initialize drawstate */
1526befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    memset(ctx, 0, sizeof(*ctx));
1527befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
1528befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!ctx->libc2d2) {
1529befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
1530728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1531728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1532728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1533728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1534befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1535befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2,
1536befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                               "c2dCreateSurface");
1537befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2,
1538befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                               "c2dUpdateSurface");
1539befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2,
1540befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                             "c2dReadSurface");
1541befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw");
1542befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush");
1543befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish");
1544befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2,
1545befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                               "c2dWaitTimestamp");
1546befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2,
1547befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                                "c2dDestroySurface");
1548befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2,
1549befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                         "c2dMapAddr");
1550befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2,
1551befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                                           "c2dUnMapAddr");
1552728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2,
1553728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                           "c2dGetDriverCapabilities");
15541cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
15551cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                                           "c2dCreateFenceFD");
1556347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2,
1557347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed                                           "c2dFillSurface");
1558befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1559befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
1560728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
1561728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
1562347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD ||
1563347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed        !LINK_c2dFillSurface) {
1564befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed        ALOGE("%s: dlsym ERROR", __FUNCTION__);
1565728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1566728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1567728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1568728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1569befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1570befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1571befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
1572befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.version = 1;
1573befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.module = (hw_module_t*)(module);
1574befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.common.close = close_copybit;
1575befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.set_parameter = set_parameter_copybit;
1576befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.get = get;
1577befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.blit = blit_copybit;
1578ac791ef899d93baf8bc2545b2e81f6a71d9bfbc1Terence Hampson    ctx->device.set_sync = set_sync_copybit;
1579befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->device.stretch = stretch_copybit;
1580728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->device.finish = finish_copybit;
15811cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    ctx->device.flush_get_fence = flush_get_fence_copybit;
1582347ca48efbcf8055f1ae733d9c0126bb5a9db8c6Naseer Ahmed    ctx->device.clear = clear_copybit;
1583905042d4ea8c4c736ea248b694d93ef2f59866d5Sushil Chauhan    ctx->device.fill_color = fill_color;
1584befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1585befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    /* Create RGB Surface */
1586befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.buffer = (void*)0xdddddddd;
1587befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.phys = (void*)0xdddddddd;
1588befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.stride = 1 * 4;
1589befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.width = 1;
1590befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.height = 1;
1591befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB;
1592befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
1593befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
1594728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
1595728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
1596728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 &surfDefinition)) {
1597728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__);
1598728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->dst[RGB_SURFACE] = 0;
1599728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1600728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1601728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1602728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1603befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1604befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1605728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    unsigned int surface_id = 0;
1606728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i = 0; i < MAX_RGB_SURFACES; i++)
1607728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    {
1608728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
1609befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
1610728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
1611728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
1612728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 &surfDefinition)) {
1613728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i);
1614728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_rgb_object[i].surface_id = 0;
1615728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            status = COPYBIT_FAILURE;
1616728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            break;
1617728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        } else {
1618728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_rgb_object[i].surface_id = surface_id;
1619728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGW("%s i = %d surface_id=%d",  __FUNCTION__, i,
1620728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                          ctx->blit_rgb_object[i].surface_id);
1621728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
1622befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1623befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1624728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (status == COPYBIT_FAILURE) {
1625728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1626728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1627728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1628728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1629728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1630befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1631728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Create 2 plane YUV surfaces
1632728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
1633befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.width = 4;
1634befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.height = 4;
1635befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa;
1636befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa;
1637befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.stride0 = 4;
1638befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1639befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa;
1640befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa;
1641befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.stride1 = 4;
1642728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),
1643befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              C2D_TARGET | C2D_SOURCE,
1644728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1645728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                               C2D_SURFACE_WITH_PHYS |
1646728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                               C2D_SURFACE_WITH_PHYS_DUMMY),
1647befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1648728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
1649728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->dst[YUV_SURFACE_2_PLANES] = 0;
1650728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1651728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1652728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1653728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1654befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1655befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1656728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++)
1657728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    {
1658728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
1659728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1660728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
1661728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
1662befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1663728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGE("%s: create YUV source %d failed", __FUNCTION__, i);
1664728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_yuv_2_plane_object[i].surface_id = 0;
1665728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            status = COPYBIT_FAILURE;
1666728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            break;
1667728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        } else {
1668728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_yuv_2_plane_object[i].surface_id = surface_id;
1669728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGW("%s: 2 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
1670728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                   ctx->blit_yuv_2_plane_object[i].surface_id);
1671728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
1672728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1673728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1674728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (status == COPYBIT_FAILURE) {
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    // Create YUV 3 plane surfaces
1682befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
1683befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
1684befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
1685befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    yuvSurfaceDef.stride2 = 4;
1686befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1687728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),
1688befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              C2D_TARGET | C2D_SOURCE,
1689728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1690728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
1691728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
1692befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1693728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
1694728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        ctx->dst[YUV_SURFACE_3_PLANES] = 0;
1695728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1696728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1697728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1698728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1699befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1700befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1701728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++)
1702728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    {
1703728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        if (LINK_c2dCreateSurface(&(surface_id),
1704befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              C2D_TARGET | C2D_SOURCE,
1705728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1706728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
1707728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
1708befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed                              &yuvSurfaceDef)) {
1709728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i);
1710728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_yuv_3_plane_object[i].surface_id = 0;
1711728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            status = COPYBIT_FAILURE;
1712728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            break;
1713728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        } else {
1714728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ctx->blit_yuv_3_plane_object[i].surface_id = surface_id;
1715728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R            ALOGW("%s: 3 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
1716728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R                                   ctx->blit_yuv_3_plane_object[i].surface_id);
1717728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        }
1718befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    }
1719befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1720728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (status == COPYBIT_FAILURE) {
1721728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        clean_up(ctx);
1722728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        status = COPYBIT_FAILURE;
1723728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1724728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1725728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1726728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1727728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) {
1728728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R         ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__);
1729728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R         clean_up(ctx);
1730728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R         status = COPYBIT_FAILURE;
1731728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        *device = NULL;
1732728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R        return status;
1733728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    }
1734728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    // Initialize context variables.
1735728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->trg_transform = C2D_TARGET_ROTATE_0;
1736728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R
1737befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_src_buffer.fd = -1;
1738befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_src_buffer.base = 0;
1739befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_src_buffer.size = 0;
1740befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1741befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_dst_buffer.fd = -1;
1742befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_dst_buffer.base = 0;
1743befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->temp_dst_buffer.size = 0;
1744befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1745befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->fb_width = 0;
1746befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    ctx->fb_height = 0;
1747befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
1748728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_rgb_count = 0;
1749728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_yuv_2_plane_count = 0;
1750728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_yuv_3_plane_count = 0;
1751728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    ctx->blit_count = 0;
1752befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed
17531cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    ctx->wait_timestamp = false;
17541cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    ctx->stop_thread = false;
17551cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL);
17561cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_cond_init(&(ctx->wait_cleanup_cond), NULL);
17571cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    /* Start the wait thread */
17581cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_attr_t attr;
17591cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_attr_init(&attr);
17601cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
17611cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
17621cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop,
17631cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R                                                            (void *)ctx);
17641cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R    pthread_attr_destroy(&attr);
17651cde4ed563137d7e6fb7a097078487d684707628Arun Kumar K.R
1766728ab97888cb24692332a038dd12cc16b2b25014Arun Kumar K.R    *device = &ctx->device.common;
1767befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed    return status;
1768befc466069680cb8a65b1f22ad44723d949128c8Naseer Ahmed}
1769