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