12ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* 22ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Copyright (C) 2008 The Android Open Source Project 32ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Copyright (c) 2010-2015, The Linux Foundation. All rights reserved. 42ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * 52ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Not a Contribution, Apache license notifications and license are retained 62ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * for attribution purposes only. 72ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * 82ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Licensed under the Apache License, Version 2.0 (the "License"); 92ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * you may not use this file except in compliance with the License. 102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * You may obtain a copy of the License at 112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * 122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * http://www.apache.org/licenses/LICENSE-2.0 132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * 142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Unless required by applicable law or agreed to in writing, software 152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * distributed under the License is distributed on an "AS IS" BASIS, 162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * See the License for the specific language governing permissions and 182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * limitations under the License. 192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel */ 202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <cutils/log.h> 212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <sys/resource.h> 222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <sys/prctl.h> 232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <stdint.h> 252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <string.h> 262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <unistd.h> 272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <errno.h> 282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <fcntl.h> 292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <sys/ioctl.h> 312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <sys/types.h> 322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <sys/mman.h> 332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <linux/msm_kgsl.h> 352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <EGL/eglplatform.h> 372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <cutils/native_handle.h> 382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <copybit.h> 402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <alloc_controller.h> 412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <memalloc.h> 422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "c2d2.h" 442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include "software_converter.h" 452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#include <dlfcn.h> 472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelusing gralloc::IMemAlloc; 492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelusing gralloc::IonController; 502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelusing gralloc::alloc_data; 512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id, 532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel uint32 surface_bits, 542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_TYPE surface_type, 552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel void *surface_definition ); 562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id, 582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel uint32 surface_bits, 592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_TYPE surface_type, 602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel void *surface_definition ); 612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id, 632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_TYPE surface_type, 642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel void *surface_definition, 652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int32 x, int32 y ); 662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dDraw)( uint32 target_id, 682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel uint32 target_config, C2D_RECT *target_scissor, 692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel uint32 target_mask_id, uint32 target_color_key, 702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_OBJECT *objects_list, uint32 num_objects ); 712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dFinish)( uint32 target_id); 732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp); 752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp ); 772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id ); 792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, size_t len, 812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel size_t offset, uint32 flags, void ** gpuaddr); 822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr); 842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info); 862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* create a fence fd for the timestamp */ 882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp, 892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int32 *fd); 902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry StrudelC2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color, 922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_RECT * fill_rect); 932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/******************************************************************************/ 952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#if defined(COPYBIT_Z180) 972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define MAX_SCALE_FACTOR (4096) 982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define MAX_DIMENSION (4096) 992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#else 1002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#error "Unsupported HW version" 1012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#endif 1022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel// The following defines can be changed as required i.e. as we encounter 1042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel// complex use cases. 1052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define MAX_RGB_SURFACES 32 // Max. RGB layers currently supported per draw 1062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw 1072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw 1082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel// +1 for the destination surface. We cannot have multiple destination surfaces. 1092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1) 1102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define NUM_SURFACE_TYPES 3 // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES 1112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel#define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw 1122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelenum { 1142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel RGB_SURFACE, 1152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel YUV_SURFACE_2_PLANES, 1162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel YUV_SURFACE_3_PLANES 1172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}; 1182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelenum eConversionType { 1202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel CONVERT_TO_ANDROID_FORMAT, 1212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel CONVERT_TO_C2D_FORMAT 1222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}; 1232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelenum eC2DFlags { 1252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel FLAGS_PREMULTIPLIED_ALPHA = 1<<0, 1262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel FLAGS_YUV_DESTINATION = 1<<1, 1272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel FLAGS_TEMP_SRC_DST = 1<<2, 1282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel FLAGS_UBWC_FORMAT_MODE = 1<<3 1292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}; 1302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic gralloc::IAllocController* sAlloc = 0; 1322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/******************************************************************************/ 1332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** State information for each device instance */ 1352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstruct copybit_context_t { 1362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_device_t device; 1372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Templates for the various source surfaces. These templates are created 1382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // to avoid the expensive create/destroy C2D Surfaces 1392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES]; 1402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES]; 1412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES]; 1422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects 1432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_DRIVER_INFO c2d_driver_info; 1442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel void *libc2d2; 1452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel alloc_data temp_src_buffer; 1462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel alloc_data temp_dst_buffer; 1472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces 1482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel uintptr_t mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit 1492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int blit_rgb_count; // Total RGB surfaces being blit 1502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being 1512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int blit_yuv_3_plane_count; // Total 3 plane YUV surfaces being blit 1522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int blit_count; // Total blit objects. 1532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unsigned int trg_transform; /* target transform */ 1542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int fb_width; 1552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int fb_height; 1562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int src_global_alpha; 1572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int config_mask; 1582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int dst_surface_type; 1592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bool is_premultiplied_alpha; 1602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel void* time_stamp; 1612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr 1622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel void* dst_surface_base; // Stores the dst surface addr 1632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bool is_src_ubwc_format; 1642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bool is_dst_ubwc_format; 1652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // used for signaling the wait thread 1672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bool wait_timestamp; 1682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_t wait_thread_id; 1692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bool stop_thread; 1702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_t wait_cleanup_lock; 1712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_cond_t wait_cleanup_cond; 1722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}; 1742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstruct bufferInfo { 1762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int width; 1772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int height; 1782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int format; 1792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}; 1802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstruct yuvPlaneInfo { 1822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int yStride; //luma stride 1832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int plane1_stride; 1842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int plane2_stride; 1852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel size_t plane1_offset; 1862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel size_t plane2_offset; 1872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}; 1882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** 1902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * Common hardware methods 1912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel */ 1922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int open_copybit(const struct hw_module_t* module, const char* name, 1942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct hw_device_t** device); 1952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 1962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic struct hw_module_methods_t copybit_module_methods = { 1972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel .open = open_copybit, 1982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}; 1992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 2002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* 2012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * The COPYBIT Module 2022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel */ 2032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstruct copybit_module_t HAL_MODULE_INFO_SYM = { 2042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel .common = { 2052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel .tag = HARDWARE_MODULE_TAG, 2062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel .version_major = 1, 2072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel .version_minor = 0, 2082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel .id = COPYBIT_HARDWARE_MODULE_ID, 2092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel .name = "QCT COPYBIT C2D 2.0 Module", 2102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel .author = "Qualcomm", 2112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel .methods = ©bit_module_methods 2122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 2132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel}; 2142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 2152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 2162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* thread function which waits on the timeStamp and cleans up the surfaces */ 2172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic void* c2d_wait_loop(void* ptr) { 2182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel copybit_context_t* ctx = (copybit_context_t*)(ptr); 2192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel char thread_name[64] = "copybitWaitThr"; 2202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0); 2212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY); 2222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 2232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel while(ctx->stop_thread == false) { 2242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_lock(&ctx->wait_cleanup_lock); 2252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel while(ctx->wait_timestamp == false && !ctx->stop_thread) { 2262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_cond_wait(&(ctx->wait_cleanup_cond), 2272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel &(ctx->wait_cleanup_lock)); 2282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 2292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(ctx->wait_timestamp) { 2302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(LINK_c2dWaitTimestamp(ctx->time_stamp)) { 2312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__); 2322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 2332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->wait_timestamp = false; 2342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Unmap any mapped addresses. 2352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel for (int i = 0; i < MAX_SURFACES; i++) { 2362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->mapped_gpu_addr[i]) { 2372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]); 2382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->mapped_gpu_addr[i] = 0; 2392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 2402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 2412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Reset the counts after the draw. 2422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_rgb_count = 0; 2432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_2_plane_count = 0; 2442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_3_plane_count = 0; 2452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_count = 0; 2462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst_surface_mapped = false; 2472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst_surface_base = 0; 2482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 2492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_unlock(&ctx->wait_cleanup_lock); 2502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(ctx->stop_thread) 2512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 2522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 2532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_exit(NULL); 2542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return NULL; 2552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 2562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 2572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 2582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* convert COPYBIT_FORMAT to C2D format */ 2592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int get_format(int format) { 2602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel switch (format) { 2612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGB_565: return C2D_COLOR_FORMAT_565_RGB; 2622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGB_888: return C2D_COLOR_FORMAT_888_RGB | 2632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_FORMAT_SWAP_RB; 2642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGBX_8888: return C2D_COLOR_FORMAT_8888_ARGB | 2652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_FORMAT_SWAP_RB | 2662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_FORMAT_DISABLE_ALPHA; 2672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGBA_8888: return C2D_COLOR_FORMAT_8888_ARGB | 2682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_FORMAT_SWAP_RB; 2692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_BGRA_8888: return C2D_COLOR_FORMAT_8888_ARGB; 2702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGBA_5551: return C2D_COLOR_FORMAT_5551_RGBA; 2712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGBA_4444: return C2D_COLOR_FORMAT_4444_RGBA; 2722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCbCr_420_SP: return C2D_COLOR_FORMAT_420_NV12; 2732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12; 2742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCrCb_420_SP: return C2D_COLOR_FORMAT_420_NV21; 2752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 | 2762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_FORMAT_MACROTILED; 2772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel default: ALOGE("%s: invalid format (0x%x", 2782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel __FUNCTION__, format); 2792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 2802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 2812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 2822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 2832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 2842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* Get the C2D formats needed for conversion to YUV */ 2852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int get_c2d_format_for_yuv_destination(int halFormat) { 2862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel switch (halFormat) { 2872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // We do not swap the RB when the target is YUV 2882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGBX_8888: return C2D_COLOR_FORMAT_8888_ARGB | 2892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_FORMAT_DISABLE_ALPHA; 2902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGBA_8888: return C2D_COLOR_FORMAT_8888_ARGB; 2912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // The U and V need to be interchanged when the target is YUV 2922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCbCr_420_SP: return C2D_COLOR_FORMAT_420_NV21; 2932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21; 2942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCrCb_420_SP: return C2D_COLOR_FORMAT_420_NV12; 2952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel default: return get_format(halFormat); 2962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 2972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 2982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 2992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* ------------------------------------------------------------------- *//*! 3012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * \internal 3022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * \brief Get the bpp for a particular color format 3032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * \param color format 3042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * \return bits per pixel 3052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *//* ------------------------------------------------------------------- */ 3062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelint c2diGetBpp(int32 colorformat) 3072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 3082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int c2dBpp = 0; 3102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel switch(colorformat&0xFF) 3122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 3132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_4444_RGBA: 3142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_4444_ARGB: 3152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_1555_ARGB: 3162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_565_RGB: 3172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_5551_RGBA: 3182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dBpp = 16; 3192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 3202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_8888_RGBA: 3212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_8888_ARGB: 3222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dBpp = 32; 3232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 3242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_888_RGB: 3252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dBpp = 24; 3262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 3272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_8_L: 3282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_8_A: 3292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dBpp = 8; 3302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 3312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_4_A: 3322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dBpp = 4; 3332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 3342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case C2D_COLOR_FORMAT_1: 3352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dBpp = 1; 3362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 3372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel default: 3382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s ERROR", __func__); 3392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 3402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 3412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return c2dBpp; 3422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 3432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic size_t c2d_get_gpuaddr(copybit_context_t* ctx, 3452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct private_handle_t *handle, int &mapped_idx) 3462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 3472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel uint32 memtype; 3482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel size_t *gpuaddr = 0; 3492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_STATUS rc; 3502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int freeindex = 0; 3512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bool mapaddr = false; 3522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(!handle) 3542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return 0; 3552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION) 3572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel memtype = KGSL_USER_MEM_TYPE_ION; 3582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel else { 3592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("Invalid handle flags: 0x%x", handle->flags); 3602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return 0; 3612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 3622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Check for a freeindex in the mapped_gpu_addr list 3642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel for (freeindex = 0; freeindex < MAX_SURFACES; freeindex++) { 3652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->mapped_gpu_addr[freeindex] == 0) { 3662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // free index is available 3672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // map GPU addr and use this as mapped_idx 3682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel mapaddr = true; 3692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 3702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 3712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 3722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(mapaddr) { 3742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size, 3752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel handle->offset, memtype, (void**)&gpuaddr); 3762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (rc == C2D_STATUS_OK) { 3782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // We have mapped the GPU address inside copybit. We need to unmap 3792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // this address after the blit. Store this address 3802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->mapped_gpu_addr[freeindex] = (size_t)gpuaddr; 3812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel mapped_idx = freeindex; 3822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 3832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 3842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return (size_t)gpuaddr; 3852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 3862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx) 3882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 3892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (!ctx || (mapped_idx == -1)) 3902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return; 3912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->mapped_gpu_addr[mapped_idx]) { 3932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]); 3942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->mapped_gpu_addr[mapped_idx] = 0; 3952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 3962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 3972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 3982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int is_supported_rgb_format(int format) 3992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 4002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel switch(format) { 4012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGBA_8888: 4022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGBX_8888: 4032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGB_888: 4042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGB_565: 4052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_BGRA_8888: 4062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGBA_5551: 4072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_RGBA_4444: { 4082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_SUCCESS; 4092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel default: 4112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 4122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 4142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 4152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int get_num_planes(int format) 4162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 4172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel switch(format) { 4182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCbCr_420_SP: 4192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCrCb_420_SP: 4202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 4212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: { 4222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return 2; 4232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YV12: { 4252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return 3; 4262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel default: 4282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 4292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 4312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 4322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int is_supported_yuv_format(int format) 4332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 4342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel switch(format) { 4352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCbCr_420_SP: 4362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCrCb_420_SP: 4372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 4382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: { 4392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_SUCCESS; 4402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel default: 4422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 4432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 4452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 4462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int is_valid_destination_format(int format) 4472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 4482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) { 4492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // C2D does not support NV12Tile as a destination format. 4502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 4512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_SUCCESS; 4532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 4542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 4552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int calculate_yuv_offset_and_stride(const bufferInfo& info, 4562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvPlaneInfo& yuvInfo) 4572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 4582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int width = info.width; 4592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int height = info.height; 4602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int format = info.format; 4612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 4622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int aligned_height = 0; 4632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int aligned_width = 0, size = 0; 4642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 4652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel switch (format) { 4662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: { 4672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel /* NV12 Tile buffers have their luma height aligned to 32bytes and width 4682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * aligned to 128 bytes. The chroma offset starts at an 8K boundary 4692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel */ 4702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel aligned_height = ALIGN(height, 32); 4712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel aligned_width = ALIGN(width, 128); 4722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel size = aligned_width * aligned_height; 4732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvInfo.plane1_offset = ALIGN(size,8192); 4742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvInfo.yStride = aligned_width; 4752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvInfo.plane1_stride = aligned_width; 4762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 4772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCbCr_420_SP: 4792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 4802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCrCb_420_SP: { 4812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel aligned_width = ALIGN(width, 32); 4822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvInfo.yStride = aligned_width; 4832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvInfo.plane1_stride = aligned_width; 4842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) { 4852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // The encoder requires a 2K aligned chroma offset 4862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048); 4872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else 4882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvInfo.plane1_offset = aligned_width * height; 4892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 4902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 4912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel default: { 4932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 4942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 4962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_SUCCESS; 4972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 4982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 4992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** create C2D surface from copybit image */ 5002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int set_image(copybit_context_t* ctx, uint32 surfaceId, 5012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel const struct copybit_image_t *rhs, 5022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel const eC2DFlags flags, int &mapped_idx) 5032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 5042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct private_handle_t* handle = (struct private_handle_t*)rhs->handle; 5052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_TYPE surfaceType; 5062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int status = COPYBIT_SUCCESS; 5072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel uint64_t gpuaddr = 0; 5082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int c2d_format; 5092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel mapped_idx = -1; 5102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (flags & FLAGS_YUV_DESTINATION) { 5122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2d_format = get_c2d_format_for_yuv_destination(rhs->format); 5132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 5142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2d_format = get_format(rhs->format); 5152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 5162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(c2d_format == -EINVAL) { 5182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: invalid format", __FUNCTION__); 5192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 5202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 5212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(handle == NULL) { 5232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: invalid handle", __func__); 5242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 5252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 5262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (handle->gpuaddr == 0) { 5282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx); 5292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(!gpuaddr) { 5302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__); 5312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 5322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 5332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 5342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel gpuaddr = handle->gpuaddr; 5352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 5362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel /* create C2D surface */ 5382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) { 5392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel /* RGB */ 5402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_RGB_SURFACE_DEF surfaceDef; 5412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS); 5432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.phys = (void*) gpuaddr; 5452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.buffer = (void*) (handle->base); 5462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.format = c2d_format | 5482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0); 5492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.format = surfaceDef.format | 5512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ((flags & FLAGS_UBWC_FORMAT_MODE) ? C2D_FORMAT_UBWC_COMPRESSED : 0); 5522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.width = rhs->w; 5542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.height = rhs->h; 5552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int aligned_width = ALIGN((int)surfaceDef.width,32); 5562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3; 5572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType, 5592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel &surfaceDef)) { 5602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__); 5612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_idx); 5622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 5632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 5642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) { 5652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_YUV_SURFACE_DEF surfaceDef; 5662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel memset(&surfaceDef, 0, sizeof(surfaceDef)); 5672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS); 5682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.format = c2d_format; 5692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bufferInfo info; 5712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel info.width = rhs->w; 5722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel info.height = rhs->h; 5732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel info.format = rhs->format; 5742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvPlaneInfo yuvInfo = {0}; 5762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = calculate_yuv_offset_and_stride(info, yuvInfo); 5772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(status != COPYBIT_SUCCESS) { 5782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__); 5792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_idx); 5802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 5812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.width = rhs->w; 5832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.height = rhs->h; 5842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.plane0 = (void*) (handle->base); 5852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.phys0 = (void*) (gpuaddr); 5862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.stride0 = yuvInfo.yStride; 5872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset); 5892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset); 5902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.stride1 = yuvInfo.plane1_stride; 5912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (3 == get_num_planes(rhs->format)) { 5922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset); 5932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset); 5942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfaceDef.stride2 = yuvInfo.plane2_stride; 5952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 5962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 5972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType, 5982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel &surfaceDef)) { 5992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__); 6002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_idx); 6012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 6022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 6042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format); 6052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_idx); 6062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 6072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 6102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 6112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** copy the bits */ 6132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int msm_copybit(struct copybit_context_t *ctx, unsigned int target) 6142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 6152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->blit_count == 0) { 6162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_SUCCESS; 6172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel for (int i = 0; i < ctx->blit_count; i++) 6202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 6212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_list[i].next = &(ctx->blit_list[i+1]); 6222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_list[ctx->blit_count-1].next = NULL; 6242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel uint32_t target_transform = ctx->trg_transform; 6252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->c2d_driver_info.capabilities_mask & 6262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) { 6272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // For A3xx - set 0x0 as the transform is set in the config_mask 6282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel target_transform = 0x0; 6292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(LINK_c2dDraw(target, target_transform, 0x0, 0, 0, ctx->blit_list, 6312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_count)) { 6322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__); 6332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 6342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_SUCCESS; 6362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 6372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd) 6412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 6422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 6432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int status = COPYBIT_FAILURE; 6442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (!ctx) 6452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 6462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_lock(&ctx->wait_cleanup_lock); 6472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]); 6482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) { 6502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__); 6512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // unlock the mutex and return failure 6522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_unlock(&ctx->wait_cleanup_lock); 6532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 6542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp, 6562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel fd)) { 6572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__); 6582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 6592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(status == COPYBIT_SUCCESS) { 6612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel //signal the wait_thread 6622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->wait_timestamp = true; 6632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_cond_signal(&ctx->wait_cleanup_cond); 6642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_unlock(&ctx->wait_cleanup_lock); 6662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 6672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 6682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int finish_copybit(struct copybit_device_t *dev) 6702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 6712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 6722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (!ctx) 6732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 6742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]); 6762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) { 6782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__); 6792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 6802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Unmap any mapped addresses. 6832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel for (int i = 0; i < MAX_SURFACES; i++) { 6842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->mapped_gpu_addr[i]) { 6852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]); 6862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->mapped_gpu_addr[i] = 0; 6872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 6892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Reset the counts after the draw. 6912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_rgb_count = 0; 6922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_2_plane_count = 0; 6932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_3_plane_count = 0; 6942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_count = 0; 6952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst_surface_mapped = false; 6962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst_surface_base = 0; 6972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 6982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 6992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 7002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 7012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int clear_copybit(struct copybit_device_t *dev, 7022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_image_t const *buf, 7032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_rect_t *rect) 7042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 7052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int ret = COPYBIT_SUCCESS; 7062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int flags = FLAGS_PREMULTIPLIED_ALPHA; 7072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int mapped_dst_idx = -1; 7082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 7092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->is_dst_ubwc_format) 7102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel flags |= FLAGS_UBWC_FORMAT_MODE; 7112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t}; 7122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_lock(&ctx->wait_cleanup_lock); 7132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(!ctx->dst_surface_mapped) { 7142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf, 7152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (eC2DFlags)flags, mapped_dst_idx); 7162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(ret) { 7172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: set_image error", __FUNCTION__); 7182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_dst_idx); 7192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_unlock(&ctx->wait_cleanup_lock); 7202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 7212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 7222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel //clear_copybit is the first call made by HWC for each composition 7232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel //with the dest surface, hence set dst_surface_mapped. 7242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst_surface_mapped = true; 7252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst_surface_base = buf->base; 7262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect); 7272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 7282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_unlock(&ctx->wait_cleanup_lock); 7292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return ret; 7302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 7312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 7322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 7332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** setup rectangles */ 7342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic void set_rects(struct copybit_context_t *ctx, 7352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_OBJECT *c2dObject, 7362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel const struct copybit_rect_t *dst, 7372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel const struct copybit_rect_t *src, 7382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel const struct copybit_rect_t *scissor) 7392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 7402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Set the target rect. 7412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if((ctx->trg_transform & C2D_TARGET_ROTATE_90) && 7422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (ctx->trg_transform & C2D_TARGET_ROTATE_180)) { 7432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel /* target rotation is 270 */ 7442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.x = (dst->t)<<16; 7452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.y = ctx->fb_width? 7462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (ALIGN(ctx->fb_width,32)- dst->r):dst->r; 7472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.y = c2dObject->target_rect.y<<16; 7482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.height = ((dst->r) - (dst->l))<<16; 7492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.width = ((dst->b) - (dst->t))<<16; 7502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) { 7512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.x = ctx->fb_height?(ctx->fb_height - dst->b):dst->b; 7522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.x = c2dObject->target_rect.x<<16; 7532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.y = (dst->l)<<16; 7542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.height = ((dst->r) - (dst->l))<<16; 7552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.width = ((dst->b) - (dst->t))<<16; 7562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) { 7572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.y = ctx->fb_height?(ctx->fb_height - dst->b):dst->b; 7582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.y = c2dObject->target_rect.y<<16; 7592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.x = ctx->fb_width? 7602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (ALIGN(ctx->fb_width,32) - dst->r):dst->r; 7612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.x = c2dObject->target_rect.x<<16; 7622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.height = ((dst->b) - (dst->t))<<16; 7632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.width = ((dst->r) - (dst->l))<<16; 7642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 7652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.x = (dst->l)<<16; 7662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.y = (dst->t)<<16; 7672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.height = ((dst->b) - (dst->t))<<16; 7682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->target_rect.width = ((dst->r) - (dst->l))<<16; 7692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 7702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->config_mask |= C2D_TARGET_RECT_BIT; 7712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 7722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Set the source rect 7732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->source_rect.x = (src->l)<<16; 7742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->source_rect.y = (src->t)<<16; 7752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->source_rect.height = ((src->b) - (src->t))<<16; 7762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->source_rect.width = ((src->r) - (src->l))<<16; 7772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->config_mask |= C2D_SOURCE_RECT_BIT; 7782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 7792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Set the scissor rect 7802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->scissor_rect.x = scissor->l; 7812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->scissor_rect.y = scissor->t; 7822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->scissor_rect.height = (scissor->b) - (scissor->t); 7832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->scissor_rect.width = (scissor->r) - (scissor->l); 7842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT; 7852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 7862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 7872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/*****************************************************************************/ 7882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 7892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** Set a parameter to value */ 7902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int set_parameter_copybit( 7912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_device_t *dev, 7922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int name, 7932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int value) 7942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 7952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 7962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int status = COPYBIT_SUCCESS; 7972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (!ctx) { 7982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: null context", __FUNCTION__); 7992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 8002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 8012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 8022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_lock(&ctx->wait_cleanup_lock); 8032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel switch(name) { 8042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_PLANE_ALPHA: 8052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 8062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (value < 0) value = 0; 8072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (value >= 256) value = 255; 8082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 8092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->src_global_alpha = value; 8102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (value < 255) 8112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT; 8122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel else 8132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT; 8142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 8152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 8162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_BLEND_MODE: 8172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 8182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (value == COPYBIT_BLENDING_NONE) { 8192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->config_mask |= C2D_ALPHA_BLEND_NONE; 8202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->is_premultiplied_alpha = true; 8212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if (value == COPYBIT_BLENDING_PREMULT) { 8222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->is_premultiplied_alpha = true; 8232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 8242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE; 8252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 8262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 8272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 8282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_TRANSFORM: 8292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 8302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unsigned int transform = 0; 8312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel uint32 config_mask = 0; 8322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG; 8332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) { 8342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel transform = C2D_TARGET_ROTATE_180; 8352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180; 8362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) { 8372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel transform = C2D_TARGET_ROTATE_90; 8382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90; 8392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if(value == COPYBIT_TRANSFORM_ROT_90) { 8402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel transform = C2D_TARGET_ROTATE_270; 8412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270; 8422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 8432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0; 8442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(value & COPYBIT_TRANSFORM_FLIP_H) { 8452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel config_mask |= C2D_MIRROR_H_BIT; 8462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if(value & COPYBIT_TRANSFORM_FLIP_V) { 8472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel config_mask |= C2D_MIRROR_V_BIT; 8482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 8492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 8502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 8512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->c2d_driver_info.capabilities_mask & 8522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) { 8532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->config_mask |= config_mask; 8542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 8552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // The transform for this surface does not match the current 8562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // target transform. Draw all previous surfaces. This will be 8572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // changed once we have a new mechanism to send different 8582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // target rotations to c2d. 8592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel finish_copybit(dev); 8602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 8612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->trg_transform = transform; 8622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 8632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 8642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_FRAMEBUFFER_WIDTH: 8652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->fb_width = value; 8662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 8672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_FRAMEBUFFER_HEIGHT: 8682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->fb_height = value; 8692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 8702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_ROTATION_DEG: 8712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_DITHER: 8722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_BLUR: 8732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_BLIT_TO_FRAMEBUFFER: 8742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Do nothing 8752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 8762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_SRC_FORMAT_MODE: 8772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->is_src_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED); 8782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 8792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_DST_FORMAT_MODE: 8802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->is_dst_ubwc_format = (value == COPYBIT_UBWC_COMPRESSED); 8812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 8822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel default: 8832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: default case param=0x%x", __FUNCTION__, name); 8842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = -EINVAL; 8852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 8862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 8872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_unlock(&ctx->wait_cleanup_lock); 8882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 8892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 8902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 8912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** Get a static info value */ 8922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int get(struct copybit_device_t *dev, int name) 8932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 8942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 8952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int value; 8962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 8972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (!ctx) { 8982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: null context error", __FUNCTION__); 8992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 9002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 9012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 9022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel switch(name) { 9032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_MINIFICATION_LIMIT: 9042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel value = MAX_SCALE_FACTOR; 9052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 9062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_MAGNIFICATION_LIMIT: 9072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel value = MAX_SCALE_FACTOR; 9082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 9092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_SCALING_FRAC_BITS: 9102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel value = 32; 9112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 9122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_ROTATION_STEP_DEG: 9132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel value = 1; 9142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 9152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case COPYBIT_UBWC_SUPPORT: 9162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel value = 0; 9172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->c2d_driver_info.capabilities_mask & C2D_DRIVER_SUPPORTS_UBWC_COMPRESSED_OP) { 9182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel value = 1; 9192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 9202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 9212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel default: 9222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: default case param=0x%x", __FUNCTION__, name); 9232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel value = -EINVAL; 9242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 9252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return value; 9262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 9272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 9282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* Function to check if we need a temporary buffer for the blit. 9292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * This would happen if the requested destination stride and the 9302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * C2D stride do not match. We ignore RGB buffers, since their 9312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * stride is always aligned to 32. 9322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel */ 9332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic bool need_temp_buffer(struct copybit_image_t const *img) 9342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 9352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format)) 9362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return false; 9372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 9382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct private_handle_t* handle = (struct private_handle_t*)img->handle; 9392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 9402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // The width parameter in the handle contains the aligned_w. We check if we 9412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // need to convert based on this param. YUV formats have bpp=1, so checking 9422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // if the requested stride is aligned should suffice. 9432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (0 == (handle->width)%32) { 9442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return false; 9452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 9462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 9472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return true; 9482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 9492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 9502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* Function to extract the information from the copybit image and set the corresponding 9512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * values in the bufferInfo struct. 9522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel */ 9532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info) 9542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 9552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel info.width = img->w; 9562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel info.height = img->h; 9572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel info.format = img->format; 9582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 9592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 9602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* Function to get the required size for a particular format, inorder for C2D to perform 9612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * the blit operation. 9622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel */ 9632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int get_size(const bufferInfo& info) 9642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 9652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int size = 0; 9662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int w = info.width; 9672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int h = info.height; 9682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int aligned_w = ALIGN(w, 32); 9692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel switch(info.format) { 9702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 9712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 9722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Chroma for this format is aligned to 2K. 9732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel size = ALIGN((aligned_w*h), 2048) + 9742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALIGN(aligned_w/2, 32) * (h/2) *2; 9752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel size = ALIGN(size, 4096); 9762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } break; 9772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCbCr_420_SP: 9782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCrCb_420_SP: 9792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 9802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel size = aligned_w * h + 9812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALIGN(aligned_w/2, 32) * (h/2) * 2; 9822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel size = ALIGN(size, 4096); 9832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } break; 9842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel default: break; 9852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 9862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return size; 9872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 9882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 9892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* Function to allocate memory for the temporary buffer. This memory is 9902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * allocated from Ashmem. It is the caller's responsibility to free this 9912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * memory. 9922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel */ 9932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int get_temp_buffer(const bufferInfo& info, alloc_data& data) 9942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 9952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGD("%s E", __FUNCTION__); 9962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Alloc memory from system heap 9972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel data.base = 0; 9982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel data.fd = -1; 9992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel data.offset = 0; 10002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel data.size = get_size(info); 10012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel data.align = getpagesize(); 10022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel data.uncached = true; 10032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int allocFlags = 0; 10042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 10052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (sAlloc == 0) { 10062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel sAlloc = gralloc::IAllocController::getInstance(); 10072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 10082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 10092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (sAlloc == 0) { 10102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: sAlloc is still NULL", __FUNCTION__); 10112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 10122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 10132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 10142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int err = sAlloc->allocate(data, allocFlags); 10152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (0 != err) { 10162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: allocate failed", __FUNCTION__); 10172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 10182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 10192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 10202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGD("%s X", __FUNCTION__); 10212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return err; 10222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 10232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 10242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* Function to free the temporary allocated memory.*/ 10252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic void free_temp_buffer(alloc_data &data) 10262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 10272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (-1 != data.fd) { 10282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType); 10292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel memalloc->free_buffer(data.base, data.size, 0, data.fd); 10302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 10312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 10322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 10332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/* Function to perform the software color conversion. Convert the 10342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel * C2D compatible format to the Android compatible format 10352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel */ 10362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int copy_image(private_handle_t *src_handle, 10372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_image_t const *rhs, 10382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel eConversionType conversionType) 10392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 10402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (src_handle->fd == -1) { 10412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: src_handle fd is invalid", __FUNCTION__); 10422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 10432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 10442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 10452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Copy the info. 10462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int ret = COPYBIT_SUCCESS; 10472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel switch(rhs->format) { 10482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_NV12_ENCODEABLE: 10492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCbCr_420_SP: 10502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel case HAL_PIXEL_FORMAT_YCrCb_420_SP: 10512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 10522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (CONVERT_TO_ANDROID_FORMAT == conversionType) { 10532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return convert_yuv_c2d_to_yuv_android(src_handle, rhs); 10542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 10552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return convert_yuv_android_to_yuv_c2d(src_handle, rhs); 10562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 10572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 10582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } break; 10592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel default: { 10602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format); 10612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ret = COPYBIT_FAILURE; 10622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } break; 10632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 10642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return ret; 10652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 10662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 10672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic void delete_handle(private_handle_t *handle) 10682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 10692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (handle) { 10702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete handle; 10712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel handle = 0; 10722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 10732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 10742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 10752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic bool need_to_execute_draw(eC2DFlags flags) 10762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 10772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (flags & FLAGS_TEMP_SRC_DST) { 10782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return true; 10792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 10802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (flags & FLAGS_YUV_DESTINATION) { 10812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return true; 10822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 10832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return false; 10842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 10852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 10862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** do a stretch blit type operation */ 10872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int stretch_copybit_internal( 10882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_device_t *dev, 10892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_image_t const *dst, 10902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_image_t const *src, 10912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_rect_t const *dst_rect, 10922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_rect_t const *src_rect, 10932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_region_t const *region, 10942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bool enableBlend) 10952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 10962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 10972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int status = COPYBIT_SUCCESS; 10982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int flags = 0; 10992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int src_surface_type; 11002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int mapped_src_idx = -1, mapped_dst_idx = -1; 11012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_OBJECT_STR src_surface; 11022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 11032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (!ctx) { 11042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: null context error", __FUNCTION__); 11052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 11062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 11072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 11082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) { 11092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: src dimension error", __FUNCTION__); 11102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 11112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 11122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 11132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) { 11142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s : dst dimension error dst w %d h %d", __FUNCTION__, dst->w, 11152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst->h); 11162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 11172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 11182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 11192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) { 11202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__, 11212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst->format); 11222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 11232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 11242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 11252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int dst_surface_type; 11262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->is_dst_ubwc_format) 11272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel flags |= FLAGS_UBWC_FORMAT_MODE; 11282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 11292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) { 11302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_surface_type = RGB_SURFACE; 11312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel flags |= FLAGS_PREMULTIPLIED_ALPHA; 11322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) { 11332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int num_planes = get_num_planes(dst->format); 11342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel flags |= FLAGS_YUV_DESTINATION; 11352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (num_planes == 2) { 11362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_surface_type = YUV_SURFACE_2_PLANES; 11372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if (num_planes == 3) { 11382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_surface_type = YUV_SURFACE_3_PLANES; 11392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 11402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x", 11412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel __FUNCTION__, dst->format); 11422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 11432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 11442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 11452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__, 11462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst->format); 11472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 11482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 11492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 11502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->blit_rgb_count == MAX_RGB_SURFACES || 11512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_2_plane_count == MAX_YUV_2_PLANE_SURFACES || 11522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_3_plane_count == MAX_YUV_2_PLANE_SURFACES || 11532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_count == MAX_BLIT_OBJECT_COUNT || 11542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst_surface_type != dst_surface_type) { 11552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // we have reached the max. limits of our internal structures or 11562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // changed the target. 11572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Draw the remaining surfaces. We need to do the finish here since 11582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // we need to free up the surface templates. 11592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel finish_copybit(dev); 11602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 11612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 11622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst_surface_type = dst_surface_type; 11632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 11642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Update the destination 11652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel copybit_image_t dst_image; 11662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_image.w = dst->w; 11672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_image.h = dst->h; 11682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_image.format = dst->format; 11692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_image.handle = dst->handle; 11702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Check if we need a temp. copy for the destination. We'd need this the destination 11712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // width is not aligned to 32. This case occurs for YUV formats. RGB formats are 11722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // aligned to 32. 11732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bool need_temp_dst = need_temp_buffer(dst); 11742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bufferInfo dst_info; 11752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel populate_buffer_info(dst, dst_info); 11762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format, 11772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_info.width, dst_info.height); 11782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (dst_hnd == NULL) { 11792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: dst_hnd is null", __FUNCTION__); 11802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 11812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 11822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (need_temp_dst) { 11832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (get_size(dst_info) != (int) ctx->temp_dst_buffer.size) { 11842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel free_temp_buffer(ctx->temp_dst_buffer); 11852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Create a temp buffer and set that as the destination. 11862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) { 11872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__); 11882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 11892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 11902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 11912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 11922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_hnd->fd = ctx->temp_dst_buffer.fd; 11932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_hnd->size = ctx->temp_dst_buffer.size; 11942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_hnd->flags = ctx->temp_dst_buffer.allocType; 11952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_hnd->base = (uintptr_t)(ctx->temp_dst_buffer.base); 11962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_hnd->offset = ctx->temp_dst_buffer.offset; 11972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_hnd->gpuaddr = 0; 11982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_image.handle = dst_hnd; 11992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 12002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(!ctx->dst_surface_mapped) { 12012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel //map the destination surface to GPU address 12022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = set_image(ctx, ctx->dst[ctx->dst_surface_type], &dst_image, 12032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (eC2DFlags)flags, mapped_dst_idx); 12042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(status) { 12052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: dst: set_image error", __FUNCTION__); 12062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 12072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_dst_idx); 12082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 12092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 12102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst_surface_mapped = true; 12112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst_surface_base = dst->base; 12122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if(ctx->dst_surface_mapped && ctx->dst_surface_base != dst->base) { 12132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Destination surface for the operation should be same for multiple 12142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // requests, this check is catch if there is any case when the 12152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // destination changes 12162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: a different destination surface!!", __FUNCTION__); 12172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 12182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 12192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Update the source 12202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel flags = 0; 12212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) { 12222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_surface_type = RGB_SURFACE; 12232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_surface = ctx->blit_rgb_object[ctx->blit_rgb_count]; 12242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) { 12252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int num_planes = get_num_planes(src->format); 12262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (num_planes == 2) { 12272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_surface_type = YUV_SURFACE_2_PLANES; 12282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_surface = ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count]; 12292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if (num_planes == 3) { 12302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_surface_type = YUV_SURFACE_3_PLANES; 12312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_surface = ctx->blit_yuv_3_plane_object[ctx->blit_yuv_2_plane_count]; 12322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 12332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: src number of YUV planes is invalid src format = 0x%x", 12342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel __FUNCTION__, src->format); 12352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 12362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_dst_idx); 12372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 12382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 12392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 12402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__, 12412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src->format); 12422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 12432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_dst_idx); 12442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 12452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 12462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 12472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel copybit_image_t src_image; 12482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_image.w = src->w; 12492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_image.h = src->h; 12502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_image.format = src->format; 12512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_image.handle = src->handle; 12522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 12532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bool need_temp_src = need_temp_buffer(src); 12542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bufferInfo src_info; 12552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel populate_buffer_info(src, src_info); 12562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format, 12572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_info.width, src_info.height); 12582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (NULL == src_hnd) { 12592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: src_hnd is null", __FUNCTION__); 12602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 12612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_dst_idx); 12622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 12632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 12642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (need_temp_src) { 12652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (get_size(src_info) != (int) ctx->temp_src_buffer.size) { 12662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel free_temp_buffer(ctx->temp_src_buffer); 12672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Create a temp buffer and set that as the destination. 12682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (COPYBIT_SUCCESS != get_temp_buffer(src_info, 12692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->temp_src_buffer)) { 12702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__); 12712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 12722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(src_hnd); 12732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_dst_idx); 12742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 12752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 12762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 12772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_hnd->fd = ctx->temp_src_buffer.fd; 12782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_hnd->size = ctx->temp_src_buffer.size; 12792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_hnd->flags = ctx->temp_src_buffer.allocType; 12802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_hnd->base = (uintptr_t)(ctx->temp_src_buffer.base); 12812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_hnd->offset = ctx->temp_src_buffer.offset; 12822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_hnd->gpuaddr = 0; 12832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_image.handle = src_hnd; 12842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 12852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Copy the source. 12862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = copy_image((private_handle_t *)src->handle, &src_image, 12872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel CONVERT_TO_C2D_FORMAT); 12882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (status == COPYBIT_FAILURE) { 12892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s:copy_image failed in temp source",__FUNCTION__); 12902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 12912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(src_hnd); 12922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_dst_idx); 12932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 12942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 12952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 12962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Clean the cache 12972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags); 12982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size, 12992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_hnd->offset, src_hnd->fd, 13002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel gralloc::CACHE_CLEAN)) { 13012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: clean_buffer failed", __FUNCTION__); 13022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 13032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(src_hnd); 13042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_dst_idx); 13052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 13062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 13092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0; 13102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0; 13112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel flags |= (ctx->is_src_ubwc_format) ? FLAGS_UBWC_FORMAT_MODE : 0; 13122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = set_image(ctx, src_surface.surface_id, &src_image, 13132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (eC2DFlags)flags, mapped_src_idx); 13142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(status) { 13152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: set_image (src) error", __FUNCTION__); 13162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 13172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(src_hnd); 13182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_dst_idx); 13192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_src_idx); 13202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 13212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 13232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_surface.config_mask = C2D_NO_ANTIALIASING_BIT | ctx->config_mask; 13242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_surface.global_alpha = ctx->src_global_alpha; 13252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (enableBlend) { 13262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) { 13272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE; 13282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(!(src_surface.global_alpha)) { 13292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // src alpha is zero 13302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 13312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(src_hnd); 13322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_dst_idx); 13332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_src_idx); 13342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 13352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 13382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel src_surface.config_mask |= C2D_ALPHA_BLEND_NONE; 13392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 13412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (src_surface_type == RGB_SURFACE) { 13422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_rgb_object[ctx->blit_rgb_count] = src_surface; 13432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_rgb_count++; 13442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else if (src_surface_type == YUV_SURFACE_2_PLANES) { 13452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count] = src_surface; 13462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_2_plane_count++; 13472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 13482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_3_plane_object[ctx->blit_yuv_3_plane_count] = src_surface; 13492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_3_plane_count++; 13502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 13522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_rect_t clip; 13532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel while ((status == 0) && region->next(region, &clip)) { 13542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip); 13552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) { 13562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGW("Reached end of blit count"); 13572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel finish_copybit(dev); 13582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_list[ctx->blit_count] = src_surface; 13602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_count++; 13612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 13632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Check if we need to perform an early draw-finish. 13642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0; 13652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (need_to_execute_draw((eC2DFlags)flags)) 13662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 13672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel finish_copybit(dev); 13682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 13702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (need_temp_dst) { 13712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // copy the temp. destination without the alignment to the actual 13722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // destination. 13732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT); 13742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (status == COPYBIT_FAILURE) { 13752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__); 13762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 13772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(src_hnd); 13782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_dst_idx); 13792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unmap_gpuaddr(ctx, mapped_src_idx); 13802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 13812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Clean the cache. 13832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags); 13842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size, 13852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel dst_hnd->offset, dst_hnd->fd, 13862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel gralloc::CACHE_CLEAN); 13872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 13882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(dst_hnd); 13892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel delete_handle(src_hnd); 13902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 13912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->is_premultiplied_alpha = false; 13922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->fb_width = 0; 13932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->fb_height = 0; 13942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->config_mask = 0; 13952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 13962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 13972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 13982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int set_sync_copybit(struct copybit_device_t *dev, 13992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int /*acquireFenceFd*/) 14002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 14012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(!dev) 14022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 14032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return 0; 14052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 14062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int stretch_copybit( 14082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_device_t *dev, 14092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_image_t const *dst, 14102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_image_t const *src, 14112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_rect_t const *dst_rect, 14122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_rect_t const *src_rect, 14132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_region_t const *region) 14142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 14152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 14162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int status = COPYBIT_SUCCESS; 14172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel bool needsBlending = (ctx->src_global_alpha != 0); 14182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_lock(&ctx->wait_cleanup_lock); 14192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect, 14202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel region, needsBlending); 14212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_unlock(&ctx->wait_cleanup_lock); 14222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 14232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 14242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** Perform a blit type operation */ 14262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int blit_copybit( 14272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_device_t *dev, 14282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_image_t const *dst, 14292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_image_t const *src, 14302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_region_t const *region) 14312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 14322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int status = COPYBIT_SUCCESS; 14332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 14342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h }; 14352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h }; 14362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_lock(&ctx->wait_cleanup_lock); 14372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false); 14382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_unlock(&ctx->wait_cleanup_lock); 14392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 14402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 14412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** Fill the rect on dst with RGBA color **/ 14432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int fill_color(struct copybit_device_t *dev, 14442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_image_t const *dst, 14452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_rect_t const *rect, 14462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel uint32_t /*color*/) 14472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 14482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // TODO: Implement once c2d driver supports color fill 14492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(!dev || !dst || !rect) 14502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 14512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return -EINVAL; 14532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 14542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/*****************************************************************************/ 14562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic void clean_up(copybit_context_t* ctx) 14582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 14592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel void* ret; 14602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (!ctx) 14612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return; 14622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // stop the wait_cleanup_thread 14642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_lock(&ctx->wait_cleanup_lock); 14652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->stop_thread = true; 14662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Signal waiting thread 14672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_cond_signal(&ctx->wait_cleanup_cond); 14682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_unlock(&ctx->wait_cleanup_lock); 14692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // waits for the cleanup thread to exit 14702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_join(ctx->wait_thread_id, &ret); 14712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_destroy(&ctx->wait_cleanup_lock); 14722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_cond_destroy (&ctx->wait_cleanup_cond); 14732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel for (int i = 0; i < NUM_SURFACE_TYPES; i++) { 14752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->dst[i]) 14762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel LINK_c2dDestroySurface(ctx->dst[i]); 14772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 14782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel for (int i = 0; i < MAX_RGB_SURFACES; i++) { 14802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->blit_rgb_object[i].surface_id) 14812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id); 14822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 14832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) { 14852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->blit_yuv_2_plane_object[i].surface_id) 14862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id); 14872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 14882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) { 14902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->blit_yuv_3_plane_object[i].surface_id) 14912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id); 14922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 14932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx->libc2d2) { 14952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ::dlclose(ctx->libc2d2); 14962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGV("dlclose(libc2d2)"); 14972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 14982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 14992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel free(ctx); 15002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 15012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 15022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** Close the copybit device */ 15032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int close_copybit(struct hw_device_t *dev) 15042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 15052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_context_t* ctx = (struct copybit_context_t*)dev; 15062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (ctx) { 15072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel free_temp_buffer(ctx->temp_src_buffer); 15082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel free_temp_buffer(ctx->temp_dst_buffer); 15092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 15102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel clean_up(ctx); 15112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return 0; 15122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 15132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 15142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel/** Open a new instance of a copybit device using name */ 15152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudelstatic int open_copybit(const struct hw_module_t* module, const char* name, 15162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct hw_device_t** device) 15172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel{ 15182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel int status = COPYBIT_SUCCESS; 15192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) { 15202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 15212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 15222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 15232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_RGB_SURFACE_DEF surfDefinition = {0}; 15242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ; 15252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel struct copybit_context_t *ctx; 15262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 15272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t)); 15282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if(!ctx) { 15292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: malloc failed", __FUNCTION__); 15302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return COPYBIT_FAILURE; 15312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 15322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 15332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel /* initialize drawstate */ 15342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel memset(ctx, 0, sizeof(*ctx)); 15352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW); 15362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (!ctx->libc2d2) { 15372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror()); 15382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel clean_up(ctx); 15392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 15402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *device = NULL; 15412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 15422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 15432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2, 15442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel "c2dCreateSurface"); 15452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2, 15462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel "c2dUpdateSurface"); 15472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2, 15482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel "c2dReadSurface"); 15492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw"); 15502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush"); 15512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish"); 15522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2, 15532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel "c2dWaitTimestamp"); 15542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2, 15552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel "c2dDestroySurface"); 15562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2, 15572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel "c2dMapAddr"); 15582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2, 15592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel "c2dUnMapAddr"); 15602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2, 15612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel "c2dGetDriverCapabilities"); 15622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2, 15632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel "c2dCreateFenceFD"); 15642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2, 15652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel "c2dFillSurface"); 15662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 15672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface 15682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp || 15692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel !LINK_c2dFinish || !LINK_c2dDestroySurface || 15702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD || 15712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel !LINK_c2dFillSurface) { 15722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: dlsym ERROR", __FUNCTION__); 15732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel clean_up(ctx); 15742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 15752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *device = NULL; 15762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 15772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 15782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 15792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.common.tag = HARDWARE_DEVICE_TAG; 15802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.common.version = 1; 15812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.common.module = (hw_module_t*)(module); 15822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.common.close = close_copybit; 15832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.set_parameter = set_parameter_copybit; 15842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.get = get; 15852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.blit = blit_copybit; 15862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.set_sync = set_sync_copybit; 15872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.stretch = stretch_copybit; 15882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.finish = finish_copybit; 15892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.flush_get_fence = flush_get_fence_copybit; 15902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.clear = clear_copybit; 15912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->device.fill_color = fill_color; 15922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 15932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel /* Create RGB Surface */ 15942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfDefinition.buffer = (void*)0xdddddddd; 15952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfDefinition.phys = (void*)0xdddddddd; 15962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfDefinition.stride = 1 * 4; 15972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfDefinition.width = 1; 15982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfDefinition.height = 1; 15992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB; 16002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE, 16012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST | 16022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS | 16032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS_DUMMY ), 16042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel &surfDefinition)) { 16052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__); 16062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst[RGB_SURFACE] = 0; 16072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel clean_up(ctx); 16082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 16092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *device = NULL; 16102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 16112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 16122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 16132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel unsigned int surface_id = 0; 16142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel for (int i = 0; i < MAX_RGB_SURFACES; i++) 16152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 16162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE, 16172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST | 16182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS | 16192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS_DUMMY ), 16202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel &surfDefinition)) { 16212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i); 16222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_rgb_object[i].surface_id = 0; 16232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 16242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 16252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 16262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_rgb_object[i].surface_id = surface_id; 16272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGW("%s i = %d surface_id=%d", __FUNCTION__, i, 16282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_rgb_object[i].surface_id); 16292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 16302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 16312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 16322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (status == COPYBIT_FAILURE) { 16332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel clean_up(ctx); 16342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 16352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *device = NULL; 16362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 16372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 16382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 16392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Create 2 plane YUV surfaces 16402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12; 16412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.width = 4; 16422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.height = 4; 16432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa; 16442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa; 16452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.stride0 = 4; 16462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 16472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa; 16482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa; 16492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.stride1 = 4; 16502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]), 16512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_TARGET | C2D_SOURCE, 16522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | 16532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS | 16542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS_DUMMY), 16552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel &yuvSurfaceDef)) { 16562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__); 16572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst[YUV_SURFACE_2_PLANES] = 0; 16582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel clean_up(ctx); 16592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 16602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *device = NULL; 16612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 16622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 16632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 16642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++) 16652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 16662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE, 16672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | 16682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS | 16692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS_DUMMY ), 16702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel &yuvSurfaceDef)) { 16712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: create YUV source %d failed", __FUNCTION__, i); 16722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_2_plane_object[i].surface_id = 0; 16732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 16742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 16752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 16762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_2_plane_object[i].surface_id = surface_id; 16772ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGW("%s: 2 Plane YUV i=%d surface_id=%d", __FUNCTION__, i, 16782ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_2_plane_object[i].surface_id); 16792ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 16802ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 16812ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 16822ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (status == COPYBIT_FAILURE) { 16832ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel clean_up(ctx); 16842ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 16852ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *device = NULL; 16862ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 16872ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 16882ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 16892ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Create YUV 3 plane surfaces 16902ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12; 16912ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa; 16922ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa; 16932ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel yuvSurfaceDef.stride2 = 4; 16942ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 16952ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]), 16962ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_TARGET | C2D_SOURCE, 16972ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | 16982ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS | 16992ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS_DUMMY), 17002ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel &yuvSurfaceDef)) { 17012ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__); 17022ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->dst[YUV_SURFACE_3_PLANES] = 0; 17032ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel clean_up(ctx); 17042ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 17052ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *device = NULL; 17062ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 17072ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 17082ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 17092ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++) 17102ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel { 17112ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (LINK_c2dCreateSurface(&(surface_id), 17122ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_TARGET | C2D_SOURCE, 17132ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | 17142ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS | 17152ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel C2D_SURFACE_WITH_PHYS_DUMMY), 17162ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel &yuvSurfaceDef)) { 17172ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i); 17182ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_3_plane_object[i].surface_id = 0; 17192ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 17202ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel break; 17212ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } else { 17222ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_3_plane_object[i].surface_id = surface_id; 17232ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGW("%s: 3 Plane YUV i=%d surface_id=%d", __FUNCTION__, i, 17242ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_3_plane_object[i].surface_id); 17252ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 17262ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 17272ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 17282ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (status == COPYBIT_FAILURE) { 17292ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel clean_up(ctx); 17302ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 17312ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *device = NULL; 17322ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 17332ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 17342ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 17352ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) { 17362ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__); 17372ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel clean_up(ctx); 17382ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel status = COPYBIT_FAILURE; 17392ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *device = NULL; 17402ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 17412ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel } 17422ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel // Initialize context variables. 17432ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->trg_transform = C2D_TARGET_ROTATE_0; 17442ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 17452ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->temp_src_buffer.fd = -1; 17462ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->temp_src_buffer.base = 0; 17472ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->temp_src_buffer.size = 0; 17482ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 17492ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->temp_dst_buffer.fd = -1; 17502ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->temp_dst_buffer.base = 0; 17512ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->temp_dst_buffer.size = 0; 17522ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 17532ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->fb_width = 0; 17542ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->fb_height = 0; 17552ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 17562ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_rgb_count = 0; 17572ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_2_plane_count = 0; 17582ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_yuv_3_plane_count = 0; 17592ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->blit_count = 0; 17602ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 17612ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->wait_timestamp = false; 17622ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel ctx->stop_thread = false; 17632ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL); 17642ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_cond_init(&(ctx->wait_cleanup_cond), NULL); 17652ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel /* Start the wait thread */ 17662ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_attr_t attr; 17672ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_attr_init(&attr); 17682ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 17692ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 17702ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop, 17712ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel (void *)ctx); 17722ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel pthread_attr_destroy(&attr); 17732ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel 17742ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel *device = &ctx->device.common; 17752ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel return status; 17762ebc25b87caae537b8cd97beb8a86a7ff5f0cdf4Thierry Strudel} 1777