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