1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "VtsHalRenderscriptV1_0TargetTest.h"
18 #include <system/window.h>
19
20 /*
21 * ContextCreateAndDestroy:
22 * Creates a RenderScript context and immediately destroys the context.
23 * Since create and destroy calls are a part of SetUp() and TearDown(),
24 * the test definition is intentionally kept empty
25 *
26 * Calls: getService<IDevice>, contextCreate, contextDestroy
27 */
TEST_P(RenderscriptHidlTest,ContextCreateAndDestroy)28 TEST_P(RenderscriptHidlTest, ContextCreateAndDestroy) {}
29
30 /*
31 * Create an Element and verify the return value is valid.
32 *
33 * Calls: elementCreate
34 */
TEST_P(RenderscriptHidlTest,ElementCreate)35 TEST_P(RenderscriptHidlTest, ElementCreate) {
36 Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
37 EXPECT_NE(Element(0), element);
38 }
39
40 /*
41 * Create an Element, a Type and an Allocation of that type, and verify the
42 * return values are valid.
43 *
44 * Calls: elementCreate, typeCreate, allocationCreateTyped, allocationGetType
45 */
TEST_P(RenderscriptHidlTest,ElementTypeAllocationCreate)46 TEST_P(RenderscriptHidlTest, ElementTypeAllocationCreate) {
47 // Element create test
48 Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
49 ASSERT_NE(Element(0), element);
50
51 // Type create test
52 Type type = context->typeCreate(element, 1, 0, 0, false, false, YuvFormat::YUV_NONE);
53 ASSERT_NE(Type(0), type);
54
55 // Allocation create test
56 Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
57 (int)((uint32_t)AllocationUsageType::ALL
58 & ~(uint32_t)AllocationUsageType::OEM),
59 (Ptr)nullptr);
60 ASSERT_NE(Allocation(0), allocation);
61
62 // Allocation type test
63 Type type2 = context->allocationGetType(allocation);
64 EXPECT_EQ(type, type2);
65 }
66
67 /*
68 * Create an Element, a Type of the Element, and verify the native metadata can
69 * be retrieved correctly.
70 *
71 * Calls: elementCreate, typeCreate, elementGetNativeMetadata,
72 * typeGetNativeMetadata
73 */
TEST_P(RenderscriptHidlTest,MetadataTest)74 TEST_P(RenderscriptHidlTest, MetadataTest) {
75 // float1
76 Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
77 ASSERT_NE(Element(0), element);
78
79 // 128 x float1
80 Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
81 ASSERT_NE(Type(0), type);
82
83 std::vector<uint32_t> elementMetadata(5);
84 context->elementGetNativeMetadata(element, [&](const hidl_vec<uint32_t>& _metadata){
85 elementMetadata = _metadata; });
86 EXPECT_EQ(DataType::FLOAT_32, (DataType)elementMetadata[0]);
87 EXPECT_EQ(DataKind::USER, (DataKind)elementMetadata[1]);
88 EXPECT_EQ(false, elementMetadata[2]);
89 EXPECT_EQ(1u, (uint32_t)elementMetadata[3]);
90 EXPECT_EQ(0u, (uint32_t)elementMetadata[4]);
91
92 std::vector<OpaqueHandle> typeMetadata(6);
93 context->typeGetNativeMetadata(type, [&typeMetadata](const hidl_vec<OpaqueHandle>& _metadata){
94 typeMetadata = _metadata; });
95 EXPECT_EQ(128u, (uint32_t)typeMetadata[0]);
96 EXPECT_EQ(0u, (uint32_t)typeMetadata[1]);
97 EXPECT_EQ(0u, (uint32_t)typeMetadata[2]);
98 EXPECT_NE(true, typeMetadata[3]);
99 EXPECT_NE(true, typeMetadata[4]);
100 EXPECT_EQ(element, (Element)typeMetadata[5]);
101 }
102
103 /*
104 * Create a Allocation, and verified allocationGetPointer and allocationResize1D
105 * return valid values.
106 *
107 * Calls: elementCreate, typeCreate, allocationCreateTyped,
108 * allocationGetPointer, allocationResize1D
109 */
TEST_P(RenderscriptHidlTest,ResizeTest)110 TEST_P(RenderscriptHidlTest, ResizeTest) {
111 // float1
112 Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
113 ASSERT_NE(Element(0), element);
114
115 // 128 x float1
116 Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
117 ASSERT_NE(Type(0), type);
118
119 // 128 x float1
120 Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
121 (int)AllocationUsageType::SCRIPT,
122 (Ptr)nullptr);
123 ASSERT_NE(Allocation(0), allocation);
124
125 Ptr dataPtr1, dataPtr2;
126 Size stride;
127 context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
128 [&](Ptr _dataPtr, Size _stride){
129 dataPtr1 = _dataPtr; stride = _stride; });
130 EXPECT_EQ(Size(0), stride);
131
132 context->allocationResize1D(allocation, 1024*1024);
133 context->allocationGetPointer(allocation, 0, AllocationCubemapFace::POSITIVE_X, 0,
134 [&](Ptr _dataPtr, Size _stride){
135 dataPtr2 = _dataPtr; stride = _stride; });
136 EXPECT_EQ(Size(0), stride);
137 EXPECT_NE(dataPtr1, dataPtr2);
138 }
139
140 /*
141 * Test creates two allocations, one with IO_INPUT and one with IO_OUTPUT. The
142 * NativeWindow (Surface) is retrieved from one allocation and set to the other.
143 *
144 * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
145 * allocationGetNativeWindow, allocationSetNativeWindow, allocationIoSend,
146 * allocationIoReceive, allocation2DRead
147 */
TEST_P(RenderscriptHidlTest,NativeWindowIoTest)148 TEST_P(RenderscriptHidlTest, NativeWindowIoTest) {
149 // uint8x4
150 Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 4);
151 ASSERT_NE(Element(0), element);
152
153 // 512 x 512 x uint8x4
154 Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
155 ASSERT_NE(Type(0), type);
156
157 std::vector<uint32_t> dataIn(512*512), dataOut(512*512);
158 std::generate(dataIn.begin(), dataIn.end(), [](){ static uint32_t val = 0; return val++; });
159 hidl_vec<uint8_t> _data;
160 _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(uint32_t));
161 // 512 x 512 x uint8x4
162 Allocation allocationRecv = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
163 (int)(AllocationUsageType::SCRIPT
164 | AllocationUsageType::IO_INPUT),
165 (Ptr)nullptr);
166 ASSERT_NE(Allocation(0), allocationRecv);
167
168 Allocation allocationSend = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
169 (int)(AllocationUsageType::SCRIPT
170 | AllocationUsageType::IO_OUTPUT),
171 (Ptr)nullptr);
172 ASSERT_NE(Allocation(0), allocationSend);
173
174 NativeWindow nativeWindow = context->allocationGetNativeWindow(allocationRecv);
175 ASSERT_NE(NativeWindow(0), nativeWindow);
176
177 ((ANativeWindow *)nativeWindow)->incStrong(nullptr);
178 native_window_api_connect((ANativeWindow*)nativeWindow,
179 NATIVE_WINDOW_API_CPU);
180
181 context->allocationSetNativeWindow(allocationSend, nativeWindow);
182 context->allocation2DWrite(allocationSend, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 512, 512,
183 _data, 0);
184 context->allocationIoSend(allocationSend);
185 context->allocationIoReceive(allocationRecv);
186 context->allocation2DRead(allocationRecv, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 512, 512,
187 (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(uint32_t), 0);
188 EXPECT_EQ(dataIn, dataOut);
189 }
190
191 /*
192 * Three allocations are created, two with IO_INPUT and one with IO_OUTPUT. The
193 * two allocations with IO_INPUT are made to share the same BufferQueue.
194 *
195 * Calls: elementCreate, typeCreate, allocationCreateTyped,
196 * allocationSetupBufferQueue, allocationShareBufferQueue,
197 * allocationGetNativeWindow, allocationSetNativeWindow,
198 * allocation2DWrite, allocation2DRead, allocationIoSend,
199 * allocationIoReceive
200 */
TEST_P(RenderscriptHidlTest,BufferQueueTest)201 TEST_P(RenderscriptHidlTest, BufferQueueTest) {
202 // uint8x4
203 Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 4);
204 ASSERT_NE(Element(0), element);
205
206 // 512 x 512 x uint8x4
207 Type type = context->typeCreate(element, 512, 512, 0, false, false, YuvFormat::YUV_NONE);
208 ASSERT_NE(Type(0), type);
209
210 std::vector<uint32_t> dataIn(512*512), dataOut1(512*512), dataOut2(512*512);
211 std::generate(dataIn.begin(), dataIn.end(), [](){ static uint32_t val = 0; return val++; });
212 hidl_vec<uint8_t> _data;
213 _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(uint32_t));
214 // 512 x 512 x uint8x4
215 Allocation allocationRecv1 = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
216 (int)(AllocationUsageType::SCRIPT
217 | AllocationUsageType::IO_INPUT),
218 (Ptr)nullptr);
219 ASSERT_NE(Allocation(0), allocationRecv1);
220
221 Allocation allocationRecv2 = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
222 (int)(AllocationUsageType::SCRIPT
223 | AllocationUsageType::IO_INPUT),
224 (Ptr)nullptr);
225 ASSERT_NE(Allocation(0), allocationRecv2);
226
227 Allocation allocationSend = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
228 (int)(AllocationUsageType::SCRIPT
229 | AllocationUsageType::IO_INPUT),
230 (Ptr)nullptr);
231 ASSERT_NE(Allocation(0), allocationSend);
232
233 context->allocationSetupBufferQueue(allocationRecv1, 2);
234 context->allocationShareBufferQueue(allocationRecv2, allocationRecv1);
235
236 NativeWindow nativeWindow1 = context->allocationGetNativeWindow(allocationRecv1);
237 ASSERT_NE(NativeWindow(0), nativeWindow1);
238
239 NativeWindow nativeWindow2 = context->allocationGetNativeWindow(allocationRecv2);
240 ASSERT_NE(NativeWindow(0), nativeWindow2);
241 EXPECT_EQ(nativeWindow2, nativeWindow1);
242
243 ((ANativeWindow *)nativeWindow1)->incStrong(nullptr);
244 native_window_api_connect((ANativeWindow*)nativeWindow1,
245 NATIVE_WINDOW_API_CPU);
246
247 context->allocationSetNativeWindow(allocationSend, nativeWindow1);
248 context->allocation2DWrite(allocationSend, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 512, 512,
249 _data, 0);
250 context->allocationIoSend(allocationSend);
251 context->allocationIoReceive(allocationRecv1);
252 context->allocation2DRead(allocationRecv1, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 512, 512,
253 (Ptr)dataOut1.data(), (Size)dataOut1.size()*sizeof(uint32_t), 0);
254 EXPECT_EQ(dataIn, dataOut1);
255
256 context->allocation2DWrite(allocationSend, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 512, 512,
257 _data, 0);
258 context->allocationIoSend(allocationSend);
259 context->allocationIoReceive(allocationRecv2);
260 context->allocation2DRead(allocationRecv2, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 512, 512,
261 (Ptr)dataOut2.data(), (Size)dataOut2.size()*sizeof(uint32_t), 0);
262 EXPECT_EQ(dataIn, dataOut2);
263 }
264
265 /*
266 * This test sets up the message queue, sends a message, peeks at the message,
267 * and reads it back.
268 *
269 * Calls: contextInitToClient, contextSendMessage, contextPeekMessage,
270 * contextGetMessage, contextDeinitToClient, contextLog
271 */
TEST_P(RenderscriptHidlTest,ContextMessageTest)272 TEST_P(RenderscriptHidlTest, ContextMessageTest) {
273 context->contextInitToClient();
274
275 const char * message = "correct";
276 std::vector<char> messageSend(message, message + sizeof(message));
277 hidl_vec<uint8_t> _data;
278 _data.setToExternal((uint8_t*)messageSend.data(), messageSend.size());
279 context->contextSendMessage(0, _data);
280 MessageToClientType messageType;
281 size_t size;
282 uint32_t subID;
283 context->contextPeekMessage([&](MessageToClientType _type, Size _size, uint32_t _subID){
284 messageType = _type; size = (uint32_t)_size; subID = _subID; });
285 std::vector<char> messageRecv(size, '\0');
286 context->contextGetMessage(messageRecv.data(), messageRecv.size(),
287 [&](MessageToClientType _type, Size _size){
288 messageType = _type; size = (uint32_t)_size; });
289 EXPECT_EQ(messageSend, messageRecv);
290
291 context->contextDeinitToClient();
292 context->contextLog();
293 }
294
295 /*
296 * Call through a bunch of APIs and make sure they don’t crash. Assign the name
297 * of a object and check getName returns the name just set.
298 *
299 * Calls: contextSetPriority, contextSetCacheDir, elementCreate, assignName,
300 * contextFinish, getName, objDestroy, samplerCreate
301 */
TEST_P(RenderscriptHidlTest,MiscellaneousTests)302 TEST_P(RenderscriptHidlTest, MiscellaneousTests) {
303 context->contextSetPriority(ThreadPriorities::NORMAL);
304 context->contextSetCacheDir("/data/local/tmp/temp/");
305
306 Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
307 ASSERT_NE(Element(0), element);
308
309 std::string nameIn = "element_test_name";
310 std::string nameOut = "not_name";
311 hidl_string _nameIn;
312 _nameIn.setToExternal(nameIn.c_str(), nameIn.length());
313 context->assignName(element, _nameIn);
314 context->contextFinish();
315 context->getName(element, [&](const hidl_string& _name){ nameOut = _name.c_str(); });
316 EXPECT_EQ("element_test_name", nameOut);
317
318 context->objDestroy(element);
319
320 Sampler sampler = context->samplerCreate(SamplerValue::LINEAR, SamplerValue::LINEAR,
321 SamplerValue::LINEAR, SamplerValue::LINEAR,
322 SamplerValue::LINEAR, 8.0f);
323 EXPECT_NE(Sampler(0), sampler);
324 }
325