diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp index 774ad020b..f6f15b539 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp @@ -17,6 +17,10 @@ #include "FrameBuffer.h" #include "EGLDispatch.h" #include "GLDispatch.h" +#include "ThreadInfo.h" +#ifdef WITH_GLES2 +#include "GL2Dispatch.h" +#endif #include ColorBuffer *ColorBuffer::create(int p_width, int p_height, @@ -134,6 +138,27 @@ bool ColorBuffer::blitFromPbuffer(EGLSurface p_pbufSurface) return true; } +bool ColorBuffer::bindToTexture() +{ + if (m_eglImage) { + RenderThreadInfo *tInfo = getRenderThreadInfo(); + if (tInfo->currContext.Ptr()) { +#ifdef WITH_GLES2 + if (tInfo->currContext->isGL2()) { + s_gl2.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); + } + else { + s_gl.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); + } +#else + s_gl.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage); +#endif + return true; + } + } + return false; +} + bool ColorBuffer::bind_fbo() { if (m_fbo) { diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h index 550c6d102..6829581ab 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h +++ b/tools/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h @@ -35,6 +35,7 @@ public: void update(GLenum p_format, GLenum p_type, void *pixels); bool blitFromPbuffer(EGLSurface p_pbufSurface); bool post(); + bool bindToTexture(); private: ColorBuffer(); diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp index a0f32c8e0..b0bd7ab95 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp @@ -97,6 +97,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window, // if (!init_egl_dispatch()) { // Failed to load EGL + printf("Failed to init_egl_dispatch\n"); return false; } @@ -105,6 +106,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window, // if (!init_gl_dispatch()) { // Failed to load GLES + printf("Failed to init_gl_dispatch\n"); return false; } @@ -113,6 +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"); return false; } @@ -135,6 +138,7 @@ 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"); delete fb; return false; } @@ -172,6 +176,7 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window, int n; if (!s_egl.eglChooseConfig(fb->m_eglDisplay, configAttribs, &eglConfig, 1, &n)) { + printf("Failed on eglChooseConfig\n"); delete fb; return false; } @@ -420,6 +425,19 @@ bool FrameBuffer::setWindowSurfaceColorBuffer(HandleType p_surface, return true; } +bool FrameBuffer::bindColorBufferToTexture(HandleType p_colorbuffer) +{ + android::Mutex::Autolock mutex(m_lock); + + ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) ); + if (c == m_colorbuffers.end()) { + // bad colorbuffer handle + return false; + } + + return (*c).second->bindToTexture(); +} + bool FrameBuffer::bindContext(HandleType p_context, HandleType p_drawSurface, HandleType p_readSurface) diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h index e30fba83a..99e499909 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h +++ b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h @@ -67,6 +67,7 @@ public: bool bindContext(HandleType p_context, HandleType p_drawSurface, HandleType p_readSurface); bool setWindowSurfaceColorBuffer(HandleType p_surface, HandleType p_colorbuffer); + bool bindColorBufferToTexture(HandleType p_colorbuffer); bool post(HandleType p_colorbuffer); diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp index 891c89b28..f68a15397 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp @@ -229,7 +229,12 @@ static void rcFBSetSwapInterval(EGLint interval) static void rcBindTexture(uint32_t colorBuffer) { - // XXX: TBD - should be implemented + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return; + } + + fb->bindColorBufferToTexture(colorBuffer); } static EGLint rcColorBufferCacheFlush(uint32_t colorBuffer, diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp index e8d7180b0..a956e2a4c 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp @@ -65,10 +65,15 @@ WindowSurface *WindowSurface::create(int p_config, int p_width, int p_height) // and either there is no need for depth or stencil buffer // or GL_KHR_gl_renderbuffer_image present. // +#if 0 + //XXX: This path should be implemented win->m_useEGLImage = (caps.has_eglimage_texture_2d && (caps.has_eglimage_renderbuffer || (fbconf->getDepthSize() + fbconf->getStencilSize() == 0)) ); +#else + win->m_useEGLImage = false; +#endif if (win->m_useEGLImage) { } diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp index 2551f6f64..da9682b41 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp @@ -121,14 +121,14 @@ bool stopOpenGLRenderer() // flag the thread it should exit s_renderThread->flagNeedExit(); - // open a dummy connection to the renderer to make it + // open a dummy connection to the renderer to make it // realize the exit request IOStream *dummy = createRenderThread(8); if (dummy) { // wait for the thread to exit int status; ret = s_renderThread->wait(&status); - + delete dummy; } @@ -143,10 +143,12 @@ IOStream *createRenderThread(int p_stream_buffer_size) { TcpStream *stream = new TcpStream(p_stream_buffer_size); if (!stream) { + ERR("createRenderThread failed to create stream\n"); return NULL; } if (stream->connect("localhost", s_renderPort) < 0) { + ERR("createRenderThread failed to connect\n"); delete stream; return NULL; } diff --git a/tools/emulator/opengl/system/GLESv1/Android.mk b/tools/emulator/opengl/system/GLESv1/Android.mk index fc7bc2dcd..aa5725c42 100644 --- a/tools/emulator/opengl/system/GLESv1/Android.mk +++ b/tools/emulator/opengl/system/GLESv1/Android.mk @@ -1,7 +1,7 @@ LOCAL_PATH := $(call my-dir) emulatorOpengl := $(LOCAL_PATH)/../.. -### EGL implementation ########################################### +### GLESv1 implementation ########################################### include $(CLEAR_VARS) # add additional depencies to ensure that the generated code that we depend on diff --git a/tools/emulator/opengl/system/GLESv1_enc/Android.mk b/tools/emulator/opengl/system/GLESv1_enc/Android.mk index 1d28673ab..16f29b1d0 100644 --- a/tools/emulator/opengl/system/GLESv1_enc/Android.mk +++ b/tools/emulator/opengl/system/GLESv1_enc/Android.mk @@ -21,11 +21,18 @@ LOCAL_C_INCLUDES += \ $(emulatorOpengl)/shared/OpenglCodecCommon \ $(emulatorOpengl)/system/OpenglSystemCommon \ $(emulatorOpengl)/host/include/libOpenglRender \ + $(emulatorOpengl)/system/renderControl_enc \ + $(call intermediates-dir-for, SHARED_LIBRARIES, lib_renderControl_enc) \ $(glesv1_intermediates) LOCAL_STATIC_LIBRARIES := \ - libOpenglCodecCommon -LOCAL_SHARED_LIBRARIES := libcutils + libOpenglSystemCommon \ + libOpenglCodecCommon \ + libqemu + +LOCAL_SHARED_LIBRARIES := \ + lib_renderControl_enc \ + libcutils EMUGEN := $(HOST_OUT_EXECUTABLES)/emugen diff --git a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp index 63fa1b396..6633d13d0 100644 --- a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp +++ b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp @@ -16,6 +16,9 @@ #include "GLEncoder.h" #include "glUtils.h" #include "FixedBuffer.h" +#include "HostConnection.h" +#include +#include "gralloc_cb.h" #include #include @@ -25,6 +28,18 @@ static GLubyte *gRendererString= (GLubyte *) "Android HW-GLES 1.0"; static GLubyte *gVersionString= (GLubyte *) "OpenGL ES-CM 1.0"; static GLubyte *gExtensionsString= (GLubyte *) ""; // no extensions at this point; +#define DEFINE_AND_VALIDATE_HOST_CONNECTION(ret) \ + HostConnection *hostCon = HostConnection::get(); \ + if (!hostCon) { \ + LOGE("egl: Failed to get host connection\n"); \ + return ret; \ + } \ + renderControl_encoder_context_t *rcEnc = hostCon->rcEncoder(); \ + if (!rcEnc) { \ + LOGE("egl: Failed to get renderControl encoder context\n"); \ + return ret; \ + } + GLint * GLEncoder::getCompressedTextureFormats() { @@ -468,6 +483,7 @@ GLEncoder::GLEncoder(IOStream *stream) : gl_encoder_context_t(stream) m_glDrawElements_enc = set_glDrawElements(s_glDrawElements); set_glGetString(s_glGetString); set_glFinish(s_glFinish); + set_glEGLImageTargetTexture2DOES(s_glEGLImageTargetTexture2DOES); } @@ -487,3 +503,22 @@ void GLEncoder::s_glFinish(void *self) GLEncoder *ctx = (GLEncoder *)self; ctx->glFinishRoundTrip(self); } + +void GLEncoder::s_glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image) +{ + //TODO: check error - we don't have a way to set gl error + android_native_buffer_t* native_buffer = (android_native_buffer_t*)image; + + if (native_buffer->common.magic != ANDROID_NATIVE_BUFFER_MAGIC) { + return; + } + + if (native_buffer->common.version != sizeof(android_native_buffer_t)) { + return; + } + + DEFINE_AND_VALIDATE_HOST_CONNECTION(); + rcEnc->rcBindTexture(rcEnc, ((cb_handle_t *)(native_buffer->handle))->hostHandle); + + return; +} diff --git a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.h b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.h index cdf365776..2d727f5de 100644 --- a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.h +++ b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.h @@ -89,6 +89,8 @@ private: static void s_glPixelStorei(void *self, GLenum param, GLint value); static void s_glFinish(void *self); + static void s_glEGLImageTargetTexture2DOES(void * self, GLenum target, GLeglImageOES image); void sendVertexData(unsigned first, unsigned count); + }; #endif diff --git a/tools/emulator/opengl/system/GLESv1_enc/gl.attrib b/tools/emulator/opengl/system/GLESv1_enc/gl.attrib index 5b54ef1b2..d3d97fcc2 100644 --- a/tools/emulator/opengl/system/GLESv1_enc/gl.attrib +++ b/tools/emulator/opengl/system/GLESv1_enc/gl.attrib @@ -674,4 +674,3 @@ glExtGetProgramsQCOM #void glExtGetProgramBinarySourceQCOM(GLuint program, GLenum shadertype, GLchar *source, GLint *length) glExtGetProgramBinarySourceQCOM flag unsupported - diff --git a/tools/emulator/opengl/system/egl/egl.cpp b/tools/emulator/opengl/system/egl/egl.cpp index 7ad176018..84a766418 100644 --- a/tools/emulator/opengl/system/egl/egl.cpp +++ b/tools/emulator/opengl/system/egl/egl.cpp @@ -118,7 +118,7 @@ struct egl_surface_t { EGLConfig config; - egl_surface_t(EGLDisplay dpy, EGLConfig config); + egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType); virtual ~egl_surface_t(); virtual EGLBoolean rcCreate() = 0; @@ -132,6 +132,7 @@ struct egl_surface_t { uint32_t getRcSurface(){ return rcSurface; } virtual EGLBoolean isValid(){ return valid; } + EGLint getSurfaceType(){ return surfaceType; } void setWidth(EGLint w){ width = w; } EGLint getWidth(){ return width; } @@ -152,14 +153,15 @@ private: EGLint texTarget; protected: + EGLint surfaceType; EGLBoolean valid; uint32_t rcSurface; //handle to surface created via remote control }; -egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config) - : dpy(dpy), config(config), valid(EGL_FALSE), rcSurface(0) +egl_surface_t::egl_surface_t(EGLDisplay dpy, EGLConfig config, EGLint surfaceType) + : dpy(dpy), config(config), surfaceType(surfaceType), valid(EGL_FALSE), rcSurface(0) { width = 0; height = 0; @@ -177,7 +179,7 @@ egl_surface_t::~egl_surface_t() struct egl_window_surface_t : public egl_surface_t { egl_window_surface_t( - EGLDisplay dpy, EGLConfig config, + EGLDisplay dpy, EGLConfig config, EGLint surfType, ANativeWindow* window); ~egl_window_surface_t(); @@ -197,9 +199,9 @@ private: egl_window_surface_t::egl_window_surface_t ( - EGLDisplay dpy, EGLConfig config, + EGLDisplay dpy, EGLConfig config, EGLint surfType, ANativeWindow* window) - : egl_surface_t(dpy, config), + : egl_surface_t(dpy, config, surfType), nativeWindow(window), buffer(NULL) { @@ -294,7 +296,7 @@ struct egl_pbuffer_surface_t : public egl_surface_t { GLenum format; egl_pbuffer_surface_t( - EGLDisplay dpy, EGLConfig config, + EGLDisplay dpy, EGLConfig config, EGLint surfType, int32_t w, int32_t h, GLenum format); virtual ~egl_pbuffer_surface_t(); @@ -310,9 +312,9 @@ private: }; egl_pbuffer_surface_t::egl_pbuffer_surface_t( - EGLDisplay dpy, EGLConfig config, + EGLDisplay dpy, EGLConfig config, EGLint surfType, int32_t w, int32_t h, GLenum pixelFormat) - : egl_surface_t(dpy, config), format(pixelFormat) + : egl_surface_t(dpy, config, surfType), format(pixelFormat) { setWidth(w); setHeight(h); @@ -530,7 +532,7 @@ EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWin } egl_surface_t* surface; - surface = new egl_window_surface_t(&s_display, config, static_cast(win)); + surface = new egl_window_surface_t(&s_display, config, surfaceType, static_cast(win)); if (!surface) return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); if (!surface->rcCreate()) { @@ -586,7 +588,7 @@ EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLin if (s_display.getConfigPixelFormat(config, &pixelFormat) == EGL_FALSE) return setError(EGL_BAD_MATCH, EGL_NO_SURFACE); - egl_surface_t* surface = new egl_pbuffer_surface_t(dpy, config, w, h, pixelFormat); + egl_surface_t* surface = new egl_pbuffer_surface_t(dpy, config, surfaceType, w, h, pixelFormat); if (!surface) return setError(EGL_BAD_ALLOC, EGL_NO_SURFACE); if (!surface->rcCreate()) { @@ -697,11 +699,35 @@ EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute return 0; } -EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) +EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface eglSurface, EGLint buffer) { - //TODO - LOGW("%s not implemented", __FUNCTION__); - return 0; + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + VALIDATE_SURFACE_RETURN(eglSurface, EGL_FALSE); + if (eglSurface == EGL_NO_SURFACE) { + return setError(EGL_BAD_SURFACE, EGL_FALSE); + } + + if (buffer != EGL_BACK_BUFFER) { + return setError(EGL_BAD_PARAMETER, EGL_FALSE); + } + + egl_surface_t* surface( static_cast(eglSurface) ); + + if (surface->getTextureFormat() == EGL_NO_TEXTURE) { + return setError(EGL_BAD_MATCH, EGL_FALSE); + } + + if (!(surface->getSurfaceType() & EGL_PBUFFER_BIT)) { + return setError(EGL_BAD_SURFACE, EGL_FALSE); + } + + //It's now safe to cast to pbuffer surface + egl_pbuffer_surface_t* pbSurface = (egl_pbuffer_surface_t*)surface; + + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); + rcEnc->rcBindTexture(rcEnc, pbSurface->getRcColorBuffer()); + + return GL_TRUE; } EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) @@ -713,9 +739,11 @@ EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) { - //TODO - LOGW("%s not implemented", __FUNCTION__); - return 0; + VALIDATE_DISPLAY_INIT(dpy, EGL_FALSE); + + DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); + rcEnc->rcFBSetSwapInterval(rcEnc, interval); //TODO: implement on the host + return EGL_TRUE; } EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)