<br>
<div class="gmail_quote">&gt;On Mon, Oct 24, 2011 at 5:44 AM, José Fonseca <span dir="ltr">&lt;<a href="mailto:jose.r.fonseca@gmail.com" target="_blank">jose.r.fonseca@gmail.com</a>&gt;</span> wrote:</div><span style="background-color:rgb(255,255,255);font-family:&#39;Droid Sans&#39;, arial, sans-serif;color:rgb(32,32,32);font-size:13px">&gt;Yes.  I was planning to refactor the last patch that Yuanhan Liu<br>


&gt;posted to this list such that the recording was done in glretrace<br>&gt;instead of apitrace, but been busy with other stuff.<br>Here is the patch for cpu/gpu time logging during retracing. </span><span class="Apple-style-span" style="color: rgb(32, 32, 32); font-family: &#39;Droid Sans&#39;, arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">Used Yuanhan Liu&#39;s patch as a reference.</span><div>

<div><span style="background-color:rgb(255,255,255)"><div><span style="background-color: rgb(255, 255, 255); font-family: &#39;Droid Sans&#39;, arial, sans-serif; color: rgb(32, 32, 32); font-size: 13px; ">This patch logs the cpu and gpu time duration per gl call. cpu time is still skewed by snappy decompression. </span></div>

<div><span style="background-color: rgb(255, 255, 255); font-family: &#39;Droid Sans&#39;, arial, sans-serif; color: rgb(32, 32, 32); font-size: 13px; ">I guess It can be fixed by moving the decompression to a separate thread. </span></div>

<div><span style="background-color: rgb(255, 255, 255); font-family: &#39;Droid Sans&#39;, arial, sans-serif; color: rgb(32, 32, 32); font-size: 13px; "><br></span></div></span></div>
<div>
<div><span style="background-color:rgb(255,255,255)">diff --git a/glretrace.py b/glretrace.py<br>index e80fedb..3a3fb96 100644<br>--- a/glretrace.py<br>+++ b/glretrace.py<br>@@ -239,9 +239,28 @@ class GlRetracer(Retracer):<br>


 <br>         if <a href="http://function.name" target="_blank">function.name</a> == &#39;memcpy&#39;:<br>             print &#39;    if (!dest || !src || !n) return;&#39;<br>+<br>+ print &#39;    long long t0, t1;&#39;<br>

+        print &#39;    if (query_index &lt; MAX_QUERIES) {&#39;<br>
+        if function.loggputime:<br>+           print &#39;        __glGenQueries(1, &amp;gpu_queries[query_index]);&#39;<br>+           print &#39;        __glBeginQuery(GL_TIME_ELAPSED, gpu_queries[query_index]);&#39;<br>


+           print &#39;        last_gpu_query = gpu_queries[query_index];&#39;<br>+        else:<br>+           print &#39;        gpu_queries[query_index] = 0;&#39;<br>+        print &#39;        t0 = OS::GetTime();&#39;<br>


+        print &#39;    }&#39;<br>         <br>         Retracer.call_function(self, function)<br> <br>+ print &#39;    if (query_index &lt; MAX_QUERIES) {&#39;<br>+ print &#39;        t1 = OS::GetTime();&#39;<br>+ if function.loggputime:<br>


+    print &#39;        __glEndQuery(GL_TIME_ELAPSED);&#39;<br>+ print &#39;        cpu_time[query_index] = (double)(t1 - t0) * 1.0E-3;&#39;<br>+ print &#39;        query_index++;&#39;<br>+ print &#39;    }&#39;<br>+ <br>


         # Error checking<br>         if <a href="http://function.name" target="_blank">function.name</a> == &quot;glBegin&quot;:<br>             print &#39;    glretrace::insideGlBeginEnd = true;&#39;<br>@@ -392,7 +411,13 @@ if __name__ == &#39;__main__&#39;:<br>


 #include &quot;glretrace.hpp&quot;<br> #include &quot;glstate.hpp&quot;<br> <br>-<br>+#define MAX_QUERIES  20000<br>+GLuint gpu_queries[MAX_QUERIES];<br>+int last_gpu_query = 0;<br>+int query_index = 0;<br>+int last_query_index = 0;<br>


+double cpu_time[MAX_QUERIES];<br>+double gpu_time[MAX_QUERIES];<br> &#39;&#39;&#39;<br>     api = glapi.glapi<br>     retracer = GlRetracer()<br>diff --git a/glretrace_glx.cpp b/glretrace_glx.cpp<br>index 8e2e469..df63034 100644<br>


