Home | History | Annotate | Download | only in libOpenglRender
      1 /*
      2 * Copyright (C) 2011 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 #include "RenderThread.h"
     17 #include "RenderControl.h"
     18 #include "ThreadInfo.h"
     19 #include "ReadBuffer.h"
     20 #include "TimeUtils.h"
     21 #include "GLDispatch.h"
     22 #include "GL2Dispatch.h"
     23 #include "EGLDispatch.h"
     24 
     25 #define STREAM_BUFFER_SIZE 4*1024*1024
     26 
     27 RenderThread::RenderThread() :
     28     osUtils::Thread(),
     29     m_stream(NULL),
     30     m_finished(false)
     31 {
     32 }
     33 
     34 RenderThread *RenderThread::create(IOStream *p_stream)
     35 {
     36     RenderThread *rt = new RenderThread();
     37     if (!rt) {
     38         return NULL;
     39     }
     40 
     41     rt->m_stream = p_stream;
     42 
     43     return rt;
     44 }
     45 
     46 int RenderThread::Main()
     47 {
     48     RenderThreadInfo * tInfo = getRenderThreadInfo();
     49     //
     50     // initialize decoders
     51     //
     52     tInfo->m_glDec.initGL( gl_dispatch_get_proc_func, NULL );
     53     tInfo->m_gl2Dec.initGL( gl2_dispatch_get_proc_func, NULL );
     54     initRenderControlContext( &m_rcDec );
     55 
     56     ReadBuffer readBuf(m_stream, STREAM_BUFFER_SIZE);
     57 
     58     int stats_totalBytes = 0;
     59     long long stats_t0 = GetCurrentTimeMS();
     60 
     61     //
     62     // open dump file if RENDER_DUMP_DIR is defined
     63     //
     64     const char *dump_dir = getenv("RENDERER_DUMP_DIR");
     65     FILE *dumpFP = NULL;
     66     if (dump_dir) {
     67         size_t bsize = strlen(dump_dir) + 32;
     68         char *fname = new char[bsize];
     69         snprintf(fname,bsize,"%s/stream_%p", dump_dir, this);
     70         dumpFP = fopen(fname, "wb");
     71         if (!dumpFP) {
     72             fprintf(stderr,"Warning: stream dump failed to open file %s\n",fname);
     73         }
     74         delete [] fname;
     75     }
     76 
     77     while (1) {
     78 
     79         int stat = readBuf.getData();
     80         if (stat <= 0) {
     81             break;
     82         }
     83 
     84         //
     85         // log received bandwidth statistics
     86         //
     87         stats_totalBytes += readBuf.validData();
     88         long long dt = GetCurrentTimeMS() - stats_t0;
     89         if (dt > 1000) {
     90             float dts = (float)dt / 1000.0f;
     91             //printf("Used Bandwidth %5.3f MB/s\n", ((float)stats_totalBytes / dts) / (1024.0f*1024.0f));
     92             stats_totalBytes = 0;
     93             stats_t0 = GetCurrentTimeMS();
     94         }
     95 
     96         //
     97         // dump stream to file if needed
     98         //
     99         if (dumpFP) {
    100             int skip = readBuf.validData() - stat;
    101             fwrite(readBuf.buf()+skip, 1, readBuf.validData()-skip, dumpFP);
    102             fflush(dumpFP);
    103         }
    104 
    105         bool progress;
    106         do {
    107             progress = false;
    108 
    109             //
    110             // try to process some of the command buffer using the GLESv1 decoder
    111             //
    112             size_t last = tInfo->m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
    113             if (last > 0) {
    114                 progress = true;
    115                 readBuf.consume(last);
    116             }
    117 
    118             //
    119             // try to process some of the command buffer using the GLESv2 decoder
    120             //
    121             last = tInfo->m_gl2Dec.decode(readBuf.buf(), readBuf.validData(), m_stream);
    122             if (last > 0) {
    123                 progress = true;
    124                 readBuf.consume(last);
    125             }
    126 
    127             //
    128             // try to process some of the command buffer using the
    129             // renderControl decoder
    130             //
    131             last = m_rcDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
    132             if (last > 0) {
    133                 readBuf.consume(last);
    134                 progress = true;
    135             }
    136 
    137         } while( progress );
    138 
    139     }
    140 
    141     if (dumpFP) {
    142         fclose(dumpFP);
    143     }
    144 
    145     //
    146     // release the thread from any EGL context
    147     // if bound to context.
    148     //
    149     EGLDisplay eglDpy = s_egl.eglGetCurrentDisplay();
    150     if (eglDpy != EGL_NO_DISPLAY) {
    151         s_egl.eglMakeCurrent(eglDpy,
    152                              EGL_NO_SURFACE,
    153                              EGL_NO_SURFACE,
    154                              EGL_NO_CONTEXT);
    155     }
    156 
    157     //
    158     // flag that this thread has finished execution
    159     m_finished = true;
    160 
    161     return 0;
    162 }
    163