diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp index f6f15b539..b30d53555 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp @@ -92,6 +92,17 @@ void ColorBuffer::update(GLenum p_format, GLenum p_type, void *pixels) fb->unbind_locked(); } +void ColorBuffer::subUpdate(int x, int y, int width, int height, GLenum p_format, GLenum p_type, void *pixels) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb->bind_locked()) return; + s_gl.glBindTexture(GL_TEXTURE_2D, m_tex); + s_gl.glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + s_gl.glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, + width, height, p_format, p_type, pixels); + fb->unbind_locked(); +} + bool ColorBuffer::blitFromPbuffer(EGLSurface p_pbufSurface) { FrameBuffer *fb = FrameBuffer::getFB(); diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h index 6829581ab..25761ce62 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h +++ b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h @@ -33,6 +33,7 @@ public: GLuint getHeight() const { return m_height; } void update(GLenum p_format, GLenum p_type, void *pixels); + void subUpdate(int x, int y, int width, int height, GLenum p_format, GLenum p_type, void *pixels); bool blitFromPbuffer(EGLSurface p_pbufSurface); bool post(); bool bindToTexture(); diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp index 635f94a60..e457e5eca 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp @@ -27,6 +27,7 @@ bool init_egl_dispatch() osUtils::dynLibrary *lib = osUtils::dynLibrary::open(libName); if (!lib) { + printf("Failed to open %s\n", libName); return NULL; } diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp index 81ba067ce..17a0f871b 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp @@ -196,7 +196,7 @@ void FBConfig::packConfigsInfo(GLuint *buffer) memcpy(buffer, s_configAttribs, s_numConfigAttribs * sizeof(GLuint)); for (int i=0; im_attribValues, + s_fbConfigs[i]->m_attribValues, s_numConfigAttribs * sizeof(GLuint)); } } @@ -222,7 +222,47 @@ int FBConfig::chooseConfig(FrameBuffer *fb, EGLint * attribs, uint32_t * configs // Query the max matching configs in the backend // EGLConfig *matchedConfigs = new EGLConfig[nConfigs]; - s_egl.eglChooseConfig(dpy, attribs, matchedConfigs, nConfigs, &nConfigs); + + // + //Until we have EGLImage implementation, we force pbuf configs + // + bool needToAddPbufAttr = true; + int attribCnt = 0; + EGLint * attrib_p = attribs; + if (attribs) { + while (attrib_p[0] != EGL_NONE) { + if (attrib_p[0] == EGL_SURFACE_TYPE) { + attrib_p[1] = EGL_PBUFFER_BIT; //replace whatever was there before + needToAddPbufAttr = false; + } + attrib_p += 2; + attribCnt += 2; + } + } + EGLint * newAttribs = new EGLint[attribCnt + 1 + ((needToAddPbufAttr) ? 2 : 0)]; + attrib_p = newAttribs; + if (needToAddPbufAttr) { + *(attrib_p++) = EGL_SURFACE_TYPE; + *(attrib_p++) = EGL_PBUFFER_BIT; + } + memcpy(attrib_p, attribs, attribCnt*sizeof(EGLint)); + attrib_p += attribCnt; + *attrib_p = EGL_NONE; + +#if 1 + DBG("EGLint %d", sizeof(EGLint)); + if (newAttribs) { + EGLint * attrib_p = newAttribs; + while (attrib_p[0] != EGL_NONE) { + DBG("attr: 0x%x %d", attrib_p[0], attrib_p[1]); + attrib_p += 2; + } + } + +#endif + s_egl.eglChooseConfig(dpy, newAttribs, matchedConfigs, nConfigs, &nConfigs); + + delete newAttribs; // // From all matchedConfigs we need only config_size FBConfigs, so we intersect both lists compating the CONFIG_ID attribute diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp index b0bd7ab95..1caaf1092 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp @@ -106,7 +106,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window, // if (!init_gl_dispatch()) { // Failed to load GLES - printf("Failed to init_gl_dispatch\n"); + ERR("Failed to init_gl_dispatch\n"); return false; } @@ -115,7 +115,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window, // FrameBuffer *fb = new FrameBuffer(p_x, p_y, p_width, p_height); if (!fb) { - printf("Fialed to create fb\n"); + ERR("Failed to create fb\n"); return false; } @@ -138,11 +138,18 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window, // fb->m_eglDisplay = s_egl.eglGetDisplay(EGL_DEFAULT_DISPLAY); if (fb->m_eglDisplay == EGL_NO_DISPLAY) { - printf("Failed to Initialize backend EGL display\n"); + ERR("Failed to Initialize backend EGL display\n"); delete fb; return false; } - s_egl.eglInitialize(fb->m_eglDisplay, &fb->m_caps.eglMajor, &fb->m_caps.eglMinor); + + if (!s_egl.eglInitialize(fb->m_eglDisplay, &fb->m_caps.eglMajor, &fb->m_caps.eglMinor)) { + ERR("Failed to eglInitialize\n"); + delete fb; + return false; + } + + DBG("egl: %d %d\n", fb->m_caps.eglMajor, fb->m_caps.eglMinor); s_egl.eglBindAPI(EGL_OPENGL_ES_API); fb->m_nativeWindow = p_window; @@ -166,17 +173,26 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window, // Create EGL context and Surface attached to the native window, for // framebuffer post rendering. // +#if 0 GLint configAttribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_NONE }; - +#else + GLint configAttribs[] = { + EGL_RED_SIZE, 1, + EGL_GREEN_SIZE, 1, + EGL_BLUE_SIZE, 1, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_NONE + }; +#endif EGLConfig eglConfig; int n; if (!s_egl.eglChooseConfig(fb->m_eglDisplay, configAttribs, &eglConfig, 1, &n)) { - printf("Failed on eglChooseConfig\n"); + ERR("Failed on eglChooseConfig\n"); delete fb; return false; } @@ -186,6 +202,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window, (EGLNativeWindowType)p_window, NULL); if (fb->m_eglSurface == EGL_NO_SURFACE) { + ERR("Failed to create surface\n"); delete fb; return false; } @@ -207,6 +224,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window, // Make the context current if (!fb->bind_locked()) { + ERR("Failed to make current\n"); delete fb; return false; } @@ -243,6 +261,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window, // InitConfigStatus configStatus = FBConfig::initConfigList(fb); if (configStatus == INIT_CONFIG_FAILED) { + ERR("Failed: Initialize set of configs\n"); delete fb; return false; } @@ -403,6 +422,21 @@ void FrameBuffer::DestroyColorBuffer(HandleType p_colorbuffer) m_colorbuffers.erase(p_colorbuffer); } +bool FrameBuffer::flushWindowSurfaceColorBuffer(HandleType p_surface) +{ + android::Mutex::Autolock mutex(m_lock); + + WindowSurfaceMap::iterator w( m_windows.find(p_surface) ); + if (w == m_windows.end()) { + // bad surface handle + return false; + } + + (*w).second->flushColorBuffer(); + + return true; +} + bool FrameBuffer::setWindowSurfaceColorBuffer(HandleType p_surface, HandleType p_colorbuffer) { @@ -425,6 +459,23 @@ bool FrameBuffer::setWindowSurfaceColorBuffer(HandleType p_surface, return true; } +bool FrameBuffer::updateColorBuffer(HandleType p_colorbuffer, + int x, int y, int width, int height, + GLenum format, GLenum type, void *pixels) +{ + android::Mutex::Autolock mutex(m_lock); + + ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) ); + if (c == m_colorbuffers.end()) { + // bad colorbuffer handle + return false; + } + + (*c).second->subUpdate(x, y, width, height, format, type, pixels); + + return true; +} + bool FrameBuffer::bindColorBufferToTexture(HandleType p_colorbuffer) { android::Mutex::Autolock mutex(m_lock); @@ -513,6 +564,7 @@ bool FrameBuffer::bindContext(HandleType p_context, tinfo->currContext = ctx; tinfo->currDrawSurf = draw; tinfo->currReadSurf = read; + tinfo->m_glDec.setContextData(&ctx->decoderContextData()); return true; } @@ -528,6 +580,7 @@ bool FrameBuffer::bind_locked() if (!s_egl.eglMakeCurrent(m_eglDisplay, m_eglSurface, m_eglSurface, m_eglContext)) { + ERR("eglMakeCurrent failed\n"); return false; } diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h index 99e499909..128d73f60 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h +++ b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h @@ -67,7 +67,11 @@ public: bool bindContext(HandleType p_context, HandleType p_drawSurface, HandleType p_readSurface); bool setWindowSurfaceColorBuffer(HandleType p_surface, HandleType p_colorbuffer); + bool flushWindowSurfaceColorBuffer(HandleType p_surface); bool bindColorBufferToTexture(HandleType p_colorbuffer); + bool updateColorBuffer(HandleType p_colorbuffer, + int x, int y, int width, int height, + GLenum format, GLenum type, void *pixels); bool post(HandleType p_colorbuffer); diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.h b/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.h index 3962adaa6..9cbb5fc9b 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.h +++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderContext.h @@ -18,6 +18,7 @@ #include "SmartPtr.h" #include +#include "GLDecoderContextData.h" class RenderContext; typedef SmartPtr RenderContextPtr; @@ -33,6 +34,8 @@ public: EGLContext getEGLContext() const { return m_ctx; } bool isGL2() const { return m_isGL2; } + GLDecoderContextData & decoderContextData() { return m_contextData; } + private: RenderContext(); @@ -40,6 +43,7 @@ private: EGLContext m_ctx; int m_config; bool m_isGL2; + GLDecoderContextData m_contextData; }; #endif diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp index f68a15397..c0f626073 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp @@ -189,6 +189,15 @@ static void rcDestroyColorBuffer(uint32_t colorbuffer) fb->DestroyColorBuffer( colorbuffer ); } +static void rcFlushWindowColorBuffer(uint32_t windowSurface) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return; + } + fb->flushWindowSurfaceColorBuffer(windowSurface); +} + static void rcSetWindowColorBuffer(uint32_t windowSurface, uint32_t colorBuffer) { @@ -257,7 +266,12 @@ static void rcUpdateColorBuffer(uint32_t colorBuffer, GLint width, GLint height, GLenum format, GLenum type, void* pixels) { - // XXX: TBD - should be implemented + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return; + } + + fb->updateColorBuffer(colorBuffer, x, y, width, height, format, type, pixels); } void initRenderControlContext(renderControl_decoder_context_t *dec) @@ -276,6 +290,7 @@ void initRenderControlContext(renderControl_decoder_context_t *dec) dec->set_rcCreateColorBuffer(rcCreateColorBuffer); dec->set_rcDestroyColorBuffer(rcDestroyColorBuffer); dec->set_rcSetWindowColorBuffer(rcSetWindowColorBuffer); + dec->set_rcFlushWindowColorBuffer(rcFlushWindowColorBuffer); dec->set_rcMakeCurrent(rcMakeCurrent); dec->set_rcFBPost(rcFBPost); dec->set_rcFBSetSwapInterval(rcFBSetSwapInterval); diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp index 95dbc3c92..cc6328306 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp @@ -32,6 +32,7 @@ RenderServer *RenderServer::create(int port) server->m_listenSock = new TcpStream(); if (server->m_listenSock->listen(port) < 0) { + ERR("RenderServer::create failed to listen on port %d\n", port); delete server; return NULL; } @@ -48,6 +49,7 @@ int RenderServer::Main() break; } + 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 if (m_exit) { break; diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp index 8dd60d525..ad5df3891 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.cpp @@ -15,6 +15,7 @@ */ #include "RenderThread.h" #include "RenderControl.h" +#include "ThreadInfo.h" #include "ReadBuffer.h" #include "TimeUtils.h" #include "GLDispatch.h" @@ -41,10 +42,11 @@ RenderThread *RenderThread::create(IOStream *p_stream) int RenderThread::Main() { + RenderThreadInfo * tInfo = getRenderThreadInfo(); // // initialize decoders // - m_glDec.initGL( gl_dispatch_get_proc_func, NULL ); + tInfo->m_glDec.initGL( gl_dispatch_get_proc_func, NULL ); initRenderControlContext( &m_rcDec ); ReadBuffer readBuf(m_stream, STREAM_BUFFER_SIZE); @@ -79,7 +81,7 @@ int RenderThread::Main() // // try to process some of the command buffer using the GLES decoder // - size_t last = m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream); + size_t last = tInfo->m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream); if (last > 0) { progress = true; readBuf.consume(last); diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.h b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.h index 2ca5755a9..ad5cde3b7 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.h +++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderThread.h @@ -32,7 +32,6 @@ private: private: IOStream *m_stream; - GLDecoder m_glDec; renderControl_decoder_context_t m_rcDec; }; diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h b/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h index 82d298069..cabeb56ba 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h +++ b/tools/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h @@ -18,12 +18,14 @@ #include "RenderContext.h" #include "WindowSurface.h" +#include "GLDecoder.h" struct RenderThreadInfo { RenderContextPtr currContext; WindowSurfacePtr currDrawSurf; WindowSurfacePtr currReadSurf; + GLDecoder m_glDec; }; RenderThreadInfo *getRenderThreadInfo(); diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp index a956e2a4c..21b92e286 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp @@ -123,12 +123,11 @@ WindowSurface *WindowSurface::create(int p_config, int p_width, int p_height) } // -// setColorBuffer - this function is called when a new color buffer needs to -// be attached to the surface. The function should make sure that the +// flushColorBuffer - The function makes sure that the // previous attached color buffer is updated, if copy or blit should be done // in order to update it - it is being done here. // -void WindowSurface::setColorBuffer(ColorBufferPtr p_colorBuffer) +void WindowSurface::flushColorBuffer() { if (m_attachedColorBuffer.Ptr() != NULL) { @@ -143,9 +142,18 @@ void WindowSurface::setColorBuffer(ColorBufferPtr p_colorBuffer) } } else { + //TODO: EGLImage } } +} +// +// setColorBuffer - this function is called when a new color buffer needs to +// be attached to the surface. The function doesn't make sure that the +// previous attached color buffer is updated, this is done by flushColorBuffer +// +void WindowSurface::setColorBuffer(ColorBufferPtr p_colorBuffer) +{ m_attachedColorBuffer = p_colorBuffer; } @@ -226,5 +234,4 @@ void WindowSurface::copyToColorBuffer() s_egl.eglMakeCurrent(fb->getDisplay(), prevDrawSurf, prevReadSurf, prevContext); - free(data); } diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h index 3a01a35f0..2a496df53 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h +++ b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h @@ -37,6 +37,7 @@ public: EGLSurface getEGLSurface() const { return m_eglSurface; } void setColorBuffer(ColorBufferPtr p_colorBuffer); + void flushColorBuffer(); void bind(RenderContextPtr p_ctx, SurfaceBindType p_bindType); private: diff --git a/tools/emulator/opengl/host/renderer/main.cpp b/tools/emulator/opengl/host/renderer/main.cpp index ccc5d6a12..73efe5953 100644 --- a/tools/emulator/opengl/host/renderer/main.cpp +++ b/tools/emulator/opengl/host/renderer/main.cpp @@ -19,6 +19,11 @@ #include #include "FrameBuffer.h" +#include +#include +#include + + static void printUsage(const char *progName) { fprintf(stderr, "Usage: %s -windowid [options]\n", progName); @@ -33,7 +38,7 @@ static void printUsage(const char *progName) int main(int argc, char *argv[]) { - int portNum = 4141; + int portNum = CODEC_SERVER_PORT; int winX = 0; int winY = 0; int winWidth = 320; @@ -84,6 +89,9 @@ int main(int argc, char *argv[]) printUsage(argv[0]); } + printf("renderer pid %d , press any key to continue...\n", getpid()); + getchar(); + // // initialize Framebuffer // @@ -95,7 +103,7 @@ int main(int argc, char *argv[]) } // - // Create and run a render server listening to the givven port number + // Create and run a render server listening to the given port number // RenderServer *server = RenderServer::create(portNum); if (!server) { diff --git a/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp b/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp index d408e4b6e..8cc097c3c 100644 --- a/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp +++ b/tools/emulator/opengl/host/tools/emugen/ApiGen.cpp @@ -348,6 +348,7 @@ int ApiGen::genEncoderImpl(const std::string &filename) e->print(fp, true, "_enc", /* classname + "::" */"", "void *self"); fprintf(fp, "{\n"); +// fprintf(fp, "\n\tDBG(\">>>> %s\\n\");\n", e->name().c_str()); fprintf(fp, "\n\t%s *ctx = (%s *)self;\n\n", classname.c_str(), classname.c_str()); @@ -454,6 +455,7 @@ int ApiGen::genEncoderImpl(const std::string &filename) } } } +//XXX fprintf(fp, "\n\tDBG(\"<<<< %s\\n\");\n", e->name().c_str()); // todo - return value for pointers if (e->retval().isPointer()) { fprintf(stderr, "WARNING: %s : return value of pointer is unsupported\n",