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