xref: /aosp_15_r20/external/angle/samples/tri_fan_microbench/TriFanMicroBench.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker //            Based on Hello_Triangle.c from
8*8975f5c5SAndroid Build Coastguard Worker // Book:      OpenGL(R) ES 2.0 Programming Guide
9*8975f5c5SAndroid Build Coastguard Worker // Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
10*8975f5c5SAndroid Build Coastguard Worker // ISBN-10:   0321502795
11*8975f5c5SAndroid Build Coastguard Worker // ISBN-13:   9780321502797
12*8975f5c5SAndroid Build Coastguard Worker // Publisher: Addison-Wesley Professional
13*8975f5c5SAndroid Build Coastguard Worker // URLs:      http://safari.informit.com/9780321563835
14*8975f5c5SAndroid Build Coastguard Worker //            http://www.opengles-book.com
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker #include "SampleApplication.h"
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker #include "util/shader_utils.h"
19*8975f5c5SAndroid Build Coastguard Worker 
20*8975f5c5SAndroid Build Coastguard Worker #include <cstring>
21*8975f5c5SAndroid Build Coastguard Worker #include <iostream>
22*8975f5c5SAndroid Build Coastguard Worker 
23*8975f5c5SAndroid Build Coastguard Worker // This small sample compares the per-frame render time for a series of
24*8975f5c5SAndroid Build Coastguard Worker // squares drawn with TRIANGLE_FANS versus squares drawn with TRIANGLES.
25*8975f5c5SAndroid Build Coastguard Worker // To exacerbate differences between the two, we use a large collection
26*8975f5c5SAndroid Build Coastguard Worker // of short buffers with pre-translated vertex data.
27*8975f5c5SAndroid Build Coastguard Worker 
28*8975f5c5SAndroid Build Coastguard Worker class TriangleFanBenchSample : public SampleApplication
29*8975f5c5SAndroid Build Coastguard Worker {
30*8975f5c5SAndroid Build Coastguard Worker   public:
TriangleFanBenchSample(int argc,char ** argv)31*8975f5c5SAndroid Build Coastguard Worker     TriangleFanBenchSample(int argc, char **argv)
32*8975f5c5SAndroid Build Coastguard Worker         : SampleApplication("Microbench", argc, argv, ClientType::ES2, 1280, 1280), mFrameCount(0)
33*8975f5c5SAndroid Build Coastguard Worker     {}
34*8975f5c5SAndroid Build Coastguard Worker 
createVertexBuffers()35*8975f5c5SAndroid Build Coastguard Worker     void createVertexBuffers()
36*8975f5c5SAndroid Build Coastguard Worker     {
37*8975f5c5SAndroid Build Coastguard Worker         const unsigned int slices         = 8;
38*8975f5c5SAndroid Build Coastguard Worker         const unsigned int numFanVertices = slices + 2;
39*8975f5c5SAndroid Build Coastguard Worker         const unsigned int fanFloats      = numFanVertices * 3;
40*8975f5c5SAndroid Build Coastguard Worker 
41*8975f5c5SAndroid Build Coastguard Worker         mNumFanVerts = numFanVertices;
42*8975f5c5SAndroid Build Coastguard Worker 
43*8975f5c5SAndroid Build Coastguard Worker         const GLfloat halfDim = 0.0625;
44*8975f5c5SAndroid Build Coastguard Worker         GLfloat fanVertices[] = {
45*8975f5c5SAndroid Build Coastguard Worker             0.0f,     0.0f,     0.0f,  // center
46*8975f5c5SAndroid Build Coastguard Worker             -halfDim, -halfDim, 0.0f,  // LL
47*8975f5c5SAndroid Build Coastguard Worker             -halfDim, 0.0f,     0.0f,  // CL
48*8975f5c5SAndroid Build Coastguard Worker             -halfDim, halfDim,  0.0f,  // UL
49*8975f5c5SAndroid Build Coastguard Worker             0.0f,     halfDim,  0.0f,  // UC
50*8975f5c5SAndroid Build Coastguard Worker             halfDim,  halfDim,  0.0f,  // UR
51*8975f5c5SAndroid Build Coastguard Worker             halfDim,  0.0f,     0.0f,  // CR
52*8975f5c5SAndroid Build Coastguard Worker             halfDim,  -halfDim, 0.0f,  // LR
53*8975f5c5SAndroid Build Coastguard Worker             0.0f,     -halfDim, 0.0f,  // LC
54*8975f5c5SAndroid Build Coastguard Worker             -halfDim, -halfDim, 0.0f   // LL (closes the fan)
55*8975f5c5SAndroid Build Coastguard Worker         };
56*8975f5c5SAndroid Build Coastguard Worker 
57*8975f5c5SAndroid Build Coastguard Worker         const GLfloat xMin = -1.0f;  // We leave viewport/worldview untransformed in this sample
58*8975f5c5SAndroid Build Coastguard Worker         const GLfloat xMax = 1.0f;
59*8975f5c5SAndroid Build Coastguard Worker         const GLfloat yMin = -1.0f;
60*8975f5c5SAndroid Build Coastguard Worker         // const GLfloat yMax = 1.0f;
61*8975f5c5SAndroid Build Coastguard Worker 
62*8975f5c5SAndroid Build Coastguard Worker         glGenBuffers(mNumSquares, mFanBufId);
63*8975f5c5SAndroid Build Coastguard Worker 
64*8975f5c5SAndroid Build Coastguard Worker         GLfloat xOffset = xMin;
65*8975f5c5SAndroid Build Coastguard Worker         GLfloat yOffset = yMin;
66*8975f5c5SAndroid Build Coastguard Worker         for (unsigned int i = 0; i < mNumSquares; ++i)
67*8975f5c5SAndroid Build Coastguard Worker         {
68*8975f5c5SAndroid Build Coastguard Worker             GLfloat tempVerts[fanFloats] = {0};
69*8975f5c5SAndroid Build Coastguard Worker             for (unsigned int j = 0; j < numFanVertices; ++j)
70*8975f5c5SAndroid Build Coastguard Worker             {
71*8975f5c5SAndroid Build Coastguard Worker                 tempVerts[j * 3]     = fanVertices[j * 3] + xOffset;
72*8975f5c5SAndroid Build Coastguard Worker                 tempVerts[j * 3 + 1] = fanVertices[j * 3 + 1] + yOffset;
73*8975f5c5SAndroid Build Coastguard Worker                 tempVerts[j * 3 + 2] = 0.0f;
74*8975f5c5SAndroid Build Coastguard Worker             }
75*8975f5c5SAndroid Build Coastguard Worker 
76*8975f5c5SAndroid Build Coastguard Worker             glBindBuffer(GL_ARRAY_BUFFER, mFanBufId[i]);
77*8975f5c5SAndroid Build Coastguard Worker             glBufferData(GL_ARRAY_BUFFER, fanFloats * sizeof(GLfloat), tempVerts, GL_STATIC_DRAW);
78*8975f5c5SAndroid Build Coastguard Worker 
79*8975f5c5SAndroid Build Coastguard Worker             xOffset += 2 * halfDim;
80*8975f5c5SAndroid Build Coastguard Worker             if (xOffset > xMax)
81*8975f5c5SAndroid Build Coastguard Worker             {
82*8975f5c5SAndroid Build Coastguard Worker                 xOffset = xMin;
83*8975f5c5SAndroid Build Coastguard Worker                 yOffset += 2 * halfDim;
84*8975f5c5SAndroid Build Coastguard Worker             }
85*8975f5c5SAndroid Build Coastguard Worker         }
86*8975f5c5SAndroid Build Coastguard Worker 
87*8975f5c5SAndroid Build Coastguard Worker         const unsigned int numTriVertices = slices * 3;
88*8975f5c5SAndroid Build Coastguard Worker         const unsigned int triFloats      = numTriVertices * 3;
89*8975f5c5SAndroid Build Coastguard Worker         GLfloat triVertices[triFloats];
90*8975f5c5SAndroid Build Coastguard Worker         GLfloat *triPointer = triVertices;
91*8975f5c5SAndroid Build Coastguard Worker 
92*8975f5c5SAndroid Build Coastguard Worker         mNumTriVerts = numTriVertices;
93*8975f5c5SAndroid Build Coastguard Worker 
94*8975f5c5SAndroid Build Coastguard Worker         for (unsigned int i = 0; i < slices; ++i)
95*8975f5c5SAndroid Build Coastguard Worker         {
96*8975f5c5SAndroid Build Coastguard Worker             memcpy(triPointer, fanVertices,
97*8975f5c5SAndroid Build Coastguard Worker                    3 * sizeof(GLfloat));  // copy center point as first vertex for this slice
98*8975f5c5SAndroid Build Coastguard Worker             triPointer += 3;
99*8975f5c5SAndroid Build Coastguard Worker             for (unsigned int j = 1; j < 3; ++j)
100*8975f5c5SAndroid Build Coastguard Worker             {
101*8975f5c5SAndroid Build Coastguard Worker                 GLfloat *vertex =
102*8975f5c5SAndroid Build Coastguard Worker                     &(fanVertices[(i + j) * 3]);  // copy two outer vertices for this point
103*8975f5c5SAndroid Build Coastguard Worker                 memcpy(triPointer, vertex, 3 * sizeof(GLfloat));
104*8975f5c5SAndroid Build Coastguard Worker                 triPointer += 3;
105*8975f5c5SAndroid Build Coastguard Worker             }
106*8975f5c5SAndroid Build Coastguard Worker         }
107*8975f5c5SAndroid Build Coastguard Worker 
108*8975f5c5SAndroid Build Coastguard Worker         // GLfloat triVertices2[triFloats];
109*8975f5c5SAndroid Build Coastguard Worker         glGenBuffers(mNumSquares, mTriBufId);
110*8975f5c5SAndroid Build Coastguard Worker         xOffset = xMin;
111*8975f5c5SAndroid Build Coastguard Worker         yOffset = yMin;
112*8975f5c5SAndroid Build Coastguard Worker 
113*8975f5c5SAndroid Build Coastguard Worker         for (unsigned int i = 0; i < mNumSquares; ++i)
114*8975f5c5SAndroid Build Coastguard Worker         {
115*8975f5c5SAndroid Build Coastguard Worker             triPointer = triVertices;
116*8975f5c5SAndroid Build Coastguard Worker             GLfloat tempVerts[triFloats];
117*8975f5c5SAndroid Build Coastguard Worker             for (unsigned int j = 0; j < numTriVertices; ++j)
118*8975f5c5SAndroid Build Coastguard Worker             {
119*8975f5c5SAndroid Build Coastguard Worker                 tempVerts[j * 3]     = triPointer[0] + xOffset;
120*8975f5c5SAndroid Build Coastguard Worker                 tempVerts[j * 3 + 1] = triPointer[1] + yOffset;
121*8975f5c5SAndroid Build Coastguard Worker                 tempVerts[j * 3 + 2] = 0.0f;
122*8975f5c5SAndroid Build Coastguard Worker                 triPointer += 3;
123*8975f5c5SAndroid Build Coastguard Worker             }
124*8975f5c5SAndroid Build Coastguard Worker 
125*8975f5c5SAndroid Build Coastguard Worker             glBindBuffer(GL_ARRAY_BUFFER, mTriBufId[i]);
126*8975f5c5SAndroid Build Coastguard Worker             glBufferData(GL_ARRAY_BUFFER, triFloats * sizeof(GLfloat), tempVerts, GL_STATIC_DRAW);
127*8975f5c5SAndroid Build Coastguard Worker             xOffset += 2 * halfDim;
128*8975f5c5SAndroid Build Coastguard Worker             if (xOffset > xMax)
129*8975f5c5SAndroid Build Coastguard Worker             {
130*8975f5c5SAndroid Build Coastguard Worker                 yOffset += 2 * halfDim;
131*8975f5c5SAndroid Build Coastguard Worker                 xOffset = xMin;
132*8975f5c5SAndroid Build Coastguard Worker             }
133*8975f5c5SAndroid Build Coastguard Worker         }
134*8975f5c5SAndroid Build Coastguard Worker     }
135*8975f5c5SAndroid Build Coastguard Worker 
initialize()136*8975f5c5SAndroid Build Coastguard Worker     bool initialize() override
137*8975f5c5SAndroid Build Coastguard Worker     {
138*8975f5c5SAndroid Build Coastguard Worker         constexpr char kVS[] = R"(attribute vec4 vPosition;
139*8975f5c5SAndroid Build Coastguard Worker void main()
140*8975f5c5SAndroid Build Coastguard Worker {
141*8975f5c5SAndroid Build Coastguard Worker     gl_Position = vPosition;
142*8975f5c5SAndroid Build Coastguard Worker })";
143*8975f5c5SAndroid Build Coastguard Worker 
144*8975f5c5SAndroid Build Coastguard Worker         constexpr char kFS[] = R"(precision mediump float;
145*8975f5c5SAndroid Build Coastguard Worker void main()
146*8975f5c5SAndroid Build Coastguard Worker {
147*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
148*8975f5c5SAndroid Build Coastguard Worker })";
149*8975f5c5SAndroid Build Coastguard Worker 
150*8975f5c5SAndroid Build Coastguard Worker         mProgram = CompileProgram(kVS, kFS);
151*8975f5c5SAndroid Build Coastguard Worker         if (!mProgram)
152*8975f5c5SAndroid Build Coastguard Worker         {
153*8975f5c5SAndroid Build Coastguard Worker             return false;
154*8975f5c5SAndroid Build Coastguard Worker         }
155*8975f5c5SAndroid Build Coastguard Worker 
156*8975f5c5SAndroid Build Coastguard Worker         glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
157*8975f5c5SAndroid Build Coastguard Worker 
158*8975f5c5SAndroid Build Coastguard Worker         createVertexBuffers();
159*8975f5c5SAndroid Build Coastguard Worker 
160*8975f5c5SAndroid Build Coastguard Worker         mFanTotalTime = 0;
161*8975f5c5SAndroid Build Coastguard Worker         mTriTotalTime = 0;
162*8975f5c5SAndroid Build Coastguard Worker 
163*8975f5c5SAndroid Build Coastguard Worker         return true;
164*8975f5c5SAndroid Build Coastguard Worker     }
165*8975f5c5SAndroid Build Coastguard Worker 
destroy()166*8975f5c5SAndroid Build Coastguard Worker     void destroy() override
167*8975f5c5SAndroid Build Coastguard Worker     {
168*8975f5c5SAndroid Build Coastguard Worker         std::cout << "Total draw time using TRIANGLE_FAN: " << mFanTotalTime << "ms ("
169*8975f5c5SAndroid Build Coastguard Worker                   << (float)mFanTotalTime / (float)mFrameCount << " average per frame)"
170*8975f5c5SAndroid Build Coastguard Worker                   << std::endl;
171*8975f5c5SAndroid Build Coastguard Worker         std::cout << "Total draw time using TRIANGLES: " << mTriTotalTime << "ms ("
172*8975f5c5SAndroid Build Coastguard Worker                   << (float)mTriTotalTime / (float)mFrameCount << " average per frame)"
173*8975f5c5SAndroid Build Coastguard Worker                   << std::endl;
174*8975f5c5SAndroid Build Coastguard Worker         glDeleteProgram(mProgram);
175*8975f5c5SAndroid Build Coastguard Worker     }
176*8975f5c5SAndroid Build Coastguard Worker 
draw()177*8975f5c5SAndroid Build Coastguard Worker     void draw() override
178*8975f5c5SAndroid Build Coastguard Worker     {
179*8975f5c5SAndroid Build Coastguard Worker         // Set the viewport
180*8975f5c5SAndroid Build Coastguard Worker         glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
181*8975f5c5SAndroid Build Coastguard Worker 
182*8975f5c5SAndroid Build Coastguard Worker         // Clear the color buffer
183*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
184*8975f5c5SAndroid Build Coastguard Worker 
185*8975f5c5SAndroid Build Coastguard Worker         // Use the program object
186*8975f5c5SAndroid Build Coastguard Worker         glUseProgram(mProgram);
187*8975f5c5SAndroid Build Coastguard Worker 
188*8975f5c5SAndroid Build Coastguard Worker         // Bind the vertex data
189*8975f5c5SAndroid Build Coastguard Worker         glEnableVertexAttribArray(0);
190*8975f5c5SAndroid Build Coastguard Worker 
191*8975f5c5SAndroid Build Coastguard Worker         // Draw using triangle fans, stored in VBO
192*8975f5c5SAndroid Build Coastguard Worker         mFanTimer.start();
193*8975f5c5SAndroid Build Coastguard Worker         for (unsigned i = 0; i < mNumSquares; ++i)
194*8975f5c5SAndroid Build Coastguard Worker         {
195*8975f5c5SAndroid Build Coastguard Worker             glBindBuffer(GL_ARRAY_BUFFER, mFanBufId[i]);
196*8975f5c5SAndroid Build Coastguard Worker             glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
197*8975f5c5SAndroid Build Coastguard Worker             glDrawArrays(GL_TRIANGLE_FAN, 0, mNumFanVerts);
198*8975f5c5SAndroid Build Coastguard Worker         }
199*8975f5c5SAndroid Build Coastguard Worker         mFanTimer.stop();
200*8975f5c5SAndroid Build Coastguard Worker 
201*8975f5c5SAndroid Build Coastguard Worker         mFanTotalTime +=
202*8975f5c5SAndroid Build Coastguard Worker             static_cast<unsigned int>(mFanTimer.getElapsedWallClockTime() *
203*8975f5c5SAndroid Build Coastguard Worker                                       1000);  // convert from usec to msec when accumulating
204*8975f5c5SAndroid Build Coastguard Worker 
205*8975f5c5SAndroid Build Coastguard Worker         // Clear to eliminate driver-side gains from occlusion
206*8975f5c5SAndroid Build Coastguard Worker         glClear(GL_COLOR_BUFFER_BIT);
207*8975f5c5SAndroid Build Coastguard Worker 
208*8975f5c5SAndroid Build Coastguard Worker         // Draw using triangles, stored in VBO
209*8975f5c5SAndroid Build Coastguard Worker         mTriTimer.start();
210*8975f5c5SAndroid Build Coastguard Worker         for (unsigned i = 1; i < mNumSquares; ++i)
211*8975f5c5SAndroid Build Coastguard Worker         {
212*8975f5c5SAndroid Build Coastguard Worker             glBindBuffer(GL_ARRAY_BUFFER, mTriBufId[i]);
213*8975f5c5SAndroid Build Coastguard Worker             glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
214*8975f5c5SAndroid Build Coastguard Worker             glDrawArrays(GL_TRIANGLES, 0, mNumTriVerts);
215*8975f5c5SAndroid Build Coastguard Worker         }
216*8975f5c5SAndroid Build Coastguard Worker         mTriTimer.stop();
217*8975f5c5SAndroid Build Coastguard Worker 
218*8975f5c5SAndroid Build Coastguard Worker         mTriTotalTime +=
219*8975f5c5SAndroid Build Coastguard Worker             static_cast<unsigned int>(mTriTimer.getElapsedWallClockTime() *
220*8975f5c5SAndroid Build Coastguard Worker                                       1000);  // convert from usec to msec when accumulating
221*8975f5c5SAndroid Build Coastguard Worker 
222*8975f5c5SAndroid Build Coastguard Worker         mFrameCount++;
223*8975f5c5SAndroid Build Coastguard Worker     }
224*8975f5c5SAndroid Build Coastguard Worker 
225*8975f5c5SAndroid Build Coastguard Worker   private:
226*8975f5c5SAndroid Build Coastguard Worker     static const unsigned int mNumSquares = 289;
227*8975f5c5SAndroid Build Coastguard Worker     unsigned int mNumFanVerts;
228*8975f5c5SAndroid Build Coastguard Worker     unsigned int mNumTriVerts;
229*8975f5c5SAndroid Build Coastguard Worker     GLuint mProgram;
230*8975f5c5SAndroid Build Coastguard Worker     GLuint mFanBufId[mNumSquares];
231*8975f5c5SAndroid Build Coastguard Worker     GLuint mTriBufId[mNumSquares];
232*8975f5c5SAndroid Build Coastguard Worker 
233*8975f5c5SAndroid Build Coastguard Worker     Timer mFanTimer;
234*8975f5c5SAndroid Build Coastguard Worker     Timer mTriTimer;
235*8975f5c5SAndroid Build Coastguard Worker     unsigned int mFrameCount;
236*8975f5c5SAndroid Build Coastguard Worker     unsigned int mTriTotalTime;
237*8975f5c5SAndroid Build Coastguard Worker     unsigned int mFanTotalTime;
238*8975f5c5SAndroid Build Coastguard Worker };
239*8975f5c5SAndroid Build Coastguard Worker 
main(int argc,char ** argv)240*8975f5c5SAndroid Build Coastguard Worker int main(int argc, char **argv)
241*8975f5c5SAndroid Build Coastguard Worker {
242*8975f5c5SAndroid Build Coastguard Worker     TriangleFanBenchSample app(argc, argv);
243*8975f5c5SAndroid Build Coastguard Worker     return app.run();
244*8975f5c5SAndroid Build Coastguard Worker }
245