* commit '3d0d98658ec74afc2c2a542fc3b051c9372502db': opengles emulator: fixed renderer termination flow
This commit is contained in:
@@ -88,4 +88,13 @@ private:
|
|||||||
size_t m_free;
|
size_t m_free;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// When a client opens a connection to the renderer, it should
|
||||||
|
// send unsigned int value indicating the "clientFlags".
|
||||||
|
// The following are the bitmask of the clientFlags.
|
||||||
|
// currently only one bit is used which flags the server
|
||||||
|
// it should exit.
|
||||||
|
//
|
||||||
|
#define IOSTREAM_CLIENT_EXIT_SERVER 1
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -85,6 +85,9 @@ static const char *getGLES2ExtensionString(EGLDisplay p_dpy,
|
|||||||
|
|
||||||
void FrameBuffer::finalize(){
|
void FrameBuffer::finalize(){
|
||||||
if(s_theFrameBuffer){
|
if(s_theFrameBuffer){
|
||||||
|
s_theFrameBuffer->m_colorbuffers.clear();
|
||||||
|
s_theFrameBuffer->m_windows.clear();
|
||||||
|
s_theFrameBuffer->m_contexts.clear();
|
||||||
s_egl.eglMakeCurrent(s_theFrameBuffer->m_eglDisplay, NULL, NULL, NULL);
|
s_egl.eglMakeCurrent(s_theFrameBuffer->m_eglDisplay, NULL, NULL, NULL);
|
||||||
s_egl.eglDestroySurface(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_eglSurface);
|
s_egl.eglDestroySurface(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_eglSurface);
|
||||||
s_egl.eglDestroyContext(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_eglContext);
|
s_egl.eglDestroyContext(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_eglContext);
|
||||||
|
|||||||
@@ -16,10 +16,14 @@
|
|||||||
#include "RenderServer.h"
|
#include "RenderServer.h"
|
||||||
#include "TcpStream.h"
|
#include "TcpStream.h"
|
||||||
#include "RenderThread.h"
|
#include "RenderThread.h"
|
||||||
|
#include "FrameBuffer.h"
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
typedef std::set<RenderThread *> RenderThreadsSet;
|
||||||
|
|
||||||
RenderServer::RenderServer() :
|
RenderServer::RenderServer() :
|
||||||
m_listenSock(NULL),
|
m_listenSock(NULL),
|
||||||
m_exit(false)
|
m_exiting(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,16 +46,26 @@ RenderServer *RenderServer::create(int port)
|
|||||||
|
|
||||||
int RenderServer::Main()
|
int RenderServer::Main()
|
||||||
{
|
{
|
||||||
while(!m_exit) {
|
RenderThreadsSet threads;
|
||||||
|
|
||||||
|
while(1) {
|
||||||
TcpStream *stream = m_listenSock->accept();
|
TcpStream *stream = m_listenSock->accept();
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
fprintf(stderr,"Error accepting connection, aborting\n");
|
fprintf(stderr,"Error accepting connection, aborting\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int clientFlags;
|
||||||
|
if (!stream->readFully(&clientFlags, sizeof(unsigned int))) {
|
||||||
|
fprintf(stderr,"Error reading clientFlags\n");
|
||||||
|
delete stream;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
DBG("\n\n\n\n Got new stream!!!! \n\n\n\n\n");
|
DBG("\n\n\n\n Got new stream!!!! \n\n\n\n\n");
|
||||||
// check if we have been requested to exit while waiting on accept
|
// check if we have been requested to exit while waiting on accept
|
||||||
if (m_exit) {
|
if ((clientFlags & IOSTREAM_CLIENT_EXIT_SERVER) != 0) {
|
||||||
|
m_exiting = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,10 +78,49 @@ int RenderServer::Main()
|
|||||||
if (!rt->start()) {
|
if (!rt->start()) {
|
||||||
fprintf(stderr,"Failed to start RenderThread\n");
|
fprintf(stderr,"Failed to start RenderThread\n");
|
||||||
delete stream;
|
delete stream;
|
||||||
|
delete rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// remove from the threads list threads which are
|
||||||
|
// no longer running
|
||||||
|
//
|
||||||
|
for (RenderThreadsSet::iterator n,t = threads.begin();
|
||||||
|
t != threads.end();
|
||||||
|
t = n) {
|
||||||
|
// first find next iterator
|
||||||
|
n = t;
|
||||||
|
n++;
|
||||||
|
|
||||||
|
// delete and erase the current iterator
|
||||||
|
// if thread is no longer running
|
||||||
|
if ((*t)->isFinished()) {
|
||||||
|
delete (*t);
|
||||||
|
threads.erase(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// insert the added thread to the list
|
||||||
|
threads.insert(rt);
|
||||||
|
|
||||||
printf("Started new RenderThread\n");
|
printf("Started new RenderThread\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Wait for all threads to finish
|
||||||
|
//
|
||||||
|
for (RenderThreadsSet::iterator t = threads.begin();
|
||||||
|
t != threads.end();
|
||||||
|
t++) {
|
||||||
|
int exitStatus;
|
||||||
|
(*t)->wait(&exitStatus);
|
||||||
|
delete (*t);
|
||||||
|
}
|
||||||
|
threads.clear();
|
||||||
|
|
||||||
|
//
|
||||||
|
// de-initialize the FrameBuffer object
|
||||||
|
//
|
||||||
|
FrameBuffer::finalize();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,14 +25,14 @@ public:
|
|||||||
static RenderServer *create(int port);
|
static RenderServer *create(int port);
|
||||||
virtual int Main();
|
virtual int Main();
|
||||||
|
|
||||||
void flagNeedExit() { m_exit = true; }
|
bool isExiting() const { return m_exiting; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RenderServer();
|
RenderServer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TcpStream *m_listenSock;
|
TcpStream *m_listenSock;
|
||||||
bool m_exit;
|
bool m_exiting;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -20,12 +20,14 @@
|
|||||||
#include "TimeUtils.h"
|
#include "TimeUtils.h"
|
||||||
#include "GLDispatch.h"
|
#include "GLDispatch.h"
|
||||||
#include "GL2Dispatch.h"
|
#include "GL2Dispatch.h"
|
||||||
|
#include "EGLDispatch.h"
|
||||||
|
|
||||||
#define STREAM_BUFFER_SIZE 4*1024*1024
|
#define STREAM_BUFFER_SIZE 4*1024*1024
|
||||||
|
|
||||||
RenderThread::RenderThread() :
|
RenderThread::RenderThread() :
|
||||||
osUtils::Thread(),
|
osUtils::Thread(),
|
||||||
m_stream(NULL)
|
m_stream(NULL),
|
||||||
|
m_finished(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,5 +143,21 @@ int RenderThread::Main()
|
|||||||
fclose(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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ class RenderThread : public osUtils::Thread
|
|||||||
public:
|
public:
|
||||||
static RenderThread *create(IOStream *p_stream);
|
static RenderThread *create(IOStream *p_stream);
|
||||||
|
|
||||||
|
bool isFinished() const { return m_finished; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RenderThread();
|
RenderThread();
|
||||||
virtual int Main();
|
virtual int Main();
|
||||||
@@ -33,6 +35,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
IOStream *m_stream;
|
IOStream *m_stream;
|
||||||
renderControl_decoder_context_t m_rcDec;
|
renderControl_decoder_context_t m_rcDec;
|
||||||
|
bool m_finished;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ static osUtils::childProcess *s_renderProc = NULL;
|
|||||||
static RenderServer *s_renderThread = NULL;
|
static RenderServer *s_renderThread = NULL;
|
||||||
static int s_renderPort = 0;
|
static int s_renderPort = 0;
|
||||||
|
|
||||||
static IOStream *createRenderThread(int p_stream_buffer_size);
|
static IOStream *createRenderThread(int p_stream_buffer_size,
|
||||||
|
unsigned int clientFlags);
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define RENDER_API_USE_THREAD
|
#define RENDER_API_USE_THREAD
|
||||||
@@ -108,7 +109,7 @@ bool initOpenGLRenderer(FBNativeWindowType window,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dummy = createRenderThread(8);
|
dummy = createRenderThread(8, 0);
|
||||||
|
|
||||||
if (!dummy) {
|
if (!dummy) {
|
||||||
// stop if the process is no longer running
|
// stop if the process is no longer running
|
||||||
@@ -139,30 +140,27 @@ bool stopOpenGLRenderer()
|
|||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
|
|
||||||
|
// open a dummy connection to the renderer to make it
|
||||||
|
// realize the exit request.
|
||||||
|
// (send the exit request in clientFlags)
|
||||||
|
IOStream *dummy = createRenderThread(8, IOSTREAM_CLIENT_EXIT_SERVER);
|
||||||
|
if (!dummy) return false;
|
||||||
|
|
||||||
if (s_renderProc) {
|
if (s_renderProc) {
|
||||||
//
|
//
|
||||||
// kill the render process
|
// wait for the process to exit
|
||||||
//
|
//
|
||||||
ret = osUtils::KillProcess(s_renderProc->getPID(), true) != 0;
|
int exitStatus;
|
||||||
if (ret) {
|
ret = s_renderProc->wait(&exitStatus);
|
||||||
delete s_renderProc;
|
|
||||||
s_renderProc = NULL;
|
delete s_renderProc;
|
||||||
}
|
s_renderProc = NULL;
|
||||||
}
|
}
|
||||||
else if (s_renderThread) {
|
else if (s_renderThread) {
|
||||||
// flag the thread it should exit
|
|
||||||
s_renderThread->flagNeedExit();
|
|
||||||
|
|
||||||
// open a dummy connection to the renderer to make it
|
// wait for the thread to exit
|
||||||
// realize the exit request
|
int status;
|
||||||
IOStream *dummy = createRenderThread(8);
|
ret = s_renderThread->wait(&status);
|
||||||
if (dummy) {
|
|
||||||
// wait for the thread to exit
|
|
||||||
int status;
|
|
||||||
ret = s_renderThread->wait(&status);
|
|
||||||
|
|
||||||
delete dummy;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete s_renderThread;
|
delete s_renderThread;
|
||||||
s_renderThread = NULL;
|
s_renderThread = NULL;
|
||||||
@@ -171,7 +169,7 @@ bool stopOpenGLRenderer()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
IOStream *createRenderThread(int p_stream_buffer_size)
|
IOStream *createRenderThread(int p_stream_buffer_size, unsigned int clientFlags)
|
||||||
{
|
{
|
||||||
TcpStream *stream = new TcpStream(p_stream_buffer_size);
|
TcpStream *stream = new TcpStream(p_stream_buffer_size);
|
||||||
if (!stream) {
|
if (!stream) {
|
||||||
@@ -185,5 +183,13 @@ IOStream *createRenderThread(int p_stream_buffer_size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// send clientFlags to the renderer
|
||||||
|
//
|
||||||
|
unsigned int *pClientFlags =
|
||||||
|
(unsigned int *)stream->allocBuffer(sizeof(unsigned int));
|
||||||
|
*pClientFlags = clientFlags;
|
||||||
|
stream->commitBuffer(sizeof(unsigned int));
|
||||||
|
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -160,6 +160,16 @@ int main(int argc, char *argv[])
|
|||||||
GetMessage(&msg, hWnd, 0, 0);
|
GetMessage(&msg, hWnd, 0, 0);
|
||||||
TranslateMessage(&msg);
|
TranslateMessage(&msg);
|
||||||
DispatchMessage(&msg);
|
DispatchMessage(&msg);
|
||||||
|
|
||||||
|
//
|
||||||
|
// if server thread has exiting
|
||||||
|
// wait for it to exit and done.
|
||||||
|
//
|
||||||
|
if (server->isExiting()) {
|
||||||
|
int exitStatus;
|
||||||
|
server->wait(&exitStatus);
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,13 @@ HostConnection *HostConnection::get()
|
|||||||
}
|
}
|
||||||
con->m_stream = stream;
|
con->m_stream = stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// send zero 'clientFlags' to the host.
|
||||||
|
unsigned int *pClientFlags =
|
||||||
|
(unsigned int *)con->m_stream->allocBuffer(sizeof(unsigned int));
|
||||||
|
*pClientFlags = 0;
|
||||||
|
con->m_stream->commitBuffer(sizeof(unsigned int));
|
||||||
|
|
||||||
LOGD("HostConnection::get() New Host Connection established %p, tid %d\n", con, gettid());
|
LOGD("HostConnection::get() New Host Connection established %p, tid %d\n", con, gettid());
|
||||||
tinfo->hostConn = con;
|
tinfo->hostConn = con;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user