diff options
Diffstat (limited to 'emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp')
-rw-r--r-- | emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp | 162 |
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; +} |