Edit

kc3-lang/angle/samples/tri_fan_microbench

Branch :

  • Show log

    Commit

  • Author : Olli Etuaho
    Date : 2017-09-18 13:32:29
    Hash : a20af6d7
    Message : Use C++11 raw string literals instead of SHADER_SOURCE macro This is better in many ways: 1. It doesn't confuse clang format 2. \n doesn't need to be included after preprocessor directives like the version directive. 3. It's using built-in functionality instead of something custom. Raw string literals should be the preferred way to include shader source in C++ files going forward. BUG=angleproject:2157 TEST=angle_end2end_tests Change-Id: I8b236a6e2d5c25d920297e5bc5b5b143eddeba1f Reviewed-on: https://chromium-review.googlesource.com/671046 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>

  • TriFanMicroBench.cpp
  • //
    // Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    //            Based on Hello_Triangle.c from
    // Book:      OpenGL(R) ES 2.0 Programming Guide
    // Authors:   Aaftab Munshi, Dan Ginsburg, Dave Shreiner
    // ISBN-10:   0321502795
    // ISBN-13:   9780321502797
    // Publisher: Addison-Wesley Professional
    // URLs:      http://safari.informit.com/9780321563835
    //            http://www.opengles-book.com
    
    #include "SampleApplication.h"
    #include "shader_utils.h"
    
    #include <cstring>
    #include <iostream>
    
    // This small sample compares the per-frame render time for a series of 
    // squares drawn with TRIANGLE_FANS versus squares drawn with TRIANGLES.
    // To exacerbate differences between the two, we use a large collection
    // of short buffers with pre-translated vertex data.
    
    class TriangleFanBenchSample : public SampleApplication
    {
      public:
        TriangleFanBenchSample()
            : SampleApplication("Microbench", 1280, 1280),
              mFrameCount(0)
        {
        }
    
        void createVertexBuffers()
        {
            const unsigned int slices = 8;
            const unsigned int numFanVertices = slices + 2;
            const unsigned int fanFloats = numFanVertices * 3;
    
            mNumFanVerts = numFanVertices;
    
            const GLfloat halfDim = 0.0625;
            GLfloat fanVertices[] =
                {    0.0f,     0.0f,  0.0f,  // center
                 -halfDim, -halfDim,  0.0f,  // LL
                 -halfDim,     0.0f,  0.0f,  // CL
                 -halfDim,  halfDim,  0.0f,  // UL
                     0.0f,  halfDim,  0.0f,  // UC
                  halfDim,  halfDim,  0.0f,  // UR
                  halfDim,     0.0f,  0.0f,  // CR
                  halfDim, -halfDim,  0.0f,  // LR
                     0.0f, -halfDim,  0.0f,  // LC
                 -halfDim, -halfDim,  0.0f   // LL (closes the fan)
                };
    
            const GLfloat xMin = -1.0f; // We leave viewport/worldview untransformed in this sample
            const GLfloat xMax = 1.0f;
            const GLfloat yMin = -1.0f;
            //const GLfloat yMax = 1.0f;
    
            glGenBuffers(mNumSquares, mFanBufId);
    
            GLfloat xOffset = xMin;
            GLfloat yOffset = yMin;
            for (unsigned int i = 0; i < mNumSquares; ++i)
            {
                GLfloat tempVerts[fanFloats] = { 0 };
                for (unsigned int j = 0; j < numFanVertices; ++j)
                {
                    tempVerts[j * 3] = fanVertices[j * 3] + xOffset;
                    tempVerts[j * 3 + 1] = fanVertices[j * 3 + 1] + yOffset;
                    tempVerts[j * 3 + 2] = 0.0f;
                }
    
                glBindBuffer(GL_ARRAY_BUFFER, mFanBufId[i]);
                glBufferData(GL_ARRAY_BUFFER, fanFloats * sizeof(GLfloat), tempVerts, GL_STATIC_DRAW);
    
                xOffset += 2 * halfDim;
                if (xOffset > xMax)
                {
                    xOffset = xMin;
                    yOffset += 2 * halfDim;
                }
            }
    
            const unsigned int numTriVertices = slices * 3;
            const unsigned int triFloats = numTriVertices * 3;
            GLfloat triVertices[triFloats];
            GLfloat *triPointer = triVertices;
    
            mNumTriVerts = numTriVertices;
    
            for (unsigned int i = 0; i < slices; ++i)
            {
                memcpy(triPointer, fanVertices, 3 * sizeof(GLfloat)); // copy center point as first vertex for this slice
                triPointer += 3;
                for (unsigned int j = 1; j < 3; ++j)
                {
                    GLfloat *vertex = &(fanVertices[(i + j) * 3]); // copy two outer vertices for this point
                    memcpy(triPointer, vertex, 3 * sizeof(GLfloat));
                    triPointer += 3;
                }
            }
    
            //GLfloat triVertices2[triFloats];
            glGenBuffers(mNumSquares, mTriBufId);
            xOffset = xMin;
            yOffset = yMin;
    
            for (unsigned int i = 0; i < mNumSquares; ++i)
            {
                triPointer = triVertices;
                GLfloat tempVerts[triFloats];
                for (unsigned int j = 0; j < numTriVertices; ++j)
                {
                    tempVerts[j * 3] = triPointer[0] + xOffset;
                    tempVerts[j * 3 + 1] = triPointer[1] + yOffset;
                    tempVerts[j * 3 + 2] = 0.0f;
                    triPointer += 3;
                }
    
                glBindBuffer(GL_ARRAY_BUFFER, mTriBufId[i]);
                glBufferData(GL_ARRAY_BUFFER, triFloats * sizeof(GLfloat), tempVerts, GL_STATIC_DRAW);
                xOffset += 2 * halfDim;
                if (xOffset > xMax)
                {
                    yOffset += 2 * halfDim;
                    xOffset = xMin;
                }
            }
        }
    
        virtual bool initialize()
        {
            const std::string vs =
                R"(attribute vec4 vPosition;
                void main()
                {
                    gl_Position = vPosition;
                })";
    
            const std::string fs =
                R"(precision mediump float;
                void main()
                {
                    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
                })";
    
            mProgram = CompileProgram(vs, fs);
            if (!mProgram)
            {
                return false;
            }
    
            glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    
            createVertexBuffers();
    
            mFanTimer = CreateTimer();
            mTriTimer = CreateTimer();
            mFanTotalTime = 0;
            mTriTotalTime = 0;
    
            return true;
        }
    
        virtual void destroy()
        {
            std::cout << "Total draw time using TRIANGLE_FAN: " << mFanTotalTime << "ms (" << (float)mFanTotalTime / (float)mFrameCount << " average per frame)" << std::endl;
            std::cout << "Total draw time using TRIANGLES: " << mTriTotalTime << "ms (" << (float)mTriTotalTime / (float)mFrameCount << " average per frame)" << std::endl;
            glDeleteProgram(mProgram);
        }
    
        virtual void draw()
        {
            // Set the viewport
            glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());
    
            // Clear the color buffer
            glClear(GL_COLOR_BUFFER_BIT);
    
            // Use the program object
            glUseProgram(mProgram);
    
            // Bind the vertex data
            glEnableVertexAttribArray(0);
    
            // Draw using triangle fans, stored in VBO
            mFanTimer->start();
            for (unsigned i = 0; i < mNumSquares; ++i)
            {
                glBindBuffer(GL_ARRAY_BUFFER, mFanBufId[i]);
                glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
                glDrawArrays(GL_TRIANGLE_FAN, 0, mNumFanVerts);
            }
            mFanTimer->stop();
    
            mFanTotalTime += static_cast<unsigned int>(mFanTimer->getElapsedTime() * 1000); // convert from usec to msec when accumulating
    
            // Clear to eliminate driver-side gains from occlusion
            glClear(GL_COLOR_BUFFER_BIT);
            
            // Draw using triangles, stored in VBO
            mTriTimer->start();
            for (unsigned i = 1; i < mNumSquares; ++i)
            {
                glBindBuffer(GL_ARRAY_BUFFER, mTriBufId[i]);
                glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
                glDrawArrays(GL_TRIANGLES, 0, mNumTriVerts);
            }
            mTriTimer->stop();
    
            mTriTotalTime += static_cast<unsigned int>(mTriTimer->getElapsedTime() * 1000); // convert from usec to msec when accumulating
    
            mFrameCount++;
        }
    
      private:
        static const unsigned int mNumSquares = 289;
        unsigned int mNumFanVerts;
        unsigned int mNumTriVerts;
        GLuint mProgram;
        GLuint mFanBufId[mNumSquares];
        GLuint mTriBufId[mNumSquares];
    
        Timer *mFanTimer;
        Timer *mTriTimer;
        unsigned int mFrameCount;
        unsigned int mTriTotalTime;
        unsigned int mFanTotalTime;
    };
    
    int main(int argc, char **argv)
    {
        TriangleFanBenchSample app;
        return app.run();
    }