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