129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Copyright (C) 2008 The Android Open Source Project
39ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R * Copyright (c) 2010-2013, The Linux Foundation. All rights reserved.
49ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R *
59ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R * Not a Contribution, Apache license notifications and license are retained
69ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R * for attribution purposes only.
729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Licensed under the Apache License, Version 2.0 (the "License");
929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * you may not use this file except in compliance with the License.
1029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * You may obtain a copy of the License at
1129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
1229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *      http://www.apache.org/licenses/LICENSE-2.0
1329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *
1429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Unless required by applicable law or agreed to in writing, software
1529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * distributed under the License is distributed on an "AS IS" BASIS,
1629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * See the License for the specific language governing permissions and
1829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * limitations under the License.
1929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
2029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <cutils/log.h>
21647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R#include <sys/resource.h>
22647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R#include <sys/prctl.h>
2329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
2429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <stdint.h>
2529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <string.h>
2629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <unistd.h>
2729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <errno.h>
2829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <fcntl.h>
2929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <sys/ioctl.h>
3129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <sys/types.h>
3229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <sys/mman.h>
3329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <linux/msm_kgsl.h>
3529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <EGL/eglplatform.h>
3729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <cutils/native_handle.h>
3829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <cutils/ashmem.h>
3929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <linux/ashmem.h>
4029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <gralloc_priv.h>
4129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <copybit.h>
4329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <alloc_controller.h>
4429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <memalloc.h>
4529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "c2d2.h"
4729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include "software_converter.h"
4829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
4929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#include <dlfcn.h>
5029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedusing gralloc::IMemAlloc;
5229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedusing gralloc::IonController;
5329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedusing gralloc::alloc_data;
5429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5529a26818d7294055539167b2fbfdaa168bcf725cNaseer AhmedC2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
5629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                     uint32 surface_bits,
5729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                     C2D_SURFACE_TYPE surface_type,
5829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                     void *surface_definition );
5929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6029a26818d7294055539167b2fbfdaa168bcf725cNaseer AhmedC2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id,
6129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                     uint32 surface_bits,
6229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                     C2D_SURFACE_TYPE surface_type,
6329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                     void *surface_definition );
6429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6529a26818d7294055539167b2fbfdaa168bcf725cNaseer AhmedC2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id,
6629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                   C2D_SURFACE_TYPE surface_type,
6729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                   void *surface_definition,
6829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                   int32 x, int32 y );
6929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7029a26818d7294055539167b2fbfdaa168bcf725cNaseer AhmedC2D_STATUS (*LINK_c2dDraw)( uint32 target_id,
7129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                            uint32 target_config, C2D_RECT *target_scissor,
7229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                            uint32 target_mask_id, uint32 target_color_key,
7329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                            C2D_OBJECT *objects_list, uint32 num_objects );
7429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7529a26818d7294055539167b2fbfdaa168bcf725cNaseer AhmedC2D_STATUS (*LINK_c2dFinish)( uint32 target_id);
7629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7729a26818d7294055539167b2fbfdaa168bcf725cNaseer AhmedC2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp);
7829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7929a26818d7294055539167b2fbfdaa168bcf725cNaseer AhmedC2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp );
8029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
8129a26818d7294055539167b2fbfdaa168bcf725cNaseer AhmedC2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
8229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
839ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.RC2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, uint32 len,
849ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                uint32 offset, uint32 flags, void ** gpuaddr);
8529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
8629a26818d7294055539167b2fbfdaa168bcf725cNaseer AhmedC2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
8729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
889ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.RC2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info);
89647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
90647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R/* create a fence fd for the timestamp */
91647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.RC2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
92647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R                                                            int32 *fd);
936f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed
946f51cecb2be306aef008773d61fea4ce7b896fc9Naseer AhmedC2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color,
956f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed                                    C2D_RECT * fill_rect);
966f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed
9729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/******************************************************************************/
9829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
9929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#if defined(COPYBIT_Z180)
10029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define MAX_SCALE_FACTOR    (4096)
10129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#define MAX_DIMENSION       (4096)
10229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#else
10329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#error "Unsupported HW version"
10429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed#endif
10529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
1069ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R// The following defines can be changed as required i.e. as we encounter
1079ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R// complex use cases.
1089ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R#define MAX_RGB_SURFACES 8        // Max. RGB layers currently supported per draw
1099ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R#define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw
1109ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R#define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw
1119ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R// +1 for the destination surface. We cannot have multiple destination surfaces.
1129ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R#define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1)
1139ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R#define NUM_SURFACE_TYPES 3      // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES
1149ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R#define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw
11529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
11629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedenum {
11729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    RGB_SURFACE,
11829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    YUV_SURFACE_2_PLANES,
11929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    YUV_SURFACE_3_PLANES
12029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
12129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
12229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedenum eConversionType {
12329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    CONVERT_TO_ANDROID_FORMAT,
12429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    CONVERT_TO_C2D_FORMAT
12529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
12629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
12729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedenum eC2DFlags {
1289ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    FLAGS_PREMULTIPLIED_ALPHA  = 1<<0,
1299ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    FLAGS_YUV_DESTINATION      = 1<<1,
1309ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    FLAGS_TEMP_SRC_DST         = 1<<2
13129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
13229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
13301d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmedstatic gralloc::IAllocController* sAlloc = 0;
13429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/******************************************************************************/
13529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
13629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** State information for each device instance */
13729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstruct copybit_context_t {
13829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t device;
1399ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // Templates for the various source surfaces. These templates are created
1409ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // to avoid the expensive create/destroy C2D Surfaces
1419ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES];
1429ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES];
1439ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES];
1449ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects
1459ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    C2D_DRIVER_INFO c2d_driver_info;
14629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    void *libc2d2;
14729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    alloc_data temp_src_buffer;
14829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    alloc_data temp_dst_buffer;
1499ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces
1509ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    unsigned int mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
1519ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int blit_rgb_count;         // Total RGB surfaces being blit
1529ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being
1539ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int blit_yuv_3_plane_count; // Total 3 plane YUV  surfaces being blit
1549ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int blit_count;             // Total blit objects.
1559ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    unsigned int trg_transform;      /* target transform */
15629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int fb_width;
15729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int fb_height;
1589ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int src_global_alpha;
1599ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int config_mask;
1609ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int dst_surface_type;
1619ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    bool is_premultiplied_alpha;
162647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    void* time_stamp;
163647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
164647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    // used for signaling the wait thread
165647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    bool wait_timestamp;
166647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_t wait_thread_id;
167647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    bool stop_thread;
168647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_mutex_t wait_cleanup_lock;
169647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_cond_t wait_cleanup_cond;
170647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
17129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
17229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
17329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstruct bufferInfo {
17429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int width;
17529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int height;
17629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int format;
17729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
17829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
17929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstruct yuvPlaneInfo {
18029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int yStride;       //luma stride
18129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int plane1_stride;
18229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int plane2_stride;
18329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int plane1_offset;
18429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int plane2_offset;
18529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
18629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
18729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/**
18829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * Common hardware methods
18929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
19029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
19129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
19229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        struct hw_device_t** device);
19329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
19429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic struct hw_module_methods_t copybit_module_methods = {
19529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedopen:  open_copybit
19629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
19729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
19829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*
19929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * The COPYBIT Module
20029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
20129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstruct copybit_module_t HAL_MODULE_INFO_SYM = {
20229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedcommon: {
20329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedtag: HARDWARE_MODULE_TAG,
20429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     version_major: 1,
20529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     version_minor: 0,
20629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     id: COPYBIT_HARDWARE_MODULE_ID,
20729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     name: "QCT COPYBIT C2D 2.0 Module",
20829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     author: "Qualcomm",
20929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed     methods: &copybit_module_methods
21029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
21129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed};
21229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
21329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
214647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R/* thread function which waits on the timeStamp and cleans up the surfaces */
215647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.Rstatic void* c2d_wait_loop(void* ptr) {
216647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    copybit_context_t* ctx = (copybit_context_t*)(ptr);
217647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    char thread_name[64] = "copybitWaitThr";
218647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
219647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
220647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
221647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    while(ctx->stop_thread == false) {
222647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        pthread_mutex_lock(&ctx->wait_cleanup_lock);
223647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        while(ctx->wait_timestamp == false && !ctx->stop_thread) {
224647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            pthread_cond_wait(&(ctx->wait_cleanup_cond),
225647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R                              &(ctx->wait_cleanup_lock));
226647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        }
227647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        if(ctx->wait_timestamp) {
228647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            if(LINK_c2dWaitTimestamp(ctx->time_stamp)) {
229647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R                ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__);
230647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            }
231647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            ctx->wait_timestamp = false;
232647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            // Unmap any mapped addresses.
233647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            for (int i = 0; i < MAX_SURFACES; i++) {
234647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R                if (ctx->mapped_gpu_addr[i]) {
235647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R                    LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
236647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R                    ctx->mapped_gpu_addr[i] = 0;
237647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R                }
238647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            }
239647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            // Reset the counts after the draw.
240647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            ctx->blit_rgb_count = 0;
241647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            ctx->blit_yuv_2_plane_count = 0;
242647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            ctx->blit_yuv_3_plane_count = 0;
243647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            ctx->blit_count = 0;
244647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        }
245647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
246647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        if(ctx->stop_thread)
247647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            break;
248647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    }
249647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_exit(NULL);
250647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    return NULL;
251647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R}
252647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
253647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
25429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/* convert COPYBIT_FORMAT to C2D format */
25529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int get_format(int format) {
25629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch (format) {
25729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGB_565:        return C2D_COLOR_FORMAT_565_RGB;
25829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
25929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                              C2D_FORMAT_SWAP_RB |
26029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                                  C2D_FORMAT_DISABLE_ALPHA;
26129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
26229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                              C2D_FORMAT_SWAP_RB;
26329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_BGRA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
26429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_5551:      return C2D_COLOR_FORMAT_5551_RGBA;
26529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_4444:      return C2D_COLOR_FORMAT_4444_RGBA;
26629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
26729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
26829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
26929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 |
27029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                                  C2D_FORMAT_MACROTILED;
2719ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        default:                              ALOGE("%s: invalid format (0x%x",
2729ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                     __FUNCTION__, format);
2739ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                              return -EINVAL;
27429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
27529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return -EINVAL;
27629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
27729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
27829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/* Get the C2D formats needed for conversion to YUV */
27929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int get_c2d_format_for_yuv_destination(int halFormat) {
28029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch (halFormat) {
28129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        // We do not swap the RB when the target is YUV
28229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
28329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                              C2D_FORMAT_DISABLE_ALPHA;
28429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
2859ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        // The U and V need to be interchanged when the target is YUV
28629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
28729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21;
28829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
28929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        default:                              return get_format(halFormat);
29029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
29129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return -EINVAL;
29229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
29329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
29429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/* ------------------------------------------------------------------- *//*!
29529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * \internal
29629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * \brief Get the bpp for a particular color format
29729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * \param color format
29829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * \return bits per pixel
29929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed *//* ------------------------------------------------------------------- */
30029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedint c2diGetBpp(int32 colorformat)
30129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
30229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
30329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int c2dBpp = 0;
30429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
30529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch(colorformat&0xFF)
30629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    {
30729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_4444_RGBA:
30829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_4444_ARGB:
30929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_1555_ARGB:
31029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_565_RGB:
31129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_5551_RGBA:
31229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            c2dBpp = 16;
31329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
31429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_8888_RGBA:
31529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_8888_ARGB:
31629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            c2dBpp = 32;
31729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
31829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_8_L:
31929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_8_A:
32029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            c2dBpp = 8;
32129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
32229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_4_A:
32329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            c2dBpp = 4;
32429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
32529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_1:
32629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            c2dBpp = 1;
32729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
32829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        default:
32929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%s ERROR", __func__);
33029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
33129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
33229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return c2dBpp;
33329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
33429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3359ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.Rstatic uint32 c2d_get_gpuaddr(copybit_context_t* ctx, struct private_handle_t *handle,
3369ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                              int &mapped_idx)
33729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
33829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    uint32 memtype, *gpuaddr;
33929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    C2D_STATUS rc;
34029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
34129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!handle)
34229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return 0;
34329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
34429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (handle->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
34529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                         private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP))
34629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memtype = KGSL_USER_MEM_TYPE_PMEM;
34729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)
34829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memtype = KGSL_USER_MEM_TYPE_ASHMEM;
34929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
35029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memtype = KGSL_USER_MEM_TYPE_ION;
35129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    else {
35229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("Invalid handle flags: 0x%x", handle->flags);
35329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return 0;
35429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
35529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3569ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size,
3579ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                      handle->offset, memtype, (void**)&gpuaddr);
3589ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
35929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (rc == C2D_STATUS_OK) {
3609ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        // We have mapped the GPU address inside copybit. We need to unmap this
3619ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        // address after the blit. Store this address
3629ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        for (int i = 0; i < MAX_SURFACES; i++) {
3639ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            if (ctx->mapped_gpu_addr[i] == 0) {
3649ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                ctx->mapped_gpu_addr[i] = (uint32) gpuaddr;
3659ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                mapped_idx = i;
3669ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                break;
3679ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            }
3689ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        }
3699ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
37029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return (uint32) gpuaddr;
37129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
37229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
37329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
37429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
3759ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.Rstatic void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx)
3769ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R{
3779ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (!ctx || (mapped_idx == -1))
3789ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return;
3799ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
3809ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (ctx->mapped_gpu_addr[mapped_idx]) {
3819ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]);
3829ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->mapped_gpu_addr[mapped_idx] = 0;
3839ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
3849ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R}
3859ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
38629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int is_supported_rgb_format(int format)
38729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
38829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch(format) {
38929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_8888:
39029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBX_8888:
39129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGB_565:
39229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_BGRA_8888:
39329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_5551:
39429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_RGBA_4444: {
39529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return COPYBIT_SUCCESS;
39629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
39729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        default:
39829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return COPYBIT_FAILURE;
39929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
40029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
40129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
40229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int get_num_planes(int format)
40329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
40429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch(format) {
40529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
40629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
40729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
40829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
40929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return 2;
41029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
41129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YV12: {
41229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return 3;
41329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
41429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        default:
41529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return COPYBIT_FAILURE;
41629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
41729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
41829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
41929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int is_supported_yuv_format(int format)
42029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
42129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch(format) {
42229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
42329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
42429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
42529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
42629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return COPYBIT_SUCCESS;
42729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
42829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        default:
42929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return COPYBIT_FAILURE;
43029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
43129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
43229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
43329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int is_valid_destination_format(int format)
43429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
43529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
43629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        // C2D does not support NV12Tile as a destination format.
43729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return COPYBIT_FAILURE;
43829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
43929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return COPYBIT_SUCCESS;
44029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
44129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
44229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int calculate_yuv_offset_and_stride(const bufferInfo& info,
44329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                           yuvPlaneInfo& yuvInfo)
44429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
44529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int width  = info.width;
44629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int height = info.height;
44729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int format = info.format;
44829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
44929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int aligned_height = 0;
45029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int aligned_width = 0, size = 0;
45129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
45229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch (format) {
45329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
45429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            /* NV12 Tile buffers have their luma height aligned to 32bytes and width
45529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed             * aligned to 128 bytes. The chroma offset starts at an 8K boundary
45629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed             */
45729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            aligned_height = ALIGN(height, 32);
45829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            aligned_width  = ALIGN(width, 128);
45929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            size = aligned_width * aligned_height;
46029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            yuvInfo.plane1_offset = ALIGN(size,8192);
46129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            yuvInfo.yStride = aligned_width;
46229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            yuvInfo.plane1_stride = aligned_width;
46329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
46429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
46529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
46629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
46729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
46829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            aligned_width = ALIGN(width, 32);
46929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            yuvInfo.yStride = aligned_width;
47029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            yuvInfo.plane1_stride = aligned_width;
47129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
47229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                // The encoder requires a 2K aligned chroma offset
47329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048);
47429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            } else
47529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                yuvInfo.plane1_offset = aligned_width * height;
47629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
47729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
47829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
47929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        default: {
48029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return COPYBIT_FAILURE;
48129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
48229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
48329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return COPYBIT_SUCCESS;
48429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
48529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
48629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** create C2D surface from copybit image */
4879ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.Rstatic int set_image(copybit_context_t* ctx, uint32 surfaceId,
4889ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                      const struct copybit_image_t *rhs,
4899ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                      const eC2DFlags flags, int &mapped_idx)
49029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
49129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
49229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    C2D_SURFACE_TYPE surfaceType;
49329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = COPYBIT_SUCCESS;
4949ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    uint32 gpuaddr = 0;
4959ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int c2d_format;
4969ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    mapped_idx = -1;
49729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
49829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (flags & FLAGS_YUV_DESTINATION) {
4999ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        c2d_format = get_c2d_format_for_yuv_destination(rhs->format);
50029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
5019ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        c2d_format = get_format(rhs->format);
50229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
50329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5049ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if(c2d_format == -EINVAL) {
50529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: invalid format", __FUNCTION__);
50629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -EINVAL;
50729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
50829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
50929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(handle == NULL) {
51029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: invalid handle", __func__);
51129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -EINVAL;
51229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
51329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
51429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (handle->gpuaddr == 0) {
5159ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx);
5169ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if(!gpuaddr) {
51729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
51829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return COPYBIT_FAILURE;
51929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
5209ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    } else {
5219ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        gpuaddr = handle->gpuaddr;
52229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
52329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
52429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    /* create C2D surface */
52529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
52629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        /* RGB */
52729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        C2D_RGB_SURFACE_DEF surfaceDef;
52829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
52929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS);
53029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5319ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        surfaceDef.phys = (void*) gpuaddr;
53229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceDef.buffer = (void*) (handle->base);
53329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5349ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        surfaceDef.format = c2d_format |
53529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
53629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceDef.width = rhs->w;
53729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceDef.height = rhs->h;
53829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        int aligned_width = ALIGN(surfaceDef.width,32);
53929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;
54029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5419ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
5429ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                  &surfaceDef)) {
54329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__);
5449ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_idx);
54529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            status = COPYBIT_FAILURE;
54629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
54729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
54829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        C2D_YUV_SURFACE_DEF surfaceDef;
54929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memset(&surfaceDef, 0, sizeof(surfaceDef));
55029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS);
5519ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        surfaceDef.format = c2d_format;
55229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
55329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        bufferInfo info;
55429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        info.width = rhs->w;
55529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        info.height = rhs->h;
55629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        info.format = rhs->format;
55729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
558b16edac51020832b4049b6709df12346b40d20d9Naseer Ahmed        yuvPlaneInfo yuvInfo = {0};
55929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = calculate_yuv_offset_and_stride(info, yuvInfo);
56029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if(status != COPYBIT_SUCCESS) {
56129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
5629ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_idx);
56329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
56429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
56529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceDef.width = rhs->w;
56629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceDef.height = rhs->h;
56729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceDef.plane0 = (void*) (handle->base);
5689ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        surfaceDef.phys0 = (void*) (gpuaddr);
56929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceDef.stride0 = yuvInfo.yStride;
57029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
57129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
5729ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset);
57329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        surfaceDef.stride1 = yuvInfo.plane1_stride;
57429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (3 == get_num_planes(rhs->format)) {
57529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset);
5769ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset);
57729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            surfaceDef.stride2 = yuvInfo.plane2_stride;
57829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
57929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
58029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
58129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                  &surfaceDef)) {
58229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__);
5839ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_idx);
58429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            status = COPYBIT_FAILURE;
58529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
58629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
58729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
5889ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_idx);
58929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        status = COPYBIT_FAILURE;
59029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
59129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
59229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
59329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
59429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
5959ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R/** copy the bits */
5969ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.Rstatic int msm_copybit(struct copybit_context_t *ctx, unsigned int target)
59729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
5989ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (ctx->blit_count == 0) {
5999ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return COPYBIT_SUCCESS;
6009ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
60129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6029ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    for (int i = 0; i < ctx->blit_count; i++)
60329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    {
6049ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_list[i].next = &(ctx->blit_list[i+1]);
60529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
6069ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->blit_list[ctx->blit_count-1].next = NULL;
60753d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R    uint32_t target_transform = ctx->trg_transform;
60853d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R    if (ctx->c2d_driver_info.capabilities_mask &
60953d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R        C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
61053d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R        // For A3xx - set 0x0 as the transform is set in the config_mask
61153d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R        target_transform = 0x0;
61253d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R    }
61353d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R    if(LINK_c2dDraw(target, target_transform, 0x0, 0, 0, ctx->blit_list,
6149ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                    ctx->blit_count)) {
6159ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
6169ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return COPYBIT_FAILURE;
61729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
61829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return COPYBIT_SUCCESS;
61929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
62029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
62129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
622647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
623647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.Rstatic int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd)
624647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R{
625647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
626647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    int status = COPYBIT_FAILURE;
627647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    if (!ctx)
628647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        return COPYBIT_FAILURE;
629647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
630647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
631647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
632647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) {
633647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__);
634647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        // unlock the mutex and return failure
635647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
636647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        return COPYBIT_FAILURE;
637647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    }
638647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp,
639647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R                                                                        fd)) {
640647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__);
641647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        status = COPYBIT_FAILURE;
642647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    }
643647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    if(status == COPYBIT_SUCCESS) {
644647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        //signal the wait_thread
645647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        ctx->wait_timestamp = true;
646647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R        pthread_cond_signal(&ctx->wait_cleanup_cond);
647647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    }
648647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
649647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    return status;
650647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R}
651647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
6529ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.Rstatic int finish_copybit(struct copybit_device_t *dev)
65329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
6549ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
6559ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (!ctx)
6569ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return COPYBIT_FAILURE;
65729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6589ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R   int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
65929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6609ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R   if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) {
6619ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
6629ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return COPYBIT_FAILURE;
66329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
66429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6659ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // Unmap any mapped addresses.
6669ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    for (int i = 0; i < MAX_SURFACES; i++) {
6679ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (ctx->mapped_gpu_addr[i]) {
6689ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
6699ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ctx->mapped_gpu_addr[i] = 0;
67029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
67129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
67229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6739ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // Reset the counts after the draw.
6749ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->blit_rgb_count = 0;
6759ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->blit_yuv_2_plane_count = 0;
6769ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->blit_yuv_3_plane_count = 0;
6779ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->blit_count = 0;
67829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
67929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
68029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
6816f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmedstatic int clear_copybit(struct copybit_device_t *dev,
6826f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed                         struct copybit_image_t const *buf,
6836f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed                         struct copybit_rect_t *rect)
6846f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed{
6850980ea10b5f426c1532bb72c5436ec74ddd958d7Arun Kumar K.R    int ret = COPYBIT_SUCCESS;
6866f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed    int flags = FLAGS_PREMULTIPLIED_ALPHA;
6876f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed    int mapped_dst_idx = -1;
6886f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
6896f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed    C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
6900980ea10b5f426c1532bb72c5436ec74ddd958d7Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
6916f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed    ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf,
6926f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed                       (eC2DFlags)flags, mapped_dst_idx);
6936f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed    if(ret) {
6946f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed        ALOGE("%s: set_image error", __FUNCTION__);
6956f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed        unmap_gpuaddr(ctx, mapped_dst_idx);
6960980ea10b5f426c1532bb72c5436ec74ddd958d7Arun Kumar K.R        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
6976f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed        return COPYBIT_FAILURE;
6986f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed    }
6996f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed
7006f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed    ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect);
7010980ea10b5f426c1532bb72c5436ec74ddd958d7Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
7026f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed    return ret;
7036f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed}
7046f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed
7056f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed
70629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** setup rectangles */
70729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void set_rects(struct copybit_context_t *ctx,
70829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      C2D_OBJECT *c2dObject,
70929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *dst,
71029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *src,
71129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      const struct copybit_rect_t *scissor)
71229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
71329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    // Set the target rect.
71429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if((ctx->trg_transform & C2D_TARGET_ROTATE_90) &&
71529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed       (ctx->trg_transform & C2D_TARGET_ROTATE_180)) {
71629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        /* target rotation is 270 */
71729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.x        = (dst->t)<<16;
71829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.y        = ctx->fb_width?(ALIGN(ctx->fb_width,32)- dst->r):dst->r;
71929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
72029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
72129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
72229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) {
72329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.x        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
72429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
72529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.y        = (dst->l)<<16;
72629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
72729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
72829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) {
72929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.y        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
73029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
73129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.x        = ctx->fb_width?(ALIGN(ctx->fb_width,32) - dst->r):dst->r;
73229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
73329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
73429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
73529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
73629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.x        = (dst->l)<<16;
73729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.y        = (dst->t)<<16;
73829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
73929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
74029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
74129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    c2dObject->config_mask |= C2D_TARGET_RECT_BIT;
74229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
74329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    // Set the source rect
74429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    c2dObject->source_rect.x        = (src->l)<<16;
74529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    c2dObject->source_rect.y        = (src->t)<<16;
74629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    c2dObject->source_rect.height   = ((src->b) - (src->t))<<16;
74729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    c2dObject->source_rect.width    = ((src->r) - (src->l))<<16;
74829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    c2dObject->config_mask |= C2D_SOURCE_RECT_BIT;
74929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
75029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    // Set the scissor rect
75129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    c2dObject->scissor_rect.x       = scissor->l;
75229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    c2dObject->scissor_rect.y       = scissor->t;
75329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    c2dObject->scissor_rect.height  = (scissor->b) - (scissor->t);
75429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    c2dObject->scissor_rect.width   = (scissor->r) - (scissor->l);
75529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT;
75629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
75729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
75829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*****************************************************************************/
75929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
76029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Set a parameter to value */
76129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int set_parameter_copybit(
76229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
76329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int name,
76429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int value)
76529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
76629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
767647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    int status = COPYBIT_SUCCESS;
76829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (!ctx) {
76929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: null context", __FUNCTION__);
77029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -EINVAL;
77129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
77229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
773647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
77429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch(name) {
77529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case COPYBIT_PLANE_ALPHA:
7769ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        {
77729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (value < 0)      value = 0;
77829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (value >= 256)   value = 255;
77929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
7809ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ctx->src_global_alpha = value;
7819ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            if (value < 255)
7829ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT;
78329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            else
7849ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT;
7859ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        }
7869ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        break;
7879ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        case COPYBIT_BLEND_MODE:
7889ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        {
7899ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            if (value == COPYBIT_BLENDING_NONE) {
7909ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                ctx->config_mask |= C2D_ALPHA_BLEND_NONE;
7919ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                ctx->is_premultiplied_alpha = true;
7929ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            } else if (value == COPYBIT_BLENDING_PREMULT) {
7939ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                ctx->is_premultiplied_alpha = true;
7949ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            } else {
7959ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE;
7969ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            }
7979ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        }
7989ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        break;
79929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case COPYBIT_TRANSFORM:
8009ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        {
8019ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            unsigned int transform = 0;
8029ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            uint32 config_mask = 0;
8039ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG;
8049ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) {
8059ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                transform = C2D_TARGET_ROTATE_180;
8069ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180;
8079ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) {
8089ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                transform = C2D_TARGET_ROTATE_90;
8099ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90;
8109ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            } else if(value == COPYBIT_TRANSFORM_ROT_90) {
8119ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                transform = C2D_TARGET_ROTATE_270;
8129ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270;
8139ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            } else {
8149ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0;
8159ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                if(value & COPYBIT_TRANSFORM_FLIP_H) {
8169ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                    config_mask |= C2D_MIRROR_H_BIT;
8179ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                } else if(value & COPYBIT_TRANSFORM_FLIP_V) {
8189ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                    config_mask |= C2D_MIRROR_V_BIT;
8199ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                }
82029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
8219ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
82253d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R            if (ctx->c2d_driver_info.capabilities_mask &
82353d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R                C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
82453d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R                ctx->config_mask |= config_mask;
82553d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R            } else {
82653d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R                // The transform for this surface does not match the current
82753d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R                // target transform. Draw all previous surfaces. This will be
82853d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R                // changed once we have a new mechanism to send different
82953d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R                // target rotations to c2d.
83053d3c37ec20cf662aeae03640d3d409888d2ac28Arun Kumar K.R                finish_copybit(dev);
8319ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            }
8329ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ctx->trg_transform = transform;
8339ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        }
8349ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        break;
83529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case COPYBIT_FRAMEBUFFER_WIDTH:
83629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ctx->fb_width = value;
83729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
83829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case COPYBIT_FRAMEBUFFER_HEIGHT:
83929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ctx->fb_height = value;
84029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
8419ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        case COPYBIT_ROTATION_DEG:
8429ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        case COPYBIT_DITHER:
8439ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        case COPYBIT_BLUR:
84445a9960377b09b1f72fe0c7ed662f1e0110e2d68Naseer Ahmed        case COPYBIT_BLIT_TO_FRAMEBUFFER:
8459ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            // Do nothing
84645a9960377b09b1f72fe0c7ed662f1e0110e2d68Naseer Ahmed            break;
84729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        default:
84829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
849647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            status = -EINVAL;
85029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
85129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
852647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
853647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    return status;
85429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
85529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
85629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Get a static info value */
85729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int get(struct copybit_device_t *dev, int name)
85829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
85929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
86029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int value;
86129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
86229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (!ctx) {
86329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: null context error", __FUNCTION__);
86429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -EINVAL;
86529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
86629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
86729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch(name) {
86829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case COPYBIT_MINIFICATION_LIMIT:
86929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            value = MAX_SCALE_FACTOR;
87029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
87129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case COPYBIT_MAGNIFICATION_LIMIT:
87229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            value = MAX_SCALE_FACTOR;
87329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
87429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case COPYBIT_SCALING_FRAC_BITS:
87529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            value = 32;
87629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
87729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case COPYBIT_ROTATION_STEP_DEG:
87829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            value = 1;
87929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
88029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        default:
88129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
88229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            value = -EINVAL;
88329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
88429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return value;
88529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
88629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
88729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int is_alpha(int cformat)
88829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
88929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int alpha = 0;
89029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch (cformat & 0xFF) {
89129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_8888_ARGB:
89229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_8888_RGBA:
89329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_5551_RGBA:
89429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case C2D_COLOR_FORMAT_4444_ARGB:
89529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            alpha = 1;
89629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
89729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        default:
89829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            alpha = 0;
89929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            break;
90029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
90129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
90229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(alpha && (cformat&C2D_FORMAT_DISABLE_ALPHA))
90329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        alpha = 0;
90429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
90529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return alpha;
90629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
90729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
90829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/* Function to check if we need a temporary buffer for the blit.
90929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * This would happen if the requested destination stride and the
91029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * C2D stride do not match. We ignore RGB buffers, since their
91129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * stride is always aligned to 32.
91229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
91329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic bool need_temp_buffer(struct copybit_image_t const *img)
91429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
91529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format))
91629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return false;
91729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
91829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct private_handle_t* handle = (struct private_handle_t*)img->handle;
91929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
92029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    // The width parameter in the handle contains the aligned_w. We check if we
92129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    // need to convert based on this param. YUV formats have bpp=1, so checking
92229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    // if the requested stride is aligned should suffice.
92329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (0 == (handle->width)%32) {
92429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return false;
92529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
92629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
92729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return true;
92829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
92929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
93029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/* Function to extract the information from the copybit image and set the corresponding
93129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * values in the bufferInfo struct.
93229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
93329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info)
93429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
93529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    info.width = img->w;
93629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    info.height = img->h;
93729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    info.format = img->format;
93829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
93929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
94029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/* Function to get the required size for a particular format, inorder for C2D to perform
94129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * the blit operation.
94229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
94329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic size_t get_size(const bufferInfo& info)
94429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
94529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    size_t size = 0;
94629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int w = info.width;
94729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int h = info.height;
94829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int aligned_w = ALIGN(w, 32);
94929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch(info.format) {
95029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
95129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            {
95229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                // Chroma for this format is aligned to 2K.
95329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                size = ALIGN((aligned_w*h), 2048) +
9549ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                        ALIGN(aligned_w/2, 32) * (h/2) *2;
95529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                size = ALIGN(size, 4096);
95629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            } break;
95729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
95829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
95929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            {
9609ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                size = aligned_w * h +
9619ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                       ALIGN(aligned_w/2, 32) * (h/2) * 2;
96229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                size = ALIGN(size, 4096);
96329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            } break;
96429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        default: break;
96529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
96629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return size;
96729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
96829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
96929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/* Function to allocate memory for the temporary buffer. This memory is
97029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * allocated from Ashmem. It is the caller's responsibility to free this
97129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * memory.
97229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
97329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int get_temp_buffer(const bufferInfo& info, alloc_data& data)
97429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
97529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ALOGD("%s E", __FUNCTION__);
97629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    // Alloc memory from system heap
97729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.base = 0;
97829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.fd = -1;
97929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.offset = 0;
98029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.size = get_size(info);
98129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.align = getpagesize();
98229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    data.uncached = true;
98329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int allocFlags = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
98429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
98529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (sAlloc == 0) {
98601d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        sAlloc = gralloc::IAllocController::getInstance();
98729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
98829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
98929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (sAlloc == 0) {
99029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: sAlloc is still NULL", __FUNCTION__);
99129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return COPYBIT_FAILURE;
99229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
99329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
99401d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed    int err = sAlloc->allocate(data, allocFlags);
99529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (0 != err) {
99629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: allocate failed", __FUNCTION__);
99729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return COPYBIT_FAILURE;
99829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
99929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
100029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ALOGD("%s X", __FUNCTION__);
100129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return err;
100229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
100329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
100429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/* Function to free the temporary allocated memory.*/
100529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void free_temp_buffer(alloc_data &data)
100629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
100729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (-1 != data.fd) {
100801d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType);
100929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memalloc->free_buffer(data.base, data.size, 0, data.fd);
101029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
101129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
101229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
101329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/* Function to perform the software color conversion. Convert the
101429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed * C2D compatible format to the Android compatible format
101529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed */
101629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int copy_image(private_handle_t *src_handle,
101729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      struct copybit_image_t const *rhs,
101829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                      eConversionType conversionType)
101929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
102029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (src_handle->fd == -1) {
102129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: src_handle fd is invalid", __FUNCTION__);
102229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return COPYBIT_FAILURE;
102329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
102429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
102529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    // Copy the info.
102629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int ret = COPYBIT_SUCCESS;
102729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    switch(rhs->format) {
102829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
102929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
103029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
103129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            {
103229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                if (CONVERT_TO_ANDROID_FORMAT == conversionType) {
103329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    return convert_yuv_c2d_to_yuv_android(src_handle, rhs);
103429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                } else {
103529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                    return convert_yuv_android_to_yuv_c2d(src_handle, rhs);
103629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                }
103729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
103829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            } break;
103929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        default: {
104029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
104129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ret = COPYBIT_FAILURE;
104229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        } break;
104329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
104429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return ret;
104529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
104629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
104729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic void delete_handle(private_handle_t *handle)
104829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
104929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (handle) {
105029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delete handle;
105129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        handle = 0;
105229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
105329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
10549ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
10559ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.Rstatic bool need_to_execute_draw(struct copybit_context_t* ctx,
10569ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                          eC2DFlags flags)
10579ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R{
10589ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (flags & FLAGS_TEMP_SRC_DST) {
10599ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return true;
10609ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
10619ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (flags & FLAGS_YUV_DESTINATION) {
10629ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return true;
10639ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
10649ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    return false;
10659ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R}
10669ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
106729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** do a stretch blit type operation */
106829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int stretch_copybit_internal(
106929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
107029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *dst,
107129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *src,
107229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t const *dst_rect,
107329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t const *src_rect,
107429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_region_t const *region,
107529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    bool enableBlend)
107629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
107729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
107829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = COPYBIT_SUCCESS;
10799ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int flags = 0;
10809ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int src_surface_type;
10819ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int mapped_src_idx = -1, mapped_dst_idx = -1;
10829ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    C2D_OBJECT_STR src_surface;
108329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
108429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (!ctx) {
108529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: null context error", __FUNCTION__);
108629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -EINVAL;
108729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
108829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
108929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
109029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: src dimension error", __FUNCTION__);
109129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -EINVAL;
109229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
109329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
109429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
10959ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ALOGE("%s : dst dimension error dst w %d h %d",  __FUNCTION__, dst->w,
10969ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                         dst->h);
109729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -EINVAL;
109829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
109929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
110029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) {
11019ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__,
11029ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                              dst->format);
110329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return COPYBIT_FAILURE;
110429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
110529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
11069ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    int dst_surface_type;
110729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
11089ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        dst_surface_type = RGB_SURFACE;
11099ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        flags |= FLAGS_PREMULTIPLIED_ALPHA;
111029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) {
111129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        int num_planes = get_num_planes(dst->format);
11129ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        flags |= FLAGS_YUV_DESTINATION;
111329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (num_planes == 2) {
11149ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            dst_surface_type = YUV_SURFACE_2_PLANES;
111529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        } else if (num_planes == 3) {
11169ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            dst_surface_type = YUV_SURFACE_3_PLANES;
111729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        } else {
111829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x",
111929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  __FUNCTION__, dst->format);
112029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return COPYBIT_FAILURE;
112129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
112229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
11239ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__,
11249ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                     dst->format);
112529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return COPYBIT_FAILURE;
112629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
112729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
11289ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (ctx->blit_rgb_count == MAX_RGB_SURFACES ||
11299ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_yuv_2_plane_count == MAX_YUV_2_PLANE_SURFACES ||
11309ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_yuv_3_plane_count == MAX_YUV_2_PLANE_SURFACES ||
11319ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_count == MAX_BLIT_OBJECT_COUNT ||
11329ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->dst_surface_type != dst_surface_type) {
11339ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        // we have reached the max. limits of our internal structures or
11349ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        // changed the target.
11359ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        // Draw the remaining surfaces. We need to do the finish here since
11369ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        // we need to free up the surface templates.
11379ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        finish_copybit(dev);
11389ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
11399ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
11409ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->dst_surface_type = dst_surface_type;
11419ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
11429ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // Update the destination
114329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    copybit_image_t dst_image;
114429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    dst_image.w = dst->w;
114529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    dst_image.h = dst->h;
114629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    dst_image.format = dst->format;
114729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    dst_image.handle = dst->handle;
114829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    // Check if we need a temp. copy for the destination. We'd need this the destination
114929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    // width is not aligned to 32. This case occurs for YUV formats. RGB formats are
115029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    // aligned to 32.
11519ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    bool need_temp_dst = need_temp_buffer(dst);
115229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    bufferInfo dst_info;
115329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    populate_buffer_info(dst, dst_info);
115429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format,
115529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                                     dst_info.width, dst_info.height);
115629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (dst_hnd == NULL) {
115729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: dst_hnd is null", __FUNCTION__);
115829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return COPYBIT_FAILURE;
115929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
11609ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (need_temp_dst) {
116129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (get_size(dst_info) != ctx->temp_dst_buffer.size) {
116229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            free_temp_buffer(ctx->temp_dst_buffer);
116329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            // Create a temp buffer and set that as the destination.
116429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) {
116529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ALOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__);
116629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                delete_handle(dst_hnd);
116729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                return COPYBIT_FAILURE;
116829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
116929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
117029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dst_hnd->fd = ctx->temp_dst_buffer.fd;
117129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dst_hnd->size = ctx->temp_dst_buffer.size;
117229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dst_hnd->flags = ctx->temp_dst_buffer.allocType;
117329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dst_hnd->base = (int)(ctx->temp_dst_buffer.base);
117429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dst_hnd->offset = ctx->temp_dst_buffer.offset;
117529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dst_hnd->gpuaddr = 0;
117629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        dst_image.handle = dst_hnd;
117729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
117829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
11799ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    status = set_image(ctx, ctx->dst[ctx->dst_surface_type], &dst_image,
11809ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                       (eC2DFlags)flags, mapped_dst_idx);
118129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(status) {
118229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: dst: set_image error", __FUNCTION__);
118329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delete_handle(dst_hnd);
11849ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_dst_idx);
118529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return COPYBIT_FAILURE;
118629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
118729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
11889ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // Update the source
11899ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    flags = 0;
119029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) {
11919ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        src_surface_type = RGB_SURFACE;
11929ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        src_surface = ctx->blit_rgb_object[ctx->blit_rgb_count];
119329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) {
119429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        int num_planes = get_num_planes(src->format);
119529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (num_planes == 2) {
11969ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            src_surface_type = YUV_SURFACE_2_PLANES;
11979ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            src_surface = ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count];
119829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        } else if (num_planes == 3) {
11999ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            src_surface_type = YUV_SURFACE_3_PLANES;
12009ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            src_surface = ctx->blit_yuv_3_plane_object[ctx->blit_yuv_2_plane_count];
120129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        } else {
120229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%s: src number of YUV planes is invalid src format = 0x%x",
120329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                  __FUNCTION__, src->format);
120429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            delete_handle(dst_hnd);
12059ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_dst_idx);
120629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return -EINVAL;
120729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
120829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
12099ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__,
12109ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                        src->format);
121129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delete_handle(dst_hnd);
12129ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_dst_idx);
121329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return -EINVAL;
121429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
121529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
121629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    copybit_image_t src_image;
121729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    src_image.w = src->w;
121829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    src_image.h = src->h;
121929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    src_image.format = src->format;
122029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    src_image.handle = src->handle;
122129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
12229ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    bool need_temp_src = need_temp_buffer(src);
122329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    bufferInfo src_info;
122429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    populate_buffer_info(src, src_info);
122529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format,
12269ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 src_info.width, src_info.height);
122729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (NULL == src_hnd) {
122829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: src_hnd is null", __FUNCTION__);
122929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delete_handle(dst_hnd);
12309ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_dst_idx);
123129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return COPYBIT_FAILURE;
123229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
12339ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (need_temp_src) {
123429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (get_size(src_info) != ctx->temp_src_buffer.size) {
123529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            free_temp_buffer(ctx->temp_src_buffer);
123629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            // Create a temp buffer and set that as the destination.
12379ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            if (COPYBIT_SUCCESS != get_temp_buffer(src_info,
12389ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                               ctx->temp_src_buffer)) {
123929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__);
124029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                delete_handle(dst_hnd);
124129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                delete_handle(src_hnd);
12429ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                unmap_gpuaddr(ctx, mapped_dst_idx);
124329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                return COPYBIT_FAILURE;
124429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
124529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
124629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        src_hnd->fd = ctx->temp_src_buffer.fd;
124729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        src_hnd->size = ctx->temp_src_buffer.size;
124829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        src_hnd->flags = ctx->temp_src_buffer.allocType;
124929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        src_hnd->base = (int)(ctx->temp_src_buffer.base);
125029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        src_hnd->offset = ctx->temp_src_buffer.offset;
125129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        src_hnd->gpuaddr = 0;
125229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        src_image.handle = src_hnd;
125329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
125429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        // Copy the source.
12559ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        status = copy_image((private_handle_t *)src->handle, &src_image,
12569ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                CONVERT_TO_C2D_FORMAT);
12579ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (status == COPYBIT_FAILURE) {
12589ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ALOGE("%s:copy_image failed in temp source",__FUNCTION__);
12599ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            delete_handle(dst_hnd);
12609ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            delete_handle(src_hnd);
12619ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_dst_idx);
12629ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            return status;
12639ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        }
126429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
12650b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed        // Clean the cache
126601d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
126729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
12680b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed                                   src_hnd->offset, src_hnd->fd,
12690b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed                                   gralloc::CACHE_CLEAN)) {
127029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            ALOGE("%s: clean_buffer failed", __FUNCTION__);
127129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            delete_handle(dst_hnd);
127229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            delete_handle(src_hnd);
12739ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_dst_idx);
127429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            return COPYBIT_FAILURE;
127529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
127629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
127729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
12789ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
12799ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
12809ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    status = set_image(ctx, src_surface.surface_id, &src_image,
12819ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                       (eC2DFlags)flags, mapped_src_idx);
128229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(status) {
12839ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ALOGE("%s: set_image (src) error", __FUNCTION__);
128429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delete_handle(dst_hnd);
128529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        delete_handle(src_hnd);
12869ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_dst_idx);
12879ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        unmap_gpuaddr(ctx, mapped_src_idx);
128829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return COPYBIT_FAILURE;
128929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
129029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
12915bcb35d75625df60a28b03e3ccd2f9037e85e2f9Arun Kumar K.R    src_surface.config_mask = C2D_NO_ANTIALIASING_BIT | ctx->config_mask;
12929ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    src_surface.global_alpha = ctx->src_global_alpha;
129329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (enableBlend) {
12949ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) {
12959ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
12969ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            if(!(src_surface.global_alpha)) {
129729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                // src alpha is zero
129829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                delete_handle(dst_hnd);
129929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                delete_handle(src_hnd);
13009ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                unmap_gpuaddr(ctx, mapped_dst_idx);
13019ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                unmap_gpuaddr(ctx, mapped_src_idx);
13029ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                return COPYBIT_FAILURE;
130329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed            }
130429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
130529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    } else {
13069ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
130729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
130829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
13099ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (src_surface_type == RGB_SURFACE) {
13109ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_rgb_object[ctx->blit_rgb_count] = src_surface;
13119ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_rgb_count++;
13129ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    } else if (src_surface_type == YUV_SURFACE_2_PLANES) {
13139ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count] = src_surface;
13149ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_yuv_2_plane_count++;
13159ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    } else {
13169ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_yuv_3_plane_object[ctx->blit_yuv_3_plane_count] = src_surface;
13179ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_yuv_3_plane_count++;
13189ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
131929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
13209ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    struct copybit_rect_t clip;
132129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    while ((status == 0) && region->next(region, &clip)) {
13229ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip);
13239ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) {
13249ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ALOGW("Reached end of blit count");
1325647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R            finish_copybit(dev);
132629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        }
13279ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_list[ctx->blit_count] = src_surface;
13289ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->blit_count++;
132929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
133029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
13319ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // Check if we need to perform an early draw-finish.
13329ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0;
13339ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (need_to_execute_draw(ctx, (eC2DFlags)flags))
13349ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    {
13359ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        finish_copybit(dev);
133629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
133729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
13389ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (need_temp_dst) {
13399ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        // copy the temp. destination without the alignment to the actual
13409ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        // destination.
13419ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
13429ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (status == COPYBIT_FAILURE) {
13439ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__);
13449ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            delete_handle(dst_hnd);
13459ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            delete_handle(src_hnd);
13469ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_dst_idx);
13479ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            unmap_gpuaddr(ctx, mapped_src_idx);
13489ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            return status;
13499ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        }
13500b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed        // Clean the cache.
135101d3fd3318a767e6ba75492ed08d57896df95d63Naseer Ahmed        IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
135229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
13530b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed                               dst_hnd->offset, dst_hnd->fd,
13540b5054e40d055687b036b626538e79bf160beebbNaseer Ahmed                               gralloc::CACHE_CLEAN);
135529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
135629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    delete_handle(dst_hnd);
135729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    delete_handle(src_hnd);
13589ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
13599ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->is_premultiplied_alpha = false;
136029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->fb_width = 0;
136129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->fb_height = 0;
13629ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->config_mask = 0;
136329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
136429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
136529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
13669ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
136729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int stretch_copybit(
136829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
136929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *dst,
137029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *src,
137129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t const *dst_rect,
137229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t const *src_rect,
137329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_region_t const *region)
137429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
137529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1376647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    int status = COPYBIT_SUCCESS;
13779ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    bool needsBlending = (ctx->src_global_alpha != 0);
1378647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
1379647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
138029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                    region, needsBlending);
1381647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
1382647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    return status;
138329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
138429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
138529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Perform a blit type operation */
138629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int blit_copybit(
138729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_device_t *dev,
138829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *dst,
138929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_image_t const *src,
139029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_region_t const *region)
139129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
13920980ea10b5f426c1532bb72c5436ec74ddd958d7Arun Kumar K.R    int status = COPYBIT_SUCCESS;
13930980ea10b5f426c1532bb72c5436ec74ddd958d7Arun Kumar K.R    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
139429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t dr = { 0, 0, dst->w, dst->h };
139529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_rect_t sr = { 0, 0, src->w, src->h };
13960980ea10b5f426c1532bb72c5436ec74ddd958d7Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
13970980ea10b5f426c1532bb72c5436ec74ddd958d7Arun Kumar K.R    status = stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false);
13980980ea10b5f426c1532bb72c5436ec74ddd958d7Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
13990980ea10b5f426c1532bb72c5436ec74ddd958d7Arun Kumar K.R    return status;
140029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
140129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
140229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/*****************************************************************************/
140329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
14049ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.Rstatic void clean_up(copybit_context_t* ctx)
14059ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R{
1406647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    void* ret;
14079ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (!ctx)
14089ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return;
14099ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
1410647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    // stop the wait_cleanup_thread
1411647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_mutex_lock(&ctx->wait_cleanup_lock);
1412647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    ctx->stop_thread = true;
1413647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    // Signal waiting thread
1414647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_cond_signal(&ctx->wait_cleanup_cond);
1415647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
1416647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    // waits for the cleanup thread to exit
1417647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_join(ctx->wait_thread_id, &ret);
1418647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_mutex_destroy(&ctx->wait_cleanup_lock);
1419647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_cond_destroy (&ctx->wait_cleanup_cond);
1420647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
14219ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    for (int i = 0; i < NUM_SURFACE_TYPES; i++) {
14229ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (ctx->dst[i])
14239ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            LINK_c2dDestroySurface(ctx->dst[i]);
14249ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
14259ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
14269ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    for (int i = 0; i < MAX_RGB_SURFACES; i++) {
14279ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (ctx->blit_rgb_object[i].surface_id)
14289ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id);
14299ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
14309ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
14319ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) {
14329ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (ctx->blit_yuv_2_plane_object[i].surface_id)
14339ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id);
14349ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
14359ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
14369ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) {
14379ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (ctx->blit_yuv_3_plane_object[i].surface_id)
14389ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id);
14399ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
14409ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
14419ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (ctx->libc2d2) {
14429ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ::dlclose(ctx->libc2d2);
14439ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ALOGV("dlclose(libc2d2)");
14449ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
14459ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
14469ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    free(ctx);
14479ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R}
14489ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
144929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Close the copybit device */
145029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int close_copybit(struct hw_device_t *dev)
145129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
145229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
145329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (ctx) {
145429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        free_temp_buffer(ctx->temp_src_buffer);
145529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        free_temp_buffer(ctx->temp_dst_buffer);
145629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
14579ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    clean_up(ctx);
145829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return 0;
145929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
146029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
146129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed/** Open a new instance of a copybit device using name */
146229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmedstatic int open_copybit(const struct hw_module_t* module, const char* name,
146329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                        struct hw_device_t** device)
146429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed{
146529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    int status = COPYBIT_SUCCESS;
146629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    C2D_RGB_SURFACE_DEF surfDefinition = {0};
146729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
146829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    struct copybit_context_t *ctx;
146929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    char fbName[64];
147029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
147129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
147229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if(!ctx) {
147329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: malloc failed", __FUNCTION__);
147429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        return COPYBIT_FAILURE;
147529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
147629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
147729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    /* initialize drawstate */
147829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    memset(ctx, 0, sizeof(*ctx));
147929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
148029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (!ctx->libc2d2) {
148129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
14829ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        clean_up(ctx);
14839ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        status = COPYBIT_FAILURE;
14849ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        *device = NULL;
14859ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return status;
148629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
148729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2,
148829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                               "c2dCreateSurface");
148929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2,
149029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                               "c2dUpdateSurface");
149129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2,
149229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                             "c2dReadSurface");
149329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw");
149429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush");
149529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish");
149629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2,
149729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                               "c2dWaitTimestamp");
149829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2,
149929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                                "c2dDestroySurface");
150029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2,
150129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                         "c2dMapAddr");
150229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2,
150329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                                           "c2dUnMapAddr");
15049ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2,
15059ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                           "c2dGetDriverCapabilities");
1506647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
1507647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R                                           "c2dCreateFenceFD");
15086f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed    *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2,
15096f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed                                           "c2dFillSurface");
151029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
151129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
15129ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
15139ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
15146f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD ||
15156f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed        !LINK_c2dFillSurface) {
151629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed        ALOGE("%s: dlsym ERROR", __FUNCTION__);
15179ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        clean_up(ctx);
15189ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        status = COPYBIT_FAILURE;
15199ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        *device = NULL;
15209ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return status;
152129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
152229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
152329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
152429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.version = 1;
152529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.module = (hw_module_t*)(module);
152629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.common.close = close_copybit;
152729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.set_parameter = set_parameter_copybit;
152829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.get = get;
152929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.blit = blit_copybit;
153029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->device.stretch = stretch_copybit;
15319ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->device.finish = finish_copybit;
1532647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    ctx->device.flush_get_fence = flush_get_fence_copybit;
15336f51cecb2be306aef008773d61fea4ce7b896fc9Naseer Ahmed    ctx->device.clear = clear_copybit;
153429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
153529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    /* Create RGB Surface */
153629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    surfDefinition.buffer = (void*)0xdddddddd;
153729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    surfDefinition.phys = (void*)0xdddddddd;
153829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    surfDefinition.stride = 1 * 4;
153929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    surfDefinition.width = 1;
154029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    surfDefinition.height = 1;
154129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB;
154229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
154329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
15449ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
15459ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
15469ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 &surfDefinition)) {
15479ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__);
15489ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->dst[RGB_SURFACE] = 0;
15499ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        clean_up(ctx);
15509ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        status = COPYBIT_FAILURE;
15519ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        *device = NULL;
15529ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return status;
155329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
155429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
15559ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    unsigned int surface_id = 0;
15569ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    for (int i = 0; i < MAX_RGB_SURFACES; i++)
15579ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    {
15589ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
155929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
15609ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
15619ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
15629ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 &surfDefinition)) {
15639ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i);
15649ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ctx->blit_rgb_object[i].surface_id = 0;
15659ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            status = COPYBIT_FAILURE;
15669ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            break;
15679ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        } else {
15689ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ctx->blit_rgb_object[i].surface_id = surface_id;
15699ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ALOGW("%s i = %d surface_id=%d",  __FUNCTION__, i,
15709ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                          ctx->blit_rgb_object[i].surface_id);
15719ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        }
157229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
157329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
15749ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (status == COPYBIT_FAILURE) {
15759ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        clean_up(ctx);
15769ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        status = COPYBIT_FAILURE;
15779ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        *device = NULL;
15789ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return status;
15799ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
158029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
15819ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // Create 2 plane YUV surfaces
15829ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
158329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.width = 4;
158429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.height = 4;
158529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa;
158629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa;
158729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.stride0 = 4;
158829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
158929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa;
159029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa;
159129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.stride1 = 4;
15929ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),
159329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              C2D_TARGET | C2D_SOURCE,
15949ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
15959ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                               C2D_SURFACE_WITH_PHYS |
15969ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                               C2D_SURFACE_WITH_PHYS_DUMMY),
159729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              &yuvSurfaceDef)) {
15989ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
15999ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->dst[YUV_SURFACE_2_PLANES] = 0;
16009ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        clean_up(ctx);
16019ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        status = COPYBIT_FAILURE;
16029ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        *device = NULL;
16039ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return status;
160429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
160529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
16069ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++)
16079ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    {
16089ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
16099ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
16109ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
16119ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
161229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              &yuvSurfaceDef)) {
16139ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ALOGE("%s: create YUV source %d failed", __FUNCTION__, i);
16149ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ctx->blit_yuv_2_plane_object[i].surface_id = 0;
16159ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            status = COPYBIT_FAILURE;
16169ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            break;
16179ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        } else {
16189ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ctx->blit_yuv_2_plane_object[i].surface_id = surface_id;
16199ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ALOGW("%s: 2 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
16209ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                   ctx->blit_yuv_2_plane_object[i].surface_id);
16219ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        }
16229ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
16239ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
16249ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (status == COPYBIT_FAILURE) {
16259ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        clean_up(ctx);
16269ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        status = COPYBIT_FAILURE;
16279ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        *device = NULL;
16289ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return status;
162929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
163029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
16319ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // Create YUV 3 plane surfaces
163229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
163329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
163429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
163529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    yuvSurfaceDef.stride2 = 4;
163629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
16379ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),
163829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              C2D_TARGET | C2D_SOURCE,
16399ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
16409ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
16419ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
164229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              &yuvSurfaceDef)) {
16439ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
16449ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        ctx->dst[YUV_SURFACE_3_PLANES] = 0;
16459ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        clean_up(ctx);
16469ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        status = COPYBIT_FAILURE;
16479ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        *device = NULL;
16489ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return status;
164929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
165029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
16519ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++)
16529ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    {
16539ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        if (LINK_c2dCreateSurface(&(surface_id),
165429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              C2D_TARGET | C2D_SOURCE,
16559ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
16569ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS |
16579ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
165829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed                              &yuvSurfaceDef)) {
16599ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i);
16609ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ctx->blit_yuv_3_plane_object[i].surface_id = 0;
16619ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            status = COPYBIT_FAILURE;
16629ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            break;
16639ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        } else {
16649ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ctx->blit_yuv_3_plane_object[i].surface_id = surface_id;
16659ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R            ALOGW("%s: 3 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
16669ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R                                   ctx->blit_yuv_3_plane_object[i].surface_id);
16679ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        }
166829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    }
166929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
16709ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (status == COPYBIT_FAILURE) {
16719ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        clean_up(ctx);
16729ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        status = COPYBIT_FAILURE;
16739ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        *device = NULL;
16749ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return status;
16759ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
16769ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
16779ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) {
16789ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R         ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__);
16799ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R         clean_up(ctx);
16809ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R         status = COPYBIT_FAILURE;
16819ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        *device = NULL;
16829ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R        return status;
16839ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    }
16849ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    // Initialize context variables.
16859ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->trg_transform = C2D_TARGET_ROTATE_0;
16869ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R
168729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->temp_src_buffer.fd = -1;
168829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->temp_src_buffer.base = 0;
168929a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->temp_src_buffer.size = 0;
169029a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
169129a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->temp_dst_buffer.fd = -1;
169229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->temp_dst_buffer.base = 0;
169329a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->temp_dst_buffer.size = 0;
169429a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
169529a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->fb_width = 0;
169629a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    ctx->fb_height = 0;
169729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
16989ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->blit_rgb_count = 0;
16999ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->blit_yuv_2_plane_count = 0;
17009ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->blit_yuv_3_plane_count = 0;
17019ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    ctx->blit_count = 0;
170229a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed
1703647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    ctx->wait_timestamp = false;
1704647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    ctx->stop_thread = false;
1705647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL);
1706647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_cond_init(&(ctx->wait_cleanup_cond), NULL);
1707647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    /* Start the wait thread */
1708647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_attr_t attr;
1709647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_attr_init(&attr);
1710647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
1711647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
1712647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop,
1713647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R                                                            (void *)ctx);
1714647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R    pthread_attr_destroy(&attr);
1715647c0289e836c3989fd9be435d5ee38639aa4e07Arun Kumar K.R
17169ef7b6a37a323bc5fd7a12ad3e5b34af15cc44a5Arun Kumar K.R    *device = &ctx->device.common;
171729a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed    return status;
171829a26818d7294055539167b2fbfdaa168bcf725cNaseer Ahmed}
1719