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