14a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/*
24a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * Copyright (C) 2008 The Android Open Source Project
34a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
44a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh *
54a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * Not a Contribution, Apache license notifications and license are retained
64a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * for attribution purposes only.
74a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh *
84a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * Licensed under the Apache License, Version 2.0 (the "License");
94a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * you may not use this file except in compliance with the License.
104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * You may obtain a copy of the License at
114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh *
124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh *      http://www.apache.org/licenses/LICENSE-2.0
134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh *
144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * Unless required by applicable law or agreed to in writing, software
154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * distributed under the License is distributed on an "AS IS" BASIS,
164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * See the License for the specific language governing permissions and
184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * limitations under the License.
194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh */
204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <cutils/log.h>
214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <sys/resource.h>
224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <sys/prctl.h>
234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <stdint.h>
254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <string.h>
264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <unistd.h>
274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <errno.h>
284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <fcntl.h>
294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <sys/ioctl.h>
314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <sys/types.h>
324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <sys/mman.h>
334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <linux/msm_kgsl.h>
354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <EGL/eglplatform.h>
374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <cutils/native_handle.h>
384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <copybit.h>
404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <alloc_controller.h>
414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <memalloc.h>
424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include "c2d2.h"
444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include "software_converter.h"
454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#include <dlfcn.h>
474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing gralloc::IMemAlloc;
494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing gralloc::IonController;
504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhusing gralloc::alloc_data;
514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                     uint32 surface_bits,
544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                     C2D_SURFACE_TYPE surface_type,
554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                     void *surface_definition );
564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id,
584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                     uint32 surface_bits,
594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                     C2D_SURFACE_TYPE surface_type,
604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                     void *surface_definition );
614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id,
634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                   C2D_SURFACE_TYPE surface_type,
644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                   void *surface_definition,
654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                   int32 x, int32 y );
664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dDraw)( uint32 target_id,
684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                            uint32 target_config, C2D_RECT *target_scissor,
694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                            uint32 target_mask_id, uint32 target_color_key,
704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                            C2D_OBJECT *objects_list, uint32 num_objects );
714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dFinish)( uint32 target_id);
734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp);
754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp );
774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );
794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, size_t len,
814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                size_t offset, uint32 flags, void ** gpuaddr);
824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);
844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info);
864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* create a fence fd for the timestamp */
884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                            int32 *fd);
904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain VongsouvanhC2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color,
924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                    C2D_RECT * fill_rect);
934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/******************************************************************************/
954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#if defined(COPYBIT_Z180)
974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define MAX_SCALE_FACTOR    (4096)
984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define MAX_DIMENSION       (4096)
994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#else
1004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#error "Unsupported HW version"
1014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#endif
1024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh// The following defines can be changed as required i.e. as we encounter
1044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh// complex use cases.
1054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define MAX_RGB_SURFACES 32       // Max. RGB layers currently supported per draw
1064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw
1074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw
1084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh// +1 for the destination surface. We cannot have multiple destination surfaces.
1094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1)
1104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define NUM_SURFACE_TYPES 3      // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES
1114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh#define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw
1124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhenum {
1144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    RGB_SURFACE,
1154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    YUV_SURFACE_2_PLANES,
1164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    YUV_SURFACE_3_PLANES
1174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh};
1184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhenum eConversionType {
1204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    CONVERT_TO_ANDROID_FORMAT,
1214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    CONVERT_TO_C2D_FORMAT
1224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh};
1234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhenum eC2DFlags {
1254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    FLAGS_PREMULTIPLIED_ALPHA  = 1<<0,
1264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    FLAGS_YUV_DESTINATION      = 1<<1,
1274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    FLAGS_TEMP_SRC_DST         = 1<<2,
1284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    FLAGS_UBWC_FORMAT_MODE     = 1<<3
1294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh};
1304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic gralloc::IAllocController* sAlloc = 0;
1324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/******************************************************************************/
1334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/** State information for each device instance */
1354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstruct copybit_context_t {
1364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_device_t device;
1374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Templates for the various source surfaces. These templates are created
1384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // to avoid the expensive create/destroy C2D Surfaces
1394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES];
1404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES];
1414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES];
1424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects
1434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    C2D_DRIVER_INFO c2d_driver_info;
1444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    void *libc2d2;
1454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    alloc_data temp_src_buffer;
1464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    alloc_data temp_dst_buffer;
1474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces
1484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    uintptr_t mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
1494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int blit_rgb_count;         // Total RGB surfaces being blit
1504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being
1514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int blit_yuv_3_plane_count; // Total 3 plane YUV  surfaces being blit
1524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int blit_count;             // Total blit objects.
1534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    unsigned int trg_transform;      /* target transform */
1544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int fb_width;
1554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int fb_height;
1564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int src_global_alpha;
1574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int config_mask;
1584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int dst_surface_type;
1594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool is_premultiplied_alpha;
1604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    void* time_stamp;
1614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr
1624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    void* dst_surface_base; // Stores the dst surface addr
1634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool is_src_ubwc_format;
1644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool is_dst_ubwc_format;
1654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // used for signaling the wait thread
1674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool wait_timestamp;
1684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_t wait_thread_id;
1694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool stop_thread;
1704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_t wait_cleanup_lock;
1714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_cond_t wait_cleanup_cond;
1724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh};
1744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstruct bufferInfo {
1764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int width;
1774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int height;
1784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int format;
1794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh};
1804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstruct yuvPlaneInfo {
1824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int yStride;       //luma stride
1834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int plane1_stride;
1844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int plane2_stride;
1854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    size_t plane1_offset;
1864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    size_t plane2_offset;
1874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh};
1884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/**
1904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * Common hardware methods
1914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh */
1924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int open_copybit(const struct hw_module_t* module, const char* name,
1944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                        struct hw_device_t** device);
1954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
1964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic struct hw_module_methods_t copybit_module_methods = {
1974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    .open = open_copybit,
1984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh};
1994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/*
2014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * The COPYBIT Module
2024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh */
2034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstruct copybit_module_t HAL_MODULE_INFO_SYM = {
2044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    .common = {
2054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        .tag =  HARDWARE_MODULE_TAG,
2064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        .version_major = 1,
2074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        .version_minor = 0,
2084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        .id = COPYBIT_HARDWARE_MODULE_ID,
2094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        .name = "QCT COPYBIT C2D 2.0 Module",
2104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        .author = "Qualcomm",
2114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        .methods =  &copybit_module_methods
2124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
2134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh};
2144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* thread function which waits on the timeStamp and cleans up the surfaces */
2174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic void* c2d_wait_loop(void* ptr) {
2184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    copybit_context_t* ctx = (copybit_context_t*)(ptr);
2194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    char thread_name[64] = "copybitWaitThr";
2204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
2214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);
2224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    while(ctx->stop_thread == false) {
2244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        pthread_mutex_lock(&ctx->wait_cleanup_lock);
2254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        while(ctx->wait_timestamp == false && !ctx->stop_thread) {
2264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            pthread_cond_wait(&(ctx->wait_cleanup_cond),
2274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              &(ctx->wait_cleanup_lock));
2284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
2294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if(ctx->wait_timestamp) {
2304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if(LINK_c2dWaitTimestamp(ctx->time_stamp)) {
2314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__);
2324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            }
2334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->wait_timestamp = false;
2344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            // Unmap any mapped addresses.
2354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            for (int i = 0; i < MAX_SURFACES; i++) {
2364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                if (ctx->mapped_gpu_addr[i]) {
2374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                    LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
2384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                    ctx->mapped_gpu_addr[i] = 0;
2394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                }
2404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            }
2414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            // Reset the counts after the draw.
2424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->blit_rgb_count = 0;
2434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->blit_yuv_2_plane_count = 0;
2444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->blit_yuv_3_plane_count = 0;
2454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->blit_count = 0;
2464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->dst_surface_mapped = false;
2474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->dst_surface_base = 0;
2484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
2494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
2504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if(ctx->stop_thread)
2514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
2524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
2534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_exit(NULL);
2544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return NULL;
2554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* convert COPYBIT_FORMAT to C2D format */
2594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int get_format(int format) {
2604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    switch (format) {
2614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGB_565:        return C2D_COLOR_FORMAT_565_RGB;
2624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGB_888:        return C2D_COLOR_FORMAT_888_RGB |
2634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                              C2D_FORMAT_SWAP_RB;
2644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
2654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                              C2D_FORMAT_SWAP_RB |
2664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                  C2D_FORMAT_DISABLE_ALPHA;
2674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
2684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                              C2D_FORMAT_SWAP_RB;
2694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_BGRA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
2704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGBA_5551:      return C2D_COLOR_FORMAT_5551_RGBA;
2714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGBA_4444:      return C2D_COLOR_FORMAT_4444_RGBA;
2724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
2734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
2744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
2754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 |
2764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                  C2D_FORMAT_MACROTILED;
2774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        default:                              ALOGE("%s: invalid format (0x%x",
2784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                     __FUNCTION__, format);
2794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                              return -EINVAL;
2804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
2814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return -EINVAL;
2824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
2844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* Get the C2D formats needed for conversion to YUV */
2854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int get_c2d_format_for_yuv_destination(int halFormat) {
2864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    switch (halFormat) {
2874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // We do not swap the RB when the target is YUV
2884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
2894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                              C2D_FORMAT_DISABLE_ALPHA;
2904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
2914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // The U and V need to be interchanged when the target is YUV
2924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
2934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21;
2944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
2954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        default:                              return get_format(halFormat);
2964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
2974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return -EINVAL;
2984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
2994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* ------------------------------------------------------------------- *//*!
3014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * \internal
3024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * \brief Get the bpp for a particular color format
3034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * \param color format
3044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * \return bits per pixel
3054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh *//* ------------------------------------------------------------------- */
3064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhint c2diGetBpp(int32 colorformat)
3074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
3084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int c2dBpp = 0;
3104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    switch(colorformat&0xFF)
3124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    {
3134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_4444_RGBA:
3144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_4444_ARGB:
3154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_1555_ARGB:
3164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_565_RGB:
3174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_5551_RGBA:
3184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            c2dBpp = 16;
3194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
3204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_8888_RGBA:
3214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_8888_ARGB:
3224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            c2dBpp = 32;
3234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
3244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_888_RGB:
3254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            c2dBpp = 24;
3264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
3274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_8_L:
3284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_8_A:
3294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            c2dBpp = 8;
3304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
3314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_4_A:
3324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            c2dBpp = 4;
3334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
3344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case C2D_COLOR_FORMAT_1:
3354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            c2dBpp = 1;
3364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
3374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        default:
3384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s ERROR", __func__);
3394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
3404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
3414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return c2dBpp;
3424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
3434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic size_t c2d_get_gpuaddr(copybit_context_t* ctx,
3454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              struct private_handle_t *handle, int &mapped_idx)
3464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
3474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    uint32 memtype;
3484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    size_t *gpuaddr = 0;
3494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    C2D_STATUS rc;
3504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int freeindex = 0;
3514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool mapaddr = false;
3524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(!handle)
3544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return 0;
3554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
3574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        memtype = KGSL_USER_MEM_TYPE_ION;
3584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    else {
3594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("Invalid handle flags: 0x%x", handle->flags);
3604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return 0;
3614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
3624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Check for a freeindex in the mapped_gpu_addr list
3644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    for (freeindex = 0; freeindex < MAX_SURFACES; freeindex++) {
3654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (ctx->mapped_gpu_addr[freeindex] == 0) {
3664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            // free index is available
3674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            // map GPU addr and use this as mapped_idx
3684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            mapaddr = true;
3694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
3704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
3714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
3724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(mapaddr) {
3744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size,
3754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                             handle->offset, memtype, (void**)&gpuaddr);
3764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (rc == C2D_STATUS_OK) {
3784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            // We have mapped the GPU address inside copybit. We need to unmap
3794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            // this address after the blit. Store this address
3804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->mapped_gpu_addr[freeindex] = (size_t)gpuaddr;
3814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            mapped_idx = freeindex;
3824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
3834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
3844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return (size_t)gpuaddr;
3854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
3864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx)
3884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
3894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (!ctx || (mapped_idx == -1))
3904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return;
3914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (ctx->mapped_gpu_addr[mapped_idx]) {
3934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]);
3944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->mapped_gpu_addr[mapped_idx] = 0;
3954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
3964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
3974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
3984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int is_supported_rgb_format(int format)
3994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
4004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    switch(format) {
4014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGBA_8888:
4024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGBX_8888:
4034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGB_888:
4044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGB_565:
4054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_BGRA_8888:
4064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGBA_5551:
4074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_RGBA_4444: {
4084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return COPYBIT_SUCCESS;
4094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
4104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        default:
4114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return COPYBIT_FAILURE;
4124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
4134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
4144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int get_num_planes(int format)
4164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
4174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    switch(format) {
4184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
4194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
4204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
4214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
4224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return 2;
4234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
4244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YV12: {
4254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return 3;
4264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
4274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        default:
4284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return COPYBIT_FAILURE;
4294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
4304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
4314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int is_supported_yuv_format(int format)
4334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
4344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    switch(format) {
4354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
4364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
4374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
4384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
4394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return COPYBIT_SUCCESS;
4404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
4414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        default:
4424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return COPYBIT_FAILURE;
4434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
4444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
4454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int is_valid_destination_format(int format)
4474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
4484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
4494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // C2D does not support NV12Tile as a destination format.
4504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
4514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
4524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return COPYBIT_SUCCESS;
4534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
4544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int calculate_yuv_offset_and_stride(const bufferInfo& info,
4564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                           yuvPlaneInfo& yuvInfo)
4574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
4584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int width  = info.width;
4594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int height = info.height;
4604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int format = info.format;
4614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int aligned_height = 0;
4634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int aligned_width = 0, size = 0;
4644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    switch (format) {
4664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
4674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            /* NV12 Tile buffers have their luma height aligned to 32bytes and width
4684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh             * aligned to 128 bytes. The chroma offset starts at an 8K boundary
4694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh             */
4704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            aligned_height = ALIGN(height, 32);
4714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            aligned_width  = ALIGN(width, 128);
4724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            size = aligned_width * aligned_height;
4734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            yuvInfo.plane1_offset = ALIGN(size,8192);
4744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            yuvInfo.yStride = aligned_width;
4754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            yuvInfo.plane1_stride = aligned_width;
4764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
4774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
4784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
4794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
4804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
4814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            aligned_width = ALIGN(width, 32);
4824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            yuvInfo.yStride = aligned_width;
4834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            yuvInfo.plane1_stride = aligned_width;
4844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
4854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                // The encoder requires a 2K aligned chroma offset
4864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048);
4874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            } else
4884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                yuvInfo.plane1_offset = aligned_width * height;
4894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
4914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
4924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        default: {
4934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return COPYBIT_FAILURE;
4944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
4954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
4964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return COPYBIT_SUCCESS;
4974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
4984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
4994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/** create C2D surface from copybit image */
5004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int set_image(copybit_context_t* ctx, uint32 surfaceId,
5014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                      const struct copybit_image_t *rhs,
5024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                      const eC2DFlags flags, int &mapped_idx)
5034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
5044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
5054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    C2D_SURFACE_TYPE surfaceType;
5064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int status = COPYBIT_SUCCESS;
5074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    uint64_t gpuaddr = 0;
5084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int c2d_format;
5094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    mapped_idx = -1;
5104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (flags & FLAGS_YUV_DESTINATION) {
5124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2d_format = get_c2d_format_for_yuv_destination(rhs->format);
5134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else {
5144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2d_format = get_format(rhs->format);
5154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
5164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(c2d_format == -EINVAL) {
5184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: invalid format", __FUNCTION__);
5194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return -EINVAL;
5204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
5214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(handle == NULL) {
5234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: invalid handle", __func__);
5244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return -EINVAL;
5254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
5264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (handle->gpuaddr == 0) {
5284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx);
5294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if(!gpuaddr) {
5304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
5314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return COPYBIT_FAILURE;
5324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
5334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else {
5344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        gpuaddr = handle->gpuaddr;
5354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
5364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    /* create C2D surface */
5384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
5394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        /* RGB */
5404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        C2D_RGB_SURFACE_DEF surfaceDef;
5414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS);
5434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.phys = (void*) gpuaddr;
5454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.buffer = (void*) (handle->base);
5464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.format = c2d_format |
5484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
5494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.format = surfaceDef.format |
5514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ((flags & FLAGS_UBWC_FORMAT_MODE) ? C2D_FORMAT_UBWC_COMPRESSED : 0);
5524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.width = rhs->w;
5544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.height = rhs->h;
5554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        int aligned_width = ALIGN((int)surfaceDef.width,32);
5564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;
5574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
5594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                  &surfaceDef)) {
5604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__);
5614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            unmap_gpuaddr(ctx, mapped_idx);
5624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            status = COPYBIT_FAILURE;
5634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
5644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
5654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        C2D_YUV_SURFACE_DEF surfaceDef;
5664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        memset(&surfaceDef, 0, sizeof(surfaceDef));
5674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS);
5684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.format = c2d_format;
5694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        bufferInfo info;
5714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        info.width = rhs->w;
5724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        info.height = rhs->h;
5734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        info.format = rhs->format;
5744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        yuvPlaneInfo yuvInfo = {0};
5764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = calculate_yuv_offset_and_stride(info, yuvInfo);
5774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if(status != COPYBIT_SUCCESS) {
5784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
5794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            unmap_gpuaddr(ctx, mapped_idx);
5804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
5814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.width = rhs->w;
5834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.height = rhs->h;
5844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.plane0 = (void*) (handle->base);
5854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.phys0 = (void*) (gpuaddr);
5864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.stride0 = yuvInfo.yStride;
5874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
5894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset);
5904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        surfaceDef.stride1 = yuvInfo.plane1_stride;
5914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (3 == get_num_planes(rhs->format)) {
5924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset);
5934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset);
5944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            surfaceDef.stride2 = yuvInfo.plane2_stride;
5954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
5964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
5974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
5984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                  &surfaceDef)) {
5994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__);
6004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            unmap_gpuaddr(ctx, mapped_idx);
6014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            status = COPYBIT_FAILURE;
6024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
6034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else {
6044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
6054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        unmap_gpuaddr(ctx, mapped_idx);
6064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = COPYBIT_FAILURE;
6074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
6084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return status;
6104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
6114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/** copy the bits */
6134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int msm_copybit(struct copybit_context_t *ctx, unsigned int target)
6144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
6154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (ctx->blit_count == 0) {
6164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_SUCCESS;
6174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
6184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    for (int i = 0; i < ctx->blit_count; i++)
6204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    {
6214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_list[i].next = &(ctx->blit_list[i+1]);
6224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
6234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->blit_list[ctx->blit_count-1].next = NULL;
6244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    uint32_t target_transform = ctx->trg_transform;
6254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (ctx->c2d_driver_info.capabilities_mask &
6264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
6274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // For A3xx - set 0x0 as the transform is set in the config_mask
6284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        target_transform = 0x0;
6294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
6304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(LINK_c2dDraw(target, target_transform, 0x0, 0, 0, ctx->blit_list,
6314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                    ctx->blit_count)) {
6324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
6334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
6344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
6354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return COPYBIT_SUCCESS;
6364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
6374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd)
6414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
6424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
6434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int status = COPYBIT_FAILURE;
6444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (!ctx)
6454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
6464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_lock(&ctx->wait_cleanup_lock);
6474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
6484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) {
6504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__);
6514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // unlock the mutex and return failure
6524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
6534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
6544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
6554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp,
6564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                                        fd)) {
6574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__);
6584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = COPYBIT_FAILURE;
6594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
6604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(status == COPYBIT_SUCCESS) {
6614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        //signal the wait_thread
6624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->wait_timestamp = true;
6634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        pthread_cond_signal(&ctx->wait_cleanup_cond);
6644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
6654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
6664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return status;
6674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
6684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int finish_copybit(struct copybit_device_t *dev)
6704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
6714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
6724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (!ctx)
6734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
6744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh   int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);
6764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh   if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) {
6784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
6794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
6804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
6814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Unmap any mapped addresses.
6834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    for (int i = 0; i < MAX_SURFACES; i++) {
6844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (ctx->mapped_gpu_addr[i]) {
6854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
6864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->mapped_gpu_addr[i] = 0;
6874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
6884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
6894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Reset the counts after the draw.
6914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->blit_rgb_count = 0;
6924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->blit_yuv_2_plane_count = 0;
6934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->blit_yuv_3_plane_count = 0;
6944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->blit_count = 0;
6954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->dst_surface_mapped = false;
6964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->dst_surface_base = 0;
6974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
6984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return status;
6994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
7004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int clear_copybit(struct copybit_device_t *dev,
7024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                         struct copybit_image_t const *buf,
7034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                         struct copybit_rect_t *rect)
7044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
7054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int ret = COPYBIT_SUCCESS;
7064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int flags = FLAGS_PREMULTIPLIED_ALPHA;
7074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int mapped_dst_idx = -1;
7084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
7094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (ctx->is_dst_ubwc_format)
7104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        flags |= FLAGS_UBWC_FORMAT_MODE;
7114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
7124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_lock(&ctx->wait_cleanup_lock);
7134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(!ctx->dst_surface_mapped) {
7144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf,
7154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                        (eC2DFlags)flags, mapped_dst_idx);
7164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if(ret) {
7174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: set_image error", __FUNCTION__);
7184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            unmap_gpuaddr(ctx, mapped_dst_idx);
7194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            pthread_mutex_unlock(&ctx->wait_cleanup_lock);
7204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return COPYBIT_FAILURE;
7214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
7224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        //clear_copybit is the first call made by HWC for each composition
7234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        //with the dest surface, hence set dst_surface_mapped.
7244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->dst_surface_mapped = true;
7254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->dst_surface_base = buf->base;
7264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect);
7274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
7284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
7294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return ret;
7304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
7314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/** setup rectangles */
7344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic void set_rects(struct copybit_context_t *ctx,
7354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                      C2D_OBJECT *c2dObject,
7364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                      const struct copybit_rect_t *dst,
7374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                      const struct copybit_rect_t *src,
7384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                      const struct copybit_rect_t *scissor)
7394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
7404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Set the target rect.
7414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if((ctx->trg_transform & C2D_TARGET_ROTATE_90) &&
7424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh       (ctx->trg_transform & C2D_TARGET_ROTATE_180)) {
7434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        /* target rotation is 270 */
7444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.x        = (dst->t)<<16;
7454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.y        = ctx->fb_width?
7464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                (ALIGN(ctx->fb_width,32)- dst->r):dst->r;
7474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
7484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
7494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
7504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) {
7514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.x        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
7524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
7534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.y        = (dst->l)<<16;
7544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
7554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
7564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) {
7574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.y        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
7584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
7594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.x        = ctx->fb_width?
7604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                (ALIGN(ctx->fb_width,32) - dst->r):dst->r;
7614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
7624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
7634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
7644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else {
7654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.x        = (dst->l)<<16;
7664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.y        = (dst->t)<<16;
7674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
7684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
7694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
7704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    c2dObject->config_mask |= C2D_TARGET_RECT_BIT;
7714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Set the source rect
7734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    c2dObject->source_rect.x        = (src->l)<<16;
7744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    c2dObject->source_rect.y        = (src->t)<<16;
7754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    c2dObject->source_rect.height   = ((src->b) - (src->t))<<16;
7764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    c2dObject->source_rect.width    = ((src->r) - (src->l))<<16;
7774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    c2dObject->config_mask |= C2D_SOURCE_RECT_BIT;
7784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Set the scissor rect
7804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    c2dObject->scissor_rect.x       = scissor->l;
7814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    c2dObject->scissor_rect.y       = scissor->t;
7824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    c2dObject->scissor_rect.height  = (scissor->b) - (scissor->t);
7834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    c2dObject->scissor_rect.width   = (scissor->r) - (scissor->l);
7844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT;
7854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
7864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/*****************************************************************************/
7884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
7894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/** Set a parameter to value */
7904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int set_parameter_copybit(
7914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_device_t *dev,
7924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int name,
7934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int value)
7944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
7954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
7964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int status = COPYBIT_SUCCESS;
7974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (!ctx) {
7984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: null context", __FUNCTION__);
7994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return -EINVAL;
8004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
8014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_lock(&ctx->wait_cleanup_lock);
8034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    switch(name) {
8044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_PLANE_ALPHA:
8054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        {
8064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if (value < 0)      value = 0;
8074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if (value >= 256)   value = 255;
8084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->src_global_alpha = value;
8104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if (value < 255)
8114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT;
8124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            else
8134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT;
8144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
8154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        break;
8164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_BLEND_MODE:
8174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        {
8184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if (value == COPYBIT_BLENDING_NONE) {
8194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                ctx->config_mask |= C2D_ALPHA_BLEND_NONE;
8204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                ctx->is_premultiplied_alpha = true;
8214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            } else if (value == COPYBIT_BLENDING_PREMULT) {
8224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                ctx->is_premultiplied_alpha = true;
8234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            } else {
8244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE;
8254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            }
8264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
8274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        break;
8284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_TRANSFORM:
8294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        {
8304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            unsigned int transform = 0;
8314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            uint32 config_mask = 0;
8324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG;
8334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) {
8344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                transform = C2D_TARGET_ROTATE_180;
8354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180;
8364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) {
8374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                transform = C2D_TARGET_ROTATE_90;
8384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90;
8394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            } else if(value == COPYBIT_TRANSFORM_ROT_90) {
8404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                transform = C2D_TARGET_ROTATE_270;
8414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270;
8424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            } else {
8434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0;
8444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                if(value & COPYBIT_TRANSFORM_FLIP_H) {
8454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                    config_mask |= C2D_MIRROR_H_BIT;
8464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                } else if(value & COPYBIT_TRANSFORM_FLIP_V) {
8474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                    config_mask |= C2D_MIRROR_V_BIT;
8484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                }
8494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            }
8504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if (ctx->c2d_driver_info.capabilities_mask &
8524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
8534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                ctx->config_mask |= config_mask;
8544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            } else {
8554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                // The transform for this surface does not match the current
8564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                // target transform. Draw all previous surfaces. This will be
8574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                // changed once we have a new mechanism to send different
8584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                // target rotations to c2d.
8594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                finish_copybit(dev);
8604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            }
8614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->trg_transform = transform;
8624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
8634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        break;
8644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_FRAMEBUFFER_WIDTH:
8654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->fb_width = value;
8664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
8674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_FRAMEBUFFER_HEIGHT:
8684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->fb_height = value;
8694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
8704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_ROTATION_DEG:
8714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_DITHER:
8724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_BLUR:
8734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_BLIT_TO_FRAMEBUFFER:
8744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            // Do nothing
8754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
8764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_SRC_FORMAT_MODE:
8774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->is_src_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
8784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
8794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_DST_FORMAT_MODE:
8804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->is_dst_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED);
8814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
8824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        default:
8834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
8844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            status = -EINVAL;
8854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
8864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
8874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
8884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return status;
8894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
8904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/** Get a static info value */
8924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int get(struct copybit_device_t *dev, int name)
8934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
8944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
8954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int value;
8964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
8974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (!ctx) {
8984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: null context error", __FUNCTION__);
8994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return -EINVAL;
9004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
9014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    switch(name) {
9034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_MINIFICATION_LIMIT:
9044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            value = MAX_SCALE_FACTOR;
9054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
9064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_MAGNIFICATION_LIMIT:
9074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            value = MAX_SCALE_FACTOR;
9084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
9094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_SCALING_FRAC_BITS:
9104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            value = 32;
9114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
9124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_ROTATION_STEP_DEG:
9134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            value = 1;
9144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
9154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case COPYBIT_UBWC_SUPPORT:
9164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            value = 0;
9174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if (ctx->c2d_driver_info.capabilities_mask & C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP) {
9184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                value = 1;
9194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            }
9204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
9214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        default:
9224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
9234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            value = -EINVAL;
9244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
9254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return value;
9264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* Function to check if we need a temporary buffer for the blit.
9294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * This would happen if the requested destination stride and the
9304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * C2D stride do not match. We ignore RGB buffers, since their
9314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * stride is always aligned to 32.
9324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh */
9334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic bool need_temp_buffer(struct copybit_image_t const *img)
9344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
9354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format))
9364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return false;
9374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct private_handle_t* handle = (struct private_handle_t*)img->handle;
9394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // The width parameter in the handle contains the aligned_w. We check if we
9414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // need to convert based on this param. YUV formats have bpp=1, so checking
9424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // if the requested stride is aligned should suffice.
9434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (0 == (handle->width)%32) {
9444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return false;
9454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
9464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return true;
9484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* Function to extract the information from the copybit image and set the corresponding
9514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * values in the bufferInfo struct.
9524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh */
9534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info)
9544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
9554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    info.width = img->w;
9564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    info.height = img->h;
9574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    info.format = img->format;
9584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* Function to get the required size for a particular format, inorder for C2D to perform
9614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * the blit operation.
9624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh */
9634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int get_size(const bufferInfo& info)
9644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
9654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int size = 0;
9664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int w = info.width;
9674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int h = info.height;
9684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int aligned_w = ALIGN(w, 32);
9694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    switch(info.format) {
9704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
9714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            {
9724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                // Chroma for this format is aligned to 2K.
9734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                size = ALIGN((aligned_w*h), 2048) +
9744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                        ALIGN(aligned_w/2, 32) * (h/2) *2;
9754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                size = ALIGN(size, 4096);
9764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            } break;
9774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
9784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
9794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            {
9804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                size = aligned_w * h +
9814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                       ALIGN(aligned_w/2, 32) * (h/2) * 2;
9824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                size = ALIGN(size, 4096);
9834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            } break;
9844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        default: break;
9854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
9864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return size;
9874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
9884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
9894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* Function to allocate memory for the temporary buffer. This memory is
9904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * allocated from Ashmem. It is the caller's responsibility to free this
9914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * memory.
9924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh */
9934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int get_temp_buffer(const bufferInfo& info, alloc_data& data)
9944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
9954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ALOGD("%s E", __FUNCTION__);
9964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Alloc memory from system heap
9974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    data.base = 0;
9984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    data.fd = -1;
9994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    data.offset = 0;
10004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    data.size = get_size(info);
10014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    data.align = getpagesize();
10024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    data.uncached = true;
10034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int allocFlags = 0;
10044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (sAlloc == 0) {
10064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        sAlloc = gralloc::IAllocController::getInstance();
10074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
10084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (sAlloc == 0) {
10104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: sAlloc is still NULL", __FUNCTION__);
10114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
10124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
10134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int err = sAlloc->allocate(data, allocFlags);
10154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (0 != err) {
10164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: allocate failed", __FUNCTION__);
10174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
10184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
10194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ALOGD("%s X", __FUNCTION__);
10214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return err;
10224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
10234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* Function to free the temporary allocated memory.*/
10254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic void free_temp_buffer(alloc_data &data)
10264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
10274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (-1 != data.fd) {
10284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType);
10294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        memalloc->free_buffer(data.base, data.size, 0, data.fd);
10304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
10314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
10324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/* Function to perform the software color conversion. Convert the
10344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh * C2D compatible format to the Android compatible format
10354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh */
10364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int copy_image(private_handle_t *src_handle,
10374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                      struct copybit_image_t const *rhs,
10384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                      eConversionType conversionType)
10394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
10404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (src_handle->fd == -1) {
10414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: src_handle fd is invalid", __FUNCTION__);
10424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
10434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
10444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Copy the info.
10464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int ret = COPYBIT_SUCCESS;
10474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    switch(rhs->format) {
10484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
10494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
10504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
10514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            {
10524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                if (CONVERT_TO_ANDROID_FORMAT == conversionType) {
10534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                    return convert_yuv_c2d_to_yuv_android(src_handle, rhs);
10544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                } else {
10554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                    return convert_yuv_android_to_yuv_c2d(src_handle, rhs);
10564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                }
10574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            } break;
10594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        default: {
10604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
10614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ret = COPYBIT_FAILURE;
10624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        } break;
10634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
10644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return ret;
10654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
10664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic void delete_handle(private_handle_t *handle)
10684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
10694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (handle) {
10704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        delete handle;
10714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        handle = 0;
10724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
10734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
10744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic bool need_to_execute_draw(eC2DFlags flags)
10764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
10774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (flags & FLAGS_TEMP_SRC_DST) {
10784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return true;
10794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
10804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (flags & FLAGS_YUV_DESTINATION) {
10814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return true;
10824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
10834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return false;
10844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
10854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
10864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/** do a stretch blit type operation */
10874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int stretch_copybit_internal(
10884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_device_t *dev,
10894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_image_t const *dst,
10904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_image_t const *src,
10914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_rect_t const *dst_rect,
10924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_rect_t const *src_rect,
10934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_region_t const *region,
10944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool enableBlend)
10954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
10964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
10974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int status = COPYBIT_SUCCESS;
10984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int flags = 0;
10994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int src_surface_type;
11004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int mapped_src_idx = -1, mapped_dst_idx = -1;
11014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    C2D_OBJECT_STR src_surface;
11024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
11034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (!ctx) {
11044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: null context error", __FUNCTION__);
11054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return -EINVAL;
11064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
11074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
11084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
11094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: src dimension error", __FUNCTION__);
11104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return -EINVAL;
11114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
11124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
11134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
11144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s : dst dimension error dst w %d h %d",  __FUNCTION__, dst->w,
11154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                         dst->h);
11164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return -EINVAL;
11174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
11184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
11194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) {
11204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__,
11214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                              dst->format);
11224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
11234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
11244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
11254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int dst_surface_type;
11264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (ctx->is_dst_ubwc_format)
11274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        flags |= FLAGS_UBWC_FORMAT_MODE;
11284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
11294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
11304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        dst_surface_type = RGB_SURFACE;
11314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        flags |= FLAGS_PREMULTIPLIED_ALPHA;
11324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) {
11334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        int num_planes = get_num_planes(dst->format);
11344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        flags |= FLAGS_YUV_DESTINATION;
11354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (num_planes == 2) {
11364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            dst_surface_type = YUV_SURFACE_2_PLANES;
11374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        } else if (num_planes == 3) {
11384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            dst_surface_type = YUV_SURFACE_3_PLANES;
11394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        } else {
11404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x",
11414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                  __FUNCTION__, dst->format);
11424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return COPYBIT_FAILURE;
11434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
11444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else {
11454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__,
11464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                     dst->format);
11474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
11484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
11494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
11504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (ctx->blit_rgb_count == MAX_RGB_SURFACES ||
11514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_yuv_2_plane_count == MAX_YUV_2_PLANE_SURFACES ||
11524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_yuv_3_plane_count == MAX_YUV_2_PLANE_SURFACES ||
11534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_count == MAX_BLIT_OBJECT_COUNT ||
11544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->dst_surface_type != dst_surface_type) {
11554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // we have reached the max. limits of our internal structures or
11564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // changed the target.
11574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // Draw the remaining surfaces. We need to do the finish here since
11584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // we need to free up the surface templates.
11594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        finish_copybit(dev);
11604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
11614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
11624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->dst_surface_type = dst_surface_type;
11634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
11644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Update the destination
11654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    copybit_image_t dst_image;
11664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    dst_image.w = dst->w;
11674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    dst_image.h = dst->h;
11684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    dst_image.format = dst->format;
11694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    dst_image.handle = dst->handle;
11704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Check if we need a temp. copy for the destination. We'd need this the destination
11714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // width is not aligned to 32. This case occurs for YUV formats. RGB formats are
11724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // aligned to 32.
11734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool need_temp_dst = need_temp_buffer(dst);
11744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bufferInfo dst_info;
11754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    populate_buffer_info(dst, dst_info);
11764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format,
11774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                     dst_info.width, dst_info.height);
11784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (dst_hnd == NULL) {
11794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: dst_hnd is null", __FUNCTION__);
11804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
11814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
11824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (need_temp_dst) {
11834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (get_size(dst_info) != (int) ctx->temp_dst_buffer.size) {
11844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            free_temp_buffer(ctx->temp_dst_buffer);
11854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            // Create a temp buffer and set that as the destination.
11864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) {
11874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                ALOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__);
11884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                delete_handle(dst_hnd);
11894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                return COPYBIT_FAILURE;
11904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            }
11914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
11924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        dst_hnd->fd = ctx->temp_dst_buffer.fd;
11934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        dst_hnd->size = ctx->temp_dst_buffer.size;
11944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        dst_hnd->flags = ctx->temp_dst_buffer.allocType;
11954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        dst_hnd->base = (uintptr_t)(ctx->temp_dst_buffer.base);
11964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        dst_hnd->offset = ctx->temp_dst_buffer.offset;
11974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        dst_hnd->gpuaddr = 0;
11984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        dst_image.handle = dst_hnd;
11994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
12004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(!ctx->dst_surface_mapped) {
12014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        //map the destination surface to GPU address
12024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = set_image(ctx, ctx->dst[ctx->dst_surface_type], &dst_image,
12034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                           (eC2DFlags)flags, mapped_dst_idx);
12044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if(status) {
12054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: dst: set_image error", __FUNCTION__);
12064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            delete_handle(dst_hnd);
12074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            unmap_gpuaddr(ctx, mapped_dst_idx);
12084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return COPYBIT_FAILURE;
12094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
12104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->dst_surface_mapped = true;
12114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->dst_surface_base = dst->base;
12124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else if(ctx->dst_surface_mapped && ctx->dst_surface_base != dst->base) {
12134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // Destination surface for the operation should be same for multiple
12144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // requests, this check is catch if there is any case when the
12154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // destination changes
12164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: a different destination surface!!", __FUNCTION__);
12174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
12184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
12194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Update the source
12204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    flags = 0;
12214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) {
12224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        src_surface_type = RGB_SURFACE;
12234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        src_surface = ctx->blit_rgb_object[ctx->blit_rgb_count];
12244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) {
12254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        int num_planes = get_num_planes(src->format);
12264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (num_planes == 2) {
12274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            src_surface_type = YUV_SURFACE_2_PLANES;
12284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            src_surface = ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count];
12294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        } else if (num_planes == 3) {
12304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            src_surface_type = YUV_SURFACE_3_PLANES;
12314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            src_surface = ctx->blit_yuv_3_plane_object[ctx->blit_yuv_2_plane_count];
12324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        } else {
12334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: src number of YUV planes is invalid src format = 0x%x",
12344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                  __FUNCTION__, src->format);
12354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            delete_handle(dst_hnd);
12364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            unmap_gpuaddr(ctx, mapped_dst_idx);
12374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return -EINVAL;
12384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
12394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else {
12404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__,
12414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                        src->format);
12424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        delete_handle(dst_hnd);
12434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        unmap_gpuaddr(ctx, mapped_dst_idx);
12444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return -EINVAL;
12454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
12464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
12474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    copybit_image_t src_image;
12484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    src_image.w = src->w;
12494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    src_image.h = src->h;
12504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    src_image.format = src->format;
12514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    src_image.handle = src->handle;
12524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
12534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool need_temp_src = need_temp_buffer(src);
12544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bufferInfo src_info;
12554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    populate_buffer_info(src, src_info);
12564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format,
12574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 src_info.width, src_info.height);
12584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (NULL == src_hnd) {
12594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: src_hnd is null", __FUNCTION__);
12604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        delete_handle(dst_hnd);
12614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        unmap_gpuaddr(ctx, mapped_dst_idx);
12624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
12634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
12644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (need_temp_src) {
12654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (get_size(src_info) != (int) ctx->temp_src_buffer.size) {
12664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            free_temp_buffer(ctx->temp_src_buffer);
12674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            // Create a temp buffer and set that as the destination.
12684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if (COPYBIT_SUCCESS != get_temp_buffer(src_info,
12694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                               ctx->temp_src_buffer)) {
12704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__);
12714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                delete_handle(dst_hnd);
12724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                delete_handle(src_hnd);
12734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                unmap_gpuaddr(ctx, mapped_dst_idx);
12744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                return COPYBIT_FAILURE;
12754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            }
12764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
12774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        src_hnd->fd = ctx->temp_src_buffer.fd;
12784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        src_hnd->size = ctx->temp_src_buffer.size;
12794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        src_hnd->flags = ctx->temp_src_buffer.allocType;
12804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        src_hnd->base = (uintptr_t)(ctx->temp_src_buffer.base);
12814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        src_hnd->offset = ctx->temp_src_buffer.offset;
12824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        src_hnd->gpuaddr = 0;
12834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        src_image.handle = src_hnd;
12844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
12854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // Copy the source.
12864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = copy_image((private_handle_t *)src->handle, &src_image,
12874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                CONVERT_TO_C2D_FORMAT);
12884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (status == COPYBIT_FAILURE) {
12894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s:copy_image failed in temp source",__FUNCTION__);
12904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            delete_handle(dst_hnd);
12914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            delete_handle(src_hnd);
12924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            unmap_gpuaddr(ctx, mapped_dst_idx);
12934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return status;
12944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
12954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
12964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // Clean the cache
12974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
12984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
12994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                   src_hnd->offset, src_hnd->fd,
13004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                   gralloc::CACHE_CLEAN)) {
13014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: clean_buffer failed", __FUNCTION__);
13024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            delete_handle(dst_hnd);
13034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            delete_handle(src_hnd);
13044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            unmap_gpuaddr(ctx, mapped_dst_idx);
13054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return COPYBIT_FAILURE;
13064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
13074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
13084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
13094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
13104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
13114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    flags |= (ctx->is_src_ubwc_format) ? FLAGS_UBWC_FORMAT_MODE : 0;
13124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    status = set_image(ctx, src_surface.surface_id, &src_image,
13134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                       (eC2DFlags)flags, mapped_src_idx);
13144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(status) {
13154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: set_image (src) error", __FUNCTION__);
13164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        delete_handle(dst_hnd);
13174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        delete_handle(src_hnd);
13184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        unmap_gpuaddr(ctx, mapped_dst_idx);
13194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        unmap_gpuaddr(ctx, mapped_src_idx);
13204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
13214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
13224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
13234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    src_surface.config_mask = C2D_NO_ANTIALIASING_BIT | ctx->config_mask;
13244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    src_surface.global_alpha = ctx->src_global_alpha;
13254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (enableBlend) {
13264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) {
13274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
13284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            if(!(src_surface.global_alpha)) {
13294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                // src alpha is zero
13304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                delete_handle(dst_hnd);
13314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                delete_handle(src_hnd);
13324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                unmap_gpuaddr(ctx, mapped_dst_idx);
13334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                unmap_gpuaddr(ctx, mapped_src_idx);
13344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                return COPYBIT_FAILURE;
13354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            }
13364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
13374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else {
13384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
13394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
13404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
13414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (src_surface_type == RGB_SURFACE) {
13424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_rgb_object[ctx->blit_rgb_count] = src_surface;
13434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_rgb_count++;
13444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else if (src_surface_type == YUV_SURFACE_2_PLANES) {
13454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count] = src_surface;
13464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_yuv_2_plane_count++;
13474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    } else {
13484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_yuv_3_plane_object[ctx->blit_yuv_3_plane_count] = src_surface;
13494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_yuv_3_plane_count++;
13504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
13514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
13524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_rect_t clip;
13534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    while ((status == 0) && region->next(region, &clip)) {
13544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip);
13554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) {
13564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGW("Reached end of blit count");
13574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            finish_copybit(dev);
13584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
13594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_list[ctx->blit_count] = src_surface;
13604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->blit_count++;
13614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
13624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
13634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Check if we need to perform an early draw-finish.
13644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0;
13654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (need_to_execute_draw((eC2DFlags)flags))
13664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    {
13674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        finish_copybit(dev);
13684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
13694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
13704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (need_temp_dst) {
13714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // copy the temp. destination without the alignment to the actual
13724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // destination.
13734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
13744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (status == COPYBIT_FAILURE) {
13754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__);
13764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            delete_handle(dst_hnd);
13774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            delete_handle(src_hnd);
13784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            unmap_gpuaddr(ctx, mapped_dst_idx);
13794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            unmap_gpuaddr(ctx, mapped_src_idx);
13804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            return status;
13814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
13824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        // Clean the cache.
13834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
13844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
13854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                               dst_hnd->offset, dst_hnd->fd,
13864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                               gralloc::CACHE_CLEAN);
13874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
13884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    delete_handle(dst_hnd);
13894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    delete_handle(src_hnd);
13904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
13914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->is_premultiplied_alpha = false;
13924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->fb_width = 0;
13934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->fb_height = 0;
13944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->config_mask = 0;
13954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return status;
13964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
13974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
13984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int set_sync_copybit(struct copybit_device_t *dev,
13994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int /*acquireFenceFd*/)
14004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
14014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(!dev)
14024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return -EINVAL;
14034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return 0;
14054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
14064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int stretch_copybit(
14084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_device_t *dev,
14094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_image_t const *dst,
14104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_image_t const *src,
14114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_rect_t const *dst_rect,
14124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_rect_t const *src_rect,
14134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_region_t const *region)
14144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
14154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
14164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int status = COPYBIT_SUCCESS;
14174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    bool needsBlending = (ctx->src_global_alpha != 0);
14184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_lock(&ctx->wait_cleanup_lock);
14194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
14204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                    region, needsBlending);
14214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
14224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return status;
14234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
14244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/** Perform a blit type operation */
14264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int blit_copybit(
14274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_device_t *dev,
14284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_image_t const *dst,
14294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_image_t const *src,
14304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_region_t const *region)
14314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
14324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int status = COPYBIT_SUCCESS;
14334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
14344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
14354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
14364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_lock(&ctx->wait_cleanup_lock);
14374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    status = stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false);
14384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
14394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return status;
14404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
14414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/** Fill the rect on dst with RGBA color **/
14434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int fill_color(struct copybit_device_t *dev,
14444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                      struct copybit_image_t const *dst,
14454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                      struct copybit_rect_t const *rect,
14464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                      uint32_t /*color*/)
14474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
14484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // TODO: Implement once c2d driver supports color fill
14494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(!dev || !dst || !rect)
14504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh       return -EINVAL;
14514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return -EINVAL;
14534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
14544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/*****************************************************************************/
14564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic void clean_up(copybit_context_t* ctx)
14584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
14594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    void* ret;
14604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (!ctx)
14614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return;
14624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // stop the wait_cleanup_thread
14644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_lock(&ctx->wait_cleanup_lock);
14654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->stop_thread = true;
14664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Signal waiting thread
14674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_cond_signal(&ctx->wait_cleanup_cond);
14684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
14694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // waits for the cleanup thread to exit
14704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_join(ctx->wait_thread_id, &ret);
14714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_destroy(&ctx->wait_cleanup_lock);
14724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_cond_destroy (&ctx->wait_cleanup_cond);
14734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    for (int i = 0; i < NUM_SURFACE_TYPES; i++) {
14754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (ctx->dst[i])
14764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            LINK_c2dDestroySurface(ctx->dst[i]);
14774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
14784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    for (int i = 0; i < MAX_RGB_SURFACES; i++) {
14804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (ctx->blit_rgb_object[i].surface_id)
14814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id);
14824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
14834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) {
14854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (ctx->blit_yuv_2_plane_object[i].surface_id)
14864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id);
14874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
14884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) {
14904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (ctx->blit_yuv_3_plane_object[i].surface_id)
14914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id);
14924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
14934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (ctx->libc2d2) {
14954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ::dlclose(ctx->libc2d2);
14964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGV("dlclose(libc2d2)");
14974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
14984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
14994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    free(ctx);
15004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
15014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
15024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/** Close the copybit device */
15034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int close_copybit(struct hw_device_t *dev)
15044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
15054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
15064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (ctx) {
15074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        free_temp_buffer(ctx->temp_src_buffer);
15084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        free_temp_buffer(ctx->temp_dst_buffer);
15094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
15104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    clean_up(ctx);
15114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return 0;
15124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
15134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
15144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh/** Open a new instance of a copybit device using name */
15154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanhstatic int open_copybit(const struct hw_module_t* module, const char* name,
15164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                        struct hw_device_t** device)
15174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh{
15184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    int status = COPYBIT_SUCCESS;
15194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
15204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
15214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
15224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
15234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    C2D_RGB_SURFACE_DEF surfDefinition = {0};
15244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
15254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    struct copybit_context_t *ctx;
15264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
15274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
15284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if(!ctx) {
15294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: malloc failed", __FUNCTION__);
15304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return COPYBIT_FAILURE;
15314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
15324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
15334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    /* initialize drawstate */
15344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    memset(ctx, 0, sizeof(*ctx));
15354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
15364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (!ctx->libc2d2) {
15374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
15384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        clean_up(ctx);
15394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = COPYBIT_FAILURE;
15404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        *device = NULL;
15414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return status;
15424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
15434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2,
15444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                               "c2dCreateSurface");
15454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2,
15464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                               "c2dUpdateSurface");
15474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2,
15484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                             "c2dReadSurface");
15494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw");
15504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush");
15514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish");
15524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2,
15534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                               "c2dWaitTimestamp");
15544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2,
15554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                "c2dDestroySurface");
15564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2,
15574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                         "c2dMapAddr");
15584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2,
15594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                           "c2dUnMapAddr");
15604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2,
15614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                           "c2dGetDriverCapabilities");
15624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
15634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                           "c2dCreateFenceFD");
15644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2,
15654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                           "c2dFillSurface");
15664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
15674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
15684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
15694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
15704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD ||
15714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        !LINK_c2dFillSurface) {
15724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: dlsym ERROR", __FUNCTION__);
15734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        clean_up(ctx);
15744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = COPYBIT_FAILURE;
15754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        *device = NULL;
15764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return status;
15774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
15784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
15794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
15804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.common.version = 1;
15814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.common.module = (hw_module_t*)(module);
15824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.common.close = close_copybit;
15834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.set_parameter = set_parameter_copybit;
15844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.get = get;
15854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.blit = blit_copybit;
15864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.set_sync = set_sync_copybit;
15874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.stretch = stretch_copybit;
15884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.finish = finish_copybit;
15894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.flush_get_fence = flush_get_fence_copybit;
15904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.clear = clear_copybit;
15914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->device.fill_color = fill_color;
15924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
15934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    /* Create RGB Surface */
15944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    surfDefinition.buffer = (void*)0xdddddddd;
15954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    surfDefinition.phys = (void*)0xdddddddd;
15964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    surfDefinition.stride = 1 * 4;
15974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    surfDefinition.width = 1;
15984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    surfDefinition.height = 1;
15994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB;
16004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
16014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
16024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 C2D_SURFACE_WITH_PHYS |
16034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
16044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 &surfDefinition)) {
16054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__);
16064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->dst[RGB_SURFACE] = 0;
16074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        clean_up(ctx);
16084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = COPYBIT_FAILURE;
16094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        *device = NULL;
16104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return status;
16114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
16124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
16134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    unsigned int surface_id = 0;
16144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    for (int i = 0; i < MAX_RGB_SURFACES; i++)
16154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    {
16164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
16174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
16184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 C2D_SURFACE_WITH_PHYS |
16194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
16204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 &surfDefinition)) {
16214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i);
16224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->blit_rgb_object[i].surface_id = 0;
16234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            status = COPYBIT_FAILURE;
16244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
16254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        } else {
16264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->blit_rgb_object[i].surface_id = surface_id;
16274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGW("%s i = %d surface_id=%d",  __FUNCTION__, i,
16284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                          ctx->blit_rgb_object[i].surface_id);
16294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
16304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
16314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
16324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (status == COPYBIT_FAILURE) {
16334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        clean_up(ctx);
16344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = COPYBIT_FAILURE;
16354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        *device = NULL;
16364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return status;
16374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
16384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
16394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Create 2 plane YUV surfaces
16404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
16414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.width = 4;
16424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.height = 4;
16434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa;
16444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa;
16454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.stride0 = 4;
16464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
16474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa;
16484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa;
16494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.stride1 = 4;
16504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),
16514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              C2D_TARGET | C2D_SOURCE,
16524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
16534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                               C2D_SURFACE_WITH_PHYS |
16544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                               C2D_SURFACE_WITH_PHYS_DUMMY),
16554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              &yuvSurfaceDef)) {
16564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
16574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->dst[YUV_SURFACE_2_PLANES] = 0;
16584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        clean_up(ctx);
16594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = COPYBIT_FAILURE;
16604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        *device = NULL;
16614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return status;
16624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
16634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
16644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++)
16654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    {
16664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
16674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
16684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 C2D_SURFACE_WITH_PHYS |
16694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
16704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              &yuvSurfaceDef)) {
16714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: create YUV source %d failed", __FUNCTION__, i);
16724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->blit_yuv_2_plane_object[i].surface_id = 0;
16734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            status = COPYBIT_FAILURE;
16744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
16754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        } else {
16764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->blit_yuv_2_plane_object[i].surface_id = surface_id;
16774a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGW("%s: 2 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
16784a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                   ctx->blit_yuv_2_plane_object[i].surface_id);
16794a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
16804a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
16814a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
16824a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (status == COPYBIT_FAILURE) {
16834a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        clean_up(ctx);
16844a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = COPYBIT_FAILURE;
16854a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        *device = NULL;
16864a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return status;
16874a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
16884a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
16894a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Create YUV 3 plane surfaces
16904a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
16914a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
16924a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
16934a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    yuvSurfaceDef.stride2 = 4;
16944a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
16954a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),
16964a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              C2D_TARGET | C2D_SOURCE,
16974a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
16984a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 C2D_SURFACE_WITH_PHYS |
16994a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
17004a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              &yuvSurfaceDef)) {
17014a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
17024a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        ctx->dst[YUV_SURFACE_3_PLANES] = 0;
17034a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        clean_up(ctx);
17044a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = COPYBIT_FAILURE;
17054a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        *device = NULL;
17064a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return status;
17074a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
17084a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
17094a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++)
17104a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    {
17114a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        if (LINK_c2dCreateSurface(&(surface_id),
17124a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              C2D_TARGET | C2D_SOURCE,
17134a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
17144a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 C2D_SURFACE_WITH_PHYS |
17154a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
17164a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                              &yuvSurfaceDef)) {
17174a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i);
17184a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->blit_yuv_3_plane_object[i].surface_id = 0;
17194a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            status = COPYBIT_FAILURE;
17204a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            break;
17214a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        } else {
17224a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ctx->blit_yuv_3_plane_object[i].surface_id = surface_id;
17234a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh            ALOGW("%s: 3 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
17244a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                   ctx->blit_yuv_3_plane_object[i].surface_id);
17254a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        }
17264a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
17274a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
17284a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (status == COPYBIT_FAILURE) {
17294a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        clean_up(ctx);
17304a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        status = COPYBIT_FAILURE;
17314a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        *device = NULL;
17324a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return status;
17334a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
17344a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
17354a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) {
17364a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh         ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__);
17374a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh         clean_up(ctx);
17384a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh         status = COPYBIT_FAILURE;
17394a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        *device = NULL;
17404a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh        return status;
17414a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    }
17424a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    // Initialize context variables.
17434a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->trg_transform = C2D_TARGET_ROTATE_0;
17444a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
17454a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->temp_src_buffer.fd = -1;
17464a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->temp_src_buffer.base = 0;
17474a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->temp_src_buffer.size = 0;
17484a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
17494a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->temp_dst_buffer.fd = -1;
17504a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->temp_dst_buffer.base = 0;
17514a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->temp_dst_buffer.size = 0;
17524a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
17534a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->fb_width = 0;
17544a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->fb_height = 0;
17554a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
17564a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->blit_rgb_count = 0;
17574a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->blit_yuv_2_plane_count = 0;
17584a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->blit_yuv_3_plane_count = 0;
17594a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->blit_count = 0;
17604a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
17614a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->wait_timestamp = false;
17624a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    ctx->stop_thread = false;
17634a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL);
17644a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_cond_init(&(ctx->wait_cleanup_cond), NULL);
17654a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    /* Start the wait thread */
17664a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_attr_t attr;
17674a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_attr_init(&attr);
17684a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
17694a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
17704a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop,
17714a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh                                                            (void *)ctx);
17724a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    pthread_attr_destroy(&attr);
17734a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh
17744a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    *device = &ctx->device.common;
17754a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh    return status;
17764a1efd0680d2e9b61739e1eaeffd89174d6d2605Alain Vongsouvanh}
1777