107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/*
207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Copyright (C) 2008 The Android Open Source Project
335bc51c90d4db20eeae2c2e807f5e045328cb8c2Sachin Bhayare * Copyright (c) 2010-2016, The Linux Foundation. All rights reserved.
407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *
507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Not a Contribution, Apache license notifications and license are retained
607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * for attribution purposes only.
707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *
807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Licensed under the Apache License, Version 2.0 (the "License");
907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * you may not use this file except in compliance with the License.
1007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * You may obtain a copy of the License at
1107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *
1207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *      http://www.apache.org/licenses/LICENSE-2.0
1307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *
1407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Unless required by applicable law or agreed to in writing, software
1507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * distributed under the License is distributed on an "AS IS" BASIS,
1607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * See the License for the specific language governing permissions and
1807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * limitations under the License.
1907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani */
2007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <cutils/log.h>
2107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <sys/resource.h>
2207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <sys/prctl.h>
2307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
2407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <stdint.h>
2507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <string.h>
2607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <unistd.h>
2707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <errno.h>
2807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <fcntl.h>
2907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
3007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <sys/ioctl.h>
3107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <sys/types.h>
3207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <sys/mman.h>
3307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
3407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <linux/msm_kgsl.h>
3507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
3607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <EGL/eglplatform.h>
3707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <cutils/native_handle.h>
3807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
3907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <copybit.h>
4007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <alloc_controller.h>
4107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <memalloc.h>
4207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
4307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include "c2d2.h"
4407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include "software_converter.h"
4507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
4607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#include <dlfcn.h>
4707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
4807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniusing gralloc::IMemAlloc;
4907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniusing gralloc::IonController;
5007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniusing gralloc::alloc_data;
5107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
5207bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
5307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                     uint32 surface_bits,
5407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                     C2D_SURFACE_TYPE surface_type,
5507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                     void *surface_definition );
5607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
5707bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id,
5807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                     uint32 surface_bits,
5907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                     C2D_SURFACE_TYPE surface_type,
6007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                     void *surface_definition );
6107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
6207bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id,
6307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                   C2D_SURFACE_TYPE surface_type,
6407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                   void *surface_definition,
6507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                   int32 x, int32 y );
6607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
6707bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dDraw)( uint32 target_id,
6807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                            uint32 target_config, C2D_RECT *target_scissor,
6907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                            uint32 target_mask_id, uint32 target_color_key,
7007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                            C2D_OBJECT *objects_list, uint32 num_objects );
7107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
7207bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dFinish)( uint32 target_id);
7307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
7407bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp);
7507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
7607bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp );
7707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
7807bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
7907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
8007bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, size_t len,
8107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                size_t offset, uint32 flags, void ** gpuaddr);
8207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
8307bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
8407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
8507bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info);
8607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
8707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/* create a fence fd for the timestamp */
8807bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
8907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                            int32 *fd);
9007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
9107bbf1e89c031a5d41a7561433e832d396c311a5Prashant MalaniC2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color,
9207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                    C2D_RECT * fill_rect);
9307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
9407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/******************************************************************************/
9507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
9607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#if defined(COPYBIT_Z180)
9707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define MAX_SCALE_FACTOR    (4096)
9807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define MAX_DIMENSION       (4096)
9907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#else
10007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#error "Unsupported HW version"
10107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#endif
10207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
10307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani// The following defines can be changed as required i.e. as we encounter
10407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani// complex use cases.
10507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define MAX_RGB_SURFACES 32       // Max. RGB layers currently supported per draw
10607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw
10707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw
10807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani// +1 for the destination surface. We cannot have multiple destination surfaces.
10907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1)
11007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define NUM_SURFACE_TYPES 3      // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES
11107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani#define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw
11207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
11307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanienum {
11407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    RGB_SURFACE,
11507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    YUV_SURFACE_2_PLANES,
11607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    YUV_SURFACE_3_PLANES
11707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani};
11807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
11907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanienum eConversionType {
12007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    CONVERT_TO_ANDROID_FORMAT,
12107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    CONVERT_TO_C2D_FORMAT
12207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani};
12307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
12407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanienum eC2DFlags {
12507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    FLAGS_PREMULTIPLIED_ALPHA  = 1<<0,
12607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    FLAGS_YUV_DESTINATION      = 1<<1,
12707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    FLAGS_TEMP_SRC_DST         = 1<<2
12807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani};
12907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
13007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic gralloc::IAllocController* sAlloc = 0;
13107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/******************************************************************************/
13207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
13307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/** State information for each device instance */
13407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistruct copybit_context_t {
13507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_device_t device;
13607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Templates for the various source surfaces. These templates are created
13707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // to avoid the expensive create/destroy C2D Surfaces
13807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES];
13907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES];
14007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES];
14107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects
14207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    C2D_DRIVER_INFO c2d_driver_info;
14307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    void *libc2d2;
14407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    alloc_data temp_src_buffer;
14507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    alloc_data temp_dst_buffer;
14607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces
14707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uintptr_t mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
14807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int blit_rgb_count;         // Total RGB surfaces being blit
14907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being
15007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int blit_yuv_3_plane_count; // Total 3 plane YUV  surfaces being blit
15107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int blit_count;             // Total blit objects.
15207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    unsigned int trg_transform;      /* target transform */
15307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int fb_width;
15407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int fb_height;
15507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int src_global_alpha;
15607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int config_mask;
15707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int dst_surface_type;
15807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bool is_premultiplied_alpha;
15907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    void* time_stamp;
16007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr
16107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    void* dst_surface_base; // Stores the dst surface addr
16207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
16307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // used for signaling the wait thread
16407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bool wait_timestamp;
16507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_t wait_thread_id;
16607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bool stop_thread;
16707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_t wait_cleanup_lock;
16807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_cond_t wait_cleanup_cond;
16907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
17007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani};
17107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
17207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistruct bufferInfo {
17307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int width;
17407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int height;
17507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int format;
17607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani};
17707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
17807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistruct yuvPlaneInfo {
17907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int yStride;       //luma stride
18007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int plane1_stride;
18107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int plane2_stride;
18207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    size_t plane1_offset;
18307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    size_t plane2_offset;
18407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani};
18507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
18607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/**
18707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * Common hardware methods
18807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani */
18907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
19007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int open_copybit(const struct hw_module_t* module, const char* name,
19107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                        struct hw_device_t** device);
19207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
19307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic struct hw_module_methods_t copybit_module_methods = {
19435bc51c90d4db20eeae2c2e807f5e045328cb8c2Sachin Bhayare    .open = open_copybit,
19507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani};
19607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
19707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/*
19807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * The COPYBIT Module
19907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani */
20007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistruct copybit_module_t HAL_MODULE_INFO_SYM = {
20135bc51c90d4db20eeae2c2e807f5e045328cb8c2Sachin Bhayare    .common = {
20235bc51c90d4db20eeae2c2e807f5e045328cb8c2Sachin Bhayare        .tag =  HARDWARE_MODULE_TAG,
20335bc51c90d4db20eeae2c2e807f5e045328cb8c2Sachin Bhayare        .version_major = 1,
20435bc51c90d4db20eeae2c2e807f5e045328cb8c2Sachin Bhayare        .version_minor = 0,
20535bc51c90d4db20eeae2c2e807f5e045328cb8c2Sachin Bhayare        .id = COPYBIT_HARDWARE_MODULE_ID,
20635bc51c90d4db20eeae2c2e807f5e045328cb8c2Sachin Bhayare        .name = "QCT COPYBIT C2D 2.0 Module",
20735bc51c90d4db20eeae2c2e807f5e045328cb8c2Sachin Bhayare        .author = "Qualcomm",
20835bc51c90d4db20eeae2c2e807f5e045328cb8c2Sachin Bhayare        .methods =  &copybit_module_methods
20935bc51c90d4db20eeae2c2e807f5e045328cb8c2Sachin Bhayare    }
21007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani};
21107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
21207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
21307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/* thread function which waits on the timeStamp and cleans up the surfaces */
21407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic void* c2d_wait_loop(void* ptr) {
21507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    copybit_context_t* ctx = (copybit_context_t*)(ptr);
21607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    char thread_name[64] = "copybitWaitThr";
21707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
21807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
21907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
22007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    while(ctx->stop_thread == false) {
22107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        pthread_mutex_lock(&ctx->wait_cleanup_lock);
22207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        while(ctx->wait_timestamp == false && !ctx->stop_thread) {
22307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            pthread_cond_wait(&(ctx->wait_cleanup_cond),
22407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              &(ctx->wait_cleanup_lock));
22507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
22607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(ctx->wait_timestamp) {
22707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if(LINK_c2dWaitTimestamp(ctx->time_stamp)) {
22807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__);
22907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            }
23007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->wait_timestamp = false;
23107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            // Unmap any mapped addresses.
23207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            for (int i = 0; i < MAX_SURFACES; i++) {
23307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                if (ctx->mapped_gpu_addr[i]) {
23407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
23507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    ctx->mapped_gpu_addr[i] = 0;
23607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                }
23707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            }
23807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            // Reset the counts after the draw.
23907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->blit_rgb_count = 0;
24007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->blit_yuv_2_plane_count = 0;
24107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->blit_yuv_3_plane_count = 0;
24207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->blit_count = 0;
24307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->dst_surface_mapped = false;
24407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->dst_surface_base = 0;
24507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
24607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
24707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(ctx->stop_thread)
24807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
24907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
25007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_exit(NULL);
25107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return NULL;
25207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
25307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
25407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
25507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/* convert COPYBIT_FORMAT to C2D format */
25607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int get_format(int format) {
25707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    switch (format) {
25807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_RGB_565:        return C2D_COLOR_FORMAT_565_RGB;
25907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_RGB_888:        return C2D_COLOR_FORMAT_888_RGB |
26007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                              C2D_FORMAT_SWAP_RB;
26107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
26207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                              C2D_FORMAT_SWAP_RB |
26307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                  C2D_FORMAT_DISABLE_ALPHA;
26407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
26507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                              C2D_FORMAT_SWAP_RB;
26607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_BGRA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
26707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
26807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
26907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
27007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 |
27107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                  C2D_FORMAT_MACROTILED;
27207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        default:                              ALOGE("%s: invalid format (0x%x",
27307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                     __FUNCTION__, format);
27407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                              return -EINVAL;
27507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
27607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return -EINVAL;
27707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
27807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
27907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/* Get the C2D formats needed for conversion to YUV */
28007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int get_c2d_format_for_yuv_destination(int halFormat) {
28107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    switch (halFormat) {
28207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // We do not swap the RB when the target is YUV
28307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
28407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                              C2D_FORMAT_DISABLE_ALPHA;
28507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
28607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // The U and V need to be interchanged when the target is YUV
28707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
28807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21;
28907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
29007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        default:                              return get_format(halFormat);
29107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
29207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return -EINVAL;
29307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
29407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
29507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/* ------------------------------------------------------------------- *//*!
29607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * \internal
29707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * \brief Get the bpp for a particular color format
29807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * \param color format
29907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * \return bits per pixel
30007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani *//* ------------------------------------------------------------------- */
30107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malaniint c2diGetBpp(int32 colorformat)
30207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
30307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
30407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int c2dBpp = 0;
30507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
30607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    switch(colorformat&0xFF)
30707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    {
30807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_4444_RGBA:
30907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_4444_ARGB:
31007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_1555_ARGB:
31107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_565_RGB:
31207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_5551_RGBA:
31307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            c2dBpp = 16;
31407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
31507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_8888_RGBA:
31607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_8888_ARGB:
31707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            c2dBpp = 32;
31807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
31907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_888_RGB:
32007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            c2dBpp = 24;
32107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
32207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_8_L:
32307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_8_A:
32407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            c2dBpp = 8;
32507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
32607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_4_A:
32707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            c2dBpp = 4;
32807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
32907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case C2D_COLOR_FORMAT_1:
33007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            c2dBpp = 1;
33107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
33207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        default:
33307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s ERROR", __func__);
33407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
33507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
33607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return c2dBpp;
33707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
33807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
33907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic size_t c2d_get_gpuaddr(copybit_context_t* ctx,
34007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              struct private_handle_t *handle, int &mapped_idx)
34107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
34207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uint32 memtype;
34307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    size_t *gpuaddr = 0;
34407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    C2D_STATUS rc;
34507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int freeindex = 0;
34607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bool mapaddr = false;
34707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
34807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!handle)
34907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return 0;
35007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
35107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (handle->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
35207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                         private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP))
35307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        memtype = KGSL_USER_MEM_TYPE_PMEM;
35407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)
35507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        memtype = KGSL_USER_MEM_TYPE_ASHMEM;
35607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
35707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        memtype = KGSL_USER_MEM_TYPE_ION;
35807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    else {
35907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("Invalid handle flags: 0x%x", handle->flags);
36007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return 0;
36107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
36207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
36307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Check for a freeindex in the mapped_gpu_addr list
36407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (freeindex = 0; freeindex < MAX_SURFACES; freeindex++) {
36507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (ctx->mapped_gpu_addr[freeindex] == 0) {
36607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            // free index is available
36707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            // map GPU addr and use this as mapped_idx
36807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            mapaddr = true;
36907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
37007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
37107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
37207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
37307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(mapaddr) {
37407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size,
37507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                             handle->offset, memtype, (void**)&gpuaddr);
37607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
37707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (rc == C2D_STATUS_OK) {
37807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            // We have mapped the GPU address inside copybit. We need to unmap
37907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            // this address after the blit. Store this address
38007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->mapped_gpu_addr[freeindex] = (size_t)gpuaddr;
38107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            mapped_idx = freeindex;
38207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
38307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
38407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return (size_t)gpuaddr;
38507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
38607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
38707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx)
38807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
38907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!ctx || (mapped_idx == -1))
39007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return;
39107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
39207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (ctx->mapped_gpu_addr[mapped_idx]) {
39307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]);
39407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->mapped_gpu_addr[mapped_idx] = 0;
39507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
39607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
39707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
39807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int is_supported_rgb_format(int format)
39907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
40007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    switch(format) {
40107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_RGBA_8888:
40207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_RGBX_8888:
40307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_RGB_888:
40407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_RGB_565:
40507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_BGRA_8888: {
40607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return COPYBIT_SUCCESS;
40707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
40807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        default:
40907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return COPYBIT_FAILURE;
41007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
41107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
41207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
41307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int get_num_planes(int format)
41407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
41507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    switch(format) {
41607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
41707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
41807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
41907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
42007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return 2;
42107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
42207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YV12: {
42307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return 3;
42407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
42507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        default:
42607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return COPYBIT_FAILURE;
42707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
42807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
42907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
43007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int is_supported_yuv_format(int format)
43107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
43207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    switch(format) {
43307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
43407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
43507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
43607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
43707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return COPYBIT_SUCCESS;
43807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
43907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        default:
44007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return COPYBIT_FAILURE;
44107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
44207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
44307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
44407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int is_valid_destination_format(int format)
44507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
44607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
44707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // C2D does not support NV12Tile as a destination format.
44807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
44907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
45007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return COPYBIT_SUCCESS;
45107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
45207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
45307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int calculate_yuv_offset_and_stride(const bufferInfo& info,
45407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                           yuvPlaneInfo& yuvInfo)
45507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
45607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int width  = info.width;
45707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int height = info.height;
45807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int format = info.format;
45907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
46007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int aligned_height = 0;
46107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int aligned_width = 0, size = 0;
46207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
46307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    switch (format) {
46407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
46507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            /* NV12 Tile buffers have their luma height aligned to 32bytes and width
46607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani             * aligned to 128 bytes. The chroma offset starts at an 8K boundary
46707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani             */
46807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            aligned_height = ALIGN(height, 32);
46907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            aligned_width  = ALIGN(width, 128);
47007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            size = aligned_width * aligned_height;
47107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            yuvInfo.plane1_offset = ALIGN(size,8192);
47207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            yuvInfo.yStride = aligned_width;
47307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            yuvInfo.plane1_stride = aligned_width;
47407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
47507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
47607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
47707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
47807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
47907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            aligned_width = ALIGN(width, 32);
48007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            yuvInfo.yStride = aligned_width;
48107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            yuvInfo.plane1_stride = aligned_width;
48207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
48307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                // The encoder requires a 2K aligned chroma offset
48407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048);
48507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            } else
48607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                yuvInfo.plane1_offset = aligned_width * height;
48707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
48807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
48907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
49007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        default: {
49107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return COPYBIT_FAILURE;
49207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
49307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
49407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return COPYBIT_SUCCESS;
49507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
49607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
49707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/** create C2D surface from copybit image */
49807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int set_image(copybit_context_t* ctx, uint32 surfaceId,
49907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                      const struct copybit_image_t *rhs,
50007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                      const eC2DFlags flags, int &mapped_idx)
50107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
50207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
50307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    C2D_SURFACE_TYPE surfaceType;
50407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int status = COPYBIT_SUCCESS;
50507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uint64_t gpuaddr = 0;
50607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int c2d_format;
50707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    mapped_idx = -1;
50807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
50907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (flags & FLAGS_YUV_DESTINATION) {
51007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2d_format = get_c2d_format_for_yuv_destination(rhs->format);
51107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else {
51207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2d_format = get_format(rhs->format);
51307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
51407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
51507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(c2d_format == -EINVAL) {
51607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: invalid format", __FUNCTION__);
51707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return -EINVAL;
51807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
51907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
52007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(handle == NULL) {
52107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: invalid handle", __func__);
52207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return -EINVAL;
52307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
52407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
52507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (handle->gpuaddr == 0) {
52607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx);
52707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(!gpuaddr) {
52807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
52907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return COPYBIT_FAILURE;
53007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
53107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else {
53207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        gpuaddr = handle->gpuaddr;
53307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
53407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
53507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    /* create C2D surface */
53607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
53707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        /* RGB */
53807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        C2D_RGB_SURFACE_DEF surfaceDef;
53907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
54007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS);
54107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
54207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.phys = (void*) gpuaddr;
54307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.buffer = (void*) (handle->base);
54407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
54507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.format = c2d_format |
54607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
54707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.width = rhs->w;
54807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.height = rhs->h;
54907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int aligned_width = ALIGN((int)surfaceDef.width,32);
55007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;
55107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
55207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
55307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                  &surfaceDef)) {
55407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__);
55507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            unmap_gpuaddr(ctx, mapped_idx);
55607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            status = COPYBIT_FAILURE;
55707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
55807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
55907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        C2D_YUV_SURFACE_DEF surfaceDef;
56007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        memset(&surfaceDef, 0, sizeof(surfaceDef));
56107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS);
56207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.format = c2d_format;
56307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
56407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        bufferInfo info;
56507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        info.width = rhs->w;
56607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        info.height = rhs->h;
56707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        info.format = rhs->format;
56807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
56907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        yuvPlaneInfo yuvInfo = {0};
57007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = calculate_yuv_offset_and_stride(info, yuvInfo);
57107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(status != COPYBIT_SUCCESS) {
57207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
57307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            unmap_gpuaddr(ctx, mapped_idx);
57407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
57507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
57607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.width = rhs->w;
57707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.height = rhs->h;
57807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.plane0 = (void*) (handle->base);
57907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.phys0 = (void*) (gpuaddr);
58007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.stride0 = yuvInfo.yStride;
58107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
58207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
58307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset);
58407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        surfaceDef.stride1 = yuvInfo.plane1_stride;
58507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (3 == get_num_planes(rhs->format)) {
58607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset);
58707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset);
58807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            surfaceDef.stride2 = yuvInfo.plane2_stride;
58907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
59007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
59107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
59207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                  &surfaceDef)) {
59307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__);
59407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            unmap_gpuaddr(ctx, mapped_idx);
59507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            status = COPYBIT_FAILURE;
59607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
59707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else {
59807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
59907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        unmap_gpuaddr(ctx, mapped_idx);
60007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = COPYBIT_FAILURE;
60107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
60207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
60307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return status;
60407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
60507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
60607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/** copy the bits */
60707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int msm_copybit(struct copybit_context_t *ctx, unsigned int target)
60807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
60907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (ctx->blit_count == 0) {
61007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_SUCCESS;
61107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
61207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
61307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (int i = 0; i < ctx->blit_count; i++)
61407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    {
61507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_list[i].next = &(ctx->blit_list[i+1]);
61607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
61707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->blit_list[ctx->blit_count-1].next = NULL;
61807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    uint32_t target_transform = ctx->trg_transform;
61907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (ctx->c2d_driver_info.capabilities_mask &
62007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
62107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // For A3xx - set 0x0 as the transform is set in the config_mask
62207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        target_transform = 0x0;
62307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
62407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(LINK_c2dDraw(target, target_transform, 0x0, 0, 0, ctx->blit_list,
62507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    ctx->blit_count)) {
62607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
62707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
62807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
62907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return COPYBIT_SUCCESS;
63007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
63107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
63207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
63307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
63407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd)
63507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
63607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
63707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int status = COPYBIT_FAILURE;
63807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!ctx)
63907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
64007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_lock(&ctx->wait_cleanup_lock);
64107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
64207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
64307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) {
64407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__);
64507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // unlock the mutex and return failure
64607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
64707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
64807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
64907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp,
65007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                                        fd)) {
65107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__);
65207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = COPYBIT_FAILURE;
65307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
65407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(status == COPYBIT_SUCCESS) {
65507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        //signal the wait_thread
65607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->wait_timestamp = true;
65707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        pthread_cond_signal(&ctx->wait_cleanup_cond);
65807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
65907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
66007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return status;
66107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
66207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
66307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int finish_copybit(struct copybit_device_t *dev)
66407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
66507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
66607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!ctx)
66707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
66807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
66907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani   int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
67007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
67107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani   if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) {
67207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
67307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
67407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
67507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
67607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Unmap any mapped addresses.
67707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (int i = 0; i < MAX_SURFACES; i++) {
67807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (ctx->mapped_gpu_addr[i]) {
67907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
68007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->mapped_gpu_addr[i] = 0;
68107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
68207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
68307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
68407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Reset the counts after the draw.
68507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->blit_rgb_count = 0;
68607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->blit_yuv_2_plane_count = 0;
68707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->blit_yuv_3_plane_count = 0;
68807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->blit_count = 0;
68907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->dst_surface_mapped = false;
69007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->dst_surface_base = 0;
69107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
69207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return status;
69307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
69407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
69507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int clear_copybit(struct copybit_device_t *dev,
69607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                         struct copybit_image_t const *buf,
69707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                         struct copybit_rect_t *rect)
69807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
69907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int ret = COPYBIT_SUCCESS;
70007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int flags = FLAGS_PREMULTIPLIED_ALPHA;
70107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int mapped_dst_idx = -1;
70207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
70307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
70407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_lock(&ctx->wait_cleanup_lock);
70507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!ctx->dst_surface_mapped) {
70607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf,
70707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                        (eC2DFlags)flags, mapped_dst_idx);
70807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(ret) {
70907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: set_image error", __FUNCTION__);
71007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            unmap_gpuaddr(ctx, mapped_dst_idx);
71107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            pthread_mutex_unlock(&ctx->wait_cleanup_lock);
71207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return COPYBIT_FAILURE;
71307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
71407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        //clear_copybit is the first call made by HWC for each composition
71507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        //with the dest surface, hence set dst_surface_mapped.
71607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->dst_surface_mapped = true;
71707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->dst_surface_base = buf->base;
71807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect);
71907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
72007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
72107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return ret;
72207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
72307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
72407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
72507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/** setup rectangles */
72607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic void set_rects(struct copybit_context_t *ctx,
72707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                      C2D_OBJECT *c2dObject,
72807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                      const struct copybit_rect_t *dst,
72907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                      const struct copybit_rect_t *src,
73007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                      const struct copybit_rect_t *scissor)
73107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
73207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Set the target rect.
73307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if((ctx->trg_transform & C2D_TARGET_ROTATE_90) &&
73407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       (ctx->trg_transform & C2D_TARGET_ROTATE_180)) {
73507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        /* target rotation is 270 */
73607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.x        = (dst->t)<<16;
73707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.y        = ctx->fb_width?
73807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                (ALIGN(ctx->fb_width,32)- dst->r):dst->r;
73907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
74007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
74107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
74207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) {
74307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.x        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
74407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
74507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.y        = (dst->l)<<16;
74607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
74707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
74807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) {
74907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.y        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
75007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
75107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.x        = ctx->fb_width?
75207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                (ALIGN(ctx->fb_width,32) - dst->r):dst->r;
75307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
75407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
75507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
75607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else {
75707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.x        = (dst->l)<<16;
75807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.y        = (dst->t)<<16;
75907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
76007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
76107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
76207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    c2dObject->config_mask |= C2D_TARGET_RECT_BIT;
76307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
76407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Set the source rect
76507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    c2dObject->source_rect.x        = (src->l)<<16;
76607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    c2dObject->source_rect.y        = (src->t)<<16;
76707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    c2dObject->source_rect.height   = ((src->b) - (src->t))<<16;
76807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    c2dObject->source_rect.width    = ((src->r) - (src->l))<<16;
76907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    c2dObject->config_mask |= C2D_SOURCE_RECT_BIT;
77007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
77107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Set the scissor rect
77207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    c2dObject->scissor_rect.x       = scissor->l;
77307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    c2dObject->scissor_rect.y       = scissor->t;
77407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    c2dObject->scissor_rect.height  = (scissor->b) - (scissor->t);
77507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    c2dObject->scissor_rect.width   = (scissor->r) - (scissor->l);
77607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT;
77707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
77807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
77907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/*****************************************************************************/
78007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
78107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/** Set a parameter to value */
78207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int set_parameter_copybit(
78307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_device_t *dev,
78407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int name,
78507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int value)
78607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
78707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
78807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int status = COPYBIT_SUCCESS;
78907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!ctx) {
79007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: null context", __FUNCTION__);
79107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return -EINVAL;
79207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
79307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
79407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_lock(&ctx->wait_cleanup_lock);
79507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    switch(name) {
79607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_PLANE_ALPHA:
79707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        {
79807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if (value < 0)      value = 0;
79907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if (value >= 256)   value = 255;
80007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
80107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->src_global_alpha = value;
80207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if (value < 255)
80307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT;
80407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            else
80507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT;
80607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
80707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        break;
80807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_BLEND_MODE:
80907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        {
81007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if (value == COPYBIT_BLENDING_NONE) {
81107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ctx->config_mask |= C2D_ALPHA_BLEND_NONE;
81207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ctx->is_premultiplied_alpha = true;
81307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            } else if (value == COPYBIT_BLENDING_PREMULT) {
81407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ctx->is_premultiplied_alpha = true;
81507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            } else {
81607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE;
81707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            }
81807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
81907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        break;
82007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_TRANSFORM:
82107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        {
82207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            unsigned int transform = 0;
82307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            uint32 config_mask = 0;
82407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG;
82507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) {
82607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                transform = C2D_TARGET_ROTATE_180;
82707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180;
82807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) {
82907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                transform = C2D_TARGET_ROTATE_90;
83007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90;
83107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            } else if(value == COPYBIT_TRANSFORM_ROT_90) {
83207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                transform = C2D_TARGET_ROTATE_270;
83307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270;
83407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            } else {
83507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0;
83607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                if(value & COPYBIT_TRANSFORM_FLIP_H) {
83707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    config_mask |= C2D_MIRROR_H_BIT;
83807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                } else if(value & COPYBIT_TRANSFORM_FLIP_V) {
83907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    config_mask |= C2D_MIRROR_V_BIT;
84007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                }
84107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            }
84207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
84307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if (ctx->c2d_driver_info.capabilities_mask &
84407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
84507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ctx->config_mask |= config_mask;
84607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            } else {
84707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                // The transform for this surface does not match the current
84807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                // target transform. Draw all previous surfaces. This will be
84907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                // changed once we have a new mechanism to send different
85007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                // target rotations to c2d.
85107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                finish_copybit(dev);
85207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            }
85307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->trg_transform = transform;
85407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
85507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        break;
85607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_FRAMEBUFFER_WIDTH:
85707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->fb_width = value;
85807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
85907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_FRAMEBUFFER_HEIGHT:
86007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->fb_height = value;
86107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
86207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_ROTATION_DEG:
86307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_DITHER:
86407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_BLUR:
86507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_BLIT_TO_FRAMEBUFFER:
86607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            // Do nothing
86707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
86807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        default:
86907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
87007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            status = -EINVAL;
87107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
87207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
87307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
87407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return status;
87507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
87607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
87707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/** Get a static info value */
87807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int get(struct copybit_device_t *dev, int name)
87907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
88007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
88107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int value;
88207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
88307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!ctx) {
88407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: null context error", __FUNCTION__);
88507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return -EINVAL;
88607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
88707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
88807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    switch(name) {
88907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_MINIFICATION_LIMIT:
89007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            value = MAX_SCALE_FACTOR;
89107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
89207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_MAGNIFICATION_LIMIT:
89307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            value = MAX_SCALE_FACTOR;
89407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
89507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_SCALING_FRAC_BITS:
89607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            value = 32;
89707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
89807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case COPYBIT_ROTATION_STEP_DEG:
89907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            value = 1;
90007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
90107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        default:
90207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
90307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            value = -EINVAL;
90407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
90507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return value;
90607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
90707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
90807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/* Function to check if we need a temporary buffer for the blit.
90907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * This would happen if the requested destination stride and the
91007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * C2D stride do not match. We ignore RGB buffers, since their
91107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * stride is always aligned to 32.
91207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani */
91307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic bool need_temp_buffer(struct copybit_image_t const *img)
91407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
91507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format))
91607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return false;
91707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
91807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct private_handle_t* handle = (struct private_handle_t*)img->handle;
91907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
92007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // The width parameter in the handle contains the aligned_w. We check if we
92107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // need to convert based on this param. YUV formats have bpp=1, so checking
92207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // if the requested stride is aligned should suffice.
92307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (0 == (handle->width)%32) {
92407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return false;
92507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
92607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
92707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return true;
92807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
92907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
93007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/* Function to extract the information from the copybit image and set the corresponding
93107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * values in the bufferInfo struct.
93207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani */
93307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info)
93407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
93507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    info.width = img->w;
93607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    info.height = img->h;
93707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    info.format = img->format;
93807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
93907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
94007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/* Function to get the required size for a particular format, inorder for C2D to perform
94107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * the blit operation.
94207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani */
94307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int get_size(const bufferInfo& info)
94407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
94507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int size = 0;
94607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int w = info.width;
94707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int h = info.height;
94807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int aligned_w = ALIGN(w, 32);
94907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    switch(info.format) {
95007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
95107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            {
95207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                // Chroma for this format is aligned to 2K.
95307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                size = ALIGN((aligned_w*h), 2048) +
95407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                        ALIGN(aligned_w/2, 32) * (h/2) *2;
95507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                size = ALIGN(size, 4096);
95607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            } break;
95707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
95807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
95907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            {
96007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                size = aligned_w * h +
96107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                       ALIGN(aligned_w/2, 32) * (h/2) * 2;
96207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                size = ALIGN(size, 4096);
96307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            } break;
96407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        default: break;
96507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
96607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return size;
96707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
96807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
96907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/* Function to allocate memory for the temporary buffer. This memory is
97007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * allocated from Ashmem. It is the caller's responsibility to free this
97107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * memory.
97207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani */
97307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int get_temp_buffer(const bufferInfo& info, alloc_data& data)
97407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
97507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ALOGD("%s E", __FUNCTION__);
97607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Alloc memory from system heap
97707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    data.base = 0;
97807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    data.fd = -1;
97907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    data.offset = 0;
98007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    data.size = get_size(info);
98107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    data.align = getpagesize();
98207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    data.uncached = true;
98307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int allocFlags = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;
98407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
98507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (sAlloc == 0) {
98607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        sAlloc = gralloc::IAllocController::getInstance();
98707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
98807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
98907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (sAlloc == 0) {
99007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: sAlloc is still NULL", __FUNCTION__);
99107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
99207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
99307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
99407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int err = sAlloc->allocate(data, allocFlags);
99507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (0 != err) {
99607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: allocate failed", __FUNCTION__);
99707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
99807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
99907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
100007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ALOGD("%s X", __FUNCTION__);
100107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return err;
100207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
100307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
100407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/* Function to free the temporary allocated memory.*/
100507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic void free_temp_buffer(alloc_data &data)
100607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
100707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (-1 != data.fd) {
100807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType);
100907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        memalloc->free_buffer(data.base, data.size, 0, data.fd);
101007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
101107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
101207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
101307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/* Function to perform the software color conversion. Convert the
101407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani * C2D compatible format to the Android compatible format
101507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani */
101607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int copy_image(private_handle_t *src_handle,
101707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                      struct copybit_image_t const *rhs,
101807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                      eConversionType conversionType)
101907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
102007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (src_handle->fd == -1) {
102107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: src_handle fd is invalid", __FUNCTION__);
102207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
102307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
102407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
102507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Copy the info.
102607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int ret = COPYBIT_SUCCESS;
102707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    switch(rhs->format) {
102807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
102907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
103007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
103107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            {
103207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                if (CONVERT_TO_ANDROID_FORMAT == conversionType) {
103307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    return convert_yuv_c2d_to_yuv_android(src_handle, rhs);
103407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                } else {
103507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                    return convert_yuv_android_to_yuv_c2d(src_handle, rhs);
103607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                }
103707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
103807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            } break;
103907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        default: {
104007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
104107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ret = COPYBIT_FAILURE;
104207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        } break;
104307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
104407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return ret;
104507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
104607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
104707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic void delete_handle(private_handle_t *handle)
104807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
104907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (handle) {
105007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        delete handle;
105107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        handle = 0;
105207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
105307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
105407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
105507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic bool need_to_execute_draw(eC2DFlags flags)
105607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
105707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (flags & FLAGS_TEMP_SRC_DST) {
105807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return true;
105907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
106007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (flags & FLAGS_YUV_DESTINATION) {
106107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return true;
106207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
106307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return false;
106407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
106507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
106607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/** do a stretch blit type operation */
106707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int stretch_copybit_internal(
106807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_device_t *dev,
106907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_image_t const *dst,
107007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_image_t const *src,
107107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_rect_t const *dst_rect,
107207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_rect_t const *src_rect,
107307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_region_t const *region,
107407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bool enableBlend)
107507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
107607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
107707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int status = COPYBIT_SUCCESS;
107807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int flags = 0;
107907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int src_surface_type;
108007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int mapped_src_idx = -1, mapped_dst_idx = -1;
108107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    C2D_OBJECT_STR src_surface;
108207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
108307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!ctx) {
108407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: null context error", __FUNCTION__);
108507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return -EINVAL;
108607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
108707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
108807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
108907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: src dimension error", __FUNCTION__);
109007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return -EINVAL;
109107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
109207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
109307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
109407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s : dst dimension error dst w %d h %d",  __FUNCTION__, dst->w,
109507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                         dst->h);
109607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return -EINVAL;
109707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
109807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
109907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) {
110007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__,
110107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                              dst->format);
110207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
110307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
110407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
110507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int dst_surface_type;
110607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
110707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        dst_surface_type = RGB_SURFACE;
110807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        flags |= FLAGS_PREMULTIPLIED_ALPHA;
110907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) {
111007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int num_planes = get_num_planes(dst->format);
111107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        flags |= FLAGS_YUV_DESTINATION;
111207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (num_planes == 2) {
111307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            dst_surface_type = YUV_SURFACE_2_PLANES;
111407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        } else if (num_planes == 3) {
111507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            dst_surface_type = YUV_SURFACE_3_PLANES;
111607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        } else {
111707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x",
111807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                  __FUNCTION__, dst->format);
111907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return COPYBIT_FAILURE;
112007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
112107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else {
112207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__,
112307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                     dst->format);
112407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
112507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
112607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
112707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (ctx->blit_rgb_count == MAX_RGB_SURFACES ||
112807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_yuv_2_plane_count == MAX_YUV_2_PLANE_SURFACES ||
112907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_yuv_3_plane_count == MAX_YUV_2_PLANE_SURFACES ||
113007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_count == MAX_BLIT_OBJECT_COUNT ||
113107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->dst_surface_type != dst_surface_type) {
113207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // we have reached the max. limits of our internal structures or
113307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // changed the target.
113407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // Draw the remaining surfaces. We need to do the finish here since
113507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // we need to free up the surface templates.
113607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        finish_copybit(dev);
113707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
113807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
113907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->dst_surface_type = dst_surface_type;
114007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
114107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Update the destination
114207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    copybit_image_t dst_image;
114307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    dst_image.w = dst->w;
114407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    dst_image.h = dst->h;
114507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    dst_image.format = dst->format;
114607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    dst_image.handle = dst->handle;
114707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Check if we need a temp. copy for the destination. We'd need this the destination
114807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // width is not aligned to 32. This case occurs for YUV formats. RGB formats are
114907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // aligned to 32.
115007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bool need_temp_dst = need_temp_buffer(dst);
115107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bufferInfo dst_info;
115207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    populate_buffer_info(dst, dst_info);
115307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format,
115407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                     dst_info.width, dst_info.height);
115507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (dst_hnd == NULL) {
115607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: dst_hnd is null", __FUNCTION__);
115707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
115807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
115907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (need_temp_dst) {
116007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (get_size(dst_info) != (int) ctx->temp_dst_buffer.size) {
116107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            free_temp_buffer(ctx->temp_dst_buffer);
116207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            // Create a temp buffer and set that as the destination.
116307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) {
116407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ALOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__);
116507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                delete_handle(dst_hnd);
116607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                return COPYBIT_FAILURE;
116707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            }
116807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
116907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        dst_hnd->fd = ctx->temp_dst_buffer.fd;
117007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        dst_hnd->size = ctx->temp_dst_buffer.size;
117107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        dst_hnd->flags = ctx->temp_dst_buffer.allocType;
117207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        dst_hnd->base = (uintptr_t)(ctx->temp_dst_buffer.base);
117307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        dst_hnd->offset = ctx->temp_dst_buffer.offset;
117407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        dst_hnd->gpuaddr = 0;
117507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        dst_image.handle = dst_hnd;
117607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
117707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!ctx->dst_surface_mapped) {
117807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        //map the destination surface to GPU address
117907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = set_image(ctx, ctx->dst[ctx->dst_surface_type], &dst_image,
118007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                           (eC2DFlags)flags, mapped_dst_idx);
118107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(status) {
118207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: dst: set_image error", __FUNCTION__);
118307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            delete_handle(dst_hnd);
118407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            unmap_gpuaddr(ctx, mapped_dst_idx);
118507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return COPYBIT_FAILURE;
118607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
118707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->dst_surface_mapped = true;
118807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->dst_surface_base = dst->base;
118907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else if(ctx->dst_surface_mapped && ctx->dst_surface_base != dst->base) {
119007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // Destination surface for the operation should be same for multiple
119107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // requests, this check is catch if there is any case when the
119207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // destination changes
119307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: a different destination surface!!", __FUNCTION__);
119407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
119507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
119607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Update the source
119707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    flags = 0;
119807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) {
119907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        src_surface_type = RGB_SURFACE;
120007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        src_surface = ctx->blit_rgb_object[ctx->blit_rgb_count];
120107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) {
120207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        int num_planes = get_num_planes(src->format);
120307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (num_planes == 2) {
120407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            src_surface_type = YUV_SURFACE_2_PLANES;
120507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            src_surface = ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count];
120607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        } else if (num_planes == 3) {
120707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            src_surface_type = YUV_SURFACE_3_PLANES;
120807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            src_surface = ctx->blit_yuv_3_plane_object[ctx->blit_yuv_2_plane_count];
120907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        } else {
121007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: src number of YUV planes is invalid src format = 0x%x",
121107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                  __FUNCTION__, src->format);
121207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            delete_handle(dst_hnd);
121307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            unmap_gpuaddr(ctx, mapped_dst_idx);
121407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return -EINVAL;
121507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
121607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else {
121707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__,
121807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                        src->format);
121907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        delete_handle(dst_hnd);
122007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        unmap_gpuaddr(ctx, mapped_dst_idx);
122107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return -EINVAL;
122207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
122307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
122407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    copybit_image_t src_image;
122507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    src_image.w = src->w;
122607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    src_image.h = src->h;
122707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    src_image.format = src->format;
122807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    src_image.handle = src->handle;
122907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
123007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bool need_temp_src = need_temp_buffer(src);
123107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bufferInfo src_info;
123207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    populate_buffer_info(src, src_info);
123307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format,
123407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 src_info.width, src_info.height);
123507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (NULL == src_hnd) {
123607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: src_hnd is null", __FUNCTION__);
123707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        delete_handle(dst_hnd);
123807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        unmap_gpuaddr(ctx, mapped_dst_idx);
123907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
124007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
124107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (need_temp_src) {
124207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (get_size(src_info) != (int) ctx->temp_src_buffer.size) {
124307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            free_temp_buffer(ctx->temp_src_buffer);
124407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            // Create a temp buffer and set that as the destination.
124507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if (COPYBIT_SUCCESS != get_temp_buffer(src_info,
124607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                               ctx->temp_src_buffer)) {
124707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__);
124807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                delete_handle(dst_hnd);
124907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                delete_handle(src_hnd);
125007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                unmap_gpuaddr(ctx, mapped_dst_idx);
125107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                return COPYBIT_FAILURE;
125207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            }
125307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
125407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        src_hnd->fd = ctx->temp_src_buffer.fd;
125507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        src_hnd->size = ctx->temp_src_buffer.size;
125607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        src_hnd->flags = ctx->temp_src_buffer.allocType;
125707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        src_hnd->base = (uintptr_t)(ctx->temp_src_buffer.base);
125807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        src_hnd->offset = ctx->temp_src_buffer.offset;
125907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        src_hnd->gpuaddr = 0;
126007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        src_image.handle = src_hnd;
126107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
126207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // Copy the source.
126307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = copy_image((private_handle_t *)src->handle, &src_image,
126407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                CONVERT_TO_C2D_FORMAT);
126507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (status == COPYBIT_FAILURE) {
126607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s:copy_image failed in temp source",__FUNCTION__);
126707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            delete_handle(dst_hnd);
126807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            delete_handle(src_hnd);
126907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            unmap_gpuaddr(ctx, mapped_dst_idx);
127007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return status;
127107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
127207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
127307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // Clean the cache
127407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
127507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
127607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                   src_hnd->offset, src_hnd->fd,
127707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                   gralloc::CACHE_CLEAN)) {
127807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: clean_buffer failed", __FUNCTION__);
127907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            delete_handle(dst_hnd);
128007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            delete_handle(src_hnd);
128107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            unmap_gpuaddr(ctx, mapped_dst_idx);
128207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return COPYBIT_FAILURE;
128307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
128407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
128507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
128607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
128707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
128807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    status = set_image(ctx, src_surface.surface_id, &src_image,
128907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                       (eC2DFlags)flags, mapped_src_idx);
129007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(status) {
129107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: set_image (src) error", __FUNCTION__);
129207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        delete_handle(dst_hnd);
129307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        delete_handle(src_hnd);
129407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        unmap_gpuaddr(ctx, mapped_dst_idx);
129507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        unmap_gpuaddr(ctx, mapped_src_idx);
129607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
129707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
129807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
129907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    src_surface.config_mask = C2D_NO_ANTIALIASING_BIT | ctx->config_mask;
130007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    src_surface.global_alpha = ctx->src_global_alpha;
130107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (enableBlend) {
130207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) {
130307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
130407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            if(!(src_surface.global_alpha)) {
130507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                // src alpha is zero
130607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                delete_handle(dst_hnd);
130707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                delete_handle(src_hnd);
130807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                unmap_gpuaddr(ctx, mapped_dst_idx);
130907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                unmap_gpuaddr(ctx, mapped_src_idx);
131007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                return COPYBIT_FAILURE;
131107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            }
131207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
131307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else {
131407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
131507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
131607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
131707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (src_surface_type == RGB_SURFACE) {
131807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_rgb_object[ctx->blit_rgb_count] = src_surface;
131907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_rgb_count++;
132007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else if (src_surface_type == YUV_SURFACE_2_PLANES) {
132107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count] = src_surface;
132207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_yuv_2_plane_count++;
132307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    } else {
132407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_yuv_3_plane_object[ctx->blit_yuv_3_plane_count] = src_surface;
132507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_yuv_3_plane_count++;
132607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
132707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
132807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_rect_t clip;
132907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    while ((status == 0) && region->next(region, &clip)) {
133007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip);
133107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) {
133207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGW("Reached end of blit count");
133307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            finish_copybit(dev);
133407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
133507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_list[ctx->blit_count] = src_surface;
133607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->blit_count++;
133707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
133807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
133907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Check if we need to perform an early draw-finish.
134007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0;
134107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (need_to_execute_draw((eC2DFlags)flags))
134207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    {
134307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        finish_copybit(dev);
134407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
134507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
134607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (need_temp_dst) {
134707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // copy the temp. destination without the alignment to the actual
134807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // destination.
134907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
135007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (status == COPYBIT_FAILURE) {
135107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__);
135207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            delete_handle(dst_hnd);
135307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            delete_handle(src_hnd);
135407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            unmap_gpuaddr(ctx, mapped_dst_idx);
135507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            unmap_gpuaddr(ctx, mapped_src_idx);
135607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            return status;
135707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
135807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        // Clean the cache.
135907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
136007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
136107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                               dst_hnd->offset, dst_hnd->fd,
136207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                               gralloc::CACHE_CLEAN);
136307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
136407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    delete_handle(dst_hnd);
136507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    delete_handle(src_hnd);
136607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
136707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->is_premultiplied_alpha = false;
136807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->fb_width = 0;
136907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->fb_height = 0;
137007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->config_mask = 0;
137107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return status;
137207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
137307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
137407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int set_sync_copybit(struct copybit_device_t *dev,
137507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int /*acquireFenceFd*/)
137607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
137707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!dev)
137807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return -EINVAL;
137907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
138007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return 0;
138107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
138207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
138307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int stretch_copybit(
138407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_device_t *dev,
138507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_image_t const *dst,
138607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_image_t const *src,
138707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_rect_t const *dst_rect,
138807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_rect_t const *src_rect,
138907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_region_t const *region)
139007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
139107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
139207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int status = COPYBIT_SUCCESS;
139307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    bool needsBlending = (ctx->src_global_alpha != 0);
139407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_lock(&ctx->wait_cleanup_lock);
139507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
139607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                    region, needsBlending);
139707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
139807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return status;
139907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
140007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
140107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/** Perform a blit type operation */
140207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int blit_copybit(
140307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_device_t *dev,
140407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_image_t const *dst,
140507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_image_t const *src,
140607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_region_t const *region)
140707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
140807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int status = COPYBIT_SUCCESS;
140907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
141007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
141107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
141207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_lock(&ctx->wait_cleanup_lock);
141307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    status = stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false);
141407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
141507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return status;
141607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
141707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
141807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/** Fill the rect on dst with RGBA color **/
141907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int fill_color(struct copybit_device_t *dev,
142007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                      struct copybit_image_t const *dst,
142107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                      struct copybit_rect_t const *rect,
142207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                      uint32_t /*color*/)
142307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
142407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // TODO: Implement once c2d driver supports color fill
142507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!dev || !dst || !rect)
142607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani       return -EINVAL;
142707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
142807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return -EINVAL;
142907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
143007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
143107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/*****************************************************************************/
143207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
143307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic void clean_up(copybit_context_t* ctx)
143407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
143507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    void* ret;
143607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!ctx)
143707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return;
143807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
143907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // stop the wait_cleanup_thread
144007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_lock(&ctx->wait_cleanup_lock);
144107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->stop_thread = true;
144207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Signal waiting thread
144307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_cond_signal(&ctx->wait_cleanup_cond);
144407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
144507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // waits for the cleanup thread to exit
144607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_join(ctx->wait_thread_id, &ret);
144707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_destroy(&ctx->wait_cleanup_lock);
144807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_cond_destroy (&ctx->wait_cleanup_cond);
144907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
145007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (int i = 0; i < NUM_SURFACE_TYPES; i++) {
145107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (ctx->dst[i])
145207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            LINK_c2dDestroySurface(ctx->dst[i]);
145307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
145407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
145507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (int i = 0; i < MAX_RGB_SURFACES; i++) {
145607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (ctx->blit_rgb_object[i].surface_id)
145707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id);
145807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
145907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
146007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) {
146107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (ctx->blit_yuv_2_plane_object[i].surface_id)
146207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id);
146307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
146407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
146507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) {
146607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (ctx->blit_yuv_3_plane_object[i].surface_id)
146707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id);
146807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
146907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
147007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (ctx->libc2d2) {
147107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ::dlclose(ctx->libc2d2);
147207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGV("dlclose(libc2d2)");
147307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
147407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
147507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    free(ctx);
147607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
147707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
147807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/** Close the copybit device */
147907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int close_copybit(struct hw_device_t *dev)
148007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
148107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
148207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (ctx) {
148307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        free_temp_buffer(ctx->temp_src_buffer);
148407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        free_temp_buffer(ctx->temp_dst_buffer);
148507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
148607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    clean_up(ctx);
148707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return 0;
148807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
148907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
149007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani/** Open a new instance of a copybit device using name */
149107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malanistatic int open_copybit(const struct hw_module_t* module, const char* name,
149207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                        struct hw_device_t** device)
149307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani{
149407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    int status = COPYBIT_SUCCESS;
149507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
149607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
149707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
149807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
149907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    C2D_RGB_SURFACE_DEF surfDefinition = {0};
150007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
150107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    struct copybit_context_t *ctx;
150207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
150307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
150407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if(!ctx) {
150507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: malloc failed", __FUNCTION__);
150607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return COPYBIT_FAILURE;
150707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
150807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
150907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    /* initialize drawstate */
151007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    memset(ctx, 0, sizeof(*ctx));
151107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
151207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!ctx->libc2d2) {
151307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
151407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        clean_up(ctx);
151507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = COPYBIT_FAILURE;
151607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        *device = NULL;
151707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return status;
151807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
151907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2,
152007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                               "c2dCreateSurface");
152107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2,
152207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                               "c2dUpdateSurface");
152307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2,
152407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                             "c2dReadSurface");
152507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw");
152607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush");
152707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish");
152807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2,
152907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                               "c2dWaitTimestamp");
153007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2,
153107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                "c2dDestroySurface");
153207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2,
153307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                         "c2dMapAddr");
153407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2,
153507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                           "c2dUnMapAddr");
153607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2,
153707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                           "c2dGetDriverCapabilities");
153807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
153907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                           "c2dCreateFenceFD");
154007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2,
154107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                           "c2dFillSurface");
154207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
154307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
154407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
154507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
154607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD ||
154707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        !LINK_c2dFillSurface) {
154807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: dlsym ERROR", __FUNCTION__);
154907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        clean_up(ctx);
155007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = COPYBIT_FAILURE;
155107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        *device = NULL;
155207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return status;
155307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
155407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
155507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
155607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.common.version = 1;
155707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.common.module = (hw_module_t*)(module);
155807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.common.close = close_copybit;
155907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.set_parameter = set_parameter_copybit;
156007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.get = get;
156107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.blit = blit_copybit;
156207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.set_sync = set_sync_copybit;
156307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.stretch = stretch_copybit;
156407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.finish = finish_copybit;
156507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.flush_get_fence = flush_get_fence_copybit;
156607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.clear = clear_copybit;
156707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->device.fill_color = fill_color;
156807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
156907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    /* Create RGB Surface */
157007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    surfDefinition.buffer = (void*)0xdddddddd;
157107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    surfDefinition.phys = (void*)0xdddddddd;
157207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    surfDefinition.stride = 1 * 4;
157307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    surfDefinition.width = 1;
157407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    surfDefinition.height = 1;
157507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB;
157607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
157707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
157807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 C2D_SURFACE_WITH_PHYS |
157907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
158007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 &surfDefinition)) {
158107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__);
158207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->dst[RGB_SURFACE] = 0;
158307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        clean_up(ctx);
158407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = COPYBIT_FAILURE;
158507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        *device = NULL;
158607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return status;
158707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
158807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
158907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    unsigned int surface_id = 0;
159007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (int i = 0; i < MAX_RGB_SURFACES; i++)
159107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    {
159207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
159307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
159407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 C2D_SURFACE_WITH_PHYS |
159507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
159607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 &surfDefinition)) {
159707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i);
159807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->blit_rgb_object[i].surface_id = 0;
159907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            status = COPYBIT_FAILURE;
160007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
160107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        } else {
160207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->blit_rgb_object[i].surface_id = surface_id;
160307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGW("%s i = %d surface_id=%d",  __FUNCTION__, i,
160407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                          ctx->blit_rgb_object[i].surface_id);
160507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
160607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
160707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
160807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (status == COPYBIT_FAILURE) {
160907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        clean_up(ctx);
161007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = COPYBIT_FAILURE;
161107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        *device = NULL;
161207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return status;
161307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
161407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
161507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Create 2 plane YUV surfaces
161607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
161707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.width = 4;
161807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.height = 4;
161907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa;
162007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa;
162107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.stride0 = 4;
162207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
162307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa;
162407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa;
162507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.stride1 = 4;
162607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),
162707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              C2D_TARGET | C2D_SOURCE,
162807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
162907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                               C2D_SURFACE_WITH_PHYS |
163007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                               C2D_SURFACE_WITH_PHYS_DUMMY),
163107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              &yuvSurfaceDef)) {
163207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
163307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->dst[YUV_SURFACE_2_PLANES] = 0;
163407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        clean_up(ctx);
163507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = COPYBIT_FAILURE;
163607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        *device = NULL;
163707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return status;
163807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
163907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
164007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++)
164107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    {
164207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
164307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
164407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 C2D_SURFACE_WITH_PHYS |
164507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
164607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              &yuvSurfaceDef)) {
164707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: create YUV source %d failed", __FUNCTION__, i);
164807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->blit_yuv_2_plane_object[i].surface_id = 0;
164907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            status = COPYBIT_FAILURE;
165007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
165107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        } else {
165207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->blit_yuv_2_plane_object[i].surface_id = surface_id;
165307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGW("%s: 2 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
165407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                   ctx->blit_yuv_2_plane_object[i].surface_id);
165507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
165607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
165707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
165807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (status == COPYBIT_FAILURE) {
165907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        clean_up(ctx);
166007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = COPYBIT_FAILURE;
166107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        *device = NULL;
166207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return status;
166307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
166407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
166507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Create YUV 3 plane surfaces
166607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
166707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
166807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
166907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    yuvSurfaceDef.stride2 = 4;
167007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
167107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),
167207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              C2D_TARGET | C2D_SOURCE,
167307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
167407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 C2D_SURFACE_WITH_PHYS |
167507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
167607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              &yuvSurfaceDef)) {
167707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
167807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        ctx->dst[YUV_SURFACE_3_PLANES] = 0;
167907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        clean_up(ctx);
168007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = COPYBIT_FAILURE;
168107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        *device = NULL;
168207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return status;
168307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
168407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
168507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++)
168607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    {
168707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        if (LINK_c2dCreateSurface(&(surface_id),
168807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              C2D_TARGET | C2D_SOURCE,
168907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
169007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 C2D_SURFACE_WITH_PHYS |
169107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
169207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                              &yuvSurfaceDef)) {
169307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i);
169407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->blit_yuv_3_plane_object[i].surface_id = 0;
169507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            status = COPYBIT_FAILURE;
169607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            break;
169707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        } else {
169807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ctx->blit_yuv_3_plane_object[i].surface_id = surface_id;
169907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani            ALOGW("%s: 3 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
170007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                   ctx->blit_yuv_3_plane_object[i].surface_id);
170107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        }
170207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
170307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
170407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (status == COPYBIT_FAILURE) {
170507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        clean_up(ctx);
170607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        status = COPYBIT_FAILURE;
170707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        *device = NULL;
170807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return status;
170907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
171007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
171107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) {
171207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani         ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__);
171307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani         clean_up(ctx);
171407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani         status = COPYBIT_FAILURE;
171507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        *device = NULL;
171607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani        return status;
171707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    }
171807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    // Initialize context variables.
171907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->trg_transform = C2D_TARGET_ROTATE_0;
172007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
172107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->temp_src_buffer.fd = -1;
172207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->temp_src_buffer.base = 0;
172307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->temp_src_buffer.size = 0;
172407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
172507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->temp_dst_buffer.fd = -1;
172607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->temp_dst_buffer.base = 0;
172707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->temp_dst_buffer.size = 0;
172807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
172907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->fb_width = 0;
173007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->fb_height = 0;
173107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
173207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->blit_rgb_count = 0;
173307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->blit_yuv_2_plane_count = 0;
173407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->blit_yuv_3_plane_count = 0;
173507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->blit_count = 0;
173607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
173707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->wait_timestamp = false;
173807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    ctx->stop_thread = false;
173907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL);
174007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_cond_init(&(ctx->wait_cleanup_cond), NULL);
174107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    /* Start the wait thread */
174207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_attr_t attr;
174307bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_attr_init(&attr);
174407bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
174507bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
174607bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop,
174707bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani                                                            (void *)ctx);
174807bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    pthread_attr_destroy(&attr);
174907bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani
175007bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    *device = &ctx->device.common;
175107bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani    return status;
175207bbf1e89c031a5d41a7561433e832d396c311a5Prashant Malani}
1753