xref: /aosp_15_r20/cts/tests/tests/uirendering/src/android/uirendering/cts/testclasses/MeshTest.kt (revision b7c941bb3fa97aba169d73cee0bed2de8ac964bf)
1 /*
<lambda>null2  * Copyright (C) 2022 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 package android.uirendering.cts.testclasses
18 
19 import android.graphics.BlendMode
20 import android.graphics.Canvas
21 import android.graphics.Color
22 import android.graphics.ColorSpace
23 import android.graphics.Mesh
24 import android.graphics.MeshSpecification
25 import android.graphics.Paint
26 import android.graphics.Point
27 import android.graphics.PointF
28 import android.graphics.Rect
29 import android.graphics.RectF
30 import android.uirendering.cts.bitmapverifiers.RectVerifier
31 import android.uirendering.cts.bitmapverifiers.SamplePointVerifier
32 import android.uirendering.cts.testinfrastructure.ActivityTestBase
33 import androidx.test.ext.junit.runners.AndroidJUnit4
34 import androidx.test.filters.MediumTest
35 import java.nio.Buffer
36 import java.nio.ByteBuffer
37 import java.nio.FloatBuffer
38 import java.nio.ShortBuffer
39 import kotlin.test.assertEquals
40 import kotlin.test.assertFalse
41 import kotlin.test.assertTrue
42 import org.junit.Assert.assertThrows
43 import org.junit.Test
44 import org.junit.runner.RunWith
45 
46 @MediumTest
47 @RunWith(AndroidJUnit4::class)
48 class MeshTest : ActivityTestBase() {
49 
50     // /////////////    MeshSpecification Tests    ///////////////
51 
52     @Test
53     fun setSmallerStride() {
54         assertThrows(IllegalArgumentException::class.java) {
55             MeshSpecification.make(
56                     simpleAttributeList, 4, simpleVaryingList,
57                     simpleVertexShader, simpleFragmentShader
58             )
59         }
60     }
61 
62     @Test
63     fun setInvalidVS() {
64         // doesn't return Varyings
65         val vs: String = ("main(const Attributes attributes) { " +
66                 "     Varyings varyings;" +
67                 "     varyings.position = attributes.position;" +
68                 "     return varyings;" +
69                 "}")
70         assertThrows(IllegalArgumentException::class.java) {
71             MeshSpecification.make(
72                     simpleAttributeList, 8, simpleVaryingList, vs,
73                     simpleFragmentShader
74             )
75         }
76     }
77 
78     @Test
79     fun setInvalidFS() {
80         val fs: String = ("float2 main(const Varyings varyings) {" +
81                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
82                 "      return varyings.position;" +
83                 "}")
84 
85         assertThrows(IllegalArgumentException::class.java) {
86             MeshSpecification.make(
87                     simpleAttributeList, 8, simpleVaryingList,
88                     simpleVertexShader, fs
89             )
90         }
91     }
92 
93     @Test
94     fun testValidMeshSpecMake() {
95         MeshSpecification.make(
96                 simpleAttributeList, 8, simpleVaryingList,
97                 simpleVertexShader, simpleFragmentShader
98         )
99     }
100 
101     @Test
102     fun testMeshSpecWithColorSpace() {
103         MeshSpecification.make(
104                 simpleAttributeList, 8, simpleVaryingList,
105                 simpleVertexShader, simpleFragmentShader,
106                 ColorSpace.get(ColorSpace.Named.DISPLAY_P3)
107         )
108     }
109 
110     @Test
111     fun testMeshSpecWithAlphaType() {
112         MeshSpecification.make(
113                 simpleAttributeList, 8, simpleVaryingList,
114                 simpleVertexShader, simpleFragmentShader,
115                 ColorSpace.get(ColorSpace.Named.DISPLAY_P3),
116                 MeshSpecification.ALPHA_TYPE_PREMULTIPLIED
117         )
118     }
119 
120     @Test
121     fun testMeshSpecWithUnpremultipliedAlphaType() {
122         MeshSpecification.make(
123             simpleAttributeList, 8, simpleVaryingList,
124             simpleVertexShader, simpleFragmentShader,
125             ColorSpace.get(ColorSpace.Named.DISPLAY_P3),
126             MeshSpecification.ALPHA_TYPE_UNPREMULTIPLIED
127         )
128     }
129 
130     @Test
131     fun testMeshSpecMakeWithUnorderedAttributes() {
132         val attList = arrayOf(
133                 MeshSpecification.Attribute(
134                         MeshSpecification.TYPE_FLOAT2,
135                         12,
136                         "position"
137                 ),
138                 MeshSpecification.Attribute(
139                         MeshSpecification.TYPE_FLOAT3,
140                         0,
141                         "test"
142                 )
143         )
144         MeshSpecification.make(
145                 attList, 20, simpleVaryingList, simpleVertexShader,
146                 simpleFragmentShader
147         )
148     }
149 
150     @Test
151     fun testMeshSpecMakeWithBiggerStride() {
152         MeshSpecification.make(
153                 simpleAttributeList, 112, simpleVaryingList,
154                 simpleVertexShader, simpleFragmentShader
155         )
156     }
157 
158     @Test
159     fun testMeshSpecMakeWithNonEmptyVaryings() {
160         val varyList = arrayOf(
161                 MeshSpecification.Varying(MeshSpecification.TYPE_FLOAT2, "uv")
162         )
163         MeshSpecification.make(
164                 simpleAttributeList, 8, varyList, simpleVertexShader,
165                 simpleFragmentShader
166         )
167     }
168 
169     // /////////////    Mesh Tests    ///////////////
170 
171     @Test
172     fun setInvalidMode() {
173         val meshSpec = MeshSpecification.make(
174                 simpleAttributeList, 8, simpleVaryingList,
175                 simpleVertexShader, simpleFragmentShader
176         )
177         val vertexBuffer = FloatBuffer.allocate(6)
178         vertexBuffer.put(0f)
179         vertexBuffer.put(0f)
180         vertexBuffer.put(50f)
181         vertexBuffer.put(50f)
182         vertexBuffer.put(0f)
183         vertexBuffer.put(50f)
184         vertexBuffer.rewind()
185         assertThrows(IllegalArgumentException::class.java) {
186             Mesh(meshSpec, 6, vertexBuffer, 3, RectF(0f, 0f, 0f, 0f))
187         }
188     }
189 
190     @Test
191     fun setWrongVertexCountSmall() {
192         val meshSpec = MeshSpecification.make(
193                 simpleAttributeList, 8, simpleVaryingList,
194                 simpleVertexShader, simpleFragmentShader
195         )
196         val vertexBuffer = FloatBuffer.allocate(6)
197         vertexBuffer.put(0f)
198         vertexBuffer.put(0f)
199         vertexBuffer.put(50f)
200         vertexBuffer.put(50f)
201         vertexBuffer.put(0f)
202         vertexBuffer.put(50f)
203         vertexBuffer.rewind()
204         assertThrows(IllegalArgumentException::class.java) {
205             Mesh(meshSpec, Mesh.TRIANGLES, vertexBuffer, 1, RectF(0f, 0f, 0f, 0f))
206         }
207     }
208 
209     @Test
210     fun setWrongVertexCountBig() {
211         val meshSpec = MeshSpecification.make(
212                 simpleAttributeList, 8, simpleVaryingList,
213                 simpleVertexShader, simpleFragmentShader
214         )
215         val vertexBuffer = FloatBuffer.allocate(6)
216         vertexBuffer.put(0f)
217         vertexBuffer.put(0f)
218         vertexBuffer.put(50f)
219         vertexBuffer.put(50f)
220         vertexBuffer.put(0f)
221         vertexBuffer.put(50f)
222         vertexBuffer.rewind()
223         assertThrows(IllegalArgumentException::class.java) {
224             Mesh(meshSpec, Mesh.TRIANGLES, vertexBuffer, 100, RectF(0f, 0f, 0f, 0f))
225         }
226     }
227 
228     @Test
229     fun setBadVertexBuffer() {
230         val meshSpec = MeshSpecification.make(
231                 simpleAttributeList, 8, simpleVaryingList,
232                 simpleVertexShader, simpleFragmentShader
233         )
234         val vertexBuffer = FloatBuffer.allocate(6)
235         vertexBuffer.put(0f)
236         vertexBuffer.put(0f)
237         vertexBuffer.put(50f)
238         vertexBuffer.put(50f)
239         vertexBuffer.put(0f)
240         vertexBuffer.put(50f)
241         assertThrows(IllegalArgumentException::class.java) {
242             Mesh(meshSpec, Mesh.TRIANGLES, vertexBuffer, 3, RectF(0f, 0f, 0f, 0f))
243         }
244     }
245 
246     @Test
247     fun testMeshMakeInvalidUniform() {
248         val meshSpec = MeshSpecification.make(
249             simpleAttributeList, 8, simpleVaryingList,
250             simpleVertexShader, simpleFragmentShader
251         )
252         val vertexBuffer = FloatBuffer.allocate(6)
253         vertexBuffer.put(0f)
254         vertexBuffer.put(0f)
255         vertexBuffer.put(50f)
256         vertexBuffer.put(50f)
257         vertexBuffer.put(0f)
258         vertexBuffer.put(50f)
259         vertexBuffer.rewind()
260         val mesh = Mesh(meshSpec, Mesh.TRIANGLES, vertexBuffer, 3, RectF(0f, 0f, 0f, 0f))
261 
262         assertThrows(IllegalArgumentException::class.java) {
263             mesh.setFloatUniform("test", 1f)
264         }
265     }
266 
267     @Test
268     fun testValidMeshMake() {
269         val meshSpec = MeshSpecification.make(
270                 simpleAttributeList, 8, simpleVaryingList,
271                 simpleVertexShader, simpleFragmentShader
272         )
273         val vertexBuffer = FloatBuffer.allocate(6)
274         vertexBuffer.put(0f)
275         vertexBuffer.put(0f)
276         vertexBuffer.put(50f)
277         vertexBuffer.put(50f)
278         vertexBuffer.put(0f)
279         vertexBuffer.put(50f)
280         vertexBuffer.rewind()
281         Mesh(meshSpec, Mesh.TRIANGLES, vertexBuffer, 3, RectF(0f, 0f, 0f, 0f))
282     }
283 
284     @Test
285     fun testValidMeshMakeIndexed() {
286         val meshSpec = MeshSpecification.make(
287                 simpleAttributeList, 8, simpleVaryingList,
288                 simpleVertexShader, simpleFragmentShader
289         )
290         val vertexBuffer = FloatBuffer.allocate(6)
291         vertexBuffer.put(0f)
292         vertexBuffer.put(0f)
293         vertexBuffer.put(50f)
294         vertexBuffer.put(50f)
295         vertexBuffer.put(0f)
296         vertexBuffer.put(50f)
297         vertexBuffer.rewind()
298         val indexBuffer = ShortBuffer.allocate(3)
299         indexBuffer.put(0, 0)
300         indexBuffer.put(1, 1)
301         indexBuffer.put(2, 2)
302         indexBuffer.rewind()
303         Mesh(
304                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 3, indexBuffer,
305                 RectF(0f, 0f, 100f, 100f)
306         )
307     }
308 
309     @Test
310     fun testMeshIndirectIndexAndVertexBuffers() {
311         // vertex -> indirect
312         // index -> indirect
313         val vertexBuffer = FloatBuffer.wrap(
314                 floatArrayOf(0f, 0f, 50f, 50f, 0f, 50f))
315         assertFalse(vertexBuffer.isDirect)
316         vertexBuffer.rewind()
317         val indexBuffer = ShortBuffer.wrap(shortArrayOf(0, 1, 2))
318         assertFalse(indexBuffer.isDirect)
319         indexBuffer.rewind()
320         testMeshHelper(vertexBuffer, indexBuffer)
321     }
322 
323     @Test
324     fun testMeshDirectIndexAndVertexBuffers() {
325         // vertex -> direct
326         // index -> direct
327         val numFloats = 6
328         val vertexBuffer = ByteBuffer.allocateDirect(numFloats * 4).asFloatBuffer().apply {
329             put(0f)
330             put(0f)
331             put(50f)
332             put(50f)
333             put(0f)
334             put(50f)
335         }
336         assertTrue(vertexBuffer.isDirect)
337         vertexBuffer.rewind()
338         val numShorts = 3
339         val indexBuffer = ByteBuffer.allocateDirect(numShorts * 2).asShortBuffer().apply {
340             put(0)
341             put(1)
342             put(2)
343         }
344         assertTrue(indexBuffer.isDirect)
345         indexBuffer.rewind()
346         testMeshHelper(vertexBuffer, indexBuffer)
347     }
348 
349     @Test
350     fun testMeshDirectVertexWithIndirectIndexBuffers() {
351         // vertex -> direct
352         // index -> indirect
353         val numFloats = 6
354         val vertexBuffer = ByteBuffer.allocateDirect(numFloats * 4).asFloatBuffer().apply {
355             put(0f)
356             put(0f)
357             put(50f)
358             put(50f)
359             put(0f)
360             put(50f)
361         }
362         assertTrue(vertexBuffer.isDirect)
363         vertexBuffer.rewind()
364         val numShorts = 3
365         val indexBuffer = ShortBuffer.allocate(numShorts).apply {
366             put(0)
367             put(1)
368             put(2)
369         }
370         assertFalse(indexBuffer.isDirect)
371         indexBuffer.rewind()
372         testMeshHelper(vertexBuffer, indexBuffer)
373     }
374 
375     @Test
376     fun testMeshIndirectVertexWithDirectIndexBuffers() {
377         // vertex -> indirect
378         // index -> direct
379         val numFloats = 6
380         val vertexBuffer = FloatBuffer.allocate(numFloats).apply {
381             put(0f)
382             put(0f)
383             put(50f)
384             put(50f)
385             put(0f)
386             put(50f)
387         }
388         assertFalse(vertexBuffer.isDirect)
389         vertexBuffer.rewind()
390         val numShorts = 3
391         val indexBuffer = ByteBuffer.allocateDirect(numShorts * 2).asShortBuffer().apply {
392             put(0)
393             put(1)
394             put(2)
395         }
396         assertTrue(indexBuffer.isDirect)
397         indexBuffer.rewind()
398         testMeshHelper(vertexBuffer, indexBuffer)
399     }
400 
401     private fun testMeshHelper(vertexBuffer: Buffer, indexBuffer: ShortBuffer) {
402         val meshSpec = MeshSpecification.make(
403                 simpleAttributeList, 8, simpleVaryingList,
404                 simpleVertexShader, simpleFragmentShader
405         )
406         Mesh(
407                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 3, indexBuffer,
408                 RectF(0f, 0f, 100f, 100f)
409         )
410     }
411 
412     // /////////////    drawMesh Tests    ///////////////
413     // @Test
414     fun testSimpleDrawMesh() {
415         val meshSpec = MeshSpecification.make(
416                 simpleAttributeList, 8, simpleVaryingList,
417                 simpleVertexShader, simpleFragmentShader
418         )
419         val vertexBuffer = FloatBuffer.allocate(12)
420         vertexBuffer.put(20f)
421         vertexBuffer.put(20f)
422         vertexBuffer.put(80f)
423         vertexBuffer.put(80f)
424         vertexBuffer.put(20f)
425         vertexBuffer.put(80f)
426         vertexBuffer.put(80f)
427         vertexBuffer.put(20f)
428         vertexBuffer.put(20f)
429         vertexBuffer.put(20f)
430         vertexBuffer.put(80f)
431         vertexBuffer.put(80f)
432         vertexBuffer.rewind()
433 
434         val rect = Rect(20, 20, 80, 80)
435         val paint = Paint()
436         paint.color = Color.BLUE
437         val mesh = Mesh(
438                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
439                 RectF(20f, 20f, 80f, 80f)
440         )
441 
442         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
443             canvas.drawMesh(mesh, BlendMode.SRC, paint)
444         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
445     }
446 
447     @Test
448     fun testSimpleIndexedDrawMesh() {
449         val meshSpec = MeshSpecification.make(
450                 simpleAttributeList, 8, simpleVaryingList,
451                 simpleVertexShader, simpleFragmentShader
452         )
453         val vertexBuffer = FloatBuffer.allocate(12)
454         vertexBuffer.put(20f) // tl
455         vertexBuffer.put(20f)
456 
457         vertexBuffer.put(80f) // br
458         vertexBuffer.put(80f)
459 
460         vertexBuffer.put(20f) // bl
461         vertexBuffer.put(80f)
462 
463         vertexBuffer.put(80f) // tr
464         vertexBuffer.put(20f)
465 
466         vertexBuffer.put(20f)
467         vertexBuffer.put(90f)
468 
469         vertexBuffer.put(90f)
470         vertexBuffer.put(80f)
471         vertexBuffer.rewind()
472         val indexBuffer = ShortBuffer.allocate(12)
473         indexBuffer.put(0, 0)
474         indexBuffer.put(1, 1)
475         indexBuffer.put(2, 2)
476 
477         indexBuffer.put(3, 0)
478         indexBuffer.put(4, 1)
479         indexBuffer.put(5, 3)
480 
481         indexBuffer.put(6, 3)
482         indexBuffer.put(7, 1)
483         indexBuffer.put(8, 5)
484 
485         indexBuffer.put(9, 1)
486         indexBuffer.put(10, 3)
487         indexBuffer.put(11, 4)
488         indexBuffer.rewind()
489 
490         val paint = Paint()
491         paint.color = Color.BLUE
492         val mesh = Mesh(
493                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
494                 indexBuffer, RectF(20f, 20f, 90f, 90f)
495         )
496         val points = Array(3) {
497             Point(30, 30)
498         }
499         points[1] = Point(40, 40)
500         points[2] = Point(89, 89)
501         val colors = intArrayOf(
502                 Color.BLUE,
503                 Color.BLUE,
504                 Color.WHITE
505         )
506         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
507             canvas.drawMesh(mesh, BlendMode.SRC, paint)
508         }, true).runWithVerifier(SamplePointVerifier(points, colors))
509     }
510 
511     @Test
512     fun testDrawMeshWithColorUniformInt() {
513         val fragmentShader = ("layout(color) uniform float4 color;" +
514                 "float2 main(const Varyings varyings, out float4 color) {\n" +
515                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
516                 "      return varyings.position;\n" +
517                 "}")
518         val meshSpec = MeshSpecification.make(
519                 simpleAttributeList, 8, simpleVaryingList,
520                 simpleVertexShader, fragmentShader
521         )
522         val vertexBuffer = FloatBuffer.allocate(12)
523         vertexBuffer.put(20f)
524         vertexBuffer.put(20f)
525         vertexBuffer.put(80f)
526         vertexBuffer.put(80f)
527         vertexBuffer.put(20f)
528         vertexBuffer.put(80f)
529         vertexBuffer.put(80f)
530         vertexBuffer.put(20f)
531         vertexBuffer.put(20f)
532         vertexBuffer.put(20f)
533         vertexBuffer.put(80f)
534         vertexBuffer.put(80f)
535         vertexBuffer.rewind()
536 
537         val rect = Rect(20, 20, 80, 80)
538         val paint = Paint()
539         paint.color = Color.BLUE
540         val mesh = Mesh(
541                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
542                 RectF(20f, 20f, 80f, 80f)
543         )
544 
545         mesh.setColorUniform("color", Color.GREEN)
546         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
547             canvas.drawMesh(mesh, BlendMode.SRC, paint)
548         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
549     }
550 
551     @Test
552     fun testDrawMeshWithColorUniformObject() {
553         val fragmentShader = ("layout(color) uniform float4 color;" +
554                 "float2 main(const Varyings varyings, out float4 color) {\n" +
555                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
556                 "      return varyings.position;\n" +
557                 "}")
558         val meshSpec = MeshSpecification.make(
559             simpleAttributeList, 8, simpleVaryingList,
560             simpleVertexShader, fragmentShader
561         )
562         val vertexBuffer = FloatBuffer.allocate(12)
563         vertexBuffer.put(20f)
564         vertexBuffer.put(20f)
565         vertexBuffer.put(80f)
566         vertexBuffer.put(80f)
567         vertexBuffer.put(20f)
568         vertexBuffer.put(80f)
569         vertexBuffer.put(80f)
570         vertexBuffer.put(20f)
571         vertexBuffer.put(20f)
572         vertexBuffer.put(20f)
573         vertexBuffer.put(80f)
574         vertexBuffer.put(80f)
575         vertexBuffer.rewind()
576 
577         val rect = Rect(20, 20, 80, 80)
578         val paint = Paint()
579         paint.color = Color.BLUE
580         val mesh = Mesh(
581                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
582                 RectF(20f, 20f, 80f, 80f)
583         )
584 
585         mesh.setColorUniform("color", Color())
586         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
587             canvas.drawMesh(mesh, BlendMode.SRC, paint)
588         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
589     }
590 
591     @Test
592     fun testDrawMeshWithColorUniformLong() {
593         val fragmentShader = ("layout(color) uniform float4 color;" +
594                 "float2 main(const Varyings varyings, out float4 color) {\n" +
595                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
596                 "      return varyings.position;\n" +
597                 "}")
598         val meshSpec = MeshSpecification.make(
599             simpleAttributeList, 8, simpleVaryingList,
600             simpleVertexShader, fragmentShader
601         )
602         val vertexBuffer = FloatBuffer.allocate(12)
603         vertexBuffer.put(20f)
604         vertexBuffer.put(20f)
605         vertexBuffer.put(80f)
606         vertexBuffer.put(80f)
607         vertexBuffer.put(20f)
608         vertexBuffer.put(80f)
609         vertexBuffer.put(80f)
610         vertexBuffer.put(20f)
611         vertexBuffer.put(20f)
612         vertexBuffer.put(20f)
613         vertexBuffer.put(80f)
614         vertexBuffer.put(80f)
615         vertexBuffer.rewind()
616 
617         val rect = Rect(20, 20, 80, 80)
618         val paint = Paint()
619         paint.color = Color.BLUE
620         val mesh = Mesh(
621                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
622                 RectF(20f, 20f, 80f, 80f)
623         )
624 
625         mesh.setColorUniform("color", 0L)
626         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
627             canvas.drawMesh(mesh, BlendMode.SRC, paint)
628         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
629     }
630 
631     @Test
632     fun testDrawMeshWithIntUniform() {
633         val fragmentShader = ("uniform int test;" +
634                 "float2 main(const Varyings varyings, out float4 color) {\n" +
635                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
636                 "      return varyings.position;\n" +
637                 "}")
638         val meshSpec = MeshSpecification.make(
639             simpleAttributeList, 8, simpleVaryingList,
640             simpleVertexShader, fragmentShader
641         )
642         val vertexBuffer = FloatBuffer.allocate(12)
643         vertexBuffer.put(20f)
644         vertexBuffer.put(20f)
645         vertexBuffer.put(80f)
646         vertexBuffer.put(80f)
647         vertexBuffer.put(20f)
648         vertexBuffer.put(80f)
649         vertexBuffer.put(80f)
650         vertexBuffer.put(20f)
651         vertexBuffer.put(20f)
652         vertexBuffer.put(20f)
653         vertexBuffer.put(80f)
654         vertexBuffer.put(80f)
655         vertexBuffer.rewind()
656 
657         val rect = Rect(20, 20, 80, 80)
658         val paint = Paint()
659         paint.color = Color.BLUE
660         val mesh = Mesh(
661                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
662                 RectF(20f, 20f, 80f, 80f)
663         )
664 
665         mesh.setIntUniform("test", 2)
666         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
667             canvas.drawMesh(mesh, BlendMode.SRC, paint)
668         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
669     }
670 
671     @Test
672     fun testDrawMeshWithIntUniformTwo() {
673         val fragmentShader = ("uniform int2 test;" +
674                 "float2 main(const Varyings varyings, out float4 color) {\n" +
675                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
676                 "      return varyings.position;\n" +
677                 "}")
678         val meshSpec = MeshSpecification.make(
679             simpleAttributeList, 8, simpleVaryingList,
680             simpleVertexShader, fragmentShader
681         )
682         val vertexBuffer = FloatBuffer.allocate(12)
683         vertexBuffer.put(20f)
684         vertexBuffer.put(20f)
685         vertexBuffer.put(80f)
686         vertexBuffer.put(80f)
687         vertexBuffer.put(20f)
688         vertexBuffer.put(80f)
689         vertexBuffer.put(80f)
690         vertexBuffer.put(20f)
691         vertexBuffer.put(20f)
692         vertexBuffer.put(20f)
693         vertexBuffer.put(80f)
694         vertexBuffer.put(80f)
695         vertexBuffer.rewind()
696 
697         val rect = Rect(20, 20, 80, 80)
698         val paint = Paint()
699         paint.color = Color.BLUE
700         val mesh = Mesh(
701                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
702                 RectF(20f, 20f, 80f, 80f)
703         )
704 
705         mesh.setIntUniform("test", 1, 2)
706         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
707             canvas.drawMesh(mesh, BlendMode.SRC, paint)
708         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
709     }
710 
711     @Test
712     fun testDrawMeshWithIntUniformThree() {
713         val fragmentShader = ("uniform int3 test;" +
714                 "float2 main(const Varyings varyings, out float4 color) {\n" +
715                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
716                 "      return varyings.position;\n" +
717                 "}")
718         val meshSpec = MeshSpecification.make(
719             simpleAttributeList, 8, simpleVaryingList,
720             simpleVertexShader, fragmentShader
721         )
722         val vertexBuffer = FloatBuffer.allocate(12)
723         vertexBuffer.put(20f)
724         vertexBuffer.put(20f)
725         vertexBuffer.put(80f)
726         vertexBuffer.put(80f)
727         vertexBuffer.put(20f)
728         vertexBuffer.put(80f)
729         vertexBuffer.put(80f)
730         vertexBuffer.put(20f)
731         vertexBuffer.put(20f)
732         vertexBuffer.put(20f)
733         vertexBuffer.put(80f)
734         vertexBuffer.put(80f)
735         vertexBuffer.rewind()
736 
737         val rect = Rect(20, 20, 80, 80)
738         val paint = Paint()
739         paint.color = Color.BLUE
740         val mesh = Mesh(
741                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
742                 RectF(20f, 20f, 80f, 80f)
743         )
744 
745         mesh.setIntUniform("test", 1, 2, 3)
746         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
747             canvas.drawMesh(mesh, BlendMode.SRC, paint)
748         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
749     }
750 
751     @Test
752     fun testDrawMeshWithIntUniformFour() {
753         val fragmentShader = ("uniform int4 test;" +
754                 "float2 main(const Varyings varyings, out float4 color) {\n" +
755                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
756                 "      return varyings.position;\n" +
757                 "}")
758         val meshSpec = MeshSpecification.make(
759             simpleAttributeList, 8, simpleVaryingList,
760             simpleVertexShader, fragmentShader
761         )
762         val vertexBuffer = FloatBuffer.allocate(12)
763         vertexBuffer.put(20f)
764         vertexBuffer.put(20f)
765         vertexBuffer.put(80f)
766         vertexBuffer.put(80f)
767         vertexBuffer.put(20f)
768         vertexBuffer.put(80f)
769         vertexBuffer.put(80f)
770         vertexBuffer.put(20f)
771         vertexBuffer.put(20f)
772         vertexBuffer.put(20f)
773         vertexBuffer.put(80f)
774         vertexBuffer.put(80f)
775         vertexBuffer.rewind()
776 
777         val rect = Rect(20, 20, 80, 80)
778         val paint = Paint()
779         paint.color = Color.BLUE
780         val mesh = Mesh(
781                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
782                 RectF(20f, 20f, 80f, 80f)
783         )
784 
785         mesh.setIntUniform("test", 1, 2, 3, 4)
786         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
787             canvas.drawMesh(mesh, BlendMode.SRC, paint)
788         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
789     }
790 
791     @Test
792     fun testDrawMeshWithIntUniformArray() {
793         val fragmentShader = ("uniform int4 test;" +
794                 "float2 main(const Varyings varyings, out float4 color) {\n" +
795                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
796                 "      return varyings.position;\n" +
797                 "}")
798         val meshSpec = MeshSpecification.make(
799             simpleAttributeList, 8, simpleVaryingList,
800             simpleVertexShader, fragmentShader
801         )
802         val vertexBuffer = FloatBuffer.allocate(12)
803         vertexBuffer.put(20f)
804         vertexBuffer.put(20f)
805         vertexBuffer.put(80f)
806         vertexBuffer.put(80f)
807         vertexBuffer.put(20f)
808         vertexBuffer.put(80f)
809         vertexBuffer.put(80f)
810         vertexBuffer.put(20f)
811         vertexBuffer.put(20f)
812         vertexBuffer.put(20f)
813         vertexBuffer.put(80f)
814         vertexBuffer.put(80f)
815         vertexBuffer.rewind()
816 
817         val rect = Rect(20, 20, 80, 80)
818         val paint = Paint()
819         paint.color = Color.BLUE
820         val mesh = Mesh(
821                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
822                 RectF(20f, 20f, 80f, 80f)
823         )
824 
825         mesh.setIntUniform("test", intArrayOf(1, 2, 3, 4))
826         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
827             canvas.drawMesh(mesh, BlendMode.SRC, paint)
828         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
829     }
830 
831     @Test
832     fun testDrawMeshWithFloatUniform() {
833         val fragmentShader = ("uniform float test;" +
834                 "float2 main(const Varyings varyings, out float4 color) {\n" +
835                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
836                 "      return varyings.position;\n" +
837                 "}")
838         val meshSpec = MeshSpecification.make(
839             simpleAttributeList, 8, simpleVaryingList,
840             simpleVertexShader, fragmentShader
841         )
842         val vertexBuffer = FloatBuffer.allocate(12)
843         vertexBuffer.put(20f)
844         vertexBuffer.put(20f)
845         vertexBuffer.put(80f)
846         vertexBuffer.put(80f)
847         vertexBuffer.put(20f)
848         vertexBuffer.put(80f)
849         vertexBuffer.put(80f)
850         vertexBuffer.put(20f)
851         vertexBuffer.put(20f)
852         vertexBuffer.put(20f)
853         vertexBuffer.put(80f)
854         vertexBuffer.put(80f)
855         vertexBuffer.rewind()
856 
857         val rect = Rect(20, 20, 80, 80)
858         val paint = Paint()
859         paint.color = Color.BLUE
860         val mesh = Mesh(
861                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
862                 RectF(20f, 20f, 80f, 80f)
863         )
864 
865         mesh.setFloatUniform("test", 1f)
866         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
867             canvas.drawMesh(mesh, BlendMode.SRC, paint)
868         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
869     }
870 
871     @Test
872     fun testDrawMeshWithFloatUniformTwo() {
873         val fragmentShader = ("uniform float2 test;" +
874                 "float2 main(const Varyings varyings, out float4 color) {\n" +
875                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
876                 "      return varyings.position;\n" +
877                 "}")
878         val meshSpec = MeshSpecification.make(
879             simpleAttributeList, 8, simpleVaryingList,
880             simpleVertexShader, fragmentShader
881         )
882         val vertexBuffer = FloatBuffer.allocate(12)
883         vertexBuffer.put(20f)
884         vertexBuffer.put(20f)
885         vertexBuffer.put(80f)
886         vertexBuffer.put(80f)
887         vertexBuffer.put(20f)
888         vertexBuffer.put(80f)
889         vertexBuffer.put(80f)
890         vertexBuffer.put(20f)
891         vertexBuffer.put(20f)
892         vertexBuffer.put(20f)
893         vertexBuffer.put(80f)
894         vertexBuffer.put(80f)
895         vertexBuffer.rewind()
896 
897         val rect = Rect(20, 20, 80, 80)
898         val paint = Paint()
899         paint.color = Color.BLUE
900         val mesh = Mesh(
901                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
902                 RectF(20f, 20f, 80f, 80f)
903         )
904 
905         mesh.setFloatUniform("test", 1f, 2f)
906         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
907             canvas.drawMesh(mesh, BlendMode.SRC, paint)
908         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
909     }
910 
911     @Test
912     fun testDrawMeshWithFloatUniformThree() {
913         val fragmentShader = ("uniform float3 test;" +
914                 "float2 main(const Varyings varyings, out float4 color) {\n" +
915                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
916                 "      return varyings.position;\n" +
917                 "}")
918         val meshSpec = MeshSpecification.make(
919             simpleAttributeList, 8, simpleVaryingList,
920             simpleVertexShader, fragmentShader
921         )
922         val vertexBuffer = FloatBuffer.allocate(12)
923         vertexBuffer.put(20f)
924         vertexBuffer.put(20f)
925         vertexBuffer.put(80f)
926         vertexBuffer.put(80f)
927         vertexBuffer.put(20f)
928         vertexBuffer.put(80f)
929         vertexBuffer.put(80f)
930         vertexBuffer.put(20f)
931         vertexBuffer.put(20f)
932         vertexBuffer.put(20f)
933         vertexBuffer.put(80f)
934         vertexBuffer.put(80f)
935         vertexBuffer.rewind()
936 
937         val rect = Rect(20, 20, 80, 80)
938         val paint = Paint()
939         paint.color = Color.BLUE
940         val mesh = Mesh(
941                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
942                 RectF(20f, 20f, 80f, 80f)
943         )
944 
945         mesh.setFloatUniform("test", 1f, 2f, 3f)
946         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
947             canvas.drawMesh(mesh, BlendMode.SRC, paint)
948         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
949     }
950 
951     @Test
952     fun testDrawMeshWithFloatUniformFour() {
953         val fragmentShader = ("uniform float4 test;" +
954                 "float2 main(const Varyings varyings, out float4 color) {\n" +
955                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
956                 "      return varyings.position;\n" +
957                 "}")
958         val meshSpec = MeshSpecification.make(
959             simpleAttributeList, 8, simpleVaryingList,
960             simpleVertexShader, fragmentShader
961         )
962         val vertexBuffer = FloatBuffer.allocate(12)
963         vertexBuffer.put(20f)
964         vertexBuffer.put(20f)
965         vertexBuffer.put(80f)
966         vertexBuffer.put(80f)
967         vertexBuffer.put(20f)
968         vertexBuffer.put(80f)
969         vertexBuffer.put(80f)
970         vertexBuffer.put(20f)
971         vertexBuffer.put(20f)
972         vertexBuffer.put(20f)
973         vertexBuffer.put(80f)
974         vertexBuffer.put(80f)
975         vertexBuffer.rewind()
976 
977         val rect = Rect(20, 20, 80, 80)
978         val paint = Paint()
979         paint.color = Color.BLUE
980         val mesh = Mesh(
981                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
982                 RectF(20f, 20f, 80f, 80f)
983         )
984 
985         mesh.setFloatUniform("test", 1f, 2f, 3f, 4f)
986         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
987             canvas.drawMesh(mesh, BlendMode.SRC, paint)
988         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
989     }
990 
991     @Test
992     fun testDrawMeshWithFloatUniformArray() {
993         val fragmentShader = ("uniform float2 test;" +
994                 "float2 main(const Varyings varyings, out float4 color) {\n" +
995                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
996                 "      return varyings.position;\n" +
997                 "}")
998         val meshSpec = MeshSpecification.make(
999             simpleAttributeList, 8, simpleVaryingList,
1000             simpleVertexShader, fragmentShader
1001         )
1002         val vertexBuffer = FloatBuffer.allocate(12)
1003         vertexBuffer.put(20f)
1004         vertexBuffer.put(20f)
1005         vertexBuffer.put(80f)
1006         vertexBuffer.put(80f)
1007         vertexBuffer.put(20f)
1008         vertexBuffer.put(80f)
1009         vertexBuffer.put(80f)
1010         vertexBuffer.put(20f)
1011         vertexBuffer.put(20f)
1012         vertexBuffer.put(20f)
1013         vertexBuffer.put(80f)
1014         vertexBuffer.put(80f)
1015         vertexBuffer.rewind()
1016 
1017         val rect = Rect(20, 20, 80, 80)
1018         val paint = Paint()
1019         paint.color = Color.BLUE
1020         val mesh = Mesh(
1021                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
1022                 RectF(20f, 20f, 80f, 80f)
1023         )
1024 
1025         mesh.setFloatUniform("test", floatArrayOf(1f, 2f))
1026         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
1027             canvas.drawMesh(mesh, BlendMode.SRC, paint)
1028         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
1029     }
1030 
1031     @Test
1032     fun testDrawMeshWithIndirectFloatUniformArray() {
1033         val fragmentShader = ("uniform float2 test;" +
1034                 "float2 main(const Varyings varyings, out float4 color) {\n" +
1035                 "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
1036                 "      return varyings.position;\n" +
1037                 "}")
1038         val meshSpec = MeshSpecification.make(
1039                 simpleAttributeList, 8, simpleVaryingList,
1040                 simpleVertexShader, fragmentShader
1041         )
1042         val vertexBuffer = FloatBuffer.wrap(floatArrayOf(20f, 20f, 80f, 80f, 20f, 80f, 80f, 20f,
1043                 20f, 20f, 80f, 80f))
1044         assertFalse(vertexBuffer.isDirect)
1045         vertexBuffer.rewind()
1046 
1047         val rect = Rect(20, 20, 80, 80)
1048         val paint = Paint()
1049         paint.color = Color.BLUE
1050         val mesh = Mesh(
1051                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 6,
1052                 RectF(20f, 20f, 80f, 80f)
1053         )
1054 
1055         mesh.setFloatUniform("test", floatArrayOf(1f, 2f))
1056         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
1057             canvas.drawMesh(mesh, BlendMode.SRC, paint)
1058         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
1059     }
1060 
1061     @Test
1062     fun testDrawMeshWithOutOfOrderAttributes() {
1063         val attList = arrayOf(
1064                 MeshSpecification.Attribute(
1065                         MeshSpecification.TYPE_FLOAT,
1066                         8,
1067                         "offset"
1068                 ),
1069                 MeshSpecification.Attribute(
1070                         MeshSpecification.TYPE_FLOAT2,
1071                         0,
1072                         "position"
1073                 )
1074         )
1075         val meshSpec = MeshSpecification.make(attList, 12, simpleVaryingList,
1076                 simpleVertexShader, simpleFragmentShader)
1077         val vertexBuffer = FloatBuffer.allocate(12)
1078         vertexBuffer.put(20f)
1079         vertexBuffer.put(20f)
1080         vertexBuffer.put(1f)
1081         vertexBuffer.put(80f)
1082         vertexBuffer.put(80f)
1083         vertexBuffer.put(2f)
1084         vertexBuffer.put(20f)
1085         vertexBuffer.put(80f)
1086         vertexBuffer.put(3f)
1087         vertexBuffer.put(80f)
1088         vertexBuffer.put(20f)
1089         vertexBuffer.put(4f)
1090         vertexBuffer.rewind()
1091         val indexBuffer = ShortBuffer.allocate(6)
1092         indexBuffer.put(0, 0)
1093         indexBuffer.put(1, 1)
1094         indexBuffer.put(2, 2)
1095         indexBuffer.put(3, 0)
1096         indexBuffer.put(4, 1)
1097         indexBuffer.put(5, 3)
1098         indexBuffer.rewind()
1099 
1100         val rect = Rect(20, 20, 80, 80)
1101         val paint = Paint()
1102         paint.color = Color.BLUE
1103         val mesh = Mesh(
1104                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 4,
1105                 indexBuffer, RectF(20f, 20f, 80f, 80f)
1106         )
1107 
1108         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
1109             canvas.drawMesh(mesh, BlendMode.SRC, paint)
1110         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, rect))
1111     }
1112 
1113     @Test
1114     fun testDrawMeshTwiceWithDifferentUniforms() {
1115         val vertexShader = """
1116                 uniform float2 positionDelta;
1117                 Varyings main(const Attributes attributes) {
1118                     Varyings varyings;
1119                     varyings.position = attributes.position + positionDelta;
1120                     return varyings;
1121                 }
1122             """.trimIndent()
1123 
1124         val meshSpec = MeshSpecification.make(simpleAttributeList, 8, simpleVaryingList,
1125                 vertexShader, simpleFragmentShader)
1126 
1127         val vertexBuffer = FloatBuffer.allocate(8)
1128         vertexBuffer.put(0f)
1129         vertexBuffer.put(0f)
1130         vertexBuffer.put(20f)
1131         vertexBuffer.put(0f)
1132         vertexBuffer.put(0f)
1133         vertexBuffer.put(20f)
1134         vertexBuffer.put(20f)
1135         vertexBuffer.put(20f)
1136         vertexBuffer.rewind()
1137 
1138         val indexBuffer = ShortBuffer.allocate(6)
1139         indexBuffer.put(0, 0)
1140         indexBuffer.put(1, 1)
1141         indexBuffer.put(2, 2)
1142         indexBuffer.put(3, 1)
1143         indexBuffer.put(4, 2)
1144         indexBuffer.put(5, 3)
1145         indexBuffer.rewind()
1146 
1147         val firstDelta = PointF(30f, 10f)
1148         val secondDelta = PointF(30f, 30f)
1149         val combinedRect = Rect(30, 10, 50, 50)
1150         val paint = Paint()
1151         paint.color = Color.BLUE
1152         val mesh = Mesh(
1153             meshSpec, Mesh.TRIANGLES, vertexBuffer, 4, indexBuffer, RectF(0f, 0f, 100f, 100f)
1154         )
1155 
1156         createTest().addCanvasClient({ canvas: Canvas, width: Int, height: Int ->
1157             mesh.setFloatUniform("positionDelta", firstDelta.x, firstDelta.y)
1158             canvas.drawMesh(mesh, BlendMode.SRC, paint)
1159             mesh.setFloatUniform("positionDelta", secondDelta.x, secondDelta.y)
1160             canvas.drawMesh(mesh, BlendMode.SRC, paint)
1161         }, true).runWithVerifier(RectVerifier(Color.WHITE, paint.color, combinedRect))
1162     }
1163 
1164     @Test
1165     fun testAttributeParams() {
1166         val attribute = MeshSpecification.Attribute(
1167             MeshSpecification.TYPE_FLOAT3, 12, "myAttribute")
1168         assertEquals(MeshSpecification.TYPE_FLOAT3, attribute.type)
1169         assertEquals(12, attribute.offset)
1170         assertEquals("myAttribute", attribute.name)
1171     }
1172 
1173     @Test
1174     fun testVaryingParams() {
1175         val varying = MeshSpecification.Varying(
1176             MeshSpecification.TYPE_FLOAT2, "myVarying")
1177         assertEquals(MeshSpecification.TYPE_FLOAT2, varying.type)
1178         assertEquals("myVarying", varying.name)
1179     }
1180 
1181     @Test
1182     fun testInvalidOffsetThrows() {
1183         val meshSpec = MeshSpecification.make(
1184             simpleAttributeList, 8, simpleVaryingList,
1185             simpleVertexShader, simpleFragmentShader
1186         )
1187         val vertexBuffer = FloatBuffer.allocate(6)
1188         vertexBuffer.put(0f)
1189         vertexBuffer.put(0f)
1190         vertexBuffer.put(50f)
1191         vertexBuffer.put(50f)
1192         vertexBuffer.put(0f)
1193         vertexBuffer.put(50f)
1194         vertexBuffer.rewind()
1195         val indexBuffer = ShortBuffer.allocate(3)
1196         indexBuffer.put(0, 0)
1197         indexBuffer.put(1, 1)
1198         indexBuffer.put(2, 2)
1199         indexBuffer.rewind()
1200         indexBuffer.position(1)
1201         assertThrows(IllegalArgumentException::class.java) {
1202             Mesh(
1203                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 3, indexBuffer,
1204                 RectF(0f, 0f, 100f, 100f)
1205             )
1206         }
1207     }
1208 
1209     @Test
1210     fun testInvalidVertexCountThrows() {
1211         val meshSpec = MeshSpecification.make(
1212             simpleAttributeList, 8, simpleVaryingList,
1213             simpleVertexShader, simpleFragmentShader
1214         )
1215         val vertexBuffer = FloatBuffer.allocate(6)
1216         vertexBuffer.put(0f)
1217         vertexBuffer.put(0f)
1218         vertexBuffer.put(50f)
1219         vertexBuffer.put(50f)
1220         vertexBuffer.put(0f)
1221         vertexBuffer.put(50f)
1222         vertexBuffer.rewind()
1223         assertThrows(IllegalArgumentException::class.java) {
1224             Mesh(
1225                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 2,
1226                 RectF(0f, 0f, 100f, 100f)
1227             )
1228         }
1229     }
1230 
1231     @Test
1232     fun testInvalidIndexCountThrows() {
1233         val meshSpec = MeshSpecification.make(
1234             simpleAttributeList, 8, simpleVaryingList,
1235             simpleVertexShader, simpleFragmentShader
1236         )
1237         val vertexBuffer = FloatBuffer.allocate(6)
1238         vertexBuffer.put(0f)
1239         vertexBuffer.put(0f)
1240         vertexBuffer.put(50f)
1241         vertexBuffer.put(50f)
1242         vertexBuffer.put(0f)
1243         vertexBuffer.put(50f)
1244         vertexBuffer.rewind()
1245         val indexBuffer = ShortBuffer.allocate(1)
1246         indexBuffer.put(0, 0)
1247         indexBuffer.rewind()
1248         assertThrows(IllegalArgumentException::class.java) {
1249             Mesh(
1250                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 3, indexBuffer,
1251                 RectF(0f, 0f, 100f, 100f)
1252             )
1253         }
1254     }
1255 
1256     @Test
1257     fun testInvalidIndexOffsetThrows() {
1258         val meshSpec = MeshSpecification.make(
1259             simpleAttributeList, 8, simpleVaryingList,
1260             simpleVertexShader, simpleFragmentShader
1261         )
1262         val vertexBuffer = FloatBuffer.allocate(6)
1263         vertexBuffer.put(0f)
1264         vertexBuffer.put(0f)
1265         vertexBuffer.put(50f)
1266         vertexBuffer.put(50f)
1267         vertexBuffer.put(0f)
1268         vertexBuffer.put(50f)
1269         vertexBuffer.rewind()
1270         val indexBuffer = ShortBuffer.allocate(1)
1271         indexBuffer.put(0, 0)
1272         indexBuffer.rewind()
1273         assertThrows(IllegalArgumentException::class.java) {
1274             Mesh(
1275                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 3, indexBuffer,
1276                 RectF(0f, 0f, 100f, 100f)
1277             )
1278         }
1279     }
1280 
1281     @Test
1282     fun testIndexOffsetBeyondBoundsThrows() {
1283         val meshSpec = MeshSpecification.make(
1284             simpleAttributeList, 8, simpleVaryingList,
1285             simpleVertexShader, simpleFragmentShader
1286         )
1287         val vertexBuffer = FloatBuffer.allocate(6)
1288         vertexBuffer.put(0f)
1289         vertexBuffer.put(0f)
1290         vertexBuffer.put(50f)
1291         vertexBuffer.put(50f)
1292         vertexBuffer.put(0f)
1293         vertexBuffer.put(50f)
1294         vertexBuffer.rewind()
1295         val indexBuffer = ShortBuffer.allocate(3)
1296         indexBuffer.put(0, 0)
1297         indexBuffer.put(1, 1)
1298         indexBuffer.put(2, 2)
1299         indexBuffer.rewind()
1300         indexBuffer.position(2)
1301         assertThrows(IllegalArgumentException::class.java) {
1302             Mesh(
1303                 meshSpec, Mesh.TRIANGLES, vertexBuffer, 3, indexBuffer,
1304                 RectF(0f, 0f, 100f, 100f)
1305             )
1306         }
1307     }
1308 
1309     // /////////////    Test Values    ///////////////
1310 
1311     private val simpleAttributeList = arrayOf(
1312             MeshSpecification.Attribute(
1313                     MeshSpecification.TYPE_FLOAT2,
1314                     0,
1315                     "position"
1316             )
1317     )
1318 
1319     private val simpleVaryingList = arrayOf<MeshSpecification.Varying>()
1320 
1321     private val simpleVertexShader =
1322         ("Varyings main(const Attributes attributes) { " +
1323             "     Varyings varyings;" +
1324             "     varyings.position = attributes.position;" +
1325             "     return varyings;" +
1326             "}")
1327 
1328     private val simpleFragmentShader =
1329         ("float2 main(const Varyings varyings, out float4 color) {\n" +
1330             "      color = vec4(1.0, 0.0, 0.0, 1.0);" +
1331             "      return varyings.position;\n" +
1332             "}")
1333 }
1334