1d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/*
2d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * Copyright (C) 2008 The Android Open Source Project
3d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
4d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *
5d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * Not a Contribution, Apache license notifications and license are retained
6d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * for attribution purposes only.
7d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *
8d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * Licensed under the Apache License, Version 2.0 (the "License");
9d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * you may not use this file except in compliance with the License.
10d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * You may obtain a copy of the License at
11d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *
12d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *      http://www.apache.org/licenses/LICENSE-2.0
13d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *
14d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * Unless required by applicable law or agreed to in writing, software
15d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * distributed under the License is distributed on an "AS IS" BASIS,
16d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * See the License for the specific language governing permissions and
18d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * limitations under the License.
19d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin */
20d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <cutils/log.h>
21d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/resource.h>
22d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/prctl.h>
23d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
24d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <stdint.h>
25d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <string.h>
26d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <unistd.h>
27d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <errno.h>
28d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <fcntl.h>
29d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
30d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/ioctl.h>
31d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/types.h>
32d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <sys/mman.h>
33d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
34d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <linux/msm_kgsl.h>
35d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
36d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <EGL/eglplatform.h>
37d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <cutils/native_handle.h>
38d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
39d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <copybit.h>
40d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <alloc_controller.h>
41d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <memalloc.h>
42d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
43d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include "c2d2.h"
44d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include "software_converter.h"
45d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
46d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#include <dlfcn.h>
47d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
48d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinusing gralloc::IMemAlloc;
49d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinusing gralloc::IonController;
50d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinusing gralloc::alloc_data;
51d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
52d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
53d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                     uint32 surface_bits,
54d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                     C2D_SURFACE_TYPE surface_type,
55d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                     void *surface_definition );
56d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
57d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id,
58d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                     uint32 surface_bits,
59d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                     C2D_SURFACE_TYPE surface_type,
60d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                     void *surface_definition );
61d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
62d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id,
63d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                   C2D_SURFACE_TYPE surface_type,
64d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                   void *surface_definition,
65d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                   int32 x, int32 y );
66d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
67d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dDraw)( uint32 target_id,
68d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                            uint32 target_config, C2D_RECT *target_scissor,
69d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                            uint32 target_mask_id, uint32 target_color_key,
70d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                            C2D_OBJECT *objects_list, uint32 num_objects );
71d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
72d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dFinish)( uint32 target_id);
73d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
74d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp);
75d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
76d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp );
77d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
78d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
79d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
80d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, size_t len,
81d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                size_t offset, uint32 flags, void ** gpuaddr);
82d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
83d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
84d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
85d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info);
86d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
87d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* create a fence fd for the timestamp */
88d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
89d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                            int32 *fd);
90d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
91d68a2e45260f864503d7bd6da93fd29589afd89ePatrick TjinC2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color,
92d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                    C2D_RECT * fill_rect);
93d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
94d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/******************************************************************************/
95d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
96d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#if defined(COPYBIT_Z180)
97d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define MAX_SCALE_FACTOR    (4096)
98d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define MAX_DIMENSION       (4096)
99d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#else
100d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#error "Unsupported HW version"
101d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#endif
102d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
103d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin// The following defines can be changed as required i.e. as we encounter
104d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin// complex use cases.
105d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define MAX_RGB_SURFACES 32       // Max. RGB layers currently supported per draw
106d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw
107d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw
108d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin// +1 for the destination surface. We cannot have multiple destination surfaces.
109d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1)
110d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define NUM_SURFACE_TYPES 3      // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES
111d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin#define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw
112d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
113d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinenum {
114d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    RGB_SURFACE,
115d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    YUV_SURFACE_2_PLANES,
116d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    YUV_SURFACE_3_PLANES
117d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin};
118d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
119d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinenum eConversionType {
120d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    CONVERT_TO_ANDROID_FORMAT,
121d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    CONVERT_TO_C2D_FORMAT
122d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin};
123d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
124d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinenum eC2DFlags {
125d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    FLAGS_PREMULTIPLIED_ALPHA  = 1<<0,
126d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    FLAGS_YUV_DESTINATION      = 1<<1,
127d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    FLAGS_TEMP_SRC_DST         = 1<<2,
128d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    FLAGS_UBWC_FORMAT_MODE     = 1<<3
129d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin};
130d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
131d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic gralloc::IAllocController* sAlloc = 0;
132d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/******************************************************************************/
133d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
134d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/** State information for each device instance */
135d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstruct copybit_context_t {
136d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_device_t device;
137d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Templates for the various source surfaces. These templates are created
138d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // to avoid the expensive create/destroy C2D Surfaces
139d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES];
140d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES];
141d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES];
142d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects
143d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    C2D_DRIVER_INFO c2d_driver_info;
144d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    void *libc2d2;
145d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    alloc_data temp_src_buffer;
146d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    alloc_data temp_dst_buffer;
147d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces
148d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    uintptr_t mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
149d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int blit_rgb_count;         // Total RGB surfaces being blit
150d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being
151d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int blit_yuv_3_plane_count; // Total 3 plane YUV  surfaces being blit
152d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int blit_count;             // Total blit objects.
153d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    unsigned int trg_transform;      /* target transform */
154d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int fb_width;
155d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int fb_height;
156d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int src_global_alpha;
157d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int config_mask;
158d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int dst_surface_type;
159d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool is_premultiplied_alpha;
160d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    void* time_stamp;
161d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr
162d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    void* dst_surface_base; // Stores the dst surface addr
163d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool is_src_ubwc_format;
164d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool is_dst_ubwc_format;
165d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
166d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // used for signaling the wait thread
167d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool wait_timestamp;
168d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_t wait_thread_id;
169d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool stop_thread;
170d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_t wait_cleanup_lock;
171d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_cond_t wait_cleanup_cond;
172d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
173d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin};
174d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
175d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstruct bufferInfo {
176d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int width;
177d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int height;
178d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int format;
179d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin};
180d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
181d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstruct yuvPlaneInfo {
182d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int yStride;       //luma stride
183d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int plane1_stride;
184d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int plane2_stride;
185d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    size_t plane1_offset;
186d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    size_t plane2_offset;
187d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin};
188d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
189d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/**
190d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * Common hardware methods
191d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin */
192d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
193d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int open_copybit(const struct hw_module_t* module, const char* name,
194d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                        struct hw_device_t** device);
195d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
196d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic struct hw_module_methods_t copybit_module_methods = {
197d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    .open = open_copybit,
198d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin};
199d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
200d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/*
201d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * The COPYBIT Module
202d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin */
203d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstruct copybit_module_t HAL_MODULE_INFO_SYM = {
204d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    .common = {
205d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        .tag =  HARDWARE_MODULE_TAG,
206d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        .version_major = 1,
207d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        .version_minor = 0,
208d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        .id = COPYBIT_HARDWARE_MODULE_ID,
209d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        .name = "QCT COPYBIT C2D 2.0 Module",
210d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        .author = "Qualcomm",
211d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        .methods =  &copybit_module_methods
212d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
213d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin};
214d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
215d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
216d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* thread function which waits on the timeStamp and cleans up the surfaces */
217d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic void* c2d_wait_loop(void* ptr) {
218d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    copybit_context_t* ctx = (copybit_context_t*)(ptr);
219d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    char thread_name[64] = "copybitWaitThr";
220d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
221d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
222d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
223d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    while(ctx->stop_thread == false) {
224d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        pthread_mutex_lock(&ctx->wait_cleanup_lock);
225d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        while(ctx->wait_timestamp == false && !ctx->stop_thread) {
226d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            pthread_cond_wait(&(ctx->wait_cleanup_cond),
227d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              &(ctx->wait_cleanup_lock));
228d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
229d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if(ctx->wait_timestamp) {
230d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if(LINK_c2dWaitTimestamp(ctx->time_stamp)) {
231d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__);
232d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            }
233d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->wait_timestamp = false;
234d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            // Unmap any mapped addresses.
235d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            for (int i = 0; i < MAX_SURFACES; i++) {
236d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                if (ctx->mapped_gpu_addr[i]) {
237d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                    LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
238d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                    ctx->mapped_gpu_addr[i] = 0;
239d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                }
240d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            }
241d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            // Reset the counts after the draw.
242d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->blit_rgb_count = 0;
243d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->blit_yuv_2_plane_count = 0;
244d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->blit_yuv_3_plane_count = 0;
245d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->blit_count = 0;
246d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->dst_surface_mapped = false;
247d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->dst_surface_base = 0;
248d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
249d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
250d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if(ctx->stop_thread)
251d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
252d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
253d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_exit(NULL);
254d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return NULL;
255d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
256d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
257d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
258d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* convert COPYBIT_FORMAT to C2D format */
259d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int get_format(int format) {
260d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch (format) {
261d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGB_565:        return C2D_COLOR_FORMAT_565_RGB;
262d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGB_888:        return C2D_COLOR_FORMAT_888_RGB |
263d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                              C2D_FORMAT_SWAP_RB;
264d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
265d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                              C2D_FORMAT_SWAP_RB |
266d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                  C2D_FORMAT_DISABLE_ALPHA;
267d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
268d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                              C2D_FORMAT_SWAP_RB;
269d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_BGRA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
270d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGBA_5551:      return C2D_COLOR_FORMAT_5551_RGBA;
271d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGBA_4444:      return C2D_COLOR_FORMAT_4444_RGBA;
272d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
273d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
274d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
275d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 |
276d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                  C2D_FORMAT_MACROTILED;
277d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        default:                              ALOGE("%s: invalid format (0x%x",
278d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                     __FUNCTION__, format);
279d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                              return -EINVAL;
280d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
281d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
282d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
283d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
284d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* Get the C2D formats needed for conversion to YUV */
285d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int get_c2d_format_for_yuv_destination(int halFormat) {
286d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch (halFormat) {
287d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // We do not swap the RB when the target is YUV
288d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
289d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                              C2D_FORMAT_DISABLE_ALPHA;
290d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
291d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // The U and V need to be interchanged when the target is YUV
292d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
293d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21;
294d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
295d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        default:                              return get_format(halFormat);
296d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
297d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
298d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
299d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
300d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* ------------------------------------------------------------------- *//*!
301d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * \internal
302d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * \brief Get the bpp for a particular color format
303d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * \param color format
304d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * \return bits per pixel
305d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin *//* ------------------------------------------------------------------- */
306d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinint c2diGetBpp(int32 colorformat)
307d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
308d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
309d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int c2dBpp = 0;
310d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
311d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch(colorformat&0xFF)
312d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    {
313d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_4444_RGBA:
314d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_4444_ARGB:
315d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_1555_ARGB:
316d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_565_RGB:
317d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_5551_RGBA:
318d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            c2dBpp = 16;
319d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
320d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_8888_RGBA:
321d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_8888_ARGB:
322d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            c2dBpp = 32;
323d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
324d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_888_RGB:
325d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            c2dBpp = 24;
326d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
327d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_8_L:
328d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_8_A:
329d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            c2dBpp = 8;
330d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
331d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_4_A:
332d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            c2dBpp = 4;
333d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
334d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case C2D_COLOR_FORMAT_1:
335d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            c2dBpp = 1;
336d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
337d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        default:
338d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s ERROR", __func__);
339d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
340d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
341d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return c2dBpp;
342d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
343d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
344d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic size_t c2d_get_gpuaddr(copybit_context_t* ctx,
345d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              struct private_handle_t *handle, int &mapped_idx)
346d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
347d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    uint32 memtype;
348d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    size_t *gpuaddr = 0;
349d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    C2D_STATUS rc;
350d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int freeindex = 0;
351d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool mapaddr = false;
352d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
353d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(!handle)
354d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return 0;
355d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
356d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
357d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        memtype = KGSL_USER_MEM_TYPE_ION;
358d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    else {
359d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("Invalid handle flags: 0x%x", handle->flags);
360d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return 0;
361d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
362d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
363d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Check for a freeindex in the mapped_gpu_addr list
364d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (freeindex = 0; freeindex < MAX_SURFACES; freeindex++) {
365d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (ctx->mapped_gpu_addr[freeindex] == 0) {
366d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            // free index is available
367d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            // map GPU addr and use this as mapped_idx
368d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            mapaddr = true;
369d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
370d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
371d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
372d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
373d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(mapaddr) {
374d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size,
375d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                             handle->offset, memtype, (void**)&gpuaddr);
376d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
377d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (rc == C2D_STATUS_OK) {
378d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            // We have mapped the GPU address inside copybit. We need to unmap
379d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            // this address after the blit. Store this address
380d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->mapped_gpu_addr[freeindex] = (size_t)gpuaddr;
381d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            mapped_idx = freeindex;
382d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
383d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
384d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return (size_t)gpuaddr;
385d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
386d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
387d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx)
388d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
389d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!ctx || (mapped_idx == -1))
390d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return;
391d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
392d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (ctx->mapped_gpu_addr[mapped_idx]) {
393d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]);
394d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->mapped_gpu_addr[mapped_idx] = 0;
395d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
396d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
397d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
398d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int is_supported_rgb_format(int format)
399d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
400d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch(format) {
401d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGBA_8888:
402d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGBX_8888:
403d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGB_888:
404d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGB_565:
405d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_BGRA_8888:
406d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGBA_5551:
407d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_RGBA_4444: {
408d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return COPYBIT_SUCCESS;
409d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
410d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        default:
411d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return COPYBIT_FAILURE;
412d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
413d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
414d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
415d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int get_num_planes(int format)
416d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
417d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch(format) {
418d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
419d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
420d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
421d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
422d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return 2;
423d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
424d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YV12: {
425d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return 3;
426d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
427d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        default:
428d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return COPYBIT_FAILURE;
429d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
430d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
431d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
432d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int is_supported_yuv_format(int format)
433d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
434d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch(format) {
435d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
436d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
437d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
438d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
439d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return COPYBIT_SUCCESS;
440d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
441d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        default:
442d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return COPYBIT_FAILURE;
443d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
444d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
445d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
446d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int is_valid_destination_format(int format)
447d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
448d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
449d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // C2D does not support NV12Tile as a destination format.
450d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
451d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
452d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return COPYBIT_SUCCESS;
453d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
454d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
455d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int calculate_yuv_offset_and_stride(const bufferInfo& info,
456d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                           yuvPlaneInfo& yuvInfo)
457d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
458d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int width  = info.width;
459d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int height = info.height;
460d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int format = info.format;
461d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
462d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int aligned_height = 0;
463d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int aligned_width = 0, size = 0;
464d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
465d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch (format) {
466d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
467d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            /* NV12 Tile buffers have their luma height aligned to 32bytes and width
468d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin             * aligned to 128 bytes. The chroma offset starts at an 8K boundary
469d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin             */
470d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            aligned_height = ALIGN(height, 32);
471d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            aligned_width  = ALIGN(width, 128);
472d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            size = aligned_width * aligned_height;
473d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            yuvInfo.plane1_offset = ALIGN(size,8192);
474d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            yuvInfo.yStride = aligned_width;
475d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            yuvInfo.plane1_stride = aligned_width;
476d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
477d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
478d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
479d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
480d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
481d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            aligned_width = ALIGN(width, 32);
482d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            yuvInfo.yStride = aligned_width;
483d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            yuvInfo.plane1_stride = aligned_width;
484d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
485d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                // The encoder requires a 2K aligned chroma offset
486d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048);
487d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            } else
488d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                yuvInfo.plane1_offset = aligned_width * height;
489d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
490d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
491d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
492d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        default: {
493d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return COPYBIT_FAILURE;
494d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
495d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
496d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return COPYBIT_SUCCESS;
497d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
498d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
499d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/** create C2D surface from copybit image */
500d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int set_image(copybit_context_t* ctx, uint32 surfaceId,
501d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                      const struct copybit_image_t *rhs,
502d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                      const eC2DFlags flags, int &mapped_idx)
503d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
504d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
505d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    C2D_SURFACE_TYPE surfaceType;
506d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int status = COPYBIT_SUCCESS;
507d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    uint64_t gpuaddr = 0;
508d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int c2d_format;
509d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    mapped_idx = -1;
510d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
511d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (flags & FLAGS_YUV_DESTINATION) {
512d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2d_format = get_c2d_format_for_yuv_destination(rhs->format);
513d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
514d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2d_format = get_format(rhs->format);
515d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
516d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
517d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(c2d_format == -EINVAL) {
518d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: invalid format", __FUNCTION__);
519d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return -EINVAL;
520d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
521d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
522d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(handle == NULL) {
523d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: invalid handle", __func__);
524d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return -EINVAL;
525d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
526d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
527d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (handle->gpuaddr == 0) {
528d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx);
529d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if(!gpuaddr) {
530d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
531d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return COPYBIT_FAILURE;
532d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
533d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
534d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        gpuaddr = handle->gpuaddr;
535d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
536d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
537d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    /* create C2D surface */
538d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
539d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        /* RGB */
540d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        C2D_RGB_SURFACE_DEF surfaceDef;
541d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
542d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS);
543d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
544d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.phys = (void*) gpuaddr;
545d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.buffer = (void*) (handle->base);
546d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
547d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.format = c2d_format |
548d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
549d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
550d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.format = surfaceDef.format |
551d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ((flags & FLAGS_UBWC_FORMAT_MODE) ? C2D_FORMAT_UBWC_COMPRESSED : 0);
552d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
553d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.width = rhs->w;
554d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.height = rhs->h;
555d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        int aligned_width = ALIGN((int)surfaceDef.width,32);
556d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;
557d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
558d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
559d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                  &surfaceDef)) {
560d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__);
561d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            unmap_gpuaddr(ctx, mapped_idx);
562d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            status = COPYBIT_FAILURE;
563d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
564d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
565d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        C2D_YUV_SURFACE_DEF surfaceDef;
566d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        memset(&surfaceDef, 0, sizeof(surfaceDef));
567d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS);
568d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.format = c2d_format;
569d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
570d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        bufferInfo info;
571d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        info.width = rhs->w;
572d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        info.height = rhs->h;
573d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        info.format = rhs->format;
574d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
575d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        yuvPlaneInfo yuvInfo = {0};
576d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = calculate_yuv_offset_and_stride(info, yuvInfo);
577d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if(status != COPYBIT_SUCCESS) {
578d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
579d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            unmap_gpuaddr(ctx, mapped_idx);
580d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
581d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
582d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.width = rhs->w;
583d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.height = rhs->h;
584d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.plane0 = (void*) (handle->base);
585d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.phys0 = (void*) (gpuaddr);
586d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.stride0 = yuvInfo.yStride;
587d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
588d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
589d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset);
590d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        surfaceDef.stride1 = yuvInfo.plane1_stride;
591d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (3 == get_num_planes(rhs->format)) {
592d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset);
593d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset);
594d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            surfaceDef.stride2 = yuvInfo.plane2_stride;
595d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
596d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
597d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
598d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                  &surfaceDef)) {
599d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__);
600d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            unmap_gpuaddr(ctx, mapped_idx);
601d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            status = COPYBIT_FAILURE;
602d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
603d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
604d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
605d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        unmap_gpuaddr(ctx, mapped_idx);
606d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = COPYBIT_FAILURE;
607d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
608d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
609d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return status;
610d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
611d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
612d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/** copy the bits */
613d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int msm_copybit(struct copybit_context_t *ctx, unsigned int target)
614d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
615d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (ctx->blit_count == 0) {
616d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_SUCCESS;
617d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
618d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
619d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (int i = 0; i < ctx->blit_count; i++)
620d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    {
621d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_list[i].next = &(ctx->blit_list[i+1]);
622d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
623d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->blit_list[ctx->blit_count-1].next = NULL;
624d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    uint32_t target_transform = ctx->trg_transform;
625d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (ctx->c2d_driver_info.capabilities_mask &
626d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
627d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // For A3xx - set 0x0 as the transform is set in the config_mask
628d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        target_transform = 0x0;
629d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
630d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(LINK_c2dDraw(target, target_transform, 0x0, 0, 0, ctx->blit_list,
631d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                    ctx->blit_count)) {
632d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
633d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
634d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
635d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return COPYBIT_SUCCESS;
636d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
637d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
638d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
639d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
640d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd)
641d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
642d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
643d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int status = COPYBIT_FAILURE;
644d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!ctx)
645d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
646d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_lock(&ctx->wait_cleanup_lock);
647d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
648d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
649d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) {
650d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__);
651d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // unlock the mutex and return failure
652d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
653d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
654d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
655d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp,
656d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                                        fd)) {
657d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__);
658d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = COPYBIT_FAILURE;
659d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
660d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(status == COPYBIT_SUCCESS) {
661d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        //signal the wait_thread
662d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->wait_timestamp = true;
663d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        pthread_cond_signal(&ctx->wait_cleanup_cond);
664d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
665d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
666d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return status;
667d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
668d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
669d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int finish_copybit(struct copybit_device_t *dev)
670d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
671d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
672d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!ctx)
673d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
674d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
675d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin   int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
676d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
677d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin   if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) {
678d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
679d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
680d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
681d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
682d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Unmap any mapped addresses.
683d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (int i = 0; i < MAX_SURFACES; i++) {
684d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (ctx->mapped_gpu_addr[i]) {
685d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
686d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->mapped_gpu_addr[i] = 0;
687d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
688d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
689d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
690d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Reset the counts after the draw.
691d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->blit_rgb_count = 0;
692d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->blit_yuv_2_plane_count = 0;
693d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->blit_yuv_3_plane_count = 0;
694d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->blit_count = 0;
695d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->dst_surface_mapped = false;
696d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->dst_surface_base = 0;
697d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
698d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return status;
699d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
700d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
701d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int clear_copybit(struct copybit_device_t *dev,
702d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                         struct copybit_image_t const *buf,
703d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                         struct copybit_rect_t *rect)
704d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
705d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int ret = COPYBIT_SUCCESS;
706d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int flags = FLAGS_PREMULTIPLIED_ALPHA;
707d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int mapped_dst_idx = -1;
708d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
709d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (ctx->is_dst_ubwc_format)
710d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        flags |= FLAGS_UBWC_FORMAT_MODE;
711d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
712d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_lock(&ctx->wait_cleanup_lock);
713d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(!ctx->dst_surface_mapped) {
714d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf,
715d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                        (eC2DFlags)flags, mapped_dst_idx);
716d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if(ret) {
717d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: set_image error", __FUNCTION__);
718d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            unmap_gpuaddr(ctx, mapped_dst_idx);
719d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            pthread_mutex_unlock(&ctx->wait_cleanup_lock);
720d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return COPYBIT_FAILURE;
721d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
722d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        //clear_copybit is the first call made by HWC for each composition
723d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        //with the dest surface, hence set dst_surface_mapped.
724d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->dst_surface_mapped = true;
725d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->dst_surface_base = buf->base;
726d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect);
727d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
728d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
729d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return ret;
730d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
731d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
732d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
733d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/** setup rectangles */
734d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic void set_rects(struct copybit_context_t *ctx,
735d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                      C2D_OBJECT *c2dObject,
736d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                      const struct copybit_rect_t *dst,
737d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                      const struct copybit_rect_t *src,
738d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                      const struct copybit_rect_t *scissor)
739d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
740d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Set the target rect.
741d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if((ctx->trg_transform & C2D_TARGET_ROTATE_90) &&
742d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin       (ctx->trg_transform & C2D_TARGET_ROTATE_180)) {
743d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        /* target rotation is 270 */
744d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.x        = (dst->t)<<16;
745d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.y        = ctx->fb_width?
746d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                (ALIGN(ctx->fb_width,32)- dst->r):dst->r;
747d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
748d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
749d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
750d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) {
751d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.x        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
752d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
753d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.y        = (dst->l)<<16;
754d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
755d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
756d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) {
757d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.y        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
758d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
759d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.x        = ctx->fb_width?
760d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                (ALIGN(ctx->fb_width,32) - dst->r):dst->r;
761d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
762d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
763d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
764d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
765d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.x        = (dst->l)<<16;
766d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.y        = (dst->t)<<16;
767d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
768d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
769d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
770d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    c2dObject->config_mask |= C2D_TARGET_RECT_BIT;
771d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
772d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Set the source rect
773d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    c2dObject->source_rect.x        = (src->l)<<16;
774d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    c2dObject->source_rect.y        = (src->t)<<16;
775d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    c2dObject->source_rect.height   = ((src->b) - (src->t))<<16;
776d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    c2dObject->source_rect.width    = ((src->r) - (src->l))<<16;
777d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    c2dObject->config_mask |= C2D_SOURCE_RECT_BIT;
778d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
779d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Set the scissor rect
780d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    c2dObject->scissor_rect.x       = scissor->l;
781d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    c2dObject->scissor_rect.y       = scissor->t;
782d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    c2dObject->scissor_rect.height  = (scissor->b) - (scissor->t);
783d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    c2dObject->scissor_rect.width   = (scissor->r) - (scissor->l);
784d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT;
785d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
786d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
787d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/*****************************************************************************/
788d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
789d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/** Set a parameter to value */
790d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int set_parameter_copybit(
791d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_device_t *dev,
792d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int name,
793d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int value)
794d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
795d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
796d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int status = COPYBIT_SUCCESS;
797d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!ctx) {
798d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: null context", __FUNCTION__);
799d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return -EINVAL;
800d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
801d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
802d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_lock(&ctx->wait_cleanup_lock);
803d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch(name) {
804d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_PLANE_ALPHA:
805d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        {
806d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if (value < 0)      value = 0;
807d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if (value >= 256)   value = 255;
808d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
809d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->src_global_alpha = value;
810d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if (value < 255)
811d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT;
812d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            else
813d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT;
814d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
815d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        break;
816d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_BLEND_MODE:
817d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        {
818d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if (value == COPYBIT_BLENDING_NONE) {
819d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                ctx->config_mask |= C2D_ALPHA_BLEND_NONE;
820d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                ctx->is_premultiplied_alpha = true;
821d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            } else if (value == COPYBIT_BLENDING_PREMULT) {
822d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                ctx->is_premultiplied_alpha = true;
823d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            } else {
824d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE;
825d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            }
826d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
827d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        break;
828d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_TRANSFORM:
829d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        {
830d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            unsigned int transform = 0;
831d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            uint32 config_mask = 0;
832d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG;
833d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) {
834d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                transform = C2D_TARGET_ROTATE_180;
835d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180;
836d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) {
837d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                transform = C2D_TARGET_ROTATE_90;
838d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90;
839d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            } else if(value == COPYBIT_TRANSFORM_ROT_90) {
840d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                transform = C2D_TARGET_ROTATE_270;
841d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270;
842d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            } else {
843d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0;
844d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                if(value & COPYBIT_TRANSFORM_FLIP_H) {
845d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                    config_mask |= C2D_MIRROR_H_BIT;
846d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                } else if(value & COPYBIT_TRANSFORM_FLIP_V) {
847d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                    config_mask |= C2D_MIRROR_V_BIT;
848d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                }
849d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            }
850d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
851d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if (ctx->c2d_driver_info.capabilities_mask &
852d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
853d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                ctx->config_mask |= config_mask;
854d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            } else {
855d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                // The transform for this surface does not match the current
856d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                // target transform. Draw all previous surfaces. This will be
857d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                // changed once we have a new mechanism to send different
858d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                // target rotations to c2d.
859d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                finish_copybit(dev);
860d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            }
861d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->trg_transform = transform;
862d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
863d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        break;
864d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_FRAMEBUFFER_WIDTH:
865d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->fb_width = value;
866d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
867d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_FRAMEBUFFER_HEIGHT:
868d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->fb_height = value;
869d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
870d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_ROTATION_DEG:
871d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_DITHER:
872d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_BLUR:
873d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_BLIT_TO_FRAMEBUFFER:
874d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            // Do nothing
875d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
876d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_SRC_FORMAT_MODE:
877d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->is_src_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
878d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
879d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_DST_FORMAT_MODE:
880d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->is_dst_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
881d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
882d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        default:
883d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
884d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            status = -EINVAL;
885d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
886d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
887d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
888d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return status;
889d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
890d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
891d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/** Get a static info value */
892d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int get(struct copybit_device_t *dev, int name)
893d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
894d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
895d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int value;
896d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
897d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!ctx) {
898d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: null context error", __FUNCTION__);
899d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return -EINVAL;
900d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
901d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
902d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch(name) {
903d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_MINIFICATION_LIMIT:
904d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            value = MAX_SCALE_FACTOR;
905d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
906d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_MAGNIFICATION_LIMIT:
907d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            value = MAX_SCALE_FACTOR;
908d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
909d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_SCALING_FRAC_BITS:
910d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            value = 32;
911d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
912d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_ROTATION_STEP_DEG:
913d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            value = 1;
914d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
915d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case COPYBIT_UBWC_SUPPORT:
916d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            value = 0;
917d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if (ctx->c2d_driver_info.capabilities_mask & C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP) {
918d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                value = 1;
919d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            }
920d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
921d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        default:
922d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
923d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            value = -EINVAL;
924d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
925d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return value;
926d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
927d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
928d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* Function to check if we need a temporary buffer for the blit.
929d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * This would happen if the requested destination stride and the
930d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * C2D stride do not match. We ignore RGB buffers, since their
931d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * stride is always aligned to 32.
932d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin */
933d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic bool need_temp_buffer(struct copybit_image_t const *img)
934d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
935d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format))
936d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return false;
937d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
938d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct private_handle_t* handle = (struct private_handle_t*)img->handle;
939d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
940d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // The width parameter in the handle contains the aligned_w. We check if we
941d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // need to convert based on this param. YUV formats have bpp=1, so checking
942d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // if the requested stride is aligned should suffice.
943d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (0 == (handle->width)%32) {
944d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return false;
945d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
946d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
947d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return true;
948d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
949d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
950d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* Function to extract the information from the copybit image and set the corresponding
951d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * values in the bufferInfo struct.
952d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin */
953d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info)
954d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
955d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    info.width = img->w;
956d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    info.height = img->h;
957d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    info.format = img->format;
958d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
959d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
960d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* Function to get the required size for a particular format, inorder for C2D to perform
961d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * the blit operation.
962d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin */
963d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int get_size(const bufferInfo& info)
964d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
965d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int size = 0;
966d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int w = info.width;
967d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int h = info.height;
968d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int aligned_w = ALIGN(w, 32);
969d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch(info.format) {
970d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
971d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            {
972d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                // Chroma for this format is aligned to 2K.
973d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                size = ALIGN((aligned_w*h), 2048) +
974d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                        ALIGN(aligned_w/2, 32) * (h/2) *2;
975d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                size = ALIGN(size, 4096);
976d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            } break;
977d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
978d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
979d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            {
980d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                size = aligned_w * h +
981d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                       ALIGN(aligned_w/2, 32) * (h/2) * 2;
982d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                size = ALIGN(size, 4096);
983d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            } break;
984d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        default: break;
985d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
986d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return size;
987d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
988d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
989d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* Function to allocate memory for the temporary buffer. This memory is
990d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * allocated from Ashmem. It is the caller's responsibility to free this
991d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * memory.
992d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin */
993d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int get_temp_buffer(const bufferInfo& info, alloc_data& data)
994d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
995d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ALOGD("%s E", __FUNCTION__);
996d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Alloc memory from system heap
997d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    data.base = 0;
998d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    data.fd = -1;
999d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    data.offset = 0;
1000d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    data.size = get_size(info);
1001d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    data.align = getpagesize();
1002d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    data.uncached = true;
1003d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int allocFlags = 0;
1004d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1005d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (sAlloc == 0) {
1006d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        sAlloc = gralloc::IAllocController::getInstance();
1007d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1008d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1009d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (sAlloc == 0) {
1010d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: sAlloc is still NULL", __FUNCTION__);
1011d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
1012d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1013d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1014d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int err = sAlloc->allocate(data, allocFlags);
1015d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (0 != err) {
1016d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: allocate failed", __FUNCTION__);
1017d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
1018d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1019d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1020d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ALOGD("%s X", __FUNCTION__);
1021d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return err;
1022d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1023d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1024d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* Function to free the temporary allocated memory.*/
1025d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic void free_temp_buffer(alloc_data &data)
1026d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1027d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (-1 != data.fd) {
1028d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType);
1029d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        memalloc->free_buffer(data.base, data.size, 0, data.fd);
1030d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1031d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1032d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1033d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/* Function to perform the software color conversion. Convert the
1034d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin * C2D compatible format to the Android compatible format
1035d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin */
1036d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int copy_image(private_handle_t *src_handle,
1037d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                      struct copybit_image_t const *rhs,
1038d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                      eConversionType conversionType)
1039d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1040d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (src_handle->fd == -1) {
1041d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: src_handle fd is invalid", __FUNCTION__);
1042d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
1043d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1044d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1045d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Copy the info.
1046d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int ret = COPYBIT_SUCCESS;
1047d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    switch(rhs->format) {
1048d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
1049d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
1050d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1051d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            {
1052d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                if (CONVERT_TO_ANDROID_FORMAT == conversionType) {
1053d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                    return convert_yuv_c2d_to_yuv_android(src_handle, rhs);
1054d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                } else {
1055d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                    return convert_yuv_android_to_yuv_c2d(src_handle, rhs);
1056d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                }
1057d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1058d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            } break;
1059d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        default: {
1060d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
1061d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ret = COPYBIT_FAILURE;
1062d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        } break;
1063d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1064d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return ret;
1065d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1066d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1067d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic void delete_handle(private_handle_t *handle)
1068d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1069d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (handle) {
1070d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        delete handle;
1071d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        handle = 0;
1072d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1073d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1074d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1075d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic bool need_to_execute_draw(eC2DFlags flags)
1076d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1077d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (flags & FLAGS_TEMP_SRC_DST) {
1078d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return true;
1079d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1080d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (flags & FLAGS_YUV_DESTINATION) {
1081d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return true;
1082d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1083d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return false;
1084d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1085d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1086d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/** do a stretch blit type operation */
1087d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int stretch_copybit_internal(
1088d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_device_t *dev,
1089d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_image_t const *dst,
1090d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_image_t const *src,
1091d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_rect_t const *dst_rect,
1092d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_rect_t const *src_rect,
1093d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_region_t const *region,
1094d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool enableBlend)
1095d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1096d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1097d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int status = COPYBIT_SUCCESS;
1098d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int flags = 0;
1099d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int src_surface_type;
1100d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int mapped_src_idx = -1, mapped_dst_idx = -1;
1101d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    C2D_OBJECT_STR src_surface;
1102d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1103d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!ctx) {
1104d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: null context error", __FUNCTION__);
1105d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return -EINVAL;
1106d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1107d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1108d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
1109d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: src dimension error", __FUNCTION__);
1110d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return -EINVAL;
1111d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1112d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1113d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
1114d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s : dst dimension error dst w %d h %d",  __FUNCTION__, dst->w,
1115d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                         dst->h);
1116d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return -EINVAL;
1117d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1118d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1119d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) {
1120d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__,
1121d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                              dst->format);
1122d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
1123d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1124d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1125d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int dst_surface_type;
1126d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (ctx->is_dst_ubwc_format)
1127d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        flags |= FLAGS_UBWC_FORMAT_MODE;
1128d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1129d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
1130d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        dst_surface_type = RGB_SURFACE;
1131d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        flags |= FLAGS_PREMULTIPLIED_ALPHA;
1132d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) {
1133d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        int num_planes = get_num_planes(dst->format);
1134d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        flags |= FLAGS_YUV_DESTINATION;
1135d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (num_planes == 2) {
1136d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            dst_surface_type = YUV_SURFACE_2_PLANES;
1137d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        } else if (num_planes == 3) {
1138d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            dst_surface_type = YUV_SURFACE_3_PLANES;
1139d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        } else {
1140d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x",
1141d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                  __FUNCTION__, dst->format);
1142d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return COPYBIT_FAILURE;
1143d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1144d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
1145d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__,
1146d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                     dst->format);
1147d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
1148d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1149d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1150d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (ctx->blit_rgb_count == MAX_RGB_SURFACES ||
1151d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_yuv_2_plane_count == MAX_YUV_2_PLANE_SURFACES ||
1152d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_yuv_3_plane_count == MAX_YUV_2_PLANE_SURFACES ||
1153d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_count == MAX_BLIT_OBJECT_COUNT ||
1154d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->dst_surface_type != dst_surface_type) {
1155d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // we have reached the max. limits of our internal structures or
1156d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // changed the target.
1157d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // Draw the remaining surfaces. We need to do the finish here since
1158d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // we need to free up the surface templates.
1159d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        finish_copybit(dev);
1160d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1161d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1162d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->dst_surface_type = dst_surface_type;
1163d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1164d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Update the destination
1165d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    copybit_image_t dst_image;
1166d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    dst_image.w = dst->w;
1167d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    dst_image.h = dst->h;
1168d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    dst_image.format = dst->format;
1169d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    dst_image.handle = dst->handle;
1170d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Check if we need a temp. copy for the destination. We'd need this the destination
1171d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // width is not aligned to 32. This case occurs for YUV formats. RGB formats are
1172d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // aligned to 32.
1173d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool need_temp_dst = need_temp_buffer(dst);
1174d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bufferInfo dst_info;
1175d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    populate_buffer_info(dst, dst_info);
1176d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format,
1177d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                     dst_info.width, dst_info.height);
1178d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (dst_hnd == NULL) {
1179d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: dst_hnd is null", __FUNCTION__);
1180d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
1181d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1182d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (need_temp_dst) {
1183d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (get_size(dst_info) != (int) ctx->temp_dst_buffer.size) {
1184d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            free_temp_buffer(ctx->temp_dst_buffer);
1185d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            // Create a temp buffer and set that as the destination.
1186d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) {
1187d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                ALOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__);
1188d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                delete_handle(dst_hnd);
1189d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                return COPYBIT_FAILURE;
1190d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            }
1191d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1192d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        dst_hnd->fd = ctx->temp_dst_buffer.fd;
1193d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        dst_hnd->size = ctx->temp_dst_buffer.size;
1194d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        dst_hnd->flags = ctx->temp_dst_buffer.allocType;
1195d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        dst_hnd->base = (uintptr_t)(ctx->temp_dst_buffer.base);
1196d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        dst_hnd->offset = ctx->temp_dst_buffer.offset;
1197d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        dst_hnd->gpuaddr = 0;
1198d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        dst_image.handle = dst_hnd;
1199d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1200d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(!ctx->dst_surface_mapped) {
1201d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        //map the destination surface to GPU address
1202d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = set_image(ctx, ctx->dst[ctx->dst_surface_type], &dst_image,
1203d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                           (eC2DFlags)flags, mapped_dst_idx);
1204d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if(status) {
1205d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: dst: set_image error", __FUNCTION__);
1206d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            delete_handle(dst_hnd);
1207d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            unmap_gpuaddr(ctx, mapped_dst_idx);
1208d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return COPYBIT_FAILURE;
1209d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1210d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->dst_surface_mapped = true;
1211d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->dst_surface_base = dst->base;
1212d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else if(ctx->dst_surface_mapped && ctx->dst_surface_base != dst->base) {
1213d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // Destination surface for the operation should be same for multiple
1214d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // requests, this check is catch if there is any case when the
1215d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // destination changes
1216d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: a different destination surface!!", __FUNCTION__);
1217d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1218d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1219d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Update the source
1220d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flags = 0;
1221d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) {
1222d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        src_surface_type = RGB_SURFACE;
1223d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        src_surface = ctx->blit_rgb_object[ctx->blit_rgb_count];
1224d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) {
1225d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        int num_planes = get_num_planes(src->format);
1226d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (num_planes == 2) {
1227d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            src_surface_type = YUV_SURFACE_2_PLANES;
1228d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            src_surface = ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count];
1229d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        } else if (num_planes == 3) {
1230d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            src_surface_type = YUV_SURFACE_3_PLANES;
1231d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            src_surface = ctx->blit_yuv_3_plane_object[ctx->blit_yuv_2_plane_count];
1232d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        } else {
1233d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: src number of YUV planes is invalid src format = 0x%x",
1234d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                  __FUNCTION__, src->format);
1235d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            delete_handle(dst_hnd);
1236d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            unmap_gpuaddr(ctx, mapped_dst_idx);
1237d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return -EINVAL;
1238d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1239d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
1240d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__,
1241d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                        src->format);
1242d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        delete_handle(dst_hnd);
1243d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        unmap_gpuaddr(ctx, mapped_dst_idx);
1244d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return -EINVAL;
1245d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1246d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1247d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    copybit_image_t src_image;
1248d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    src_image.w = src->w;
1249d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    src_image.h = src->h;
1250d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    src_image.format = src->format;
1251d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    src_image.handle = src->handle;
1252d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1253d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool need_temp_src = need_temp_buffer(src);
1254d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bufferInfo src_info;
1255d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    populate_buffer_info(src, src_info);
1256d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format,
1257d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 src_info.width, src_info.height);
1258d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (NULL == src_hnd) {
1259d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: src_hnd is null", __FUNCTION__);
1260d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        delete_handle(dst_hnd);
1261d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        unmap_gpuaddr(ctx, mapped_dst_idx);
1262d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
1263d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1264d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (need_temp_src) {
1265d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (get_size(src_info) != (int) ctx->temp_src_buffer.size) {
1266d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            free_temp_buffer(ctx->temp_src_buffer);
1267d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            // Create a temp buffer and set that as the destination.
1268d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if (COPYBIT_SUCCESS != get_temp_buffer(src_info,
1269d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                               ctx->temp_src_buffer)) {
1270d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__);
1271d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                delete_handle(dst_hnd);
1272d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                delete_handle(src_hnd);
1273d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                unmap_gpuaddr(ctx, mapped_dst_idx);
1274d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                return COPYBIT_FAILURE;
1275d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            }
1276d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1277d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        src_hnd->fd = ctx->temp_src_buffer.fd;
1278d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        src_hnd->size = ctx->temp_src_buffer.size;
1279d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        src_hnd->flags = ctx->temp_src_buffer.allocType;
1280d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        src_hnd->base = (uintptr_t)(ctx->temp_src_buffer.base);
1281d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        src_hnd->offset = ctx->temp_src_buffer.offset;
1282d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        src_hnd->gpuaddr = 0;
1283d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        src_image.handle = src_hnd;
1284d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1285d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // Copy the source.
1286d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = copy_image((private_handle_t *)src->handle, &src_image,
1287d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                CONVERT_TO_C2D_FORMAT);
1288d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (status == COPYBIT_FAILURE) {
1289d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s:copy_image failed in temp source",__FUNCTION__);
1290d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            delete_handle(dst_hnd);
1291d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            delete_handle(src_hnd);
1292d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            unmap_gpuaddr(ctx, mapped_dst_idx);
1293d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return status;
1294d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1295d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1296d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // Clean the cache
1297d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
1298d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
1299d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                   src_hnd->offset, src_hnd->fd,
1300d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                   gralloc::CACHE_CLEAN)) {
1301d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: clean_buffer failed", __FUNCTION__);
1302d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            delete_handle(dst_hnd);
1303d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            delete_handle(src_hnd);
1304d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            unmap_gpuaddr(ctx, mapped_dst_idx);
1305d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return COPYBIT_FAILURE;
1306d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1307d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1308d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1309d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
1310d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
1311d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flags |= (ctx->is_src_ubwc_format) ? FLAGS_UBWC_FORMAT_MODE : 0;
1312d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    status = set_image(ctx, src_surface.surface_id, &src_image,
1313d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                       (eC2DFlags)flags, mapped_src_idx);
1314d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(status) {
1315d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: set_image (src) error", __FUNCTION__);
1316d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        delete_handle(dst_hnd);
1317d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        delete_handle(src_hnd);
1318d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        unmap_gpuaddr(ctx, mapped_dst_idx);
1319d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        unmap_gpuaddr(ctx, mapped_src_idx);
1320d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
1321d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1322d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1323d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    src_surface.config_mask = C2D_NO_ANTIALIASING_BIT | ctx->config_mask;
1324d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    src_surface.global_alpha = ctx->src_global_alpha;
1325d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (enableBlend) {
1326d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) {
1327d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
1328d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            if(!(src_surface.global_alpha)) {
1329d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                // src alpha is zero
1330d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                delete_handle(dst_hnd);
1331d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                delete_handle(src_hnd);
1332d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                unmap_gpuaddr(ctx, mapped_dst_idx);
1333d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                unmap_gpuaddr(ctx, mapped_src_idx);
1334d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                return COPYBIT_FAILURE;
1335d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            }
1336d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1337d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
1338d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
1339d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1340d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1341d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (src_surface_type == RGB_SURFACE) {
1342d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_rgb_object[ctx->blit_rgb_count] = src_surface;
1343d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_rgb_count++;
1344d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else if (src_surface_type == YUV_SURFACE_2_PLANES) {
1345d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count] = src_surface;
1346d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_yuv_2_plane_count++;
1347d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    } else {
1348d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_yuv_3_plane_object[ctx->blit_yuv_3_plane_count] = src_surface;
1349d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_yuv_3_plane_count++;
1350d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1351d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1352d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_rect_t clip;
1353d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    while ((status == 0) && region->next(region, &clip)) {
1354d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip);
1355d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) {
1356d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGW("Reached end of blit count");
1357d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            finish_copybit(dev);
1358d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1359d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_list[ctx->blit_count] = src_surface;
1360d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->blit_count++;
1361d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1362d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1363d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Check if we need to perform an early draw-finish.
1364d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0;
1365d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (need_to_execute_draw((eC2DFlags)flags))
1366d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    {
1367d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        finish_copybit(dev);
1368d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1369d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1370d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (need_temp_dst) {
1371d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // copy the temp. destination without the alignment to the actual
1372d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // destination.
1373d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
1374d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (status == COPYBIT_FAILURE) {
1375d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__);
1376d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            delete_handle(dst_hnd);
1377d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            delete_handle(src_hnd);
1378d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            unmap_gpuaddr(ctx, mapped_dst_idx);
1379d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            unmap_gpuaddr(ctx, mapped_src_idx);
1380d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            return status;
1381d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1382d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        // Clean the cache.
1383d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
1384d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
1385d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                               dst_hnd->offset, dst_hnd->fd,
1386d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                               gralloc::CACHE_CLEAN);
1387d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1388d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    delete_handle(dst_hnd);
1389d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    delete_handle(src_hnd);
1390d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1391d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->is_premultiplied_alpha = false;
1392d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->fb_width = 0;
1393d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->fb_height = 0;
1394d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->config_mask = 0;
1395d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return status;
1396d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1397d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1398d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int set_sync_copybit(struct copybit_device_t *dev,
1399d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int /*acquireFenceFd*/)
1400d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1401d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(!dev)
1402d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return -EINVAL;
1403d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1404d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
1405d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1406d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1407d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int stretch_copybit(
1408d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_device_t *dev,
1409d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_image_t const *dst,
1410d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_image_t const *src,
1411d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_rect_t const *dst_rect,
1412d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_rect_t const *src_rect,
1413d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_region_t const *region)
1414d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1415d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1416d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int status = COPYBIT_SUCCESS;
1417d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    bool needsBlending = (ctx->src_global_alpha != 0);
1418d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_lock(&ctx->wait_cleanup_lock);
1419d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
1420d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                    region, needsBlending);
1421d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
1422d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return status;
1423d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1424d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1425d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/** Perform a blit type operation */
1426d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int blit_copybit(
1427d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_device_t *dev,
1428d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_image_t const *dst,
1429d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_image_t const *src,
1430d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_region_t const *region)
1431d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1432d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int status = COPYBIT_SUCCESS;
1433d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1434d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
1435d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
1436d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_lock(&ctx->wait_cleanup_lock);
1437d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    status = stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false);
1438d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
1439d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return status;
1440d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1441d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1442d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/** Fill the rect on dst with RGBA color **/
1443d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int fill_color(struct copybit_device_t *dev,
1444d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                      struct copybit_image_t const *dst,
1445d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                      struct copybit_rect_t const *rect,
1446d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                      uint32_t /*color*/)
1447d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1448d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // TODO: Implement once c2d driver supports color fill
1449d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(!dev || !dst || !rect)
1450d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin       return -EINVAL;
1451d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1452d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return -EINVAL;
1453d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1454d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1455d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/*****************************************************************************/
1456d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1457d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic void clean_up(copybit_context_t* ctx)
1458d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1459d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    void* ret;
1460d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!ctx)
1461d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return;
1462d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1463d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // stop the wait_cleanup_thread
1464d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_lock(&ctx->wait_cleanup_lock);
1465d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->stop_thread = true;
1466d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Signal waiting thread
1467d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_cond_signal(&ctx->wait_cleanup_cond);
1468d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
1469d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // waits for the cleanup thread to exit
1470d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_join(ctx->wait_thread_id, &ret);
1471d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_destroy(&ctx->wait_cleanup_lock);
1472d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_cond_destroy (&ctx->wait_cleanup_cond);
1473d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1474d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (int i = 0; i < NUM_SURFACE_TYPES; i++) {
1475d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (ctx->dst[i])
1476d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            LINK_c2dDestroySurface(ctx->dst[i]);
1477d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1478d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1479d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (int i = 0; i < MAX_RGB_SURFACES; i++) {
1480d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (ctx->blit_rgb_object[i].surface_id)
1481d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id);
1482d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1483d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1484d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) {
1485d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (ctx->blit_yuv_2_plane_object[i].surface_id)
1486d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id);
1487d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1488d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1489d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) {
1490d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (ctx->blit_yuv_3_plane_object[i].surface_id)
1491d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id);
1492d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1493d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1494d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (ctx->libc2d2) {
1495d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ::dlclose(ctx->libc2d2);
1496d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGV("dlclose(libc2d2)");
1497d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1498d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1499d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    free(ctx);
1500d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1501d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1502d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/** Close the copybit device */
1503d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int close_copybit(struct hw_device_t *dev)
1504d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1505d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
1506d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (ctx) {
1507d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        free_temp_buffer(ctx->temp_src_buffer);
1508d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        free_temp_buffer(ctx->temp_dst_buffer);
1509d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1510d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    clean_up(ctx);
1511d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return 0;
1512d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1513d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1514d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin/** Open a new instance of a copybit device using name */
1515d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjinstatic int open_copybit(const struct hw_module_t* module, const char* name,
1516d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                        struct hw_device_t** device)
1517d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin{
1518d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    int status = COPYBIT_SUCCESS;
1519d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
1520d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
1521d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1522d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1523d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    C2D_RGB_SURFACE_DEF surfDefinition = {0};
1524d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
1525d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    struct copybit_context_t *ctx;
1526d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1527d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
1528d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if(!ctx) {
1529d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: malloc failed", __FUNCTION__);
1530d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return COPYBIT_FAILURE;
1531d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1532d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1533d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    /* initialize drawstate */
1534d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    memset(ctx, 0, sizeof(*ctx));
1535d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
1536d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!ctx->libc2d2) {
1537d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
1538d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        clean_up(ctx);
1539d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = COPYBIT_FAILURE;
1540d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        *device = NULL;
1541d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return status;
1542d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1543d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2,
1544d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                               "c2dCreateSurface");
1545d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2,
1546d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                               "c2dUpdateSurface");
1547d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2,
1548d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                             "c2dReadSurface");
1549d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw");
1550d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush");
1551d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish");
1552d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2,
1553d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                               "c2dWaitTimestamp");
1554d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2,
1555d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                "c2dDestroySurface");
1556d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2,
1557d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                         "c2dMapAddr");
1558d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2,
1559d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                           "c2dUnMapAddr");
1560d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2,
1561d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                           "c2dGetDriverCapabilities");
1562d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
1563d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                           "c2dCreateFenceFD");
1564d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2,
1565d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                           "c2dFillSurface");
1566d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1567d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
1568d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
1569d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
1570d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD ||
1571d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        !LINK_c2dFillSurface) {
1572d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: dlsym ERROR", __FUNCTION__);
1573d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        clean_up(ctx);
1574d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = COPYBIT_FAILURE;
1575d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        *device = NULL;
1576d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return status;
1577d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1578d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1579d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
1580d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.common.version = 1;
1581d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.common.module = (hw_module_t*)(module);
1582d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.common.close = close_copybit;
1583d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.set_parameter = set_parameter_copybit;
1584d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.get = get;
1585d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.blit = blit_copybit;
1586d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.set_sync = set_sync_copybit;
1587d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.stretch = stretch_copybit;
1588d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.finish = finish_copybit;
1589d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.flush_get_fence = flush_get_fence_copybit;
1590d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.clear = clear_copybit;
1591d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->device.fill_color = fill_color;
1592d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1593d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    /* Create RGB Surface */
1594d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    surfDefinition.buffer = (void*)0xdddddddd;
1595d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    surfDefinition.phys = (void*)0xdddddddd;
1596d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    surfDefinition.stride = 1 * 4;
1597d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    surfDefinition.width = 1;
1598d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    surfDefinition.height = 1;
1599d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB;
1600d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
1601d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
1602d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 C2D_SURFACE_WITH_PHYS |
1603d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
1604d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 &surfDefinition)) {
1605d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__);
1606d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->dst[RGB_SURFACE] = 0;
1607d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        clean_up(ctx);
1608d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = COPYBIT_FAILURE;
1609d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        *device = NULL;
1610d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return status;
1611d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1612d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1613d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    unsigned int surface_id = 0;
1614d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (int i = 0; i < MAX_RGB_SURFACES; i++)
1615d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    {
1616d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
1617d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
1618d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 C2D_SURFACE_WITH_PHYS |
1619d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
1620d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 &surfDefinition)) {
1621d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i);
1622d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->blit_rgb_object[i].surface_id = 0;
1623d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            status = COPYBIT_FAILURE;
1624d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
1625d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        } else {
1626d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->blit_rgb_object[i].surface_id = surface_id;
1627d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGW("%s i = %d surface_id=%d",  __FUNCTION__, i,
1628d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                          ctx->blit_rgb_object[i].surface_id);
1629d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1630d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1631d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1632d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (status == COPYBIT_FAILURE) {
1633d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        clean_up(ctx);
1634d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = COPYBIT_FAILURE;
1635d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        *device = NULL;
1636d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return status;
1637d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1638d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1639d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Create 2 plane YUV surfaces
1640d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
1641d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.width = 4;
1642d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.height = 4;
1643d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa;
1644d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa;
1645d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.stride0 = 4;
1646d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1647d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa;
1648d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa;
1649d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.stride1 = 4;
1650d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),
1651d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              C2D_TARGET | C2D_SOURCE,
1652d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1653d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                               C2D_SURFACE_WITH_PHYS |
1654d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                               C2D_SURFACE_WITH_PHYS_DUMMY),
1655d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              &yuvSurfaceDef)) {
1656d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
1657d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->dst[YUV_SURFACE_2_PLANES] = 0;
1658d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        clean_up(ctx);
1659d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = COPYBIT_FAILURE;
1660d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        *device = NULL;
1661d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return status;
1662d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1663d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1664d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++)
1665d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    {
1666d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
1667d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1668d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 C2D_SURFACE_WITH_PHYS |
1669d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
1670d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              &yuvSurfaceDef)) {
1671d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: create YUV source %d failed", __FUNCTION__, i);
1672d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->blit_yuv_2_plane_object[i].surface_id = 0;
1673d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            status = COPYBIT_FAILURE;
1674d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
1675d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        } else {
1676d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->blit_yuv_2_plane_object[i].surface_id = surface_id;
1677d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGW("%s: 2 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
1678d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                   ctx->blit_yuv_2_plane_object[i].surface_id);
1679d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1680d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1681d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1682d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (status == COPYBIT_FAILURE) {
1683d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        clean_up(ctx);
1684d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = COPYBIT_FAILURE;
1685d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        *device = NULL;
1686d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return status;
1687d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1688d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1689d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Create YUV 3 plane surfaces
1690d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
1691d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
1692d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
1693d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    yuvSurfaceDef.stride2 = 4;
1694d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1695d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),
1696d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              C2D_TARGET | C2D_SOURCE,
1697d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1698d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 C2D_SURFACE_WITH_PHYS |
1699d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
1700d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              &yuvSurfaceDef)) {
1701d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
1702d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        ctx->dst[YUV_SURFACE_3_PLANES] = 0;
1703d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        clean_up(ctx);
1704d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = COPYBIT_FAILURE;
1705d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        *device = NULL;
1706d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return status;
1707d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1708d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1709d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++)
1710d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    {
1711d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        if (LINK_c2dCreateSurface(&(surface_id),
1712d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              C2D_TARGET | C2D_SOURCE,
1713d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
1714d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 C2D_SURFACE_WITH_PHYS |
1715d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
1716d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                              &yuvSurfaceDef)) {
1717d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i);
1718d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->blit_yuv_3_plane_object[i].surface_id = 0;
1719d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            status = COPYBIT_FAILURE;
1720d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            break;
1721d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        } else {
1722d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ctx->blit_yuv_3_plane_object[i].surface_id = surface_id;
1723d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin            ALOGW("%s: 3 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
1724d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                   ctx->blit_yuv_3_plane_object[i].surface_id);
1725d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        }
1726d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1727d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1728d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (status == COPYBIT_FAILURE) {
1729d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        clean_up(ctx);
1730d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        status = COPYBIT_FAILURE;
1731d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        *device = NULL;
1732d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return status;
1733d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1734d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1735d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) {
1736d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin         ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__);
1737d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin         clean_up(ctx);
1738d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin         status = COPYBIT_FAILURE;
1739d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        *device = NULL;
1740d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin        return status;
1741d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    }
1742d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    // Initialize context variables.
1743d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->trg_transform = C2D_TARGET_ROTATE_0;
1744d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1745d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->temp_src_buffer.fd = -1;
1746d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->temp_src_buffer.base = 0;
1747d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->temp_src_buffer.size = 0;
1748d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1749d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->temp_dst_buffer.fd = -1;
1750d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->temp_dst_buffer.base = 0;
1751d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->temp_dst_buffer.size = 0;
1752d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1753d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->fb_width = 0;
1754d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->fb_height = 0;
1755d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1756d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->blit_rgb_count = 0;
1757d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->blit_yuv_2_plane_count = 0;
1758d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->blit_yuv_3_plane_count = 0;
1759d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->blit_count = 0;
1760d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1761d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->wait_timestamp = false;
1762d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    ctx->stop_thread = false;
1763d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL);
1764d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_cond_init(&(ctx->wait_cleanup_cond), NULL);
1765d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    /* Start the wait thread */
1766d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_attr_t attr;
1767d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_attr_init(&attr);
1768d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
1769d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1770d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop,
1771d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin                                                            (void *)ctx);
1772d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    pthread_attr_destroy(&attr);
1773d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin
1774d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    *device = &ctx->device.common;
1775d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin    return status;
1776d68a2e45260f864503d7bd6da93fd29589afd89ePatrick Tjin}
1777