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