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 
19 /*
20  * Create a Blur intrinsic with scriptIntrinsicCreate, and call
21  * scriptSetTimeZone to make sure it is not crashing.
22  *
23  * Calls: elementCreate, scriptIntrinsicCreate, scriptSetTimeZone
24  */
TEST_F(RenderscriptHidlTest,IntrinsicTest)25 TEST_F(RenderscriptHidlTest, IntrinsicTest) {
26     // uint8
27     Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
28     EXPECT_NE(Element(0), element);
29 
30     Script script = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_BLUR, element);
31     EXPECT_NE(Script(0), script);
32 
33     context->scriptSetTimeZone(script, "UTF-8");
34 }
35 
36 /*
37  * Create a user script “struct_test”, and verified the setters and getters work
38  * for the global variables.
39  *
40  * Calls: scriptCCreate, scriptGetVarV, scriptSetVarI, scriptSetVarJ,
41  * scriptSetVarF, scriptSetVarD, elementCreate, typeCreate,
42  * allocationCreateTyped, scriptSetVarObj, scriptSetVarV, scriptSetVarVE
43  */
TEST_F(RenderscriptHidlTest,ScriptVarTest)44 TEST_F(RenderscriptHidlTest, ScriptVarTest) {
45     hidl_vec<uint8_t> bitcode;
46     bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
47     Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
48     ASSERT_NE(Script(0), script);
49 
50     // arg tests
51     context->scriptSetVarI(script, mExportVarIdx_var_int, 100);
52     int resultI = 0;
53     context->scriptGetVarV(script, mExportVarIdx_var_int, sizeof(int),
54                            [&](const hidl_vec<uint8_t>& _data){ resultI = *((int*)_data.data()); });
55     EXPECT_EQ(100, resultI);
56 
57     context->scriptSetVarJ(script, mExportVarIdx_var_long, 101l);
58     int resultJ = 0;
59     context->scriptGetVarV(script, mExportVarIdx_var_long, sizeof(long),
60                            [&](const hidl_vec<uint8_t>& _data){
61                                resultJ = *((long*)_data.data()); });
62     EXPECT_EQ(101l, resultJ);
63 
64     context->scriptSetVarF(script, mExportVarIdx_var_float, 102.0f);
65     int resultF = 0.0f;
66     context->scriptGetVarV(script, mExportVarIdx_var_float, sizeof(float),
67                            [&](const hidl_vec<uint8_t>& _data){
68                                resultF = *((float*)_data.data()); });
69     EXPECT_EQ(102.0f, resultF);
70 
71     context->scriptSetVarD(script, mExportVarIdx_var_double, 103.0);
72     int resultD = 0.0;
73     context->scriptGetVarV(script, mExportVarIdx_var_double, sizeof(double),
74                            [&](const hidl_vec<uint8_t>& _data){
75                                resultD = *((double*)_data.data()); });
76     EXPECT_EQ(103.0, resultD);
77 
78     // float1
79     Element element = context->elementCreate(DataType::FLOAT_32, DataKind::USER, false, 1);
80     ASSERT_NE(Element(0), element);
81 
82     // 128 x float1
83     Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
84     ASSERT_NE(Type(0), type);
85 
86     // 128 x float1
87     Allocation allocationIn = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
88                                                              (int)AllocationUsageType::SCRIPT,
89                                                              (Ptr)nullptr);
90     ASSERT_NE(Allocation(0), allocationIn);
91 
92     Allocation allocationOut = Allocation(0);
93     context->scriptSetVarObj(script, mExportVarIdx_var_allocation, (ObjectBase)allocationIn);
94     context->scriptGetVarV(script, mExportVarIdx_var_allocation, sizeof(ObjectBase),
95                            [&](const hidl_vec<uint8_t>& _data){
96                                allocationOut = (Allocation) *((ObjectBase*)_data.data()); });
97     EXPECT_EQ(allocationOut, allocationIn);
98 
99     uint32_t valueV = 104u;
100     hidl_vec<uint8_t> _dataV;
101     _dataV.setToExternal((uint8_t*)&valueV, sizeof(uint32_t));
102     context->scriptSetVarV(script, mExportVarIdx_var_uint32_t, _dataV);
103     uint32_t resultV = 0u;
104     context->scriptGetVarV(script, mExportVarIdx_var_uint32_t, sizeof(uint32_t),
105                            [&](const hidl_vec<uint8_t>& _data){
106                                resultV = *((uint32_t*)_data.data()); });
107     EXPECT_EQ(104u, resultV);
108 
109     std::vector<int> dataVE = {1000, 1001};
110     std::vector<uint32_t> dimsVE = {1};
111     std::vector<int> outVE(2);
112     hidl_vec<uint8_t> _dataVE;
113     hidl_vec<uint32_t> _dimsVE;
114     _dataVE.setToExternal((uint8_t*)dataVE.data(), dataVE.size()*sizeof(int));
115     _dimsVE.setToExternal((uint32_t*)dimsVE.data(), dimsVE.size());
116     // intx2 to represent point2 which is {int, int}
117     Element elementVE = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 2);
118     ASSERT_NE(Element(0), elementVE);
119 
120     context->scriptSetVarVE(script, mExportVarIdx_var_point2, _dataVE, elementVE, _dimsVE);
121     context->scriptGetVarV(script, mExportVarIdx_var_point2, 2*sizeof(int),
122                            [&](const hidl_vec<uint8_t>& _data){
123                                outVE = std::vector<int>(
124                                    (int*)_data.data(), (int*)_data.data() + 2); });
125     EXPECT_EQ(1000, outVE[0]);
126     EXPECT_EQ(1001, outVE[1]);
127 }
128 
129 /*
130  * Create a user script “struct_test”, and input and output Allocations.
131  * Verified the foreach launch correctly for the invoke kernel.
132  *
133  * Calls: scriptCCreate, scriptInvoke, scriptGetVarV, scriptInvokeV
134  */
TEST_F(RenderscriptHidlTest,ScriptInvokeTest)135 TEST_F(RenderscriptHidlTest, ScriptInvokeTest) {
136     hidl_vec<uint8_t> bitcode;
137     bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
138     Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
139     ASSERT_NE(Script(0), script);
140 
141     // invoke test
142     int resultI = 0;
143     long resultJ = 0l;
144     float resultF = 0.0f;
145     double resultD = 0.0;
146     uint32_t resultV = 0u;
147     std::vector<int> resultVE(2);
148     context->scriptInvoke(script, mExportFuncIdx_function);
149     context->scriptGetVarV(script, mExportVarIdx_var_int, sizeof(int),
150                            [&](const hidl_vec<uint8_t>& _data){ resultI = *((int*)_data.data()); });
151     context->scriptGetVarV(script, mExportVarIdx_var_long, sizeof(long),
152                            [&](const hidl_vec<uint8_t>& _data){
153                                resultJ = *((long*)_data.data()); });
154     context->scriptGetVarV(script, mExportVarIdx_var_float, sizeof(float),
155                            [&](const hidl_vec<uint8_t>& _data){
156                                resultF = *((float*)_data.data()); });
157     context->scriptGetVarV(script, mExportVarIdx_var_double, sizeof(double),
158                            [&](const hidl_vec<uint8_t>& _data){
159                                resultD = *((double*)_data.data()); });
160     context->scriptGetVarV(script, mExportVarIdx_var_uint32_t, sizeof(uint32_t),
161                            [&](const hidl_vec<uint8_t>& _data){
162                                resultV = *((uint32_t*)_data.data()); });
163     context->scriptGetVarV(script, mExportVarIdx_var_point2, 2*sizeof(int),
164                            [&](const hidl_vec<uint8_t>& _data){
165                                resultVE = std::vector<int>(
166                                    (int*)_data.data(), (int*)_data.data() + 2); });
167     EXPECT_EQ(1, resultI);
168     EXPECT_EQ(2l, resultJ);
169     EXPECT_EQ(3.0f, resultF);
170     EXPECT_EQ(4.0, resultD);
171     EXPECT_EQ(5u, resultV);
172     EXPECT_EQ(6, resultVE[0]);
173     EXPECT_EQ(7, resultVE[1]);
174 
175     // invokeV test
176     int functionV_arg = 5;
177     int functionV_res = 0;
178     hidl_vec<uint8_t> functionV_data;
179     functionV_data.setToExternal((uint8_t*)&functionV_arg, sizeof(int));
180     context->scriptInvokeV(script, mExportFuncIdx_functionV, functionV_data);
181     context->scriptGetVarV(script, mExportVarIdx_var_int, sizeof(int),
182                            [&](const hidl_vec<uint8_t>& _data){
183                                functionV_res = *((int*)_data.data()); });
184     EXPECT_EQ(5, functionV_res);
185 }
186 
187 /*
188  * Create a user script “struct_test”, and input and output Allocations.
189  * Verified the foreach launch correctly for the foreach kernel.
190  *
191  * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
192  * allocation1DWrite, scriptForEach, allocationRead
193  */
TEST_F(RenderscriptHidlTest,ScriptForEachTest)194 TEST_F(RenderscriptHidlTest, ScriptForEachTest) {
195     hidl_vec<uint8_t> bitcode;
196     bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
197     Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
198     ASSERT_NE(Script(0), script);
199 
200     // uint8_t
201     Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
202     ASSERT_NE(Element(0), element);
203 
204     // 64 x uint8_t
205     Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
206     ASSERT_NE(Type(0), type);
207 
208     std::vector<uint8_t> dataIn(64), dataOut(64), expected(64);
209     std::generate(dataIn.begin(), dataIn.end(), [](){ static uint8_t val = 0; return val++; });
210     std::generate(expected.begin(), expected.end(), [](){ static uint8_t val = 1; return val++; });
211     hidl_vec<uint8_t> _data;
212     _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size());
213     // 64 x float1
214     Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
215                                                            (int)AllocationUsageType::SCRIPT,
216                                                            (Ptr)nullptr);
217     ASSERT_NE(Allocation(0), allocation);
218 
219     Allocation vout = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
220                                                      (int)AllocationUsageType::SCRIPT,
221                                                      (Ptr)nullptr);
222     ASSERT_NE(Allocation(0), vout);
223 
224     context->allocation1DWrite(allocation, 0, 0, (Size)dataIn.size(), _data);
225     hidl_vec<Allocation> vains;
226     vains.setToExternal(&allocation, 1);
227     hidl_vec<uint8_t> params;
228     context->scriptForEach(script, mExportForEachIdx_increment, vains, vout, params, nullptr);
229     context->allocationRead(vout, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(uint8_t));
230     EXPECT_EQ(expected, dataOut);
231 }
232 
233 /*
234  * Create a user script “struct_test”, and input and output Allocations.
235  * Verified the foreach launch correctly for the reduction kernel.
236  *
237  * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
238  * allocation1DWrite, scriptReduce, contextFinish, allocationRead
239  */
TEST_F(RenderscriptHidlTest,ScriptReduceTest)240 TEST_F(RenderscriptHidlTest, ScriptReduceTest) {
241     hidl_vec<uint8_t> bitcode;
242     bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
243     Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
244     ASSERT_NE(Script(0), script);
245 
246     // uint8_t
247     Element element = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 1);
248     ASSERT_NE(Element(0), element);
249 
250     // 64 x uint8_t
251     Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
252     ASSERT_NE(Type(0), type);
253 
254     Type type2 = context->typeCreate(element, 1, 0, 0, false, false, YuvFormat::YUV_NONE);
255     ASSERT_NE(Type(0), type2);
256 
257     std::vector<int> dataIn(64), dataOut(1);
258     std::generate(dataIn.begin(), dataIn.end(), [](){ static int val = 0; return val++; });
259     hidl_vec<uint8_t> _data;
260     _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(int));
261     // 64 x float1
262     Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
263                                                            (int)AllocationUsageType::SCRIPT,
264                                                            (Ptr)nullptr);
265     ASSERT_NE(Allocation(0), allocation);
266 
267     Allocation vaout = context->allocationCreateTyped(type2, AllocationMipmapControl::NONE,
268                                                       (int)AllocationUsageType::SCRIPT,
269                                                       (Ptr)nullptr);
270     ASSERT_NE(Allocation(0), vaout);
271 
272     context->allocation1DWrite(allocation, 0, 0, (Size)dataIn.size(), _data);
273     hidl_vec<Allocation> vains;
274     vains.setToExternal(&allocation, 1);
275     context->scriptReduce(script, mExportReduceIdx_summation, vains, vaout, nullptr);
276     context->contextFinish();
277     context->allocationRead(vaout, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(int));
278     // sum of 0, 1, 2, ..., 62, 63
279     int sum = 63*64/2;
280     EXPECT_EQ(sum, dataOut[0]);
281 }
282 
283 /*
284  * This test creates an allocation and binds it to a data segment in the
285  * RenderScript script, represented in the bitcode.
286  *
287  * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
288  * allocation1DWrite, scriptBindAllocation, scriptSetVarV, scriptBindAllocation,
289  * allocationRead, scriptInvokeV, allocationRead
290  */
TEST_F(RenderscriptHidlTest,ScriptBindTest)291 TEST_F(RenderscriptHidlTest, ScriptBindTest) {
292     hidl_vec<uint8_t> bitcode;
293     bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
294     Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
295     ASSERT_NE(Script(0), script);
296 
297     // in32
298     Element element = context->elementCreate(DataType::SIGNED_32, DataKind::USER, false, 1);
299     ASSERT_NE(Element(0), element);
300 
301     // 64 x int32
302     Type type = context->typeCreate(element, 64, 0, 0, false, false, YuvFormat::YUV_NONE);
303     ASSERT_NE(Type(0), type);
304 
305     // 64 x int32
306     Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
307                                                            (int)AllocationUsageType::SCRIPT,
308                                                            (Ptr)nullptr);
309     ASSERT_NE(Allocation(0), allocation);
310 
311     std::vector<int> dataIn(64), dataOut(64), expected(64, 5);
312     hidl_vec<uint8_t> _data;
313     _data.setToExternal((uint8_t*)dataIn.data(), dataIn.size()*sizeof(int));
314     context->allocation1DWrite(allocation, 0, 0, (Size)dataIn.size(), _data);
315     context->scriptBindAllocation(script, allocation, mExportVarIdx_var_int_ptr);
316     int dim = 64;
317     hidl_vec<uint8_t> _dim;
318     _dim.setToExternal((uint8_t*)&dim, sizeof(int));
319     context->scriptInvokeV(script, mExportFuncIdx_setBuffer, _dim);
320     context->allocationRead(allocation, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(int));
321     EXPECT_EQ(expected, dataOut);
322 }
323 
324 /*
325  * This test groups together two RenderScript intrinsic kernels to run one after
326  * the other asynchronously with respect to the client. The test configures
327  * Blend and Blur, and links them together such that Blur will execute after
328  * Blend and use its result. The test checks the data returned to make sure it
329  * was changed after passing through the entire ScriptGroup.
330  *
331  * Calls: elementCreate, typeCreate, allocationCreateTyped, allocation2DWrite,
332  * scriptIntrinsicCreate, scriptKernelIDCreate, scriptFieldIDCreate,
333  * scriptGroupCreate, scriptGroupSetInput, scriptGroupSetOutput,
334  * scriptGroupExecute, contextFinish, allocation2DRead
335  */
TEST_F(RenderscriptHidlTest,ScriptGroupTest)336 TEST_F(RenderscriptHidlTest, ScriptGroupTest) {
337     std::vector<uint8_t> dataIn(256 * 256 * 4, 128), dataOut(256 * 256 * 4, 0),
338         zeros(256 * 256 * 4, 0);
339     hidl_vec<uint8_t> _dataIn, _dataOut;
340     _dataIn.setToExternal(dataIn.data(), dataIn.size());
341     _dataOut.setToExternal(dataOut.data(), dataOut.size());
342 
343     // 256 x 256 YUV pixels
344     Element element1 = context->elementCreate(DataType::UNSIGNED_8,
345                                               DataKind::PIXEL_RGBA, true, 4);
346     ASSERT_NE(Element(0), element1);
347 
348     Type type1 = context->typeCreate(element1, 256, 256, 0, false, false,
349                                      YuvFormat::YUV_NONE);
350     ASSERT_NE(Type(0), type1);
351 
352     Allocation allocation1 = context->allocationCreateTyped(type1, AllocationMipmapControl::NONE,
353                                                            (int)AllocationUsageType::SCRIPT,
354                                                            (Ptr)nullptr);
355     ASSERT_NE(Allocation(0), allocation1);
356 
357     context->allocation2DWrite(allocation1, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
358                                _dataIn, 0);
359 
360     // 256 x 256 RGBA pixels
361     Element element2 = context->elementCreate(DataType::UNSIGNED_8, DataKind::PIXEL_RGBA, true, 4);
362     ASSERT_NE(Element(0), element2);
363 
364     Type type2 = context->typeCreate(element2, 256, 256, 0, false, false, YuvFormat::YUV_NONE);
365     ASSERT_NE(Type(0), type2);
366 
367     Allocation allocation2 = context->allocationCreateTyped(type2, AllocationMipmapControl::NONE,
368                                                            (int)AllocationUsageType::SCRIPT,
369                                                            (Ptr)nullptr);
370     ASSERT_NE(Allocation(0), allocation2);
371 
372     context->allocation2DWrite(allocation2, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
373                                _dataOut, 0);
374 
375     // create scripts
376     Script blend =
377         context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_BLEND, element1);
378     ASSERT_NE(Script(0), blend);
379 
380     ScriptKernelID blendKID = context->scriptKernelIDCreate(blend, 1, 3);
381     ASSERT_NE(ScriptKernelID(0), blendKID);
382 
383     Script blur = context->scriptIntrinsicCreate(ScriptIntrinsicID::ID_BLUR, element2);
384     ASSERT_NE(Script(0), blur);
385 
386     ScriptKernelID blurKID = context->scriptKernelIDCreate(blur, 0, 2);
387     ASSERT_NE(ScriptKernelID(0), blurKID);
388 
389     ScriptFieldID blurFID = context->scriptFieldIDCreate(blur, 1);
390     ASSERT_NE(ScriptFieldID(0), blurFID);
391 
392     // ScriptGroup
393     hidl_vec<ScriptKernelID> kernels = {blendKID, blurKID};
394     hidl_vec<ScriptKernelID> srcK = {blendKID};
395     hidl_vec<ScriptKernelID> dstK = {ScriptKernelID(0)};
396     hidl_vec<ScriptFieldID> dstF = {blurFID};
397     hidl_vec<Type> types = {type2};
398     ScriptGroup scriptGroup = context->scriptGroupCreate(kernels, srcK, dstK, dstF, types);
399     ASSERT_NE(ScriptGroup(0), scriptGroup);
400 
401     context->scriptGroupSetInput(scriptGroup, blendKID, allocation1);
402     context->scriptGroupSetOutput(scriptGroup, blurKID, allocation2);
403     context->scriptGroupExecute(scriptGroup);
404     context->contextFinish();
405 
406     // verify contents were changed
407     context->allocation2DRead(allocation2, 0, 0, 0, AllocationCubemapFace::POSITIVE_X, 256, 256,
408                               (Ptr)dataOut.data(), (Size)dataOut.size(), 0);
409     EXPECT_NE(zeros, dataOut);
410 }
411 
412 /*
413  * Similar to the ScriptGroup test, this test verifies the execution flow of
414  * RenderScript kernels and invokables.
415  *
416  * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
417  * allocation1DWrite, scriptFieldIDCreate, scriptInvokeIDCreate,
418  * invokeClosureCreate, closureCreate, closureSetGlobal, scriptGroup2Create,
419  * scriptGroupExecute, allocationRead
420  */
TEST_F(RenderscriptHidlTest,ScriptGroup2Test)421 TEST_F(RenderscriptHidlTest, ScriptGroup2Test) {
422     hidl_vec<uint8_t> bitcode;
423     bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
424     Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
425     ASSERT_NE(Script(0), script);
426 
427     std::vector<uint8_t> dataIn(128, 128), dataOut(128, 0), expected(128, 7+1);
428     hidl_vec<uint8_t> _dataIn, _dataOut;
429     _dataIn.setToExternal(dataIn.data(), dataIn.size());
430 
431     // 256 x 256 YUV pixels
432     Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
433     ASSERT_NE(Element(0), element);
434 
435     Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
436     ASSERT_NE(Type(0), type);
437 
438     Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
439                                                            (int)AllocationUsageType::SCRIPT,
440                                                            (Ptr)nullptr);
441     ASSERT_NE(Allocation(0), allocation);
442 
443     context->allocation1DWrite(allocation, 0, 0, (Size)_dataIn.size(), _dataIn);
444 
445     ScriptFieldID fieldID = context->scriptFieldIDCreate(script, mExportVarIdx_var_allocation);
446     ASSERT_NE(ScriptFieldID(0), fieldID);
447 
448     // invoke
449     ScriptInvokeID invokeID = context->scriptInvokeIDCreate(script, mExportFuncIdx_setAllocation);
450     ASSERT_NE(ScriptInvokeID(0), invokeID);
451 
452     int dim = 128;
453     hidl_vec<uint8_t> params;
454     params.setToExternal((uint8_t*)&dim, sizeof(dim));
455     hidl_vec<ScriptFieldID> fieldIDS1 = {fieldID};
456     hidl_vec<int64_t> values1 = {int64_t(0)};
457     hidl_vec<int32_t> sizes1 = {int32_t(0)};
458     Closure closure1 = context->invokeClosureCreate(invokeID, params, fieldIDS1, values1, sizes1);
459     ASSERT_NE(Closure(0), closure1);
460 
461     // kernel
462     ScriptKernelID kernelID = context->scriptKernelIDCreate(script, mExportForEachIdx_increment, 3);
463     ASSERT_NE(ScriptKernelID(0), kernelID);
464 
465     hidl_vec<ScriptFieldID> fieldIDS2 = {ScriptFieldID(0)};
466     hidl_vec<int64_t> values2 = {(int64_t)(intptr_t)allocation};
467     hidl_vec<int32_t> sizes2 = {-1 /* allocation */};
468     hidl_vec<Closure> depClosures2 = {closure1};
469     hidl_vec<ScriptFieldID> depFieldIDS2 = {fieldID};
470     Closure closure2 = context->closureCreate(kernelID, allocation /* returnValue */, fieldIDS2,
471                                               values2, sizes2, depClosures2, depFieldIDS2);
472     ASSERT_NE(Closure(0), closure2);
473 
474     // set argument
475     context->closureSetGlobal(closure1, fieldID, (int64_t)(intptr_t)allocation,
476                               -1 /* allocation */);
477 
478     // execute
479     hidl_string name = "script_group_2_test";
480     hidl_string cacheDir = "/data/local/tmp";
481     hidl_vec<Closure> closures = {closure1, closure2};
482     ScriptGroup2 scriptGroup2 = context->scriptGroup2Create(name, cacheDir, closures);
483     ASSERT_NE(ScriptGroup2(0), scriptGroup2);
484 
485     context->scriptGroupExecute(scriptGroup2);
486     context->allocationRead(allocation, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(uint8_t));
487     EXPECT_EQ(expected, dataOut);
488 }
489 
490 /*
491  * Similar to the ScriptGroup test, this test verifies a single kernel can be
492  * called by ScriptGroup with an unbound allocation specified before launch
493  *
494  * Calls: scriptCCreate, elementCreate, typeCreate, allocationCreateTyped,
495  * allocation1DWrite, scriptKernelIDCreate, closureCreate, closureSetArg,
496  * scriptGroup2Create, scriptGroupExecute, allocationRead
497  */
TEST_F(RenderscriptHidlTest,ScriptGroup2KernelTest)498 TEST_F(RenderscriptHidlTest, ScriptGroup2KernelTest) {
499     hidl_vec<uint8_t> bitcode;
500     bitcode.setToExternal((uint8_t*)bitCode, bitCodeLength);
501     Script script = context->scriptCCreate("struct_test", "/data/local/tmp/", bitcode);
502     ASSERT_NE(Script(0), script);
503 
504     std::vector<uint8_t> dataIn(128, 128), dataOut(128, 0), expected(128, 128 + 1);
505     hidl_vec<uint8_t> _dataIn, _dataOut;
506     _dataIn.setToExternal(dataIn.data(), dataIn.size());
507 
508     // 256 x 256 YUV pixels
509     Element element = context->elementCreate(DataType::UNSIGNED_8, DataKind::USER, false, 1);
510     ASSERT_NE(Element(0), element);
511 
512     Type type = context->typeCreate(element, 128, 0, 0, false, false, YuvFormat::YUV_NONE);
513     ASSERT_NE(Type(0), type);
514 
515     Allocation allocation = context->allocationCreateTyped(type, AllocationMipmapControl::NONE,
516                                                            (int)AllocationUsageType::SCRIPT,
517                                                            (Ptr)nullptr);
518     ASSERT_NE(Allocation(0), allocation);
519 
520     context->allocation1DWrite(allocation, 0, 0, (Size)_dataIn.size(), _dataIn);
521 
522     // kernel
523     ScriptKernelID kernelID = context->scriptKernelIDCreate(script, mExportForEachIdx_increment, 3);
524     ASSERT_NE(ScriptKernelID(0), kernelID);
525 
526     hidl_vec<ScriptFieldID> fieldIDS = {ScriptFieldID(0)};
527     hidl_vec<int64_t> values = {int64_t(0)};
528     hidl_vec<int32_t> sizes = {int32_t(0)};
529     hidl_vec<Closure> depClosures = {Closure(0)};
530     hidl_vec<ScriptFieldID> depFieldIDS = {ScriptFieldID(0)};
531     Closure closure = context->closureCreate(kernelID, allocation /* returnValue */, fieldIDS,
532                                               values, sizes, depClosures, depFieldIDS);
533     ASSERT_NE(Closure(0), closure);
534 
535     // set argument
536     context->closureSetArg(closure, 0 /* first argument */, (Ptr)allocation, -1);
537 
538     // execute
539     hidl_string name = "script_group_2_test";
540     hidl_string cacheDir = "/data/local/tmp";
541     hidl_vec<Closure> closures = {closure};
542     ScriptGroup2 scriptGroup2 = context->scriptGroup2Create(name, cacheDir, closures);
543     ASSERT_NE(ScriptGroup2(0), scriptGroup2);
544 
545     context->scriptGroupExecute(scriptGroup2);
546     context->allocationRead(allocation, (Ptr)dataOut.data(), (Size)dataOut.size()*sizeof(uint8_t));
547     EXPECT_EQ(expected, dataOut);
548 }
549