aboutsummaryrefslogtreecommitdiffstats
path: root/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp')
-rw-r--r--emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp162
1 files changed, 162 insertions, 0 deletions
diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp b/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
new file mode 100644
index 0000000..0119133
--- /dev/null
+++ b/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp
@@ -0,0 +1,162 @@
+/*
+* Copyright (C) 2011 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#include "RenderThread.h"
+#include "RenderControl.h"
+#include "ThreadInfo.h"
+#include "ReadBuffer.h"
+#include "TimeUtils.h"
+#include "GLDispatch.h"
+#include "GL2Dispatch.h"
+#include "EGLDispatch.h"
+
+#define STREAM_BUFFER_SIZE 4*1024*1024
+
+RenderThread::RenderThread() :
+ osUtils::Thread(),
+ m_stream(NULL),
+ m_finished(false)
+{
+}
+
+RenderThread *RenderThread::create(IOStream *p_stream)
+{
+ RenderThread *rt = new RenderThread();
+ if (!rt) {
+ return NULL;
+ }
+
+ rt->m_stream = p_stream;
+
+ return rt;
+}
+
+int RenderThread::Main()
+{
+ RenderThreadInfo * tInfo = getRenderThreadInfo();
+ //
+ // initialize decoders
+ //
+ tInfo->m_glDec.initGL( gl_dispatch_get_proc_func, NULL );
+ tInfo->m_gl2Dec.initGL( gl2_dispatch_get_proc_func, NULL );
+ initRenderControlContext( &m_rcDec );
+
+ ReadBuffer readBuf(m_stream, STREAM_BUFFER_SIZE);
+
+ int stats_totalBytes = 0;
+ long long stats_t0 = GetCurrentTimeMS();
+
+ //
+ // open dump file if RENDER_DUMP_DIR is defined
+ //
+ const char *dump_dir = getenv("RENDERER_DUMP_DIR");
+ FILE *dumpFP = NULL;
+ if (dump_dir) {
+ size_t bsize = strlen(dump_dir) + 32;
+ char *fname = new char[bsize];
+ snprintf(fname,bsize,"%s/stream_%p", dump_dir, this);
+ dumpFP = fopen(fname, "wb");
+ if (!dumpFP) {
+ fprintf(stderr,"Warning: stream dump failed to open file %s\n",fname);
+ }
+ delete [] fname;
+ }
+
+ while (1) {
+
+ int stat = readBuf.getData();
+ if (stat <= 0) {
+ break;
+ }
+
+ //
+ // log received bandwidth statistics
+ //
+ stats_totalBytes += readBuf.validData();
+ long long dt = GetCurrentTimeMS() - stats_t0;
+ if (dt > 1000) {
+ float dts = (float)dt / 1000.0f;
+ //printf("Used Bandwidth %5.3f MB/s\n", ((float)stats_totalBytes / dts) / (1024.0f*1024.0f));
+ stats_totalBytes = 0;
+ stats_t0 = GetCurrentTimeMS();
+ }
+
+ //
+ // dump stream to file if needed
+ //
+ if (dumpFP) {
+ int skip = readBuf.validData() - stat;
+ fwrite(readBuf.buf()+skip, 1, readBuf.validData()-skip, dumpFP);
+ fflush(dumpFP);
+ }
+
+ bool progress;
+ do {
+ progress = false;
+
+ //
+ // try to process some of the command buffer using the GLESv1 decoder
+ //
+ size_t last = tInfo->m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
+ if (last > 0) {
+ progress = true;
+ readBuf.consume(last);
+ }
+
+ //
+ // try to process some of the command buffer using the GLESv2 decoder
+ //
+ last = tInfo->m_gl2Dec.decode(readBuf.buf(), readBuf.validData(), m_stream);
+ if (last > 0) {
+ progress = true;
+ readBuf.consume(last);
+ }
+
+ //
+ // try to process some of the command buffer using the
+ // renderControl decoder
+ //
+ last = m_rcDec.decode(readBuf.buf(), readBuf.validData(), m_stream);
+ if (last > 0) {
+ readBuf.consume(last);
+ progress = true;
+ }
+
+ } while( progress );
+
+ }
+
+ if (dumpFP) {
+ fclose(dumpFP);
+ }
+
+ //
+ // release the thread from any EGL context
+ // if bound to context.
+ //
+ EGLDisplay eglDpy = s_egl.eglGetCurrentDisplay();
+ if (eglDpy != EGL_NO_DISPLAY) {
+ s_egl.eglMakeCurrent(eglDpy,
+ EGL_NO_SURFACE,
+ EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ }
+
+ //
+ // flag that this thread has finished execution
+ m_finished = true;
+
+ return 0;
+}