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