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             fprintf(stderr, "client shutdown\n");
     82             break;
     83         }
     84 
     85         //
     86         // log received bandwidth statistics
     87         //
     88         stats_totalBytes += readBuf.validData();
     89         long long dt = GetCurrentTimeMS() - stats_t0;
     90         if (dt > 1000) {
     91             float dts = (float)dt / 1000.0f;
     92             //printf("Used Bandwidth %5.3f MB/s\n", ((float)stats_totalBytes / dts) / (1024.0f*1024.0f));
     93             stats_totalBytes = 0;
     94             stats_t0 = GetCurrentTimeMS();
     95         }
     96 
     97         //
     98         // dump stream to file if needed
     99         //
    100         if (dumpFP) {
    101             int skip = readBuf.validData() - stat;
    102             fwrite(readBuf.buf()+skip, 1, readBuf.validData()-skip, dumpFP);
    103             fflush(dumpFP);
    104         }
    105 
    106         bool progress;
    107         do {
    108             progress = false;
    109 
    110             //
    111             // try to process some of the command buffer using the GLESv1 decoder
    112             //
    113             size_t last = tInfo->m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
    114             if (last > 0) {
    115                 progress = true;
    116                 readBuf.consume(last);
    117             }
    118 
    119             //
    120             // try to process some of the command buffer using the GLESv2 decoder
    121             //
    122             last = tInfo->m_gl2Dec.decode(readBuf.buf(), readBuf.validData(), m_stream);
    123             if (last > 0) {
    124                 progress = true;
    125                 readBuf.consume(last);
    126             }
    127 
    128             //
    129             // try to process some of the command buffer using the
    130             // renderControl decoder
    131             //
    132             last = m_rcDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
    133             if (last > 0) {
    134                 readBuf.consume(last);
    135                 progress = true;
    136             }
    137 
    138         } while( progress );
    139 
    140     }
    141 
    142     if (dumpFP) {
    143         fclose(dumpFP);
    144     }
    145 
    146     //
    147     // release the thread from any EGL context
    148     // if bound to context.
    149     //
    150     EGLDisplay eglDpy = s_egl.eglGetCurrentDisplay();
    151     if (eglDpy != EGL_NO_DISPLAY) {
    152         s_egl.eglMakeCurrent(eglDpy,
    153                              EGL_NO_SURFACE,
    154                              EGL_NO_SURFACE,
    155                              EGL_NO_CONTEXT);
    156     }
    157 
    158     //
    159     // flag that this thread has finished execution
    160     m_finished = true;
    161 
    162     return 0;
    163 }
    164