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