1 /*
2  * Copyright (C) 2023 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 com.android.test.hwui;
18 
19 import android.app.Activity;
20 import android.content.Context;
21 import android.graphics.BlendMode;
22 import android.graphics.Canvas;
23 import android.graphics.Color;
24 import android.graphics.Mesh;
25 import android.graphics.MeshSpecification;
26 import android.graphics.MeshSpecification.Attribute;
27 import android.graphics.MeshSpecification.Varying;
28 import android.graphics.Paint;
29 import android.graphics.RectF;
30 import android.os.Bundle;
31 import android.view.View;
32 
33 import java.nio.FloatBuffer;
34 import java.nio.ShortBuffer;
35 
36 public class MeshLargeActivity extends Activity {
37     @Override
onCreate(Bundle savedInstanceState)38     protected void onCreate(Bundle savedInstanceState) {
39         super.onCreate(savedInstanceState);
40 
41         setContentView(new MeshView(this));
42     }
43 
44     static class MeshView extends View {
MeshView(Context c)45         MeshView(Context c) {
46             super(c);
47             this.setOnTouchListener((v, event) -> {
48                 invalidate();
49                 return true;
50             });
51         }
52 
53         @Override
onDraw(Canvas canvas)54         protected void onDraw(Canvas canvas) {
55             super.onDraw(canvas);
56 
57             MeshSpecification meshSpec = createMeshSpecification();
58             int numTriangles = 10000;
59             // number of triangles plus first 2 vertices
60             FloatBuffer vertexBuffer = FloatBuffer.allocate((numTriangles + 2) * 30);
61             ShortBuffer indexBuffer = ShortBuffer.allocate(numTriangles * 3);
62 
63             float origin = 500.0f;
64             int radius = 200;
65 
66             // origin
67             vertexBuffer.put(0, origin);
68             vertexBuffer.put(1, origin);
69             for (int i = 0; i < 7; i++) {
70                 vertexBuffer.put(2 + (i * 4), 1.0f);
71                 vertexBuffer.put(2 + (i * 4) + 1, 1.0f);
72                 vertexBuffer.put(2 + (i * 4) + 2, 1.0f);
73                 vertexBuffer.put(2 + (i * 4) + 3, 1.0f);
74             }
75 
76             // first point
77             vertexBuffer.put(30, origin + radius);
78             vertexBuffer.put(31, origin);
79             for (int i = 0; i < 7; i++) {
80                 vertexBuffer.put(32 + (i * 4), 1.0f);
81                 vertexBuffer.put(32 + (i * 4) + 1, 1.0f);
82                 vertexBuffer.put(32 + (i * 4) + 2, 1.0f);
83                 vertexBuffer.put(32 + (i * 4) + 3, 1.0f);
84             }
85 
86             int nVert = 2;
87             int nInd = 0;
88             for (int i = 2; i <= numTriangles + 1; i++) {
89                 double angle = 2 * Math.PI * i / numTriangles;
90                 double x = radius * Math.cos(angle);
91                 double y = radius * Math.sin(angle);
92                 // position
93                 vertexBuffer.put(i * 30, origin + (float) x);
94                 vertexBuffer.put(i * 30 + 1, origin + (float) y);
95 
96                 // test through test7
97                 for (int j = 0; j < 7; j++) {
98                     vertexBuffer.put((i * 30 + 2) + (j * 4), 1.0f);
99                     vertexBuffer.put((i * 30 + 2) + (j * 4) + 1, 1.0f);
100                     vertexBuffer.put((i * 30 + 2) + (j * 4) + 2, 1.0f);
101                     vertexBuffer.put((i * 30 + 2) + (j * 4) + 3, 1.0f);
102                 }
103 
104                 indexBuffer.put(nInd++, (short) 0);
105                 indexBuffer.put(nInd++, (short) (nVert - 1));
106                 indexBuffer.put(nInd++, (short) nVert);
107                 nVert++;
108             }
109             vertexBuffer.rewind();
110             indexBuffer.rewind();
111             Mesh mesh = new Mesh(
112                     meshSpec, Mesh.TRIANGLES, vertexBuffer, numTriangles + 2, indexBuffer,
113                     new RectF(0, 0, 1000, 1000)
114             );
115             mesh.setFloatUniform("test", 1.0f, 2.0f);
116             Paint paint = new Paint();
117             paint.setColor(Color.BLUE);
118 
119             canvas.drawMesh(mesh, BlendMode.SRC, paint);
120         }
121 
createMeshSpecification()122         private MeshSpecification createMeshSpecification() {
123             String vs = "Varyings main(const Attributes attributes) { "
124                     + "     Varyings varyings;"
125                     + "     varyings.position = attributes.position;"
126                     + "     return varyings;"
127                     + "}";
128             String fs = "uniform float2 test;"
129                     + "float2 main(const Varyings varyings, out float4 color) {\n"
130                     + "      color = vec4(1.0, 0.0, 0.0, 1.0);"
131                     + "      return varyings.position;\n"
132                     + "}";
133             Attribute[] attList = new Attribute[]{
134                     new Attribute(MeshSpecification.TYPE_FLOAT2, 0, "position"),
135                     new Attribute(MeshSpecification.TYPE_FLOAT4, 8, "test"),
136                     new Attribute(MeshSpecification.TYPE_FLOAT4, 24, "test2"),
137                     new Attribute(
138                             MeshSpecification.TYPE_FLOAT4,
139                             40,
140                             "test3"
141                     ),
142                     new Attribute(
143                             MeshSpecification.TYPE_FLOAT4,
144                             56,
145                             "test4"
146                     ),
147                     new Attribute(
148                             MeshSpecification.TYPE_FLOAT4,
149                             72,
150                             "test5"
151                     ),
152                     new Attribute(
153                             MeshSpecification.TYPE_FLOAT4,
154                             88,
155                             "test6"
156                     ),
157                     new Attribute(
158                             MeshSpecification.TYPE_FLOAT4,
159                             104,
160                             "test7"
161                     )
162             };
163             Varying[] varyList = new Varying[0];
164             return MeshSpecification.make(attList, 120, varyList, vs, fs);
165         }
166     }
167 }
168