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