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
RenderThread()27 RenderThread::RenderThread() :
28 osUtils::Thread(),
29 m_stream(NULL),
30 m_finished(false)
31 {
32 }
33
create(IOStream * p_stream)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
Main()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