--- a/glretrace_glx.cpp<br>+++ b/glretrace_glx.cpp<br>@@ -28,9 +28,12 @@<br> #include &quot;retrace.hpp&quot;<br> #include &quot;glretrace.hpp&quot;<br> <br>-<br> using namespace glretrace;<br>-<br>+extern GLuint gpu_queries[];<br>


+extern int last_gpu_query;<br>+extern int query_index;<br>+extern int last_query_index;<br>+extern double gpu_time[];<br> <br> typedef std::map&lt;unsigned long, glws::Drawable *&gt; DrawableMap;<br> typedef std::map&lt;unsigned long long, glws::Context *&gt; ContextMap;<br>


@@ -128,6 +131,23 @@ static void retrace_glXSwapBuffers(Trace::Call &amp;call) {<br>     } else {<br>         glFlush();<br>     }<br>+<br>+    if (last_gpu_query &gt; 0) {<br>+        int done = 0;<br>+        while (!done)<br>


+             __glGetQueryObjectiv(last_gpu_query, GL_QUERY_RESULT_AVAILABLE, &amp;done);<br>+       }<br>+       for (int i = last_query_index;  i &lt; query_index; i++) {<br>+            GLuint time_gpu;<br>+            if (gpu_queries[i]) {<br>


+                __glGetQueryObjectuiv(gpu_queries[i], GL_QUERY_RESULT, &amp;time_gpu);<br>+                __glDeleteQueries(1, &amp;gpu_queries[i]);<br>+            } else<br>+                time_gpu = 0;<br>+     gpu_time[i] = time_gpu * 1.0E-6;<br>


+       }<br>+       last_gpu_query = 0;<br>+       last_query_index = query_index;<br> }<br> <br> static void retrace_glXCreateNewContext(Trace::Call &amp;call) {<br>diff --git a/glretrace_main.cpp b/glretrace_main.cpp<br>


index 4e4b8ae..a41e14a 100644<br>--- a/glretrace_main.cpp<br>+++ b/glretrace_main.cpp<br>@@ -32,6 +32,9 @@<br> #include &quot;glstate.hpp&quot;<br> #include &quot;glretrace.hpp&quot;<br> <br>+extern double cpu_time[];<br>


+extern double gpu_time[];<br>+extern int query_index;<br> <br> namespace glretrace {<br> <br>@@ -200,20 +203,19 @@ static void display(void) {<br>     Trace::Call *call;<br> <br>     while ((call = parser.parse_call())) {<br>


-        retracer.retrace(*call);<br>-<br>-        if (!insideGlBeginEnd &amp;&amp;<br>+  retracer.retrace(*call);<br>+         <br>+  if (!insideGlBeginEnd &amp;&amp;<br>             drawable &amp;&amp; context &amp;&amp;<br>


             call-&gt;no &gt;= dump_state) {<br>             glstate::dumpCurrentContext(std::cout);<br>             exit(0);<br>         }<br>-<br>         delete call;<br>     }<br>-<br>-    // Reached the end of trace<br>


-    glFlush();<br>+       <br>+   // Reached the end of trace.Before logging endTime, call glFinish() to complete the execution of all previous gl calls.<br>+     glFinish();<br> <br>     long long endTime = OS::GetTime();<br>

     float timeInterval = (endTime - startTime) * 1.0E-6;<br>
@@ -222,16 +224,39 @@ static void display(void) {<br>         std::cout &lt;&lt; <br>             &quot;Rendered &quot; &lt;&lt; frame &lt;&lt; &quot; frames&quot;<br>             &quot; in &quot; &lt;&lt;  timeInterval &lt;&lt; &quot; secs,&quot;<br>


-            &quot; average of &quot; &lt;&lt; (frame/timeInterval) &lt;&lt; &quot; fps\n&quot;;<br>+            &quot; average of &quot; &lt;&lt; (frame/timeInterval) &lt;&lt; &quot; fps\n&quot;<br>+            &quot;Refer to time.log file for timing information\n&quot;;<br>


     }<br>-<br>-    if (wait) {<br>+    if (wait) <br>         while (glws::processEvents()) {}<br>-    } else {<br>-        exit(0);<br>-    }<br> }<br> <br>+static void reparser(void) {<br>+    Trace::Call *call;<br>+    FILE *timefile = fopen(&quot;time.log&quot;, &quot;w+&quot;);<br>


+    int i = 0;<br>+    fprintf(timefile,&quot;Call#\t\t  Function Name\t\tCPU Time\t\t\tGPU Time\n&quot;);<br>+    while ( ( call = parser.parse_call() ) &amp;&amp; ( i &lt;= query_index) ) {<br>+  if ( !(call-&gt;name()[0] == &#39;g&#39; &amp;&amp; call-&gt;name()[1] == &#39;l&#39; &amp;&amp; call-&gt;name()[2] == &#39;X&#39;) &amp;&amp; <br>


+       !(call-&gt;name()[2] == &#39;G&#39; &amp;&amp; call-&gt;name()[3] == &#39;e&#39; &amp;&amp; call-&gt;name()[4] == &#39;t&#39;)) {<br>+             <br>+             fprintf(timefile,&quot;%5d\t\t&quot;, call-&gt;no); <br>


+             fprintf(timefile,&quot;%15s\t\t&quot;, call-&gt;name());<br>+             // Minimum cpu time logging can be set appropriately<br>+      if ( cpu_time[i] &gt; 0.001 || gpu_time[i] )<br>+                 fprintf(timefile,&quot;cpu time = %4.4f  ms\t\t&quot;, cpu_time[i]);<br>


+      if ( gpu_time[i] )<br>+          fprintf(timefile,&quot;gpu time = %4.4f  ms&quot;, gpu_time[i]);<br>+      fprintf(timefile,&quot;\n&quot;);<br>+             i++;  <br>+  }<br>+         delete call;<br>+    }<br>

+    if(timefile != NULL) <br>
+       fclose(timefile);<br>+  <br>+    exit(0);<br>+}<br> <br> static void usage(void) {<br>     std::cout &lt;&lt; <br>@@ -325,11 +350,21 @@ int main(int argc, char **argv)<br>             std::cerr &lt;&lt; &quot;error: failed to open &quot; &lt;&lt; argv[i] &lt;&lt; &quot;\n&quot;;<br>


             return 1;<br>         }<br>-<br>         display();<br> <br>         parser.close();<br>     }<br>+    // Reparsing is required to dump a logfile containing cpu time and gpu time <br>+    // for each gl call. As gpu time for a gl call is available only at the end of <br>


+    // a frame, It&#39;s really difficult to write gpu time when parsing for the first time.<br>+    // It is an overhead but doesn&#39;t effect the cpu or gpu time in anyway. <br>+    // logging of gpu time can be enabled or disabled by setting a flag in specs/glapi.py<br>


+    if (!parser.open(argv[1])) {<br>+        std::cerr &lt;&lt; &quot;error: failed to open &quot; &lt;&lt; argv[i] &lt;&lt; &quot;\n&quot;;<br>+        return 1;<br>+    }<br>+    reparser();<br>+    parser.close();<br>


     <br>     delete visual;<br>     glws::cleanup();<br>diff --git a/specs/glapi.py b/specs/glapi.py<br>index 0268479..5566157 100644<br>--- a/specs/glapi.py<br>+++ b/specs/glapi.py<br>@@ -63,9 +63,9 @@ glapi.add_functions([<br>


     GlFunction(Void, &quot;glTexImage1D&quot;, [(GLenum, &quot;target&quot;), (GLint, &quot;level&quot;), (GLenum_int, &quot;internalformat&quot;), (GLsizei, &quot;width&quot;), (GLint, &quot;border&quot;), (GLenum, &quot;format&quot;), (GLenum, &quot;type&quot;), (Blob(Const(GLvoid), &quot;__glTexImage1D_size(format, type, width)&quot;), &quot;pixels&quot;)]),<br>


     GlFunction(Void, &quot;glTexImage2D&quot;, [(GLenum, &quot;target&quot;), (GLint, &quot;level&quot;), (GLenum_int, &quot;internalformat&quot;), (GLsizei, &quot;width&quot;), (GLsizei, &quot;height&quot;), (GLint, &quot;border&quot;), (GLenum, &quot;format&quot;), (GLenum, &quot;type&quot;), (Blob(Const(GLvoid), &quot;__glTexImage2D_size(format, type, width, height)&quot;), &quot;pixels&quot;)]),<br>


     GlFunction(Void, &quot;glDrawBuffer&quot;, [(GLenum, &quot;mode&quot;)]),<br>-    GlFunction(Void, &quot;glClear&quot;, [(GLbitfield_attrib, &quot;mask&quot;)]),<br>-    GlFunction(Void, &quot;glClearColor&quot;, [(GLclampf, &quot;red&quot;), (GLclampf, &quot;green&quot;), (GLclampf, &quot;blue&quot;), (GLclampf, &quot;alpha&quot;)]),<br>


-    GlFunction(Void, &quot;glClearStencil&quot;, [(GLint, &quot;s&quot;)]),<br>+    GlFunction(Void, &quot;glClear&quot;, [(GLbitfield_attrib, &quot;mask&quot;)],loggputime=True),<br>+    GlFunction(Void, &quot;glClearColor&quot;, [(GLclampf, &quot;red&quot;), (GLclampf, &quot;green&quot;), (GLclampf, &quot;blue&quot;), (GLclampf, &quot;alpha&quot;)],loggputime=True),<br>


+    GlFunction(Void, &quot;glClearStencil&quot;, [(GLint, &quot;s&quot;)],loggputime=True),<br>     GlFunction(Void, &quot;glClearDepth&quot;, [(GLclampd, &quot;depth&quot;)]),<br>     GlFunction(Void, &quot;glStencilMask&quot;, [(GLuint, &quot;mask&quot;)]),<br>


     GlFunction(Void, &quot;glColorMask&quot;, [(GLboolean, &quot;red&quot;), (GLboolean, &quot;green&quot;), (GLboolean, &quot;blue&quot;), (GLboolean, &quot;alpha&quot;)]),<br>@@ -82,7 +82,7 @@ glapi.add_functions([<br>


     GlFunction(Void, &quot;glPixelStoref&quot;, [(GLenum, &quot;pname&quot;), (GLfloat, &quot;param&quot;)]),<br>     GlFunction(Void, &quot;glPixelStorei&quot;, [(GLenum, &quot;pname&quot;), (GLint, &quot;param&quot;)]),<br>


     GlFunction(Void, &quot;glReadBuffer&quot;, [(GLenum, &quot;mode&quot;)]),<br>-    GlFunction(Void, &quot;glReadPixels&quot;, [(GLint, &quot;x&quot;), (GLint, &quot;y&quot;), (GLsizei, &quot;width&quot;), (GLsizei, &quot;height&quot;), (GLenum, &quot;format&quot;), (GLenum, &quot;type&quot;), Out(GLpointer, &quot;pixels&quot;)]),<br>


+    GlFunction(Void, &quot;glReadPixels&quot;, [(GLint, &quot;x&quot;), (GLint, &quot;y&quot;), (GLsizei, &quot;width&quot;), (GLsizei, &quot;height&quot;), (GLenum, &quot;format&quot;), (GLenum, &quot;type&quot;), Out(GLpointer, &quot;pixels&quot;)],loggputime=True),<br>


     GlFunction(Void, &quot;glGetBooleanv&quot;, [(GLenum, &quot;pname&quot;), Out(Array(GLboolean, &quot;__gl_param_size(pname)&quot;), &quot;params&quot;)], sideeffects=False),<br>     GlFunction(Void, &quot;glGetDoublev&quot;, [(GLenum, &quot;pname&quot;), Out(Array(GLdouble, &quot;__gl_param_size(pname)&quot;), &quot;params&quot;)], sideeffects=False),<br>


     GlFunction(GLenum_error, &quot;glGetError&quot;, [], sideeffects=False),<br>@@ -322,7 +322,7 @@ glapi.add_functions([<br>     GlFunction(Void, &quot;glPixelMapuiv&quot;, [(GLenum, &quot;map&quot;), (GLsizei, &quot;mapsize&quot;), (Array(Const(GLuint), &quot;mapsize&quot;), &quot;values&quot;)]),<br>


     GlFunction(Void, &quot;glPixelMapusv&quot;, [(GLenum, &quot;map&quot;), (GLsizei, &quot;mapsize&quot;), (Array(Const(GLushort), &quot;mapsize&quot;), &quot;values&quot;)]),<br>     GlFunction(Void, &quot;glCopyPixels&quot;, [(GLint, &quot;x&quot;), (GLint, &quot;y&quot;), (GLsizei, &quot;width&quot;), (GLsizei, &quot;height&quot;), (GLenum, &quot;type&quot;)]),<br>


-    GlFunction(Void, &quot;glDrawPixels&quot;, [(GLsizei, &quot;width&quot;), (GLsizei, &quot;height&quot;), (GLenum, &quot;format&quot;), (GLenum, &quot;type&quot;), (Blob(Const(GLvoid), &quot;__glDrawPixels_size(format, type, width, height)&quot;), &quot;pixels&quot;)]),<br>


+    GlFunction(Void, &quot;glDrawPixels&quot;, [(GLsizei, &quot;width&quot;), (GLsizei, &quot;height&quot;), (GLenum, &quot;format&quot;), (GLenum, &quot;type&quot;), (Blob(Const(GLvoid), &quot;__glDrawPixels_size(format, type, width, height)&quot;), &quot;pixels&quot;)], loggputime=True),<br>


     GlFunction(Void, &quot;glGetClipPlane&quot;, [(GLenum, &quot;plane&quot;), Out(Array(GLdouble, 4), &quot;equation&quot;)], sideeffects=False),<br>     GlFunction(Void, &quot;glGetLightfv&quot;, [(GLenum, &quot;light&quot;), (GLenum, &quot;pname&quot;), Out(Array(GLfloat, &quot;__gl_param_size(pname)&quot;), &quot;params&quot;)], sideeffects=False),<br>


     GlFunction(Void, &quot;glGetLightiv&quot;, [(GLenum, &quot;light&quot;), (GLenum, &quot;pname&quot;), Out(Array(GLint, &quot;__gl_param_size(pname)&quot;), &quot;params&quot;)], sideeffects=False),<br>@@ -359,8 +359,8 @@ glapi.add_functions([<br>


     GlFunction(Void, &quot;glTranslatef&quot;, [(GLfloat, &quot;x&quot;), (GLfloat, &quot;y&quot;), (GLfloat, &quot;z&quot;)]),<br> <br>     # GL_VERSION_1_1<br>-    GlFunction(Void, &quot;glDrawArrays&quot;, [(GLenum_mode, &quot;mode&quot;), (GLint, &quot;first&quot;), (GLsizei, &quot;count&quot;)]),<br>


-    GlFunction(Void, &quot;glDrawElements&quot;, [(GLenum_mode, &quot;mode&quot;), (GLsizei, &quot;count&quot;), (GLenum, &quot;type&quot;), (GLpointerConst, &quot;indices&quot;)]),<br>+    GlFunction(Void, &quot;glDrawArrays&quot;, [(GLenum_mode, &quot;mode&quot;), (GLint, &quot;first&quot;), (GLsizei, &quot;count&quot;)], loggputime=True),<br>


+    GlFunction(Void, &quot;glDrawElements&quot;, [(GLenum_mode, &quot;mode&quot;), (GLsizei, &quot;count&quot;), (GLenum, &quot;type&quot;), (GLpointerConst, &quot;indices&quot;)], loggputime=True),<br>     GlFunction(Void, &quot;glGetPointerv&quot;, [(GLenum, &quot;pname&quot;), Out(Pointer(GLpointer), &quot;params&quot;)], sideeffects=False),<br>


     GlFunction(Void, &quot;glPolygonOffset&quot;, [(GLfloat, &quot;factor&quot;), (GLfloat, &quot;units&quot;)]),<br>     GlFunction(Void, &quot;glCopyTexImage1D&quot;, [(GLenum, &quot;target&quot;), (GLint, &quot;level&quot;), (GLenum, &quot;internalformat&quot;), (GLint, &quot;x&quot;), (GLint, &quot;y&quot;), (GLsizei, &quot;width&quot;), (GLint, &quot;border&quot;)]),<br>


diff --git a/specs/stdapi.py b/specs/stdapi.py<br>index 0b2fe82..2617813 100644<br>--- a/specs/stdapi.py<br>+++ b/specs/stdapi.py<br>@@ -254,7 +254,7 @@ class Function:<br>     # 0-3 are reserved to memcpy, malloc, free, and realloc<br>


     __id = 4<br> <br>-    def __init__(self, type, name, args, call = &#39;&#39;, fail = None, sideeffects=True):<br>+    def __init__(self, type, name, args, call = &#39;&#39;, fail = None, sideeffects=True, loggputime=False):<br>


         <a href="http://self.id" target="_blank">self.id</a> = Function.__id<br>         Function.__id += 1<br> <br>@@ -278,6 +278,7 @@ class Function:<br>         self.call = call<br>         self.fail = fail<br>         self.sideeffects = sideeffects<br>


+ self.loggputime = loggputime<br> <br>     def prototype(self, name=None):<br>         if name is not None:</span></div>
<div><span style="background-color:rgb(255,255,255)"><br></span> </div>
<div><span style="background-color:rgb(255,255,255);font-family:&#39;Droid Sans&#39;, arial, sans-serif;color:rgb(32,32,32);font-size:13px"><br>&gt;My idea was to have glretrace output the timings to stdout in a TSV format like:<br>


&gt;# call no    function name    cpu start   cpu stop    gpu start    gpu stop<br>&gt;50 glDrawArrays 1.4  1.5     2.4 2.5<br>&gt; ...<br>&gt;The GUI could then use this to produce a joint visualization of both<br>&gt;cpu and gpu timelines.</span></div>

<div><span style="background-color:rgb(255,255,255);font-family:&#39;Droid Sans&#39;, arial, sans-serif;color:rgb(32,32,32);font-size:13px">As gpu executes the gl commands asynchronously, </span><span class="Apple-style-span" style="color: rgb(32, 32, 32); font-family: &#39;Droid Sans&#39;, arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">I didn&#39;t find a way to query the gpu start time.</span></div>

<div><span class="Apple-style-span" style="color: rgb(32, 32, 32); font-family: &#39;Droid Sans&#39;, arial, sans-serif; font-size: 13px; background-color: rgb(255, 255, 255); ">Is there any way to query the gpu start/stop time per gl call?</span></div>

<div><span style="background-color:rgb(255,255,255);font-family:&#39;Droid Sans&#39;, arial, sans-serif;color:rgb(32,32,32);font-size:13px"><br>
I&#39;ll appreciate your comments on above patch.</span></div></div><div><span style="background-color:rgb(255,255,255);font-family:&#39;Droid Sans&#39;, arial, sans-serif;color:rgb(32,32,32);font-size:13px"><br></span></div>

<div><span style="background-color:rgb(255,255,255);font-family:&#39;Droid Sans&#39;, arial, sans-serif;color:rgb(32,32,32);font-size:13px">Sample time.log file:</span></div><div><span style="background-color:rgb(255,255,255);font-family:&#39;Droid Sans&#39;, arial, sans-serif;color:rgb(32,32,32);font-size:13px"><div>

Call#             Function Name         CPU Time                           GPU Time</div><div>    7              glShadeModel         cpu time = 0.0060  ms  </div><div>    8              glClearColor            cpu time = 0.0040  ms</div>

<div>    9                   glClear              cpu time = 0.3240  ms           gpu time = 0.0040  ms</div><div>   10                 glColor3f             cpu time = 0.0120  ms</div><div>   11              glPushMatrix         cpu time = 0.0050  ms</div>

<div>   12                 glRotatef             cpu time = 0.0040  ms</div><div>   13                   glBegin             cpu time = 0.0200  ms</div><div>   14                glVertex2f            cpu time = 0.0040  ms</div>

<div>   15                glVertex2f </div><div>   16                glVertex2f</div><div>   17                     glEnd              cpu time = 0.0020  ms</div><div>   18               glPopMatrix           cpu time = 16.2530  ms</div>

<div>   21                   glFlush             cpu time = 0.0020  ms</div><div>   22                glViewport            cpu time = 0.0030  ms</div><div>   23              glMatrixMode         cpu time = 0.0020  ms</div>

<div>   24            glLoadIdentity           cpu time = 0.0020  ms</div><div>   25                   glOrtho             cpu time = 0.0030  ms</div><div>   27                   glFlush</div><div>   28                glViewport</div>

<div>   29              glMatrixMode</div><div>   30            glLoadIdentity</div><div>   31                   glOrtho</div><div>   33              glShadeModel</div><div>   34              glClearColor</div><div>   35                   glClear             cpu time = 40.7830  ms          gpu time = 0.1890  ms</div>

<div>   36                 glColor3f            cpu time = 0.0030  ms</div><div>   37              glPushMatrix         cpu time = 0.0020  ms</div><div>   38                 glRotatef            cpu time = 0.0030  ms</div>

<div><br></div></span></div><div><font class="Apple-style-span" color="#202020" face="&#39;Droid Sans&#39;, arial, sans-serif"><br></font></div><div><font class="Apple-style-span" color="#202020" face="&#39;Droid Sans&#39;, arial, sans-serif">Thanks</font></div>

<div><font class="Apple-style-span" color="#202020" face="&#39;Droid Sans&#39;, arial, sans-serif">Anuj</font></div>
</div>