1 /*
2  * Copyright (C) 2020 ARM Limited. All rights reserved.
3  *
4  * Copyright 2016 The Android Open Source Project
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 #ifndef _GRALLOC_BUFFER_DESCRIPTOR_H_
19 #define _GRALLOC_BUFFER_DESCRIPTOR_H_
20 
21 #include "core/mali_gralloc_bufferdescriptor.h"
22 #include "hidl_common.h"
23 
24 #include <assert.h>
25 #include <inttypes.h>
26 #include <string.h>
27 
28 namespace arm {
29 namespace mapper {
30 namespace common {
31 
32 const size_t DESCRIPTOR_32BIT_FIELDS = 5;
33 const size_t DESCRIPTOR_64BIT_FIELDS = 2;
34 
35 const uint64_t validUsageBits =
36 		static_cast<uint64_t>(BufferUsage::GPU_CUBE_MAP) |
37 		static_cast<uint64_t>(BufferUsage::GPU_MIPMAP_COMPLETE) |
38 		static_cast<uint64_t>(BufferUsage::CPU_READ_MASK) | static_cast<uint64_t>(BufferUsage::CPU_WRITE_MASK) |
39 		static_cast<uint64_t>(BufferUsage::GPU_TEXTURE) | static_cast<uint64_t>(BufferUsage::GPU_RENDER_TARGET) |
40 		static_cast<uint64_t>(BufferUsage::COMPOSER_OVERLAY) | static_cast<uint64_t>(BufferUsage::COMPOSER_CLIENT_TARGET) |
41 		static_cast<uint64_t>(BufferUsage::CAMERA_INPUT) | static_cast<uint64_t>(BufferUsage::CAMERA_OUTPUT) |
42 		static_cast<uint64_t>(BufferUsage::PROTECTED) |
43 		static_cast<uint64_t>(BufferUsage::COMPOSER_CURSOR) |
44 		static_cast<uint64_t>(BufferUsage::VIDEO_ENCODER) |
45 		static_cast<uint64_t>(BufferUsage::RENDERSCRIPT) |
46 		static_cast<uint64_t>(BufferUsage::VIDEO_DECODER) |
47 		static_cast<uint64_t>(BufferUsage::SENSOR_DIRECT_DATA) |
48 		static_cast<uint64_t>(BufferUsage::GPU_DATA_BUFFER) |
49 		static_cast<uint64_t>(BufferUsage::VENDOR_MASK) |
50 		static_cast<uint64_t>(BufferUsage::VENDOR_MASK_HI);
51 
52 template<typename BufferDescriptorInfoT>
validateDescriptorInfo(const BufferDescriptorInfoT & descriptorInfo)53 static bool validateDescriptorInfo(const BufferDescriptorInfoT &descriptorInfo)
54 {
55 	if (descriptorInfo.width == 0 || descriptorInfo.height == 0 || descriptorInfo.layerCount == 0)
56 	{
57 		return false;
58 	}
59 
60 	if (static_cast<int32_t>(descriptorInfo.format) == 0)
61 	{
62 		return false;
63 	}
64 
65 	return true;
66 }
67 
68 template <typename vecT>
push_descriptor_uint32(frameworks_vec<vecT> * vec,size_t * pos,uint32_t val)69 static void push_descriptor_uint32(frameworks_vec<vecT> *vec, size_t *pos, uint32_t val)
70 {
71 	static_assert(sizeof(val) % sizeof(vecT) == 0, "Unsupported vector type");
72 	memcpy(vec->data() + *pos, &val, sizeof(val));
73 	*pos += sizeof(val) / sizeof(vecT);
74 }
75 
76 template <typename vecT>
pop_descriptor_uint32(const frameworks_vec<vecT> & vec,size_t * pos)77 static uint32_t pop_descriptor_uint32(const frameworks_vec<vecT> &vec, size_t *pos)
78 {
79 	uint32_t val;
80 	static_assert(sizeof(val) % sizeof(vecT) == 0, "Unsupported vector type");
81 	memcpy(&val, vec.data() + *pos, sizeof(val));
82 	*pos += sizeof(val) / sizeof(vecT);
83 	return val;
84 }
85 
86 template <typename vecT>
push_descriptor_uint64(frameworks_vec<vecT> * vec,size_t * pos,uint64_t val)87 static void push_descriptor_uint64(frameworks_vec<vecT> *vec, size_t *pos, uint64_t val)
88 {
89 	static_assert(sizeof(val) % sizeof(vecT) == 0, "Unsupported vector type");
90 	memcpy(vec->data() + *pos, &val, sizeof(val));
91 	*pos += sizeof(val) / sizeof(vecT);
92 }
93 
94 template <typename vecT>
pop_descriptor_uint64(const frameworks_vec<vecT> & vec,size_t * pos)95 static uint64_t pop_descriptor_uint64(const frameworks_vec<vecT> &vec, size_t *pos)
96 {
97 	uint64_t val;
98 	static_assert(sizeof(val) % sizeof(vecT) == 0, "Unsupported vector type");
99 	memcpy(&val, vec.data() + *pos, sizeof(val));
100 	*pos += sizeof(val) / sizeof(vecT);
101 	return val;
102 }
103 
104 // There can only be one string at the end of the descriptor
push_descriptor_string(frameworks_vec<uint8_t> * vec,size_t * pos,const std::string & str)105 static void push_descriptor_string(frameworks_vec<uint8_t> *vec, size_t *pos, const std::string &str)
106 {
107 	strcpy(reinterpret_cast<char *>(vec->data() + *pos), str.c_str());
108 	*pos += strlen(str.c_str()) + 1;
109 }
110 
pop_descriptor_string(const frameworks_vec<uint8_t> & vec,size_t * pos)111 static std::string pop_descriptor_string(const frameworks_vec<uint8_t> &vec, size_t *pos)
112 {
113 	const char* charstr = reinterpret_cast<const char *>(vec.data() + *pos);
114 	charstr += '\0';
115 	std::string str(charstr);
116 	str.resize(strlen(charstr));
117 	return str;
118 }
119 
120 #if defined(GRALLOC_MAPPER_4)
121 template <typename vecT, typename BufferDescriptorInfoT>
grallocEncodeBufferDescriptor(const BufferDescriptorInfoT & descriptorInfo)122 static const frameworks_vec<vecT> grallocEncodeBufferDescriptor(const BufferDescriptorInfoT &descriptorInfo)
123 {
124 	frameworks_vec<vecT> descriptor;
125 
126 	static_assert(sizeof(uint32_t) % sizeof(vecT) == 0, "Unsupported vector type");
127 	size_t dynamic_size = 0;
128 	constexpr size_t static_size = (DESCRIPTOR_32BIT_FIELDS * sizeof(uint32_t) / sizeof(vecT)) +
129 	                               (DESCRIPTOR_64BIT_FIELDS * sizeof(uint64_t) / sizeof(vecT));
130 
131 	/* Include the name and '\0' in the descriptor. */
132 	dynamic_size += strlen(descriptorInfo.name.c_str()) + 1;
133 
134 	size_t pos = 0;
135 	descriptor.resize(dynamic_size + static_size);
136 	push_descriptor_uint32(&descriptor, &pos, HIDL_MAPPER_VERSION_SCALED / 10);
137 	push_descriptor_uint32(&descriptor, &pos, descriptorInfo.width);
138 	push_descriptor_uint32(&descriptor, &pos, descriptorInfo.height);
139 	push_descriptor_uint32(&descriptor, &pos, descriptorInfo.layerCount);
140 	push_descriptor_uint32(&descriptor, &pos, static_cast<uint32_t>(descriptorInfo.format));
141 	push_descriptor_uint64(&descriptor, &pos, static_cast<uint64_t>(descriptorInfo.usage));
142 
143 	push_descriptor_uint64(&descriptor, &pos, descriptorInfo.reservedSize);
144 
145 	assert(pos == static_size);
146 
147 	push_descriptor_string(&descriptor, &pos, descriptorInfo.name);
148 
149 	return descriptor;
150 }
151 
152 #endif // GRALLOC_MAPPER_4
153 
154 template <typename vecT>
grallocDecodeBufferDescriptor(const frameworks_vec<vecT> & androidDescriptor,buffer_descriptor_t & grallocDescriptor)155 static bool grallocDecodeBufferDescriptor(const frameworks_vec<vecT> &androidDescriptor, buffer_descriptor_t &grallocDescriptor)
156 {
157 	static_assert(sizeof(uint32_t) % sizeof(vecT) == 0, "Unsupported vector type");
158 	size_t pos = 0;
159 
160 	if (((DESCRIPTOR_32BIT_FIELDS * sizeof(uint32_t) / sizeof(vecT)) +
161 	     (DESCRIPTOR_64BIT_FIELDS * sizeof(uint64_t) / sizeof(vecT))) +
162 	     sizeof('\0') > androidDescriptor.size())
163 	{
164 		MALI_GRALLOC_LOGE("Descriptor is too small");
165 		return false;
166 	}
167 
168 	if (static_cast<char>(androidDescriptor[androidDescriptor.size() - 1]) != '\0') {
169 		MALI_GRALLOC_LOGE("Descriptor does not contain an ending null character");
170 		return false;
171 	}
172 
173 	if (pop_descriptor_uint32(androidDescriptor, &pos) != HIDL_MAPPER_VERSION_SCALED / 10)
174 	{
175 		MALI_GRALLOC_LOGE("Corrupted buffer version in descriptor = %p, pid = %d ", &androidDescriptor, getpid());
176 		return false;
177 	}
178 
179 	grallocDescriptor.width = pop_descriptor_uint32(androidDescriptor, &pos);
180 	grallocDescriptor.height = pop_descriptor_uint32(androidDescriptor, &pos);
181 	grallocDescriptor.layer_count = pop_descriptor_uint32(androidDescriptor, &pos);
182 	grallocDescriptor.hal_format = static_cast<uint64_t>(pop_descriptor_uint32(androidDescriptor, &pos));
183 	grallocDescriptor.producer_usage = pop_descriptor_uint64(androidDescriptor, &pos);
184 	grallocDescriptor.consumer_usage = grallocDescriptor.producer_usage;
185 	grallocDescriptor.format_type = MALI_GRALLOC_FORMAT_TYPE_USAGE;
186 	grallocDescriptor.signature = sizeof(buffer_descriptor_t);
187 	grallocDescriptor.reserved_size = pop_descriptor_uint64(androidDescriptor, &pos);
188 	grallocDescriptor.name = pop_descriptor_string(androidDescriptor, &pos);
189 
190 	return true;
191 }
192 
193 } // namespace common
194 } // namespace mapper
195 } // namespace arm
196 #endif
197