diff options
author | Jesse Hall <jessehall@google.com> | 2012-04-17 08:42:23 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-04-17 08:42:23 -0700 |
commit | 6b80c7f80e5a13cec02e649d7dbf7e1b90f7f364 (patch) | |
tree | 4066ed47918e0b3a8c91144af22728a25b031ad3 /emulator/opengl/host/libs/libOpenglRender | |
parent | 536c05c1a50cafea74ce637d6c4030b1235a0111 (diff) | |
parent | ce6c3389061fb9fcdefc94fab2044a8e11600b52 (diff) | |
download | sdk-6b80c7f80e5a13cec02e649d7dbf7e1b90f7f364.zip sdk-6b80c7f80e5a13cec02e649d7dbf7e1b90f7f364.tar.gz sdk-6b80c7f80e5a13cec02e649d7dbf7e1b90f7f364.tar.bz2 |
Merge "Move emulator GLES from development.git to sdk.git"
Diffstat (limited to 'emulator/opengl/host/libs/libOpenglRender')
34 files changed, 5012 insertions, 0 deletions
diff --git a/emulator/opengl/host/libs/libOpenglRender/Android.mk b/emulator/opengl/host/libs/libOpenglRender/Android.mk new file mode 100644 index 0000000..1d923b4 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/Android.mk @@ -0,0 +1,83 @@ +LOCAL_PATH := $(call my-dir) + +host_OS_SRCS := +host_common_LDLIBS := + +ifeq ($(HOST_OS),linux) + host_OS_SRCS = NativeLinuxSubWindow.cpp + host_common_LDLIBS += -lX11 +endif + +ifeq ($(HOST_OS),darwin) + host_OS_SRCS = NativeMacSubWindow.m + host_common_LDLIBS += -Wl,-framework,AppKit +endif + +ifeq ($(HOST_OS),windows) + host_OS_SRCS = NativeWindowsSubWindow.cpp +endif + +host_common_SRC_FILES := \ + $(host_OS_SRCS) \ + render_api.cpp \ + ColorBuffer.cpp \ + EGLDispatch.cpp \ + FBConfig.cpp \ + FrameBuffer.cpp \ + GLDispatch.cpp \ + GL2Dispatch.cpp \ + RenderContext.cpp \ + WindowSurface.cpp \ + RenderControl.cpp \ + ThreadInfo.cpp \ + RenderThread.cpp \ + ReadBuffer.cpp \ + RenderServer.cpp + +host_common_CFLAGS := + +#For gl debbuging +#host_common_CFLAGS += -DCHECK_GL_ERROR + + +### host libOpenglRender ################################################# +$(call emugl-begin-host-shared-library,libOpenglRender) + +$(call emugl-import,libGLESv1_dec libGLESv2_dec lib_renderControl_dec libOpenglCodecCommon libOpenglOsUtils) + +LOCAL_LDLIBS += $(host_common_LDLIBS) + +LOCAL_SRC_FILES := $(host_common_SRC_FILES) +$(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/host/include) +$(call emugl-export,C_INCLUDES,$(LOCAL_PATH)) + +# use Translator's egl/gles headers +LOCAL_C_INCLUDES += $(EMUGL_PATH)/host/libs/Translator/include + +LOCAL_STATIC_LIBRARIES += libutils liblog + +$(call emugl-export,CFLAGS,$(host_common_CFLAGS)) + +$(call emugl-end-module) + + +### host libOpenglRender, 64-bit ######################################### +$(call emugl-begin-host-shared-library,lib64OpenglRender) + +$(call emugl-import,lib64GLESv1_dec lib64GLESv2_dec lib64_renderControl_dec lib64OpenglCodecCommon lib64OpenglOsUtils) + +#LOCAL_LDFLAGS += -m64 # adding -m64 here doesn't work, because it somehow appear BEFORE -m32 in command-line. +LOCAL_LDLIBS += $(host_common_LDLIBS) -m64 # Put -m64 it in LOCAL_LDLIBS instead. + +LOCAL_SRC_FILES := $(host_common_SRC_FILES) +$(call emugl-export,C_INCLUDES,$(EMUGL_PATH)/host/include) +$(call emugl-export,C_INCLUDES,$(LOCAL_PATH)) + +# use Translator's egl/gles headers +LOCAL_C_INCLUDES += $(EMUGL_PATH)/host/libs/Translator/include + +LOCAL_STATIC_LIBRARIES += lib64utils lib64log + +$(call emugl-export,CFLAGS,$(host_common_CFLAGS) -m64) + +$(call emugl-end-module) diff --git a/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp b/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp new file mode 100644 index 0000000..218f32b --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.cpp @@ -0,0 +1,346 @@ +/* +* 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 "ColorBuffer.h" +#include "FrameBuffer.h" +#include "EGLDispatch.h" +#include "GLDispatch.h" +#include "ThreadInfo.h" +#ifdef WITH_GLES2 +#include "GL2Dispatch.h" +#endif +#include <stdio.h> + +ColorBuffer *ColorBuffer::create(int p_width, int p_height, + GLenum p_internalFormat) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + + GLenum texInternalFormat = 0; + + switch(p_internalFormat) { + case GL_RGB: + case GL_RGB565_OES: + texInternalFormat = GL_RGB; + break; + + case GL_RGBA: + case GL_RGB5_A1_OES: + case GL_RGBA4_OES: + texInternalFormat = GL_RGBA; + break; + + default: + return NULL; + break; + } + + if (!fb->bind_locked()) { + return NULL; + } + + ColorBuffer *cb = new ColorBuffer(); + + + s_gl.glGenTextures(1, &cb->m_tex); + s_gl.glBindTexture(GL_TEXTURE_2D, cb->m_tex); + int nComp = (texInternalFormat == GL_RGB ? 3 : 4); + char *zBuff = new char[nComp*p_width*p_height]; + if (zBuff) { + memset(zBuff, 0, nComp*p_width*p_height); + } + s_gl.glTexImage2D(GL_TEXTURE_2D, 0, texInternalFormat, + p_width, p_height, 0, + texInternalFormat, + GL_UNSIGNED_BYTE, zBuff); + delete [] zBuff; + s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + // + // create another texture for that colorbuffer for blit + // + s_gl.glGenTextures(1, &cb->m_blitTex); + s_gl.glBindTexture(GL_TEXTURE_2D, cb->m_blitTex); + s_gl.glTexImage2D(GL_TEXTURE_2D, 0, texInternalFormat, + p_width, p_height, 0, + texInternalFormat, + GL_UNSIGNED_BYTE, NULL); + s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + s_gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + + cb->m_width = p_width; + cb->m_height = p_height; + cb->m_internalFormat = texInternalFormat; + + if (fb->getCaps().has_eglimage_texture_2d) { + cb->m_eglImage = s_egl.eglCreateImageKHR(fb->getDisplay(), + s_egl.eglGetCurrentContext(), + EGL_GL_TEXTURE_2D_KHR, + (EGLClientBuffer)cb->m_tex, + NULL); + + cb->m_blitEGLImage = s_egl.eglCreateImageKHR(fb->getDisplay(), + s_egl.eglGetCurrentContext(), + EGL_GL_TEXTURE_2D_KHR, + (EGLClientBuffer)cb->m_blitTex, + NULL); + } + + fb->unbind_locked(); + return cb; +} + +ColorBuffer::ColorBuffer() : + m_tex(0), + m_eglImage(NULL), + m_fbo(0), + m_internalFormat(0), + m_warYInvertBug(false) +{ +#if __APPLE__ + // On Macs running OS X 10.6 and 10.7 with Intel HD Graphics 3000, some + // screens or parts of the screen are displayed upside down. The exact + // conditions/sequence that triggers this aren't known yet; I haven't + // been able to reproduce it in a standalone test. This way of enabling the + // workaround will break if it is a driver bug (rather than a bug in this + // code which works by accident elsewhere) and Apple/Intel release a fix for + // it. Running a standalone test to detect the problem at runtime would be + // more robust. + if (strstr((const char*)s_gl.glGetString(GL_RENDERER), "Intel HD Graphics 3000")) + m_warYInvertBug = true; +#endif +} + +ColorBuffer::~ColorBuffer() +{ + FrameBuffer *fb = FrameBuffer::getFB(); + fb->bind_locked(); + s_gl.glDeleteTextures(1, &m_tex); + if (m_eglImage) { + s_egl.eglDestroyImageKHR(fb->getDisplay(), m_eglImage); + } + if (m_fbo) { + s_gl.glDeleteFramebuffersOES(1, &m_fbo); + } + 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::blitFromCurrentReadBuffer() +{ + RenderThreadInfo *tInfo = getRenderThreadInfo(); + if (!tInfo->currContext.Ptr()) { + // no Current context + return false; + } + + // + // Create a temporary texture inside the current context + // from the blit_texture EGLImage and copy the pixels + // from the current read buffer to that texture + // + GLuint tmpTex; + GLint currTexBind; + if (tInfo->currContext->isGL2()) { + s_gl2.glGetIntegerv(GL_TEXTURE_BINDING_2D, &currTexBind); + s_gl2.glGenTextures(1,&tmpTex); + s_gl2.glBindTexture(GL_TEXTURE_2D, tmpTex); + s_gl2.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_blitEGLImage); + s_gl2.glCopyTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, + 0, 0, m_width, m_height, 0); + } + else { + s_gl.glGetIntegerv(GL_TEXTURE_BINDING_2D, &currTexBind); + s_gl.glGenTextures(1,&tmpTex); + s_gl.glBindTexture(GL_TEXTURE_2D, tmpTex); + s_gl.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_blitEGLImage); + s_gl.glCopyTexImage2D(GL_TEXTURE_2D, 0, m_internalFormat, + 0, 0, m_width, m_height, 0); + } + + + // + // Now bind the frame buffer context and blit from + // m_blitTex into m_tex + // + FrameBuffer *fb = FrameBuffer::getFB(); + if (fb->bind_locked()) { + + // + // bind FBO object which has this colorbuffer as render target + // + if (bind_fbo()) { + + // + // save current viewport and match it to the current + // colorbuffer size + // + GLint vport[4]; + s_gl.glGetIntegerv(GL_VIEWPORT, vport); + s_gl.glViewport(0, 0, m_width, m_height); + + // render m_blitTex + s_gl.glBindTexture(GL_TEXTURE_2D, m_blitTex); + s_gl.glEnable(GL_TEXTURE_2D); + s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + drawTexQuad(!m_warYInvertBug); + + // unbind the fbo + s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); + + // restrore previous viewport + s_gl.glViewport(vport[0], vport[1], vport[2], vport[3]); + } + + // unbind from the FrameBuffer context + fb->unbind_locked(); + } + + // + // delete the temporary texture and restore the texture binding + // inside the current context + // + if (tInfo->currContext->isGL2()) { + s_gl2.glDeleteTextures(1, &tmpTex); + s_gl2.glBindTexture(GL_TEXTURE_2D, currTexBind); + } + else { + s_gl.glDeleteTextures(1, &tmpTex); + s_gl.glBindTexture(GL_TEXTURE_2D, currTexBind); + } + + 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::bindToRenderbuffer() +{ + if (m_eglImage) { + RenderThreadInfo *tInfo = getRenderThreadInfo(); + if (tInfo->currContext.Ptr()) { +#ifdef WITH_GLES2 + if (tInfo->currContext->isGL2()) { + s_gl2.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER_OES, m_eglImage); + } + else { + s_gl.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER_OES, m_eglImage); + } +#else + s_gl.glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER_OES, m_eglImage); +#endif + return true; + } + } + return false; +} + +bool ColorBuffer::bind_fbo() +{ + if (m_fbo) { + // fbo already exist - just bind + s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_fbo); + return true; + } + + s_gl.glGenFramebuffersOES(1, &m_fbo); + s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, m_fbo); + s_gl.glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, + GL_COLOR_ATTACHMENT0_OES, + GL_TEXTURE_2D, m_tex, 0); + GLenum status = s_gl.glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES); + if (status != GL_FRAMEBUFFER_COMPLETE_OES) { + s_gl.glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0); + s_gl.glDeleteFramebuffersOES(1, &m_fbo); + m_fbo = 0; + return false; + } + + return true; +} + +bool ColorBuffer::post() +{ + s_gl.glBindTexture(GL_TEXTURE_2D, m_tex); + s_gl.glEnable(GL_TEXTURE_2D); + s_gl.glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + drawTexQuad(true); + + return true; +} + +void ColorBuffer::drawTexQuad(bool flipy) +{ + GLfloat verts[] = { -1.0f, -1.0f, 0.0f, + -1.0f, +1.0f, 0.0f, + +1.0f, -1.0f, 0.0f, + +1.0f, +1.0f, 0.0f }; + + GLfloat tcoords[] = { 0.0f, 1.0f, + 0.0f, 0.0f, + 1.0f, 1.0f, + 1.0f, 0.0f }; + + if (!flipy) { + for (int i = 0; i < 4; i++) { + // swap 0.0/1.0 in second element of each tcoord vector + tcoords[2*i + 1] = tcoords[2*i + 1] == 0.0f ? 1.0f : 0.0f; + } + } + + s_gl.glClientActiveTexture(GL_TEXTURE0); + s_gl.glEnableClientState(GL_TEXTURE_COORD_ARRAY); + s_gl.glTexCoordPointer(2, GL_FLOAT, 0, tcoords); + + s_gl.glEnableClientState(GL_VERTEX_ARRAY); + s_gl.glVertexPointer(3, GL_FLOAT, 0, verts); + s_gl.glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); +} diff --git a/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h b/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h new file mode 100644 index 0000000..4a2c6b4 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/ColorBuffer.h @@ -0,0 +1,60 @@ +/* +* 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. +*/ +#ifndef _LIBRENDER_COLORBUFFER_H +#define _LIBRENDER_COLORBUFFER_H + +#include <EGL/egl.h> +#include <EGL/eglext.h> +#include <GLES/gl.h> +#include <SmartPtr.h> + +class ColorBuffer +{ +public: + static ColorBuffer *create(int p_width, int p_height, + GLenum p_internalFormat); + ~ColorBuffer(); + + GLuint getGLTextureName() const { return m_tex; } + GLuint getWidth() const { return m_width; } + GLuint getHeight() const { return m_height; } + + void subUpdate(int x, int y, int width, int height, GLenum p_format, GLenum p_type, void *pixels); + bool post(); + bool bindToTexture(); + bool bindToRenderbuffer(); + bool blitFromCurrentReadBuffer(); + +private: + ColorBuffer(); + void drawTexQuad(bool flipy); + bool bind_fbo(); // binds a fbo which have this texture as render target + +private: + GLuint m_tex; + GLuint m_blitTex; + EGLImageKHR m_eglImage; + EGLImageKHR m_blitEGLImage; + GLuint m_width; + GLuint m_height; + GLuint m_fbo; + GLenum m_internalFormat; + bool m_warYInvertBug; +}; + +typedef SmartPtr<ColorBuffer> ColorBufferPtr; + +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp b/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp new file mode 100644 index 0000000..3cf5dbc --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.cpp @@ -0,0 +1,87 @@ +/* +* 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 "EGLDispatch.h" +#include <stdio.h> +#include <stdlib.h> +#include "osDynLibrary.h" + +EGLDispatch s_egl; + +#define DEFAULT_EGL_LIB EMUGL_LIBNAME("EGL_translator") + +bool init_egl_dispatch() +{ + + const char *libName = getenv("ANDROID_EGL_LIB"); + if (!libName) libName = DEFAULT_EGL_LIB; + + osUtils::dynLibrary *lib = osUtils::dynLibrary::open(libName); + if (!lib) { + printf("Failed to open %s\n", libName); + return NULL; + } + s_egl.eglGetError = (eglGetError_t) lib->findSymbol("eglGetError"); + s_egl.eglGetDisplay = (eglGetDisplay_t) lib->findSymbol("eglGetDisplay"); + s_egl.eglInitialize = (eglInitialize_t) lib->findSymbol("eglInitialize"); + s_egl.eglTerminate = (eglTerminate_t) lib->findSymbol("eglTerminate"); + s_egl.eglQueryString = (eglQueryString_t) lib->findSymbol("eglQueryString"); + s_egl.eglGetConfigs = (eglGetConfigs_t) lib->findSymbol("eglGetConfigs"); + s_egl.eglChooseConfig = (eglChooseConfig_t) lib->findSymbol("eglChooseConfig"); + s_egl.eglGetConfigAttrib = (eglGetConfigAttrib_t) lib->findSymbol("eglGetConfigAttrib"); + s_egl.eglCreateWindowSurface = (eglCreateWindowSurface_t) lib->findSymbol("eglCreateWindowSurface"); + s_egl.eglCreatePbufferSurface = (eglCreatePbufferSurface_t) lib->findSymbol("eglCreatePbufferSurface"); + s_egl.eglCreatePixmapSurface = (eglCreatePixmapSurface_t) lib->findSymbol("eglCreatePixmapSurface"); + s_egl.eglDestroySurface = (eglDestroySurface_t) lib->findSymbol("eglDestroySurface"); + s_egl.eglQuerySurface = (eglQuerySurface_t) lib->findSymbol("eglQuerySurface"); + s_egl.eglBindAPI = (eglBindAPI_t) lib->findSymbol("eglBindAPI"); + s_egl.eglQueryAPI = (eglQueryAPI_t) lib->findSymbol("eglQueryAPI"); + s_egl.eglWaitClient = (eglWaitClient_t) lib->findSymbol("eglWaitClient"); + s_egl.eglReleaseThread = (eglReleaseThread_t) lib->findSymbol("eglReleaseThread"); + s_egl.eglCreatePbufferFromClientBuffer = (eglCreatePbufferFromClientBuffer_t) lib->findSymbol("eglCreatePbufferFromClientBuffer"); + s_egl.eglSurfaceAttrib = (eglSurfaceAttrib_t) lib->findSymbol("eglSurfaceAttrib"); + s_egl.eglBindTexImage = (eglBindTexImage_t) lib->findSymbol("eglBindTexImage"); + s_egl.eglReleaseTexImage = (eglReleaseTexImage_t) lib->findSymbol("eglReleaseTexImage"); + s_egl.eglSwapInterval = (eglSwapInterval_t) lib->findSymbol("eglSwapInterval"); + s_egl.eglCreateContext = (eglCreateContext_t) lib->findSymbol("eglCreateContext"); + s_egl.eglDestroyContext = (eglDestroyContext_t) lib->findSymbol("eglDestroyContext"); + s_egl.eglMakeCurrent = (eglMakeCurrent_t) lib->findSymbol("eglMakeCurrent"); + s_egl.eglGetCurrentContext = (eglGetCurrentContext_t) lib->findSymbol("eglGetCurrentContext"); + s_egl.eglGetCurrentSurface = (eglGetCurrentSurface_t) lib->findSymbol("eglGetCurrentSurface"); + s_egl.eglGetCurrentDisplay = (eglGetCurrentDisplay_t) lib->findSymbol("eglGetCurrentDisplay"); + s_egl.eglQueryContext = (eglQueryContext_t) lib->findSymbol("eglQueryContext"); + s_egl.eglWaitGL = (eglWaitGL_t) lib->findSymbol("eglWaitGL"); + s_egl.eglWaitNative = (eglWaitNative_t) lib->findSymbol("eglWaitNative"); + s_egl.eglSwapBuffers = (eglSwapBuffers_t) lib->findSymbol("eglSwapBuffers"); + s_egl.eglCopyBuffers = (eglCopyBuffers_t) lib->findSymbol("eglCopyBuffers"); + s_egl.eglGetProcAddress = (eglGetProcAddress_t) lib->findSymbol("eglGetProcAddress"); + +#define INIT_EGL_EXT_FUNC(name) \ + if (s_egl.eglGetProcAddress) s_egl.name = (name ## _t) s_egl.eglGetProcAddress(#name); \ + if (!s_egl.name || !s_egl.eglGetProcAddress) s_egl.name = (name ## _t) lib->findSymbol(#name) + + INIT_EGL_EXT_FUNC(eglLockSurfaceKHR); + INIT_EGL_EXT_FUNC(eglUnlockSurfaceKHR); + INIT_EGL_EXT_FUNC(eglCreateImageKHR); + INIT_EGL_EXT_FUNC(eglDestroyImageKHR); + INIT_EGL_EXT_FUNC(eglCreateSyncKHR); + INIT_EGL_EXT_FUNC(eglDestroySyncKHR); + INIT_EGL_EXT_FUNC(eglClientWaitSyncKHR); + INIT_EGL_EXT_FUNC(eglSignalSyncKHR); + INIT_EGL_EXT_FUNC(eglGetSyncAttribKHR); + INIT_EGL_EXT_FUNC(eglSetSwapRectangleANDROID); + + return true; +} diff --git a/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.h b/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.h new file mode 100644 index 0000000..f74acba --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/EGLDispatch.h @@ -0,0 +1,72 @@ +/* +* 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. +*/ +#ifndef _EGL_DISPATCH_H +#define _EGL_DISPATCH_H + +#include "egl_proc.h" + +struct EGLDispatch { + eglGetError_t eglGetError; + eglGetDisplay_t eglGetDisplay; + eglInitialize_t eglInitialize; + eglTerminate_t eglTerminate; + eglQueryString_t eglQueryString; + eglGetConfigs_t eglGetConfigs; + eglChooseConfig_t eglChooseConfig; + eglGetConfigAttrib_t eglGetConfigAttrib; + eglCreateWindowSurface_t eglCreateWindowSurface; + eglCreatePbufferSurface_t eglCreatePbufferSurface; + eglCreatePixmapSurface_t eglCreatePixmapSurface; + eglDestroySurface_t eglDestroySurface; + eglQuerySurface_t eglQuerySurface; + eglBindAPI_t eglBindAPI; + eglQueryAPI_t eglQueryAPI; + eglWaitClient_t eglWaitClient; + eglReleaseThread_t eglReleaseThread; + eglCreatePbufferFromClientBuffer_t eglCreatePbufferFromClientBuffer; + eglSurfaceAttrib_t eglSurfaceAttrib; + eglBindTexImage_t eglBindTexImage; + eglReleaseTexImage_t eglReleaseTexImage; + eglSwapInterval_t eglSwapInterval; + eglCreateContext_t eglCreateContext; + eglDestroyContext_t eglDestroyContext; + eglMakeCurrent_t eglMakeCurrent; + eglGetCurrentContext_t eglGetCurrentContext; + eglGetCurrentSurface_t eglGetCurrentSurface; + eglGetCurrentDisplay_t eglGetCurrentDisplay; + eglQueryContext_t eglQueryContext; + eglWaitGL_t eglWaitGL; + eglWaitNative_t eglWaitNative; + eglSwapBuffers_t eglSwapBuffers; + eglCopyBuffers_t eglCopyBuffers; + eglGetProcAddress_t eglGetProcAddress; + eglLockSurfaceKHR_t eglLockSurfaceKHR; + eglUnlockSurfaceKHR_t eglUnlockSurfaceKHR; + eglCreateImageKHR_t eglCreateImageKHR; + eglDestroyImageKHR_t eglDestroyImageKHR; + eglCreateSyncKHR_t eglCreateSyncKHR; + eglDestroySyncKHR_t eglDestroySyncKHR; + eglClientWaitSyncKHR_t eglClientWaitSyncKHR; + eglSignalSyncKHR_t eglSignalSyncKHR; + eglGetSyncAttribKHR_t eglGetSyncAttribKHR; + eglSetSwapRectangleANDROID_t eglSetSwapRectangleANDROID; +}; + +bool init_egl_dispatch(); + +extern EGLDispatch s_egl; + +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp b/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp new file mode 100644 index 0000000..089f1da --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/FBConfig.cpp @@ -0,0 +1,258 @@ +/* +* 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 "FBConfig.h" +#include "FrameBuffer.h" +#include "EGLDispatch.h" +#include <stdio.h> + +FBConfig **FBConfig::s_fbConfigs = NULL; +int FBConfig::s_numConfigs = 0; + +const GLuint FBConfig::s_configAttribs[] = { + EGL_DEPTH_SIZE, // must be first - see getDepthSize() + EGL_STENCIL_SIZE, // must be second - see getStencilSize() + EGL_RENDERABLE_TYPE,// must be third - see getRenderableType() + EGL_SURFACE_TYPE, // must be fourth - see getSurfaceType() + EGL_CONFIG_ID, // must be fifth - see chooseConfig() + EGL_BUFFER_SIZE, + EGL_ALPHA_SIZE, + EGL_BLUE_SIZE, + EGL_GREEN_SIZE, + EGL_RED_SIZE, + EGL_CONFIG_CAVEAT, + EGL_LEVEL, + EGL_MAX_PBUFFER_HEIGHT, + EGL_MAX_PBUFFER_PIXELS, + EGL_MAX_PBUFFER_WIDTH, + EGL_NATIVE_RENDERABLE, + EGL_NATIVE_VISUAL_ID, + EGL_NATIVE_VISUAL_TYPE, + EGL_SAMPLES, + EGL_SAMPLE_BUFFERS, + EGL_TRANSPARENT_TYPE, + EGL_TRANSPARENT_BLUE_VALUE, + EGL_TRANSPARENT_GREEN_VALUE, + EGL_TRANSPARENT_RED_VALUE, + EGL_BIND_TO_TEXTURE_RGB, + EGL_BIND_TO_TEXTURE_RGBA, + EGL_MIN_SWAP_INTERVAL, + EGL_MAX_SWAP_INTERVAL, + EGL_LUMINANCE_SIZE, + EGL_ALPHA_MASK_SIZE, + EGL_COLOR_BUFFER_TYPE, + //EGL_MATCH_NATIVE_PIXMAP, + EGL_CONFORMANT +}; + +const int FBConfig::s_numConfigAttribs = sizeof(FBConfig::s_configAttribs) / sizeof(GLuint); + +InitConfigStatus FBConfig::initConfigList(FrameBuffer *fb) +{ + InitConfigStatus ret = INIT_CONFIG_FAILED; + + if (!fb) { + return ret; + } + + const FrameBufferCaps &caps = fb->getCaps(); + EGLDisplay dpy = fb->getDisplay(); + + if (dpy == EGL_NO_DISPLAY) { + fprintf(stderr,"Could not get EGL Display\n"); + return ret; + } + + // + // Query the set of configs in the EGL backend + // + EGLint nConfigs; + if (!s_egl.eglGetConfigs(dpy, NULL, 0, &nConfigs)) { + fprintf(stderr, "Could not get number of available configs\n"); + return ret; + } + EGLConfig *configs = new EGLConfig[nConfigs]; + s_egl.eglGetConfigs(dpy, configs, nConfigs, &nConfigs); + + // + // copy the config attributes, filter out + // configs we do not want to support. + // + int j = 0; + s_fbConfigs = new FBConfig*[nConfigs]; + for (int i=0; i<nConfigs; i++) { + + // + // filter out configs which does not support pbuffers. + // we only support pbuffer configs since we use a pbuffer + // handle to bind a guest created window object. + // + EGLint surfaceType; + s_egl.eglGetConfigAttrib(dpy, configs[i], + EGL_SURFACE_TYPE, &surfaceType); + if (!(surfaceType & EGL_PBUFFER_BIT)) continue; + + // + // Filter out not RGB configs + // + EGLint redSize, greenSize, blueSize; + s_egl.eglGetConfigAttrib(dpy, configs[i], EGL_RED_SIZE, &redSize); + s_egl.eglGetConfigAttrib(dpy, configs[i], EGL_BLUE_SIZE, &blueSize); + s_egl.eglGetConfigAttrib(dpy, configs[i], EGL_GREEN_SIZE, &greenSize); + if (redSize==0 || greenSize==0 || blueSize==0) continue; + + s_fbConfigs[j++] = new FBConfig(dpy, configs[i]); + } + s_numConfigs = j; + + delete[] configs; + + return s_numConfigs > 0 ? INIT_CONFIG_PASSED : INIT_CONFIG_FAILED; +} + +const FBConfig *FBConfig::get(int p_config) +{ + if (p_config >= 0 && p_config < s_numConfigs) { + return s_fbConfigs[p_config]; + } + return NULL; +} + +int FBConfig::getNumConfigs() +{ + return s_numConfigs; +} + +void FBConfig::packConfigsInfo(GLuint *buffer) +{ + memcpy(buffer, s_configAttribs, s_numConfigAttribs * sizeof(GLuint)); + for (int i=0; i<s_numConfigs; i++) { + memcpy(buffer+(i+1)*s_numConfigAttribs, + s_fbConfigs[i]->m_attribValues, + s_numConfigAttribs * sizeof(GLuint)); + } +} + +int FBConfig::chooseConfig(FrameBuffer *fb, EGLint * attribs, uint32_t * configs, uint32_t configs_size) +{ + EGLDisplay dpy = fb->getDisplay(); + int ret = 0; + + if (dpy == EGL_NO_DISPLAY) { + fprintf(stderr,"Could not get EGL Display\n"); + return ret; + } + // + // Query the num of configs in the EGL backend + // + EGLint nConfigs; + if (!s_egl.eglGetConfigs(dpy, NULL, 0, &nConfigs)) { + fprintf(stderr, "Could not get number of available configs\n"); + return ret; + } + // + // Query the max matching configs in the backend + // + EGLConfig *matchedConfigs = new EGLConfig[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 0 + 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 + // + uint32_t nVerifiedCfgs = 0; + for (int matchedIdx=0; matchedIdx<nConfigs; matchedIdx++) { + if ((configs != NULL) && (configs_size > 0) && (nVerifiedCfgs >= configs_size)) break; //We have enouhgt configs + int sCfgId; + s_egl.eglGetConfigAttrib(dpy, matchedConfigs[matchedIdx], EGL_CONFIG_ID, &sCfgId); + for (int fbIdx=0; fbIdx<s_numConfigs; fbIdx++) { + int dCfgId = s_fbConfigs[fbIdx]->m_attribValues[4]; //CONFIG_ID + if (sCfgId == dCfgId) { + //This config matches the requested attributes and filtered into fbConfigs, so we're happy with it + if (configs && nVerifiedCfgs < configs_size) { + configs[nVerifiedCfgs] = fbIdx; + } + nVerifiedCfgs++; + break; + } + } + } + + delete[] matchedConfigs; + + return nVerifiedCfgs; +} + +FBConfig::FBConfig(EGLDisplay p_eglDpy, EGLConfig p_eglCfg) +{ + m_eglConfig = p_eglCfg; + m_attribValues = new GLint[s_numConfigAttribs]; + for (int i=0; i<s_numConfigAttribs; i++) { + m_attribValues[i] = 0; + s_egl.eglGetConfigAttrib(p_eglDpy, p_eglCfg, s_configAttribs[i], &m_attribValues[i]); + + // + // All exported configs supports android native window rendering + // + if (s_configAttribs[i] == EGL_SURFACE_TYPE) { + m_attribValues[i] |= EGL_WINDOW_BIT; + } + } +} + +FBConfig::~FBConfig() +{ + if (m_attribValues) { + delete[] m_attribValues; + } +} diff --git a/emulator/opengl/host/libs/libOpenglRender/FBConfig.h b/emulator/opengl/host/libs/libOpenglRender/FBConfig.h new file mode 100644 index 0000000..6388549 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/FBConfig.h @@ -0,0 +1,60 @@ +/* +* 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. +*/ +#ifndef _LIBRENDER_FBCONFIG_H +#define _LIBRENDER_FBCONFIG_H + +#include <EGL/egl.h> +#include <GLES/gl.h> + +class FrameBuffer; + +enum InitConfigStatus { + INIT_CONFIG_FAILED = 0, + INIT_CONFIG_PASSED = 1 +}; + +class FBConfig +{ +public: + static InitConfigStatus initConfigList(FrameBuffer *fb); + static const FBConfig *get(int p_config); + static int getNumConfigs(); + static int getNumAttribs() { return s_numConfigAttribs; } + static void packConfigsInfo(GLuint *buffer); + static int chooseConfig(FrameBuffer *fb, EGLint * attribs, uint32_t * configs, uint32_t configs_size); + ~FBConfig(); + + EGLConfig getEGLConfig() const { return m_eglConfig; } + GLuint getDepthSize() const { return (m_attribValues ? m_attribValues[0] : 0); } + GLuint getStencilSize() const { return (m_attribValues ? m_attribValues[1] : 0); } + GLuint getRenderableType() const { return (m_attribValues ? m_attribValues[2] : 0); } + GLuint getSurfaceType() const { return (m_attribValues ? m_attribValues[3] : 0); } + +private: + FBConfig(EGLDisplay p_eglDpy, EGLConfig p_eglCfg); + +private: + static FBConfig **s_fbConfigs; + static int s_numConfigs; + static const int s_numConfigAttribs; + static const GLuint s_configAttribs[]; + +private: + EGLConfig m_eglConfig; + GLint *m_attribValues; +}; + +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp new file mode 100644 index 0000000..b7599ce --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp @@ -0,0 +1,868 @@ +/* +* 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 "FrameBuffer.h" +#include "NativeSubWindow.h" +#include "FBConfig.h" +#include "EGLDispatch.h" +#include "GLDispatch.h" +#include "GL2Dispatch.h" +#include "ThreadInfo.h" +#include <stdio.h> +#include "TimeUtils.h" + +FrameBuffer *FrameBuffer::s_theFrameBuffer = NULL; +HandleType FrameBuffer::s_nextHandle = 0; + +#ifdef WITH_GLES2 +static const char *getGLES2ExtensionString(EGLDisplay p_dpy) +{ + EGLConfig config; + EGLSurface surface; + + GLint configAttribs[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_NONE + }; + + int n; + if (!s_egl.eglChooseConfig(p_dpy, configAttribs, + &config, 1, &n)) { + return NULL; + } + + EGLint pbufAttribs[] = { + EGL_WIDTH, 1, + EGL_HEIGHT, 1, + EGL_NONE + }; + + surface = s_egl.eglCreatePbufferSurface(p_dpy, config, pbufAttribs); + if (surface == EGL_NO_SURFACE) { + return NULL; + } + + GLint gl2ContextAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 2, + EGL_NONE + }; + + EGLContext ctx = s_egl.eglCreateContext(p_dpy, config, + EGL_NO_CONTEXT, + gl2ContextAttribs); + if (ctx == EGL_NO_CONTEXT) { + s_egl.eglDestroySurface(p_dpy, surface); + return NULL; + } + + if (!s_egl.eglMakeCurrent(p_dpy, surface, surface, ctx)) { + s_egl.eglDestroySurface(p_dpy, surface); + s_egl.eglDestroyContext(p_dpy, ctx); + return NULL; + } + + const char *extString = (const char *)s_gl2.glGetString(GL_EXTENSIONS); + if (!extString) { + extString = ""; + } + + s_egl.eglMakeCurrent(p_dpy, NULL, NULL, NULL); + s_egl.eglDestroyContext(p_dpy, ctx); + s_egl.eglDestroySurface(p_dpy, surface); + + return extString; +} +#endif + +void FrameBuffer::finalize(){ + if(s_theFrameBuffer){ + s_theFrameBuffer->removeSubWindow(); + 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.eglDestroyContext(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_eglContext); + s_egl.eglDestroyContext(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_pbufContext); + s_egl.eglDestroySurface(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_pbufSurface); + s_theFrameBuffer = NULL; + } +} + +bool FrameBuffer::initialize(int width, int height, OnPostFn onPost, void* onPostContext) +{ + if (s_theFrameBuffer != NULL) { + return true; + } + + // + // allocate space for the FrameBuffer object + // + FrameBuffer *fb = new FrameBuffer(width, height, onPost, onPostContext); + if (!fb) { + ERR("Failed to create fb\n"); + return false; + } + +#ifdef WITH_GLES2 + // + // Try to load GLES2 Plugin, not mandatory + // + if (getenv("ANDROID_NO_GLES2")) { + fb->m_caps.hasGL2 = false; + } + else { + fb->m_caps.hasGL2 = s_gl2_enabled; + } +#else + fb->m_caps.hasGL2 = false; +#endif + + // + // Initialize backend EGL display + // + fb->m_eglDisplay = s_egl.eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (fb->m_eglDisplay == EGL_NO_DISPLAY) { + ERR("Failed to Initialize backend EGL display\n"); + delete fb; + return false; + } + + 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); + + // + // if GLES2 plugin has loaded - try to make GLES2 context and + // get GLES2 extension string + // + const char *gl2Extensions = NULL; +#ifdef WITH_GLES2 + if (fb->m_caps.hasGL2) { + gl2Extensions = getGLES2ExtensionString(fb->m_eglDisplay); + if (!gl2Extensions) { + // Could not create GLES2 context - drop GL2 capability + fb->m_caps.hasGL2 = false; + } + } +#endif + + // + // Create EGL context 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_PBUFFER_BIT, + EGL_NONE + }; +#endif + + int n; + if (!s_egl.eglChooseConfig(fb->m_eglDisplay, configAttribs, + &fb->m_eglConfig, 1, &n)) { + ERR("Failed on eglChooseConfig\n"); + delete fb; + return false; + } + + GLint glContextAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 1, + EGL_NONE + }; + + fb->m_eglContext = s_egl.eglCreateContext(fb->m_eglDisplay, fb->m_eglConfig, + EGL_NO_CONTEXT, + glContextAttribs); + if (fb->m_eglContext == EGL_NO_CONTEXT) { + printf("Failed to create Context 0x%x\n", s_egl.eglGetError()); + delete fb; + return false; + } + + // + // Create another context which shares with the eglContext to be used + // when we bind the pbuffer. That prevent switching drawable binding + // back and forth on framebuffer context. + // The main purpose of it is to solve a "blanking" behaviour we see on + // on Mac platform when switching binded drawable for a context however + // it is more efficient on other platforms as well. + // + fb->m_pbufContext = s_egl.eglCreateContext(fb->m_eglDisplay, fb->m_eglConfig, + fb->m_eglContext, + glContextAttribs); + if (fb->m_pbufContext == EGL_NO_CONTEXT) { + printf("Failed to create Pbuffer Context 0x%x\n", s_egl.eglGetError()); + delete fb; + return false; + } + + // + // create a 1x1 pbuffer surface which will be used for binding + // the FB context. + // The FB output will go to a subwindow, if one exist. + // + EGLint pbufAttribs[] = { + EGL_WIDTH, 1, + EGL_HEIGHT, 1, + EGL_NONE + }; + + fb->m_pbufSurface = s_egl.eglCreatePbufferSurface(fb->m_eglDisplay, + fb->m_eglConfig, + pbufAttribs); + if (fb->m_pbufSurface == EGL_NO_SURFACE) { + printf("Failed to create pbuf surface for FB 0x%x\n", s_egl.eglGetError()); + delete fb; + return false; + } + + // Make the context current + if (!fb->bind_locked()) { + ERR("Failed to make current\n"); + delete fb; + return false; + } + + // + // Initilize framebuffer capabilities + // + const char *glExtensions = (const char *)s_gl.glGetString(GL_EXTENSIONS); + bool has_gl_oes_image = false; + if (glExtensions) { + has_gl_oes_image = strstr(glExtensions, "GL_OES_EGL_image") != NULL; + } + + if (fb->m_caps.hasGL2 && has_gl_oes_image) { + has_gl_oes_image &= (strstr(gl2Extensions, "GL_OES_EGL_image") != NULL); + } + + const char *eglExtensions = s_egl.eglQueryString(fb->m_eglDisplay, + EGL_EXTENSIONS); + + if (eglExtensions && has_gl_oes_image) { + fb->m_caps.has_eglimage_texture_2d = + strstr(eglExtensions, "EGL_KHR_gl_texture_2D_image") != NULL; + fb->m_caps.has_eglimage_renderbuffer = + strstr(eglExtensions, "EGL_KHR_gl_renderbuffer_image") != NULL; + } + else { + fb->m_caps.has_eglimage_texture_2d = false; + fb->m_caps.has_eglimage_renderbuffer = false; + } + + // + // Fail initialization if not all of the following extensions + // exist: + // EGL_KHR_gl_texture_2d_image + // GL_OES_EGL_IMAGE (by both GLES implementations [1 and 2]) + // + if (!fb->m_caps.has_eglimage_texture_2d) { + ERR("Failed: Missing egl_image related extension(s)\n"); + delete fb; + return false; + } + + // + // Initialize set of configs + // + InitConfigStatus configStatus = FBConfig::initConfigList(fb); + if (configStatus == INIT_CONFIG_FAILED) { + ERR("Failed: Initialize set of configs\n"); + delete fb; + return false; + } + + // + // Check that we have config for each GLES and GLES2 + // + int nConfigs = FBConfig::getNumConfigs(); + int nGLConfigs = 0; + int nGL2Configs = 0; + for (int i=0; i<nConfigs; i++) { + GLint rtype = FBConfig::get(i)->getRenderableType(); + if (0 != (rtype & EGL_OPENGL_ES_BIT)) { + nGLConfigs++; + } + if (0 != (rtype & EGL_OPENGL_ES2_BIT)) { + nGL2Configs++; + } + } + + // + // Fail initialization if no GLES configs exist + // + if (nGLConfigs == 0) { + delete fb; + return false; + } + + // + // If no GLES2 configs exist - not GLES2 capability + // + if (nGL2Configs == 0) { + fb->m_caps.hasGL2 = false; + } + + // + // Initialize some GL state in the pbuffer context + // + fb->initGLState(); + + // + // Allocate space for the onPost framebuffer image + // + if (onPost) { + fb->m_fbImage = (unsigned char*)malloc(4 * width * height); + if (!fb->m_fbImage) { + delete fb; + return false; + } + } + + // release the FB context + fb->unbind_locked(); + + // + // Keep the singleton framebuffer pointer + // + s_theFrameBuffer = fb; + return true; +} + +FrameBuffer::FrameBuffer(int p_width, int p_height, + OnPostFn onPost, void* onPostContext) : + m_width(p_width), + m_height(p_height), + m_eglDisplay(EGL_NO_DISPLAY), + m_eglSurface(EGL_NO_SURFACE), + m_eglContext(EGL_NO_CONTEXT), + m_pbufContext(EGL_NO_CONTEXT), + m_prevContext(EGL_NO_CONTEXT), + m_prevReadSurf(EGL_NO_SURFACE), + m_prevDrawSurf(EGL_NO_SURFACE), + m_subWin(NULL), + m_subWinDisplay(NULL), + m_lastPostedColorBuffer(0), + m_zRot(0.0f), + m_eglContextInitialized(false), + m_statsNumFrames(0), + m_statsStartTime(0LL), + m_onPost(onPost), + m_onPostContext(onPostContext), + m_fbImage(NULL) +{ + m_fpsStats = getenv("SHOW_FPS_STATS") != NULL; +} + +FrameBuffer::~FrameBuffer() +{ + free(m_fbImage); +} + +bool FrameBuffer::setupSubWindow(FBNativeWindowType p_window, + int p_x, int p_y, + int p_width, int p_height, float zRot) +{ + bool success = false; + + if (s_theFrameBuffer) { + s_theFrameBuffer->m_lock.lock(); + FrameBuffer *fb = s_theFrameBuffer; + if (!fb->m_subWin) { + + // create native subwindow for FB display output + fb->m_subWin = createSubWindow(p_window, + &fb->m_subWinDisplay, + p_x,p_y,p_width,p_height); + if (fb->m_subWin) { + fb->m_nativeWindow = p_window; + + // create EGLSurface from the generated subwindow + fb->m_eglSurface = s_egl.eglCreateWindowSurface(fb->m_eglDisplay, + fb->m_eglConfig, + fb->m_subWin, + NULL); + + if (fb->m_eglSurface == EGL_NO_SURFACE) { + ERR("Failed to create surface\n"); + destroySubWindow(fb->m_subWinDisplay, fb->m_subWin); + fb->m_subWin = NULL; + } + else if (fb->bindSubwin_locked()) { + // Subwin creation was successfull, + // update viewport and z rotation and draw + // the last posted color buffer. + s_gl.glViewport(0, 0, p_width, p_height); + fb->m_zRot = zRot; + fb->post( fb->m_lastPostedColorBuffer, false ); + fb->unbind_locked(); + success = true; + } + } + } + s_theFrameBuffer->m_lock.unlock(); + } + + return success; +} + +bool FrameBuffer::removeSubWindow() +{ + bool removed = false; + if (s_theFrameBuffer) { + s_theFrameBuffer->m_lock.lock(); + if (s_theFrameBuffer->m_subWin) { + s_egl.eglMakeCurrent(s_theFrameBuffer->m_eglDisplay, NULL, NULL, NULL); + s_egl.eglDestroySurface(s_theFrameBuffer->m_eglDisplay, + s_theFrameBuffer->m_eglSurface); + destroySubWindow(s_theFrameBuffer->m_subWinDisplay, + s_theFrameBuffer->m_subWin); + + s_theFrameBuffer->m_eglSurface = EGL_NO_SURFACE; + s_theFrameBuffer->m_subWin = NULL; + removed = true; + } + s_theFrameBuffer->m_lock.unlock(); + } + return removed; +} + +HandleType FrameBuffer::genHandle() +{ + HandleType id; + do { + id = ++s_nextHandle; + } while( id == 0 || + m_contexts.find(id) != m_contexts.end() || + m_windows.find(id) != m_windows.end() ); + + return id; +} + +HandleType FrameBuffer::createColorBuffer(int p_width, int p_height, + GLenum p_internalFormat) +{ + android::Mutex::Autolock mutex(m_lock); + HandleType ret = 0; + + ColorBufferPtr cb( ColorBuffer::create(p_width, p_height, p_internalFormat) ); + if (cb.Ptr() != NULL) { + ret = genHandle(); + m_colorbuffers[ret].cb = cb; + m_colorbuffers[ret].refcount = 1; + } + return ret; +} + +HandleType FrameBuffer::createRenderContext(int p_config, HandleType p_share, + bool p_isGL2) +{ + android::Mutex::Autolock mutex(m_lock); + HandleType ret = 0; + + RenderContextPtr share(NULL); + if (p_share != 0) { + RenderContextMap::iterator s( m_contexts.find(p_share) ); + if (s == m_contexts.end()) { + return 0; + } + share = (*s).second; + } + + RenderContextPtr rctx( RenderContext::create(p_config, share, p_isGL2) ); + if (rctx.Ptr() != NULL) { + ret = genHandle(); + m_contexts[ret] = rctx; + } + return ret; +} + +HandleType FrameBuffer::createWindowSurface(int p_config, int p_width, int p_height) +{ + android::Mutex::Autolock mutex(m_lock); + + HandleType ret = 0; + WindowSurfacePtr win( WindowSurface::create(p_config, p_width, p_height) ); + if (win.Ptr() != NULL) { + ret = genHandle(); + m_windows[ret] = win; + } + + return ret; +} + +void FrameBuffer::DestroyRenderContext(HandleType p_context) +{ + android::Mutex::Autolock mutex(m_lock); + m_contexts.erase(p_context); +} + +void FrameBuffer::DestroyWindowSurface(HandleType p_surface) +{ + android::Mutex::Autolock mutex(m_lock); + m_windows.erase(p_surface); +} + +void FrameBuffer::openColorBuffer(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; + } + (*c).second.refcount++; +} + +void FrameBuffer::closeColorBuffer(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; + } + if (--(*c).second.refcount == 0) { + m_colorbuffers.erase(c); + } +} + +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) +{ + android::Mutex::Autolock mutex(m_lock); + + WindowSurfaceMap::iterator w( m_windows.find(p_surface) ); + if (w == m_windows.end()) { + // bad surface handle + return false; + } + + ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) ); + if (c == m_colorbuffers.end()) { + // bad colorbuffer handle + return false; + } + + (*w).second->setColorBuffer( (*c).second.cb ); + + 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.cb->subUpdate(x, y, width, height, format, type, pixels); + + 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.cb->bindToTexture(); +} + +bool FrameBuffer::bindColorBufferToRenderbuffer(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.cb->bindToRenderbuffer(); +} + +bool FrameBuffer::bindContext(HandleType p_context, + HandleType p_drawSurface, + HandleType p_readSurface) +{ + android::Mutex::Autolock mutex(m_lock); + + WindowSurfacePtr draw(NULL), read(NULL); + RenderContextPtr ctx(NULL); + + // + // if this is not an unbind operation - make sure all handles are good + // + if (p_context || p_drawSurface || p_readSurface) { + RenderContextMap::iterator r( m_contexts.find(p_context) ); + if (r == m_contexts.end()) { + // bad context handle + return false; + } + + ctx = (*r).second; + WindowSurfaceMap::iterator w( m_windows.find(p_drawSurface) ); + if (w == m_windows.end()) { + // bad surface handle + return false; + } + draw = (*w).second; + + if (p_readSurface != p_drawSurface) { + WindowSurfaceMap::iterator w( m_windows.find(p_readSurface) ); + if (w == m_windows.end()) { + // bad surface handle + return false; + } + read = (*w).second; + } + else { + read = draw; + } + } + + if (!s_egl.eglMakeCurrent(m_eglDisplay, + draw ? draw->getEGLSurface() : EGL_NO_SURFACE, + read ? read->getEGLSurface() : EGL_NO_SURFACE, + ctx ? ctx->getEGLContext() : EGL_NO_CONTEXT)) { + // MakeCurrent failed + return false; + } + + // + // Bind the surface(s) to the context + // + RenderThreadInfo *tinfo = getRenderThreadInfo(); + if (draw.Ptr() == NULL && read.Ptr() == NULL) { + // if this is an unbind operation - make sure the current bound + // surfaces get unbound from the context. + draw = tinfo->currDrawSurf; + read = tinfo->currReadSurf; + } + + if (draw.Ptr() != NULL && read.Ptr() != NULL) { + if (p_readSurface != p_drawSurface) { + draw->bind( ctx, SURFACE_BIND_DRAW ); + read->bind( ctx, SURFACE_BIND_READ ); + } + else { + draw->bind( ctx, SURFACE_BIND_READDRAW ); + } + } + + // + // update thread info with current bound context + // + tinfo->currContext = ctx; + tinfo->currDrawSurf = draw; + tinfo->currReadSurf = read; + if (ctx) { + if (ctx->isGL2()) tinfo->m_gl2Dec.setContextData(&ctx->decoderContextData()); + else tinfo->m_glDec.setContextData(&ctx->decoderContextData()); + } + else { + tinfo->m_glDec.setContextData(NULL); + tinfo->m_gl2Dec.setContextData(NULL); + } + return true; +} + +// +// The framebuffer lock should be held when calling this function ! +// +bool FrameBuffer::bind_locked() +{ + EGLContext prevContext = s_egl.eglGetCurrentContext(); + EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); + EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); + + if (!s_egl.eglMakeCurrent(m_eglDisplay, m_pbufSurface, + m_pbufSurface, m_pbufContext)) { + ERR("eglMakeCurrent failed\n"); + return false; + } + + m_prevContext = prevContext; + m_prevReadSurf = prevReadSurf; + m_prevDrawSurf = prevDrawSurf; + return true; +} + +bool FrameBuffer::bindSubwin_locked() +{ + EGLContext prevContext = s_egl.eglGetCurrentContext(); + EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); + EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); + + if (!s_egl.eglMakeCurrent(m_eglDisplay, m_eglSurface, + m_eglSurface, m_eglContext)) { + ERR("eglMakeCurrent failed\n"); + return false; + } + + // + // initialize GL state in eglContext if not yet initilaized + // + if (!m_eglContextInitialized) { + initGLState(); + m_eglContextInitialized = true; + } + + m_prevContext = prevContext; + m_prevReadSurf = prevReadSurf; + m_prevDrawSurf = prevDrawSurf; + return true; +} + +bool FrameBuffer::unbind_locked() +{ + if (!s_egl.eglMakeCurrent(m_eglDisplay, m_prevDrawSurf, + m_prevReadSurf, m_prevContext)) { + return false; + } + + m_prevContext = EGL_NO_CONTEXT; + m_prevReadSurf = EGL_NO_SURFACE; + m_prevDrawSurf = EGL_NO_SURFACE; + return true; +} + +bool FrameBuffer::post(HandleType p_colorbuffer, bool needLock) +{ + if (needLock) m_lock.lock(); + bool ret = false; + + ColorBufferMap::iterator c( m_colorbuffers.find(p_colorbuffer) ); + if (c != m_colorbuffers.end()) { + + m_lastPostedColorBuffer = p_colorbuffer; + if (!m_subWin) { + // no subwindow created for the FB output + // cannot post the colorbuffer + if (needLock) m_lock.unlock(); + return ret; + } + + + // bind the subwindow eglSurface + if (!bindSubwin_locked()) { + ERR("FrameBuffer::post eglMakeCurrent failed\n"); + if (needLock) m_lock.unlock(); + return false; + } + + // + // render the color buffer to the window + // + s_gl.glPushMatrix(); + s_gl.glRotatef(m_zRot, 0.0f, 0.0f, 1.0f); + if (m_zRot != 0.0f) { + s_gl.glClear(GL_COLOR_BUFFER_BIT); + } + ret = (*c).second.cb->post(); + s_gl.glPopMatrix(); + + if (ret) { + // + // Send framebuffer (without FPS overlay) to callback + // + if (m_onPost) { + s_gl.glReadPixels(0, 0, m_width, m_height, + GL_RGBA, GL_UNSIGNED_BYTE, m_fbImage); + m_onPost(m_onPostContext, m_width, m_height, -1, + GL_RGBA, GL_UNSIGNED_BYTE, m_fbImage); + } + + // + // output FPS statistics + // + if (m_fpsStats) { + long long currTime = GetCurrentTimeMS(); + m_statsNumFrames++; + if (currTime - m_statsStartTime >= 1000) { + float dt = (float)(currTime - m_statsStartTime) / 1000.0f; + printf("FPS: %5.3f\n", (float)m_statsNumFrames / dt); + m_statsStartTime = currTime; + m_statsNumFrames = 0; + } + } + + s_egl.eglSwapBuffers(m_eglDisplay, m_eglSurface); + } + + // restore previous binding + unbind_locked(); + } + + if (needLock) m_lock.unlock(); + return ret; +} + +bool FrameBuffer::repost() +{ + if (m_lastPostedColorBuffer) { + return post( m_lastPostedColorBuffer ); + } + return false; +} + +void FrameBuffer::initGLState() +{ + s_gl.glMatrixMode(GL_PROJECTION); + s_gl.glLoadIdentity(); + s_gl.glOrthof(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); + s_gl.glMatrixMode(GL_MODELVIEW); + s_gl.glLoadIdentity(); +} diff --git a/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h new file mode 100644 index 0000000..343f384 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h @@ -0,0 +1,137 @@ +/* +* 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. +*/ +#ifndef _LIBRENDER_FRAMEBUFFER_H +#define _LIBRENDER_FRAMEBUFFER_H + +#include "libOpenglRender/render_api.h" +#include "ColorBuffer.h" +#include "RenderContext.h" +#include "WindowSurface.h" +#include <utils/threads.h> +#include <map> +#include <EGL/egl.h> +#include <stdint.h> + +typedef uint32_t HandleType; +struct ColorBufferRef { + ColorBufferPtr cb; + uint32_t refcount; // number of client-side references +}; +typedef std::map<HandleType, RenderContextPtr> RenderContextMap; +typedef std::map<HandleType, WindowSurfacePtr> WindowSurfaceMap; +typedef std::map<HandleType, ColorBufferRef> ColorBufferMap; + +struct FrameBufferCaps +{ + bool hasGL2; + bool has_eglimage_texture_2d; + bool has_eglimage_renderbuffer; + EGLint eglMajor; + EGLint eglMinor; +}; + +class FrameBuffer +{ +public: + static bool initialize(int width, int height, OnPostFn onPost, void* onPostContext); + static bool setupSubWindow(FBNativeWindowType p_window, + int x, int y, + int width, int height, float zRot); + static bool removeSubWindow(); + static void finalize(); + static FrameBuffer *getFB() { return s_theFrameBuffer; } + + const FrameBufferCaps &getCaps() const { return m_caps; } + + int getWidth() const { return m_width; } + int getHeight() const { return m_height; } + + HandleType createRenderContext(int p_config, HandleType p_share, bool p_isGL2 = false); + HandleType createWindowSurface(int p_config, int p_width, int p_height); + HandleType createColorBuffer(int p_width, int p_height, GLenum p_internalFormat); + void DestroyRenderContext(HandleType p_context); + void DestroyWindowSurface(HandleType p_surface); + void openColorBuffer(HandleType p_colorbuffer); + void closeColorBuffer(HandleType p_colorbuffer); + + 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 bindColorBufferToRenderbuffer(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, bool needLock = true); + bool repost(); + + EGLDisplay getDisplay() const { return m_eglDisplay; } + EGLNativeWindowType getSubWindow() const { return m_subWin; } + bool bind_locked(); + bool unbind_locked(); + + void setDisplayRotation(float zRot) { + m_zRot = zRot; + repost(); + } + +private: + FrameBuffer(int p_width, int p_height, OnPostFn onPost, void* onPostContext); + ~FrameBuffer(); + HandleType genHandle(); + bool bindSubwin_locked(); + void initGLState(); + +private: + static FrameBuffer *s_theFrameBuffer; + static HandleType s_nextHandle; + int m_x; + int m_y; + int m_width; + int m_height; + android::Mutex m_lock; + FBNativeWindowType m_nativeWindow; + FrameBufferCaps m_caps; + EGLDisplay m_eglDisplay; + RenderContextMap m_contexts; + WindowSurfaceMap m_windows; + ColorBufferMap m_colorbuffers; + + EGLSurface m_eglSurface; + EGLContext m_eglContext; + EGLSurface m_pbufSurface; + EGLContext m_pbufContext; + + EGLContext m_prevContext; + EGLSurface m_prevReadSurf; + EGLSurface m_prevDrawSurf; + EGLNativeWindowType m_subWin; + EGLNativeDisplayType m_subWinDisplay; + EGLConfig m_eglConfig; + HandleType m_lastPostedColorBuffer; + float m_zRot; + bool m_eglContextInitialized; + + int m_statsNumFrames; + long long m_statsStartTime; + bool m_fpsStats; + + OnPostFn m_onPost; + void* m_onPostContext; + unsigned char* m_fbImage; +}; +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp b/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp new file mode 100644 index 0000000..cda205f --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.cpp @@ -0,0 +1,64 @@ +/* +* 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. +*/ +#ifdef WITH_GLES2 +#include "GL2Dispatch.h" +#include <stdio.h> +#include <stdlib.h> +#include "osDynLibrary.h" + +gl2_decoder_context_t s_gl2; +int s_gl2_enabled; + +static osUtils::dynLibrary *s_gles2_lib = NULL; + +#define DEFAULT_GLES_V2_LIB EMUGL_LIBNAME("GLES_V2_translator") + +// +// This function is called only once during initialiation before +// any thread has been created - hence it should NOT be thread safe. +// +bool init_gl2_dispatch() +{ + const char *libName = getenv("ANDROID_GLESv2_LIB"); + if (!libName) libName = DEFAULT_GLES_V2_LIB; + + // + // Load the GLES library + // + s_gles2_lib = osUtils::dynLibrary::open(libName); + if (!s_gles2_lib) return false; + + // + // init the GLES dispatch table + // + s_gl2.initDispatchByName( gl2_dispatch_get_proc_func, NULL ); + s_gl2_enabled = true; + return true; +} + +// +// This function is called only during initialiation before +// any thread has been created - hence it should NOT be thread safe. +// +void *gl2_dispatch_get_proc_func(const char *name, void *userData) +{ + if (!s_gles2_lib) { + return NULL; + } + return (void *)s_gles2_lib->findSymbol(name); +} + +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.h b/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.h new file mode 100644 index 0000000..89f3651 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/GL2Dispatch.h @@ -0,0 +1,30 @@ +/* +* 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. +*/ +#ifndef _GLES2_DISPATCH_H +#define _GLES2_DISPATCH_H + +#ifdef WITH_GLES2 + +#include "gl2_dec.h" + +bool init_gl2_dispatch(); +void *gl2_dispatch_get_proc_func(const char *name, void *userData); + +extern gl2_decoder_context_t s_gl2; +extern int s_gl2_enabled; + +#endif +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/GLDispatch.cpp b/emulator/opengl/host/libs/libOpenglRender/GLDispatch.cpp new file mode 100644 index 0000000..089512a --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/GLDispatch.cpp @@ -0,0 +1,325 @@ +/* +* 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 "GLDispatch.h" +#include <stdio.h> +#include <stdlib.h> +#include "osDynLibrary.h" + +GLDispatch s_gl; + +static osUtils::dynLibrary *s_gles_lib = NULL; + +// +// This function is called only once during initialiation before +// any thread has been created - hence it should NOT be thread safe. +// + +#define DEFAULT_GLES_CM_LIB EMUGL_LIBNAME("GLES_CM_translator") + +bool init_gl_dispatch() +{ + const char *libName = getenv("ANDROID_GLESv1_LIB"); + if (!libName) libName = DEFAULT_GLES_CM_LIB; + + s_gles_lib = osUtils::dynLibrary::open(libName); + if (!s_gles_lib) return false; + + s_gl.glAlphaFunc = (glAlphaFunc_t) s_gles_lib->findSymbol("glAlphaFunc"); + s_gl.glClearColor = (glClearColor_t) s_gles_lib->findSymbol("glClearColor"); + s_gl.glClearDepthf = (glClearDepthf_t) s_gles_lib->findSymbol("glClearDepthf"); + s_gl.glClipPlanef = (glClipPlanef_t) s_gles_lib->findSymbol("glClipPlanef"); + s_gl.glColor4f = (glColor4f_t) s_gles_lib->findSymbol("glColor4f"); + s_gl.glDepthRangef = (glDepthRangef_t) s_gles_lib->findSymbol("glDepthRangef"); + s_gl.glFogf = (glFogf_t) s_gles_lib->findSymbol("glFogf"); + s_gl.glFogfv = (glFogfv_t) s_gles_lib->findSymbol("glFogfv"); + s_gl.glFrustumf = (glFrustumf_t) s_gles_lib->findSymbol("glFrustumf"); + s_gl.glGetClipPlanef = (glGetClipPlanef_t) s_gles_lib->findSymbol("glGetClipPlanef"); + s_gl.glGetFloatv = (glGetFloatv_t) s_gles_lib->findSymbol("glGetFloatv"); + s_gl.glGetLightfv = (glGetLightfv_t) s_gles_lib->findSymbol("glGetLightfv"); + s_gl.glGetMaterialfv = (glGetMaterialfv_t) s_gles_lib->findSymbol("glGetMaterialfv"); + s_gl.glGetTexEnvfv = (glGetTexEnvfv_t) s_gles_lib->findSymbol("glGetTexEnvfv"); + s_gl.glGetTexParameterfv = (glGetTexParameterfv_t) s_gles_lib->findSymbol("glGetTexParameterfv"); + s_gl.glLightModelf = (glLightModelf_t) s_gles_lib->findSymbol("glLightModelf"); + s_gl.glLightModelfv = (glLightModelfv_t) s_gles_lib->findSymbol("glLightModelfv"); + s_gl.glLightf = (glLightf_t) s_gles_lib->findSymbol("glLightf"); + s_gl.glLightfv = (glLightfv_t) s_gles_lib->findSymbol("glLightfv"); + s_gl.glLineWidth = (glLineWidth_t) s_gles_lib->findSymbol("glLineWidth"); + s_gl.glLoadMatrixf = (glLoadMatrixf_t) s_gles_lib->findSymbol("glLoadMatrixf"); + s_gl.glMaterialf = (glMaterialf_t) s_gles_lib->findSymbol("glMaterialf"); + s_gl.glMaterialfv = (glMaterialfv_t) s_gles_lib->findSymbol("glMaterialfv"); + s_gl.glMultMatrixf = (glMultMatrixf_t) s_gles_lib->findSymbol("glMultMatrixf"); + s_gl.glMultiTexCoord4f = (glMultiTexCoord4f_t) s_gles_lib->findSymbol("glMultiTexCoord4f"); + s_gl.glNormal3f = (glNormal3f_t) s_gles_lib->findSymbol("glNormal3f"); + s_gl.glOrthof = (glOrthof_t) s_gles_lib->findSymbol("glOrthof"); + s_gl.glPointParameterf = (glPointParameterf_t) s_gles_lib->findSymbol("glPointParameterf"); + s_gl.glPointParameterfv = (glPointParameterfv_t) s_gles_lib->findSymbol("glPointParameterfv"); + s_gl.glPointSize = (glPointSize_t) s_gles_lib->findSymbol("glPointSize"); + s_gl.glPolygonOffset = (glPolygonOffset_t) s_gles_lib->findSymbol("glPolygonOffset"); + s_gl.glRotatef = (glRotatef_t) s_gles_lib->findSymbol("glRotatef"); + s_gl.glScalef = (glScalef_t) s_gles_lib->findSymbol("glScalef"); + s_gl.glTexEnvf = (glTexEnvf_t) s_gles_lib->findSymbol("glTexEnvf"); + s_gl.glTexEnvfv = (glTexEnvfv_t) s_gles_lib->findSymbol("glTexEnvfv"); + s_gl.glTexParameterf = (glTexParameterf_t) s_gles_lib->findSymbol("glTexParameterf"); + s_gl.glTexParameterfv = (glTexParameterfv_t) s_gles_lib->findSymbol("glTexParameterfv"); + s_gl.glTranslatef = (glTranslatef_t) s_gles_lib->findSymbol("glTranslatef"); + s_gl.glActiveTexture = (glActiveTexture_t) s_gles_lib->findSymbol("glActiveTexture"); + s_gl.glAlphaFuncx = (glAlphaFuncx_t) s_gles_lib->findSymbol("glAlphaFuncx"); + s_gl.glBindBuffer = (glBindBuffer_t) s_gles_lib->findSymbol("glBindBuffer"); + s_gl.glBindTexture = (glBindTexture_t) s_gles_lib->findSymbol("glBindTexture"); + s_gl.glBlendFunc = (glBlendFunc_t) s_gles_lib->findSymbol("glBlendFunc"); + s_gl.glBufferData = (glBufferData_t) s_gles_lib->findSymbol("glBufferData"); + s_gl.glBufferSubData = (glBufferSubData_t) s_gles_lib->findSymbol("glBufferSubData"); + s_gl.glClear = (glClear_t) s_gles_lib->findSymbol("glClear"); + s_gl.glClearColorx = (glClearColorx_t) s_gles_lib->findSymbol("glClearColorx"); + s_gl.glClearDepthx = (glClearDepthx_t) s_gles_lib->findSymbol("glClearDepthx"); + s_gl.glClearStencil = (glClearStencil_t) s_gles_lib->findSymbol("glClearStencil"); + s_gl.glClientActiveTexture = (glClientActiveTexture_t) s_gles_lib->findSymbol("glClientActiveTexture"); + s_gl.glClipPlanex = (glClipPlanex_t) s_gles_lib->findSymbol("glClipPlanex"); + s_gl.glColor4ub = (glColor4ub_t) s_gles_lib->findSymbol("glColor4ub"); + s_gl.glColor4x = (glColor4x_t) s_gles_lib->findSymbol("glColor4x"); + s_gl.glColorMask = (glColorMask_t) s_gles_lib->findSymbol("glColorMask"); + s_gl.glColorPointer = (glColorPointer_t) s_gles_lib->findSymbol("glColorPointer"); + s_gl.glCompressedTexImage2D = (glCompressedTexImage2D_t) s_gles_lib->findSymbol("glCompressedTexImage2D"); + s_gl.glCompressedTexSubImage2D = (glCompressedTexSubImage2D_t) s_gles_lib->findSymbol("glCompressedTexSubImage2D"); + s_gl.glCopyTexImage2D = (glCopyTexImage2D_t) s_gles_lib->findSymbol("glCopyTexImage2D"); + s_gl.glCopyTexSubImage2D = (glCopyTexSubImage2D_t) s_gles_lib->findSymbol("glCopyTexSubImage2D"); + s_gl.glCullFace = (glCullFace_t) s_gles_lib->findSymbol("glCullFace"); + s_gl.glDeleteBuffers = (glDeleteBuffers_t) s_gles_lib->findSymbol("glDeleteBuffers"); + s_gl.glDeleteTextures = (glDeleteTextures_t) s_gles_lib->findSymbol("glDeleteTextures"); + s_gl.glDepthFunc = (glDepthFunc_t) s_gles_lib->findSymbol("glDepthFunc"); + s_gl.glDepthMask = (glDepthMask_t) s_gles_lib->findSymbol("glDepthMask"); + s_gl.glDepthRangex = (glDepthRangex_t) s_gles_lib->findSymbol("glDepthRangex"); + s_gl.glDisable = (glDisable_t) s_gles_lib->findSymbol("glDisable"); + s_gl.glDisableClientState = (glDisableClientState_t) s_gles_lib->findSymbol("glDisableClientState"); + s_gl.glDrawArrays = (glDrawArrays_t) s_gles_lib->findSymbol("glDrawArrays"); + s_gl.glDrawElements = (glDrawElements_t) s_gles_lib->findSymbol("glDrawElements"); + s_gl.glEnable = (glEnable_t) s_gles_lib->findSymbol("glEnable"); + s_gl.glEnableClientState = (glEnableClientState_t) s_gles_lib->findSymbol("glEnableClientState"); + s_gl.glFinish = (glFinish_t) s_gles_lib->findSymbol("glFinish"); + s_gl.glFlush = (glFlush_t) s_gles_lib->findSymbol("glFlush"); + s_gl.glFogx = (glFogx_t) s_gles_lib->findSymbol("glFogx"); + s_gl.glFogxv = (glFogxv_t) s_gles_lib->findSymbol("glFogxv"); + s_gl.glFrontFace = (glFrontFace_t) s_gles_lib->findSymbol("glFrontFace"); + s_gl.glFrustumx = (glFrustumx_t) s_gles_lib->findSymbol("glFrustumx"); + s_gl.glGetBooleanv = (glGetBooleanv_t) s_gles_lib->findSymbol("glGetBooleanv"); + s_gl.glGetBufferParameteriv = (glGetBufferParameteriv_t) s_gles_lib->findSymbol("glGetBufferParameteriv"); + s_gl.glGetClipPlanex = (glGetClipPlanex_t) s_gles_lib->findSymbol("glGetClipPlanex"); + s_gl.glGenBuffers = (glGenBuffers_t) s_gles_lib->findSymbol("glGenBuffers"); + s_gl.glGenTextures = (glGenTextures_t) s_gles_lib->findSymbol("glGenTextures"); + s_gl.glGetError = (glGetError_t) s_gles_lib->findSymbol("glGetError"); + s_gl.glGetFixedv = (glGetFixedv_t) s_gles_lib->findSymbol("glGetFixedv"); + s_gl.glGetIntegerv = (glGetIntegerv_t) s_gles_lib->findSymbol("glGetIntegerv"); + s_gl.glGetLightxv = (glGetLightxv_t) s_gles_lib->findSymbol("glGetLightxv"); + s_gl.glGetMaterialxv = (glGetMaterialxv_t) s_gles_lib->findSymbol("glGetMaterialxv"); + s_gl.glGetPointerv = (glGetPointerv_t) s_gles_lib->findSymbol("glGetPointerv"); + s_gl.glGetString = (glGetString_t) s_gles_lib->findSymbol("glGetString"); + s_gl.glGetTexEnviv = (glGetTexEnviv_t) s_gles_lib->findSymbol("glGetTexEnviv"); + s_gl.glGetTexEnvxv = (glGetTexEnvxv_t) s_gles_lib->findSymbol("glGetTexEnvxv"); + s_gl.glGetTexParameteriv = (glGetTexParameteriv_t) s_gles_lib->findSymbol("glGetTexParameteriv"); + s_gl.glGetTexParameterxv = (glGetTexParameterxv_t) s_gles_lib->findSymbol("glGetTexParameterxv"); + s_gl.glHint = (glHint_t) s_gles_lib->findSymbol("glHint"); + s_gl.glIsBuffer = (glIsBuffer_t) s_gles_lib->findSymbol("glIsBuffer"); + s_gl.glIsEnabled = (glIsEnabled_t) s_gles_lib->findSymbol("glIsEnabled"); + s_gl.glIsTexture = (glIsTexture_t) s_gles_lib->findSymbol("glIsTexture"); + s_gl.glLightModelx = (glLightModelx_t) s_gles_lib->findSymbol("glLightModelx"); + s_gl.glLightModelxv = (glLightModelxv_t) s_gles_lib->findSymbol("glLightModelxv"); + s_gl.glLightx = (glLightx_t) s_gles_lib->findSymbol("glLightx"); + s_gl.glLightxv = (glLightxv_t) s_gles_lib->findSymbol("glLightxv"); + s_gl.glLineWidthx = (glLineWidthx_t) s_gles_lib->findSymbol("glLineWidthx"); + s_gl.glLoadIdentity = (glLoadIdentity_t) s_gles_lib->findSymbol("glLoadIdentity"); + s_gl.glLoadMatrixx = (glLoadMatrixx_t) s_gles_lib->findSymbol("glLoadMatrixx"); + s_gl.glLogicOp = (glLogicOp_t) s_gles_lib->findSymbol("glLogicOp"); + s_gl.glMaterialx = (glMaterialx_t) s_gles_lib->findSymbol("glMaterialx"); + s_gl.glMaterialxv = (glMaterialxv_t) s_gles_lib->findSymbol("glMaterialxv"); + s_gl.glMatrixMode = (glMatrixMode_t) s_gles_lib->findSymbol("glMatrixMode"); + s_gl.glMultMatrixx = (glMultMatrixx_t) s_gles_lib->findSymbol("glMultMatrixx"); + s_gl.glMultiTexCoord4x = (glMultiTexCoord4x_t) s_gles_lib->findSymbol("glMultiTexCoord4x"); + s_gl.glNormal3x = (glNormal3x_t) s_gles_lib->findSymbol("glNormal3x"); + s_gl.glNormalPointer = (glNormalPointer_t) s_gles_lib->findSymbol("glNormalPointer"); + s_gl.glOrthox = (glOrthox_t) s_gles_lib->findSymbol("glOrthox"); + s_gl.glPixelStorei = (glPixelStorei_t) s_gles_lib->findSymbol("glPixelStorei"); + s_gl.glPointParameterx = (glPointParameterx_t) s_gles_lib->findSymbol("glPointParameterx"); + s_gl.glPointParameterxv = (glPointParameterxv_t) s_gles_lib->findSymbol("glPointParameterxv"); + s_gl.glPointSizex = (glPointSizex_t) s_gles_lib->findSymbol("glPointSizex"); + s_gl.glPolygonOffsetx = (glPolygonOffsetx_t) s_gles_lib->findSymbol("glPolygonOffsetx"); + s_gl.glPopMatrix = (glPopMatrix_t) s_gles_lib->findSymbol("glPopMatrix"); + s_gl.glPushMatrix = (glPushMatrix_t) s_gles_lib->findSymbol("glPushMatrix"); + s_gl.glReadPixels = (glReadPixels_t) s_gles_lib->findSymbol("glReadPixels"); + s_gl.glRotatex = (glRotatex_t) s_gles_lib->findSymbol("glRotatex"); + s_gl.glSampleCoverage = (glSampleCoverage_t) s_gles_lib->findSymbol("glSampleCoverage"); + s_gl.glSampleCoveragex = (glSampleCoveragex_t) s_gles_lib->findSymbol("glSampleCoveragex"); + s_gl.glScalex = (glScalex_t) s_gles_lib->findSymbol("glScalex"); + s_gl.glScissor = (glScissor_t) s_gles_lib->findSymbol("glScissor"); + s_gl.glShadeModel = (glShadeModel_t) s_gles_lib->findSymbol("glShadeModel"); + s_gl.glStencilFunc = (glStencilFunc_t) s_gles_lib->findSymbol("glStencilFunc"); + s_gl.glStencilMask = (glStencilMask_t) s_gles_lib->findSymbol("glStencilMask"); + s_gl.glStencilOp = (glStencilOp_t) s_gles_lib->findSymbol("glStencilOp"); + s_gl.glTexCoordPointer = (glTexCoordPointer_t) s_gles_lib->findSymbol("glTexCoordPointer"); + s_gl.glTexEnvi = (glTexEnvi_t) s_gles_lib->findSymbol("glTexEnvi"); + s_gl.glTexEnvx = (glTexEnvx_t) s_gles_lib->findSymbol("glTexEnvx"); + s_gl.glTexEnviv = (glTexEnviv_t) s_gles_lib->findSymbol("glTexEnviv"); + s_gl.glTexEnvxv = (glTexEnvxv_t) s_gles_lib->findSymbol("glTexEnvxv"); + s_gl.glTexImage2D = (glTexImage2D_t) s_gles_lib->findSymbol("glTexImage2D"); + s_gl.glTexParameteri = (glTexParameteri_t) s_gles_lib->findSymbol("glTexParameteri"); + s_gl.glTexParameterx = (glTexParameterx_t) s_gles_lib->findSymbol("glTexParameterx"); + s_gl.glTexParameteriv = (glTexParameteriv_t) s_gles_lib->findSymbol("glTexParameteriv"); + s_gl.glTexParameterxv = (glTexParameterxv_t) s_gles_lib->findSymbol("glTexParameterxv"); + s_gl.glTexSubImage2D = (glTexSubImage2D_t) s_gles_lib->findSymbol("glTexSubImage2D"); + s_gl.glTranslatex = (glTranslatex_t) s_gles_lib->findSymbol("glTranslatex"); + s_gl.glVertexPointer = (glVertexPointer_t) s_gles_lib->findSymbol("glVertexPointer"); + s_gl.glViewport = (glViewport_t) s_gles_lib->findSymbol("glViewport"); + s_gl.glPointSizePointerOES = (glPointSizePointerOES_t) s_gles_lib->findSymbol("glPointSizePointerOES"); + s_gl.glBlendEquationSeparateOES = (glBlendEquationSeparateOES_t) s_gles_lib->findSymbol("glBlendEquationSeparateOES"); + s_gl.glBlendFuncSeparateOES = (glBlendFuncSeparateOES_t) s_gles_lib->findSymbol("glBlendFuncSeparateOES"); + s_gl.glBlendEquationOES = (glBlendEquationOES_t) s_gles_lib->findSymbol("glBlendEquationOES"); + s_gl.glDrawTexsOES = (glDrawTexsOES_t) s_gles_lib->findSymbol("glDrawTexsOES"); + s_gl.glDrawTexiOES = (glDrawTexiOES_t) s_gles_lib->findSymbol("glDrawTexiOES"); + s_gl.glDrawTexxOES = (glDrawTexxOES_t) s_gles_lib->findSymbol("glDrawTexxOES"); + s_gl.glDrawTexsvOES = (glDrawTexsvOES_t) s_gles_lib->findSymbol("glDrawTexsvOES"); + s_gl.glDrawTexivOES = (glDrawTexivOES_t) s_gles_lib->findSymbol("glDrawTexivOES"); + s_gl.glDrawTexxvOES = (glDrawTexxvOES_t) s_gles_lib->findSymbol("glDrawTexxvOES"); + s_gl.glDrawTexfOES = (glDrawTexfOES_t) s_gles_lib->findSymbol("glDrawTexfOES"); + s_gl.glDrawTexfvOES = (glDrawTexfvOES_t) s_gles_lib->findSymbol("glDrawTexfvOES"); + s_gl.glEGLImageTargetTexture2DOES = (glEGLImageTargetTexture2DOES_t) s_gles_lib->findSymbol("glEGLImageTargetTexture2DOES"); + s_gl.glEGLImageTargetRenderbufferStorageOES = (glEGLImageTargetRenderbufferStorageOES_t) s_gles_lib->findSymbol("glEGLImageTargetRenderbufferStorageOES"); + s_gl.glAlphaFuncxOES = (glAlphaFuncxOES_t) s_gles_lib->findSymbol("glAlphaFuncxOES"); + s_gl.glClearColorxOES = (glClearColorxOES_t) s_gles_lib->findSymbol("glClearColorxOES"); + s_gl.glClearDepthxOES = (glClearDepthxOES_t) s_gles_lib->findSymbol("glClearDepthxOES"); + s_gl.glClipPlanexOES = (glClipPlanexOES_t) s_gles_lib->findSymbol("glClipPlanexOES"); + s_gl.glColor4xOES = (glColor4xOES_t) s_gles_lib->findSymbol("glColor4xOES"); + s_gl.glDepthRangexOES = (glDepthRangexOES_t) s_gles_lib->findSymbol("glDepthRangexOES"); + s_gl.glFogxOES = (glFogxOES_t) s_gles_lib->findSymbol("glFogxOES"); + s_gl.glFogxvOES = (glFogxvOES_t) s_gles_lib->findSymbol("glFogxvOES"); + s_gl.glFrustumxOES = (glFrustumxOES_t) s_gles_lib->findSymbol("glFrustumxOES"); + s_gl.glGetClipPlanexOES = (glGetClipPlanexOES_t) s_gles_lib->findSymbol("glGetClipPlanexOES"); + s_gl.glGetFixedvOES = (glGetFixedvOES_t) s_gles_lib->findSymbol("glGetFixedvOES"); + s_gl.glGetLightxvOES = (glGetLightxvOES_t) s_gles_lib->findSymbol("glGetLightxvOES"); + s_gl.glGetMaterialxvOES = (glGetMaterialxvOES_t) s_gles_lib->findSymbol("glGetMaterialxvOES"); + s_gl.glGetTexEnvxvOES = (glGetTexEnvxvOES_t) s_gles_lib->findSymbol("glGetTexEnvxvOES"); + s_gl.glGetTexParameterxvOES = (glGetTexParameterxvOES_t) s_gles_lib->findSymbol("glGetTexParameterxvOES"); + s_gl.glLightModelxOES = (glLightModelxOES_t) s_gles_lib->findSymbol("glLightModelxOES"); + s_gl.glLightModelxvOES = (glLightModelxvOES_t) s_gles_lib->findSymbol("glLightModelxvOES"); + s_gl.glLightxOES = (glLightxOES_t) s_gles_lib->findSymbol("glLightxOES"); + s_gl.glLightxvOES = (glLightxvOES_t) s_gles_lib->findSymbol("glLightxvOES"); + s_gl.glLineWidthxOES = (glLineWidthxOES_t) s_gles_lib->findSymbol("glLineWidthxOES"); + s_gl.glLoadMatrixxOES = (glLoadMatrixxOES_t) s_gles_lib->findSymbol("glLoadMatrixxOES"); + s_gl.glMaterialxOES = (glMaterialxOES_t) s_gles_lib->findSymbol("glMaterialxOES"); + s_gl.glMaterialxvOES = (glMaterialxvOES_t) s_gles_lib->findSymbol("glMaterialxvOES"); + s_gl.glMultMatrixxOES = (glMultMatrixxOES_t) s_gles_lib->findSymbol("glMultMatrixxOES"); + s_gl.glMultiTexCoord4xOES = (glMultiTexCoord4xOES_t) s_gles_lib->findSymbol("glMultiTexCoord4xOES"); + s_gl.glNormal3xOES = (glNormal3xOES_t) s_gles_lib->findSymbol("glNormal3xOES"); + s_gl.glOrthoxOES = (glOrthoxOES_t) s_gles_lib->findSymbol("glOrthoxOES"); + s_gl.glPointParameterxOES = (glPointParameterxOES_t) s_gles_lib->findSymbol("glPointParameterxOES"); + s_gl.glPointParameterxvOES = (glPointParameterxvOES_t) s_gles_lib->findSymbol("glPointParameterxvOES"); + s_gl.glPointSizexOES = (glPointSizexOES_t) s_gles_lib->findSymbol("glPointSizexOES"); + s_gl.glPolygonOffsetxOES = (glPolygonOffsetxOES_t) s_gles_lib->findSymbol("glPolygonOffsetxOES"); + s_gl.glRotatexOES = (glRotatexOES_t) s_gles_lib->findSymbol("glRotatexOES"); + s_gl.glSampleCoveragexOES = (glSampleCoveragexOES_t) s_gles_lib->findSymbol("glSampleCoveragexOES"); + s_gl.glScalexOES = (glScalexOES_t) s_gles_lib->findSymbol("glScalexOES"); + s_gl.glTexEnvxOES = (glTexEnvxOES_t) s_gles_lib->findSymbol("glTexEnvxOES"); + s_gl.glTexEnvxvOES = (glTexEnvxvOES_t) s_gles_lib->findSymbol("glTexEnvxvOES"); + s_gl.glTexParameterxOES = (glTexParameterxOES_t) s_gles_lib->findSymbol("glTexParameterxOES"); + s_gl.glTexParameterxvOES = (glTexParameterxvOES_t) s_gles_lib->findSymbol("glTexParameterxvOES"); + s_gl.glTranslatexOES = (glTranslatexOES_t) s_gles_lib->findSymbol("glTranslatexOES"); + s_gl.glIsRenderbufferOES = (glIsRenderbufferOES_t) s_gles_lib->findSymbol("glIsRenderbufferOES"); + s_gl.glBindRenderbufferOES = (glBindRenderbufferOES_t) s_gles_lib->findSymbol("glBindRenderbufferOES"); + s_gl.glDeleteRenderbuffersOES = (glDeleteRenderbuffersOES_t) s_gles_lib->findSymbol("glDeleteRenderbuffersOES"); + s_gl.glGenRenderbuffersOES = (glGenRenderbuffersOES_t) s_gles_lib->findSymbol("glGenRenderbuffersOES"); + s_gl.glRenderbufferStorageOES = (glRenderbufferStorageOES_t) s_gles_lib->findSymbol("glRenderbufferStorageOES"); + s_gl.glGetRenderbufferParameterivOES = (glGetRenderbufferParameterivOES_t) s_gles_lib->findSymbol("glGetRenderbufferParameterivOES"); + s_gl.glIsFramebufferOES = (glIsFramebufferOES_t) s_gles_lib->findSymbol("glIsFramebufferOES"); + s_gl.glBindFramebufferOES = (glBindFramebufferOES_t) s_gles_lib->findSymbol("glBindFramebufferOES"); + s_gl.glDeleteFramebuffersOES = (glDeleteFramebuffersOES_t) s_gles_lib->findSymbol("glDeleteFramebuffersOES"); + s_gl.glGenFramebuffersOES = (glGenFramebuffersOES_t) s_gles_lib->findSymbol("glGenFramebuffersOES"); + s_gl.glCheckFramebufferStatusOES = (glCheckFramebufferStatusOES_t) s_gles_lib->findSymbol("glCheckFramebufferStatusOES"); + s_gl.glFramebufferRenderbufferOES = (glFramebufferRenderbufferOES_t) s_gles_lib->findSymbol("glFramebufferRenderbufferOES"); + s_gl.glFramebufferTexture2DOES = (glFramebufferTexture2DOES_t) s_gles_lib->findSymbol("glFramebufferTexture2DOES"); + s_gl.glGetFramebufferAttachmentParameterivOES = (glGetFramebufferAttachmentParameterivOES_t) s_gles_lib->findSymbol("glGetFramebufferAttachmentParameterivOES"); + s_gl.glGenerateMipmapOES = (glGenerateMipmapOES_t) s_gles_lib->findSymbol("glGenerateMipmapOES"); + s_gl.glMapBufferOES = (glMapBufferOES_t) s_gles_lib->findSymbol("glMapBufferOES"); + s_gl.glUnmapBufferOES = (glUnmapBufferOES_t) s_gles_lib->findSymbol("glUnmapBufferOES"); + s_gl.glGetBufferPointervOES = (glGetBufferPointervOES_t) s_gles_lib->findSymbol("glGetBufferPointervOES"); + s_gl.glCurrentPaletteMatrixOES = (glCurrentPaletteMatrixOES_t) s_gles_lib->findSymbol("glCurrentPaletteMatrixOES"); + s_gl.glLoadPaletteFromModelViewMatrixOES = (glLoadPaletteFromModelViewMatrixOES_t) s_gles_lib->findSymbol("glLoadPaletteFromModelViewMatrixOES"); + s_gl.glMatrixIndexPointerOES = (glMatrixIndexPointerOES_t) s_gles_lib->findSymbol("glMatrixIndexPointerOES"); + s_gl.glWeightPointerOES = (glWeightPointerOES_t) s_gles_lib->findSymbol("glWeightPointerOES"); + s_gl.glQueryMatrixxOES = (glQueryMatrixxOES_t) s_gles_lib->findSymbol("glQueryMatrixxOES"); + s_gl.glDepthRangefOES = (glDepthRangefOES_t) s_gles_lib->findSymbol("glDepthRangefOES"); + s_gl.glFrustumfOES = (glFrustumfOES_t) s_gles_lib->findSymbol("glFrustumfOES"); + s_gl.glOrthofOES = (glOrthofOES_t) s_gles_lib->findSymbol("glOrthofOES"); + s_gl.glClipPlanefOES = (glClipPlanefOES_t) s_gles_lib->findSymbol("glClipPlanefOES"); + s_gl.glGetClipPlanefOES = (glGetClipPlanefOES_t) s_gles_lib->findSymbol("glGetClipPlanefOES"); + s_gl.glClearDepthfOES = (glClearDepthfOES_t) s_gles_lib->findSymbol("glClearDepthfOES"); + s_gl.glTexGenfOES = (glTexGenfOES_t) s_gles_lib->findSymbol("glTexGenfOES"); + s_gl.glTexGenfvOES = (glTexGenfvOES_t) s_gles_lib->findSymbol("glTexGenfvOES"); + s_gl.glTexGeniOES = (glTexGeniOES_t) s_gles_lib->findSymbol("glTexGeniOES"); + s_gl.glTexGenivOES = (glTexGenivOES_t) s_gles_lib->findSymbol("glTexGenivOES"); + s_gl.glTexGenxOES = (glTexGenxOES_t) s_gles_lib->findSymbol("glTexGenxOES"); + s_gl.glTexGenxvOES = (glTexGenxvOES_t) s_gles_lib->findSymbol("glTexGenxvOES"); + s_gl.glGetTexGenfvOES = (glGetTexGenfvOES_t) s_gles_lib->findSymbol("glGetTexGenfvOES"); + s_gl.glGetTexGenivOES = (glGetTexGenivOES_t) s_gles_lib->findSymbol("glGetTexGenivOES"); + s_gl.glGetTexGenxvOES = (glGetTexGenxvOES_t) s_gles_lib->findSymbol("glGetTexGenxvOES"); + s_gl.glBindVertexArrayOES = (glBindVertexArrayOES_t) s_gles_lib->findSymbol("glBindVertexArrayOES"); + s_gl.glDeleteVertexArraysOES = (glDeleteVertexArraysOES_t) s_gles_lib->findSymbol("glDeleteVertexArraysOES"); + s_gl.glGenVertexArraysOES = (glGenVertexArraysOES_t) s_gles_lib->findSymbol("glGenVertexArraysOES"); + s_gl.glIsVertexArrayOES = (glIsVertexArrayOES_t) s_gles_lib->findSymbol("glIsVertexArrayOES"); + s_gl.glDiscardFramebufferEXT = (glDiscardFramebufferEXT_t) s_gles_lib->findSymbol("glDiscardFramebufferEXT"); + s_gl.glMultiDrawArraysEXT = (glMultiDrawArraysEXT_t) s_gles_lib->findSymbol("glMultiDrawArraysEXT"); + s_gl.glMultiDrawElementsEXT = (glMultiDrawElementsEXT_t) s_gles_lib->findSymbol("glMultiDrawElementsEXT"); + s_gl.glClipPlanefIMG = (glClipPlanefIMG_t) s_gles_lib->findSymbol("glClipPlanefIMG"); + s_gl.glClipPlanexIMG = (glClipPlanexIMG_t) s_gles_lib->findSymbol("glClipPlanexIMG"); + s_gl.glRenderbufferStorageMultisampleIMG = (glRenderbufferStorageMultisampleIMG_t) s_gles_lib->findSymbol("glRenderbufferStorageMultisampleIMG"); + s_gl.glFramebufferTexture2DMultisampleIMG = (glFramebufferTexture2DMultisampleIMG_t) s_gles_lib->findSymbol("glFramebufferTexture2DMultisampleIMG"); + s_gl.glDeleteFencesNV = (glDeleteFencesNV_t) s_gles_lib->findSymbol("glDeleteFencesNV"); + s_gl.glGenFencesNV = (glGenFencesNV_t) s_gles_lib->findSymbol("glGenFencesNV"); + s_gl.glIsFenceNV = (glIsFenceNV_t) s_gles_lib->findSymbol("glIsFenceNV"); + s_gl.glTestFenceNV = (glTestFenceNV_t) s_gles_lib->findSymbol("glTestFenceNV"); + s_gl.glGetFenceivNV = (glGetFenceivNV_t) s_gles_lib->findSymbol("glGetFenceivNV"); + s_gl.glFinishFenceNV = (glFinishFenceNV_t) s_gles_lib->findSymbol("glFinishFenceNV"); + s_gl.glSetFenceNV = (glSetFenceNV_t) s_gles_lib->findSymbol("glSetFenceNV"); + s_gl.glGetDriverControlsQCOM = (glGetDriverControlsQCOM_t) s_gles_lib->findSymbol("glGetDriverControlsQCOM"); + s_gl.glGetDriverControlStringQCOM = (glGetDriverControlStringQCOM_t) s_gles_lib->findSymbol("glGetDriverControlStringQCOM"); + s_gl.glEnableDriverControlQCOM = (glEnableDriverControlQCOM_t) s_gles_lib->findSymbol("glEnableDriverControlQCOM"); + s_gl.glDisableDriverControlQCOM = (glDisableDriverControlQCOM_t) s_gles_lib->findSymbol("glDisableDriverControlQCOM"); + s_gl.glExtGetTexturesQCOM = (glExtGetTexturesQCOM_t) s_gles_lib->findSymbol("glExtGetTexturesQCOM"); + s_gl.glExtGetBuffersQCOM = (glExtGetBuffersQCOM_t) s_gles_lib->findSymbol("glExtGetBuffersQCOM"); + s_gl.glExtGetRenderbuffersQCOM = (glExtGetRenderbuffersQCOM_t) s_gles_lib->findSymbol("glExtGetRenderbuffersQCOM"); + s_gl.glExtGetFramebuffersQCOM = (glExtGetFramebuffersQCOM_t) s_gles_lib->findSymbol("glExtGetFramebuffersQCOM"); + s_gl.glExtGetTexLevelParameterivQCOM = (glExtGetTexLevelParameterivQCOM_t) s_gles_lib->findSymbol("glExtGetTexLevelParameterivQCOM"); + s_gl.glExtTexObjectStateOverrideiQCOM = (glExtTexObjectStateOverrideiQCOM_t) s_gles_lib->findSymbol("glExtTexObjectStateOverrideiQCOM"); + s_gl.glExtGetTexSubImageQCOM = (glExtGetTexSubImageQCOM_t) s_gles_lib->findSymbol("glExtGetTexSubImageQCOM"); + s_gl.glExtGetBufferPointervQCOM = (glExtGetBufferPointervQCOM_t) s_gles_lib->findSymbol("glExtGetBufferPointervQCOM"); + s_gl.glExtGetShadersQCOM = (glExtGetShadersQCOM_t) s_gles_lib->findSymbol("glExtGetShadersQCOM"); + s_gl.glExtGetProgramsQCOM = (glExtGetProgramsQCOM_t) s_gles_lib->findSymbol("glExtGetProgramsQCOM"); + s_gl.glExtIsProgramBinaryQCOM = (glExtIsProgramBinaryQCOM_t) s_gles_lib->findSymbol("glExtIsProgramBinaryQCOM"); + s_gl.glExtGetProgramBinarySourceQCOM = (glExtGetProgramBinarySourceQCOM_t) s_gles_lib->findSymbol("glExtGetProgramBinarySourceQCOM"); + s_gl.glStartTilingQCOM = (glStartTilingQCOM_t) s_gles_lib->findSymbol("glStartTilingQCOM"); + s_gl.glEndTilingQCOM = (glEndTilingQCOM_t) s_gles_lib->findSymbol("glEndTilingQCOM"); + + return true; +} + +// +// This function is called only during initialiation before +// any thread has been created - hence it should NOT be thread safe. +// +void *gl_dispatch_get_proc_func(const char *name, void *userData) +{ + if (!s_gles_lib) { + return NULL; + } + return (void *)s_gles_lib->findSymbol(name); +} diff --git a/emulator/opengl/host/libs/libOpenglRender/GLDispatch.h b/emulator/opengl/host/libs/libOpenglRender/GLDispatch.h new file mode 100644 index 0000000..5fe98f1 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/GLDispatch.h @@ -0,0 +1,300 @@ +/* +* 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. +*/ +#ifndef _GLES_DISPATCH_H +#define _GLES_DISPATCH_H + +#include "gl_proc.h" + + +struct GLDispatch { + glAlphaFunc_t glAlphaFunc; + glClearColor_t glClearColor; + glClearDepthf_t glClearDepthf; + glClipPlanef_t glClipPlanef; + glColor4f_t glColor4f; + glDepthRangef_t glDepthRangef; + glFogf_t glFogf; + glFogfv_t glFogfv; + glFrustumf_t glFrustumf; + glGetClipPlanef_t glGetClipPlanef; + glGetFloatv_t glGetFloatv; + glGetLightfv_t glGetLightfv; + glGetMaterialfv_t glGetMaterialfv; + glGetTexEnvfv_t glGetTexEnvfv; + glGetTexParameterfv_t glGetTexParameterfv; + glLightModelf_t glLightModelf; + glLightModelfv_t glLightModelfv; + glLightf_t glLightf; + glLightfv_t glLightfv; + glLineWidth_t glLineWidth; + glLoadMatrixf_t glLoadMatrixf; + glMaterialf_t glMaterialf; + glMaterialfv_t glMaterialfv; + glMultMatrixf_t glMultMatrixf; + glMultiTexCoord4f_t glMultiTexCoord4f; + glNormal3f_t glNormal3f; + glOrthof_t glOrthof; + glPointParameterf_t glPointParameterf; + glPointParameterfv_t glPointParameterfv; + glPointSize_t glPointSize; + glPolygonOffset_t glPolygonOffset; + glRotatef_t glRotatef; + glScalef_t glScalef; + glTexEnvf_t glTexEnvf; + glTexEnvfv_t glTexEnvfv; + glTexParameterf_t glTexParameterf; + glTexParameterfv_t glTexParameterfv; + glTranslatef_t glTranslatef; + glActiveTexture_t glActiveTexture; + glAlphaFuncx_t glAlphaFuncx; + glBindBuffer_t glBindBuffer; + glBindTexture_t glBindTexture; + glBlendFunc_t glBlendFunc; + glBufferData_t glBufferData; + glBufferSubData_t glBufferSubData; + glClear_t glClear; + glClearColorx_t glClearColorx; + glClearDepthx_t glClearDepthx; + glClearStencil_t glClearStencil; + glClientActiveTexture_t glClientActiveTexture; + glClipPlanex_t glClipPlanex; + glColor4ub_t glColor4ub; + glColor4x_t glColor4x; + glColorMask_t glColorMask; + glColorPointer_t glColorPointer; + glCompressedTexImage2D_t glCompressedTexImage2D; + glCompressedTexSubImage2D_t glCompressedTexSubImage2D; + glCopyTexImage2D_t glCopyTexImage2D; + glCopyTexSubImage2D_t glCopyTexSubImage2D; + glCullFace_t glCullFace; + glDeleteBuffers_t glDeleteBuffers; + glDeleteTextures_t glDeleteTextures; + glDepthFunc_t glDepthFunc; + glDepthMask_t glDepthMask; + glDepthRangex_t glDepthRangex; + glDisable_t glDisable; + glDisableClientState_t glDisableClientState; + glDrawArrays_t glDrawArrays; + glDrawElements_t glDrawElements; + glEnable_t glEnable; + glEnableClientState_t glEnableClientState; + glFinish_t glFinish; + glFlush_t glFlush; + glFogx_t glFogx; + glFogxv_t glFogxv; + glFrontFace_t glFrontFace; + glFrustumx_t glFrustumx; + glGetBooleanv_t glGetBooleanv; + glGetBufferParameteriv_t glGetBufferParameteriv; + glGetClipPlanex_t glGetClipPlanex; + glGenBuffers_t glGenBuffers; + glGenTextures_t glGenTextures; + glGetError_t glGetError; + glGetFixedv_t glGetFixedv; + glGetIntegerv_t glGetIntegerv; + glGetLightxv_t glGetLightxv; + glGetMaterialxv_t glGetMaterialxv; + glGetPointerv_t glGetPointerv; + glGetString_t glGetString; + glGetTexEnviv_t glGetTexEnviv; + glGetTexEnvxv_t glGetTexEnvxv; + glGetTexParameteriv_t glGetTexParameteriv; + glGetTexParameterxv_t glGetTexParameterxv; + glHint_t glHint; + glIsBuffer_t glIsBuffer; + glIsEnabled_t glIsEnabled; + glIsTexture_t glIsTexture; + glLightModelx_t glLightModelx; + glLightModelxv_t glLightModelxv; + glLightx_t glLightx; + glLightxv_t glLightxv; + glLineWidthx_t glLineWidthx; + glLoadIdentity_t glLoadIdentity; + glLoadMatrixx_t glLoadMatrixx; + glLogicOp_t glLogicOp; + glMaterialx_t glMaterialx; + glMaterialxv_t glMaterialxv; + glMatrixMode_t glMatrixMode; + glMultMatrixx_t glMultMatrixx; + glMultiTexCoord4x_t glMultiTexCoord4x; + glNormal3x_t glNormal3x; + glNormalPointer_t glNormalPointer; + glOrthox_t glOrthox; + glPixelStorei_t glPixelStorei; + glPointParameterx_t glPointParameterx; + glPointParameterxv_t glPointParameterxv; + glPointSizex_t glPointSizex; + glPolygonOffsetx_t glPolygonOffsetx; + glPopMatrix_t glPopMatrix; + glPushMatrix_t glPushMatrix; + glReadPixels_t glReadPixels; + glRotatex_t glRotatex; + glSampleCoverage_t glSampleCoverage; + glSampleCoveragex_t glSampleCoveragex; + glScalex_t glScalex; + glScissor_t glScissor; + glShadeModel_t glShadeModel; + glStencilFunc_t glStencilFunc; + glStencilMask_t glStencilMask; + glStencilOp_t glStencilOp; + glTexCoordPointer_t glTexCoordPointer; + glTexEnvi_t glTexEnvi; + glTexEnvx_t glTexEnvx; + glTexEnviv_t glTexEnviv; + glTexEnvxv_t glTexEnvxv; + glTexImage2D_t glTexImage2D; + glTexParameteri_t glTexParameteri; + glTexParameterx_t glTexParameterx; + glTexParameteriv_t glTexParameteriv; + glTexParameterxv_t glTexParameterxv; + glTexSubImage2D_t glTexSubImage2D; + glTranslatex_t glTranslatex; + glVertexPointer_t glVertexPointer; + glViewport_t glViewport; + glPointSizePointerOES_t glPointSizePointerOES; + glBlendEquationSeparateOES_t glBlendEquationSeparateOES; + glBlendFuncSeparateOES_t glBlendFuncSeparateOES; + glBlendEquationOES_t glBlendEquationOES; + glDrawTexsOES_t glDrawTexsOES; + glDrawTexiOES_t glDrawTexiOES; + glDrawTexxOES_t glDrawTexxOES; + glDrawTexsvOES_t glDrawTexsvOES; + glDrawTexivOES_t glDrawTexivOES; + glDrawTexxvOES_t glDrawTexxvOES; + glDrawTexfOES_t glDrawTexfOES; + glDrawTexfvOES_t glDrawTexfvOES; + glEGLImageTargetTexture2DOES_t glEGLImageTargetTexture2DOES; + glEGLImageTargetRenderbufferStorageOES_t glEGLImageTargetRenderbufferStorageOES; + glAlphaFuncxOES_t glAlphaFuncxOES; + glClearColorxOES_t glClearColorxOES; + glClearDepthxOES_t glClearDepthxOES; + glClipPlanexOES_t glClipPlanexOES; + glColor4xOES_t glColor4xOES; + glDepthRangexOES_t glDepthRangexOES; + glFogxOES_t glFogxOES; + glFogxvOES_t glFogxvOES; + glFrustumxOES_t glFrustumxOES; + glGetClipPlanexOES_t glGetClipPlanexOES; + glGetFixedvOES_t glGetFixedvOES; + glGetLightxvOES_t glGetLightxvOES; + glGetMaterialxvOES_t glGetMaterialxvOES; + glGetTexEnvxvOES_t glGetTexEnvxvOES; + glGetTexParameterxvOES_t glGetTexParameterxvOES; + glLightModelxOES_t glLightModelxOES; + glLightModelxvOES_t glLightModelxvOES; + glLightxOES_t glLightxOES; + glLightxvOES_t glLightxvOES; + glLineWidthxOES_t glLineWidthxOES; + glLoadMatrixxOES_t glLoadMatrixxOES; + glMaterialxOES_t glMaterialxOES; + glMaterialxvOES_t glMaterialxvOES; + glMultMatrixxOES_t glMultMatrixxOES; + glMultiTexCoord4xOES_t glMultiTexCoord4xOES; + glNormal3xOES_t glNormal3xOES; + glOrthoxOES_t glOrthoxOES; + glPointParameterxOES_t glPointParameterxOES; + glPointParameterxvOES_t glPointParameterxvOES; + glPointSizexOES_t glPointSizexOES; + glPolygonOffsetxOES_t glPolygonOffsetxOES; + glRotatexOES_t glRotatexOES; + glSampleCoveragexOES_t glSampleCoveragexOES; + glScalexOES_t glScalexOES; + glTexEnvxOES_t glTexEnvxOES; + glTexEnvxvOES_t glTexEnvxvOES; + glTexParameterxOES_t glTexParameterxOES; + glTexParameterxvOES_t glTexParameterxvOES; + glTranslatexOES_t glTranslatexOES; + glIsRenderbufferOES_t glIsRenderbufferOES; + glBindRenderbufferOES_t glBindRenderbufferOES; + glDeleteRenderbuffersOES_t glDeleteRenderbuffersOES; + glGenRenderbuffersOES_t glGenRenderbuffersOES; + glRenderbufferStorageOES_t glRenderbufferStorageOES; + glGetRenderbufferParameterivOES_t glGetRenderbufferParameterivOES; + glIsFramebufferOES_t glIsFramebufferOES; + glBindFramebufferOES_t glBindFramebufferOES; + glDeleteFramebuffersOES_t glDeleteFramebuffersOES; + glGenFramebuffersOES_t glGenFramebuffersOES; + glCheckFramebufferStatusOES_t glCheckFramebufferStatusOES; + glFramebufferRenderbufferOES_t glFramebufferRenderbufferOES; + glFramebufferTexture2DOES_t glFramebufferTexture2DOES; + glGetFramebufferAttachmentParameterivOES_t glGetFramebufferAttachmentParameterivOES; + glGenerateMipmapOES_t glGenerateMipmapOES; + glMapBufferOES_t glMapBufferOES; + glUnmapBufferOES_t glUnmapBufferOES; + glGetBufferPointervOES_t glGetBufferPointervOES; + glCurrentPaletteMatrixOES_t glCurrentPaletteMatrixOES; + glLoadPaletteFromModelViewMatrixOES_t glLoadPaletteFromModelViewMatrixOES; + glMatrixIndexPointerOES_t glMatrixIndexPointerOES; + glWeightPointerOES_t glWeightPointerOES; + glQueryMatrixxOES_t glQueryMatrixxOES; + glDepthRangefOES_t glDepthRangefOES; + glFrustumfOES_t glFrustumfOES; + glOrthofOES_t glOrthofOES; + glClipPlanefOES_t glClipPlanefOES; + glGetClipPlanefOES_t glGetClipPlanefOES; + glClearDepthfOES_t glClearDepthfOES; + glTexGenfOES_t glTexGenfOES; + glTexGenfvOES_t glTexGenfvOES; + glTexGeniOES_t glTexGeniOES; + glTexGenivOES_t glTexGenivOES; + glTexGenxOES_t glTexGenxOES; + glTexGenxvOES_t glTexGenxvOES; + glGetTexGenfvOES_t glGetTexGenfvOES; + glGetTexGenivOES_t glGetTexGenivOES; + glGetTexGenxvOES_t glGetTexGenxvOES; + glBindVertexArrayOES_t glBindVertexArrayOES; + glDeleteVertexArraysOES_t glDeleteVertexArraysOES; + glGenVertexArraysOES_t glGenVertexArraysOES; + glIsVertexArrayOES_t glIsVertexArrayOES; + glDiscardFramebufferEXT_t glDiscardFramebufferEXT; + glMultiDrawArraysEXT_t glMultiDrawArraysEXT; + glMultiDrawElementsEXT_t glMultiDrawElementsEXT; + glClipPlanefIMG_t glClipPlanefIMG; + glClipPlanexIMG_t glClipPlanexIMG; + glRenderbufferStorageMultisampleIMG_t glRenderbufferStorageMultisampleIMG; + glFramebufferTexture2DMultisampleIMG_t glFramebufferTexture2DMultisampleIMG; + glDeleteFencesNV_t glDeleteFencesNV; + glGenFencesNV_t glGenFencesNV; + glIsFenceNV_t glIsFenceNV; + glTestFenceNV_t glTestFenceNV; + glGetFenceivNV_t glGetFenceivNV; + glFinishFenceNV_t glFinishFenceNV; + glSetFenceNV_t glSetFenceNV; + glGetDriverControlsQCOM_t glGetDriverControlsQCOM; + glGetDriverControlStringQCOM_t glGetDriverControlStringQCOM; + glEnableDriverControlQCOM_t glEnableDriverControlQCOM; + glDisableDriverControlQCOM_t glDisableDriverControlQCOM; + glExtGetTexturesQCOM_t glExtGetTexturesQCOM; + glExtGetBuffersQCOM_t glExtGetBuffersQCOM; + glExtGetRenderbuffersQCOM_t glExtGetRenderbuffersQCOM; + glExtGetFramebuffersQCOM_t glExtGetFramebuffersQCOM; + glExtGetTexLevelParameterivQCOM_t glExtGetTexLevelParameterivQCOM; + glExtTexObjectStateOverrideiQCOM_t glExtTexObjectStateOverrideiQCOM; + glExtGetTexSubImageQCOM_t glExtGetTexSubImageQCOM; + glExtGetBufferPointervQCOM_t glExtGetBufferPointervQCOM; + glExtGetShadersQCOM_t glExtGetShadersQCOM; + glExtGetProgramsQCOM_t glExtGetProgramsQCOM; + glExtIsProgramBinaryQCOM_t glExtIsProgramBinaryQCOM; + glExtGetProgramBinarySourceQCOM_t glExtGetProgramBinarySourceQCOM; + glStartTilingQCOM_t glStartTilingQCOM; + glEndTilingQCOM_t glEndTilingQCOM; +}; + +bool init_gl_dispatch(); +void *gl_dispatch_get_proc_func(const char *name, void *userData); + +extern GLDispatch s_gl; +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/NativeLinuxSubWindow.cpp b/emulator/opengl/host/libs/libOpenglRender/NativeLinuxSubWindow.cpp new file mode 100644 index 0000000..ff335df --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/NativeLinuxSubWindow.cpp @@ -0,0 +1,48 @@ +/* +* 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 "NativeSubWindow.h" + +static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg) +{ + if (e->type == MapNotify && e->xmap.window == (Window)arg) { + return 1; + } + return 0; +} + +static Display *s_display = NULL; + +EGLNativeWindowType createSubWindow(FBNativeWindowType p_window, + EGLNativeDisplayType* display_out, + int x, int y,int width, int height){ + + // The call to this function is protected by a lock + // in FrameBuffer so it is safe to check and initialize s_display here + if (!s_display) s_display = XOpenDisplay(NULL); + *display_out = s_display; + + XSetWindowAttributes wa; + wa.event_mask = StructureNotifyMask; + Window win = XCreateWindow(*display_out,p_window,x,y, width,height,0,CopyFromParent,CopyFromParent,CopyFromParent,CWEventMask,&wa); + XMapWindow(*display_out,win); + XEvent e; + XIfEvent(*display_out, &e, WaitForMapNotify, (char *)win); + return win; +} + +void destroySubWindow(EGLNativeDisplayType dis,EGLNativeWindowType win){ + XDestroyWindow(dis, win); +} diff --git a/emulator/opengl/host/libs/libOpenglRender/NativeMacSubWindow.m b/emulator/opengl/host/libs/libOpenglRender/NativeMacSubWindow.m new file mode 100644 index 0000000..f57f661 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/NativeMacSubWindow.m @@ -0,0 +1,64 @@ +/* +* 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 "NativeSubWindow.h" +#include <Cocoa/Cocoa.h> + +/* + * EmuGLView inherit from NSView and override the isOpaque + * method to return YES. That prevents drawing of underlying window/view + * when the view needs to be redrawn. + */ +@interface EmuGLView : NSView { +} @end + +@implementation EmuGLView + + - (BOOL)isOpaque { + return YES; + } + +@end + + +EGLNativeWindowType createSubWindow(FBNativeWindowType p_window, + EGLNativeDisplayType* display_out, + int x, int y,int width, int height){ + NSWindow *win = (NSWindow *)p_window; + if (!win) { + return NULL; + } + + /* (x,y) assume an upper-left origin, but Cocoa uses a lower-left origin */ + NSRect content_rect = [win contentRectForFrameRect:[win frame]]; + int cocoa_y = (int)content_rect.size.height - (y + height); + NSRect contentRect = NSMakeRect(x, cocoa_y, width, height); + + NSView *glView = [[EmuGLView alloc] initWithFrame:contentRect]; + if (glView) { + [[win contentView] addSubview:glView]; + [win makeKeyAndOrderFront:nil]; + } + + return (EGLNativeWindowType)glView; +} + +void destroySubWindow(EGLNativeDisplayType dis,EGLNativeWindowType win){ + if(win){ + NSView *glView = (NSView *)win; + [glView removeFromSuperview]; + [glView release]; + } +} diff --git a/emulator/opengl/host/libs/libOpenglRender/NativeSubWindow.h b/emulator/opengl/host/libs/libOpenglRender/NativeSubWindow.h new file mode 100644 index 0000000..1965978 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/NativeSubWindow.h @@ -0,0 +1,37 @@ +/* +* 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. +*/ +#ifndef NATIVE_SUB_WINDOW_H +#define NATIVE_SUB_WINDOW_H + +#include <EGL/egl.h> +#include "libOpenglRender/render_api_platform_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +EGLNativeWindowType createSubWindow(FBNativeWindowType p_window, + EGLNativeDisplayType* display_out, + int x, int y,int width, int height); + + +void destroySubWindow(EGLNativeDisplayType dis,EGLNativeWindowType win); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/NativeWindowsSubWindow.cpp b/emulator/opengl/host/libs/libOpenglRender/NativeWindowsSubWindow.cpp new file mode 100644 index 0000000..e519b68 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/NativeWindowsSubWindow.cpp @@ -0,0 +1,57 @@ +/* +* 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 "NativeSubWindow.h" +#include <stdio.h> + +LRESULT CALLBACK myWndProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) +{ + return DefWindowProc(hwnd, uMsg, wParam, lParam); +} + +EGLNativeWindowType createSubWindow(FBNativeWindowType p_window, + EGLNativeDisplayType* display_out, + int x, int y,int width, int height){ + WNDCLASS wc; + wc.style = CS_OWNDC |CS_HREDRAW |CS_VREDRAW; // redraw if size changes + wc.lpfnWndProc = myWndProc; // points to window procedure + wc.cbClsExtra = 0; // no extra class memory + wc.cbWndExtra = sizeof(void*); // save extra window memory, to store VasWindow instance + wc.hInstance = NULL; // handle to instance + wc.hIcon = NULL; // predefined app. icon + wc.hCursor = NULL; + wc.hbrBackground = NULL; // no background brush + wc.lpszMenuName = NULL; // name of menu resource + wc.lpszClassName = "subWin"; // name of window class + + RegisterClass(&wc); + printf("creating window %d %d %d %d\n",x,y,width,height); + EGLNativeWindowType ret = CreateWindowEx( + WS_EX_NOPARENTNOTIFY, // do not bother our parent window + "subWin", + "sub", + WS_CHILD|WS_DISABLED, + x,y,width,height, + p_window, + NULL, + NULL, + NULL); + ShowWindow(ret,SW_SHOW); + return ret; +} + +void destroySubWindow(EGLNativeDisplayType dis,EGLNativeWindowType win){ + PostMessage(win, WM_CLOSE, 0, 0); +} diff --git a/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.cpp b/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.cpp new file mode 100644 index 0000000..837b094 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.cpp @@ -0,0 +1,73 @@ +/* +* 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 "ReadBuffer.h" +#include <string.h> +#include <assert.h> +#include <limits.h> +#include "ErrorLog.h" + +ReadBuffer::ReadBuffer(IOStream *stream, size_t bufsize) +{ + m_size = bufsize; + m_stream = stream; + m_buf = (unsigned char*)malloc(m_size*sizeof(unsigned char)); + m_validData = 0; + m_readPtr = m_buf; +} + +ReadBuffer::~ReadBuffer() +{ + free(m_buf); +} + +int ReadBuffer::getData() +{ + if ((m_validData > 0) && (m_readPtr > m_buf)) { + memmove(m_buf, m_readPtr, m_validData); + } + // get fresh data into the buffer; + size_t len = m_size - m_validData; + if (len==0) { + //we need to inc our buffer + size_t new_size = m_size*2; + unsigned char* new_buf; + if (new_size < m_size) { // overflow check + new_size = INT_MAX; + } + + new_buf = (unsigned char*)realloc(m_buf, new_size); + if (!new_buf) { + ERR("Failed to alloc %zu bytes for ReadBuffer\n", new_size); + return -1; + } + m_size = new_size; + m_buf = new_buf; + len = m_size - m_validData; + } + m_readPtr = m_buf; + if (NULL != m_stream->read(m_buf + m_validData, &len)) { + m_validData += len; + return len; + } + return -1; +} + +void ReadBuffer::consume(size_t amount) +{ + assert(amount <= m_validData); + m_validData -= amount; + m_readPtr += amount; +} diff --git a/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.h b/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.h new file mode 100644 index 0000000..f2dfbce --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/ReadBuffer.h @@ -0,0 +1,36 @@ +/* +* 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. +*/ +#ifndef _READ_BUFFER_H +#define _READ_BUFFER_H + +#include "IOStream.h" + +class ReadBuffer { +public: + ReadBuffer(IOStream *stream, size_t bufSize); + ~ReadBuffer(); + int getData(); // get fresh data from the stream + unsigned char *buf() { return m_readPtr; } // return the next read location + size_t validData() { return m_validData; } // return the amount of valid data in readptr + void consume(size_t amount); // notify that 'amount' data has been consumed; +private: + unsigned char *m_buf; + unsigned char *m_readPtr; + size_t m_size; + size_t m_validData; + IOStream *m_stream; +}; +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderContext.cpp b/emulator/opengl/host/libs/libOpenglRender/RenderContext.cpp new file mode 100644 index 0000000..f5cbd67 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/RenderContext.cpp @@ -0,0 +1,76 @@ +/* +* 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 "RenderContext.h" +#include "FBConfig.h" +#include "FrameBuffer.h" +#include "EGLDispatch.h" +#include "GLDispatch.h" + +RenderContext *RenderContext::create(int p_config, + RenderContextPtr p_shareContext, + bool p_isGL2) +{ + const FBConfig *fbconf = FBConfig::get(p_config); + if (!fbconf) { + return NULL; + } + + RenderContext *c = new RenderContext(); + if (!c) { + return NULL; + } + + EGLContext share = EGL_NO_CONTEXT; + if (p_shareContext.Ptr() != NULL) { + share = p_shareContext->getEGLContext(); + } + + GLint glContextAttribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 1, + EGL_NONE + }; + + if (p_isGL2) { + glContextAttribs[1] = 2; + c->m_isGL2 = true; + } + + c->m_ctx = s_egl.eglCreateContext(FrameBuffer::getFB()->getDisplay(), + fbconf->getEGLConfig(), share, + glContextAttribs); + + if (c->m_ctx == EGL_NO_CONTEXT) { + delete c; + return NULL; + } + + c->m_config = p_config; + return c; +} + +RenderContext::RenderContext() : + m_ctx(EGL_NO_CONTEXT), + m_config(0), + m_isGL2(false) +{ +} + +RenderContext::~RenderContext() +{ + if (m_ctx != EGL_NO_CONTEXT) { + s_egl.eglDestroyContext(FrameBuffer::getFB()->getDisplay(), m_ctx); + } +} diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderContext.h b/emulator/opengl/host/libs/libOpenglRender/RenderContext.h new file mode 100644 index 0000000..9cbb5fc --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/RenderContext.h @@ -0,0 +1,49 @@ +/* +* 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. +*/ +#ifndef _LIBRENDER_RENDERCONTEXT_H +#define _LIBRENDER_RENDERCONTEXT_H + +#include "SmartPtr.h" +#include <EGL/egl.h> +#include "GLDecoderContextData.h" + +class RenderContext; +typedef SmartPtr<RenderContext> RenderContextPtr; + +class RenderContext +{ +public: + static RenderContext *create(int p_config, RenderContextPtr p_shareContext, + bool p_isGL2 = false); + ~RenderContext(); + int getConfig() const { return m_config; } + + EGLContext getEGLContext() const { return m_ctx; } + bool isGL2() const { return m_isGL2; } + + GLDecoderContextData & decoderContextData() { return m_contextData; } + +private: + RenderContext(); + +private: + EGLContext m_ctx; + int m_config; + bool m_isGL2; + GLDecoderContextData m_contextData; +}; + +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp b/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp new file mode 100644 index 0000000..6b8f8fd --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/RenderControl.cpp @@ -0,0 +1,360 @@ +/* +* 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 "renderControl_dec.h" +#include "FrameBuffer.h" +#include "FBConfig.h" +#include "EGLDispatch.h" +#include "GLDispatch.h" +#include "GL2Dispatch.h" +#include "ThreadInfo.h" + +static const GLint rendererVersion = 1; + +static GLint rcGetRendererVersion() +{ + return rendererVersion; +} + +static EGLint rcGetEGLVersion(EGLint* major, EGLint* minor) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return EGL_FALSE; + } + *major = (EGLint)fb->getCaps().eglMajor; + *minor = (EGLint)fb->getCaps().eglMinor; + + return EGL_TRUE; +} + +static EGLint rcQueryEGLString(EGLenum name, void* buffer, EGLint bufferSize) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return 0; + } + + const char *str = s_egl.eglQueryString(fb->getDisplay(), name); + if (!str) { + return 0; + } + + int len = strlen(str) + 1; + if (!buffer || len > bufferSize) { + return -len; + } + + strcpy((char *)buffer, str); + return len; +} + +static EGLint rcGetGLString(EGLenum name, void* buffer, EGLint bufferSize) +{ + RenderThreadInfo *tInfo = getRenderThreadInfo(); + if (!tInfo || !tInfo->currContext.Ptr()) { + return 0; + } + + const char *str = NULL; +#ifdef WITH_GLES2 + if (tInfo->currContext->isGL2()) { + str = (const char *)s_gl2.glGetString(name); + } + else { +#endif + str = (const char *)s_gl.glGetString(name); +#ifdef WITH_GLES2 + } +#endif + + if (!str) { + return 0; + } + + int len = strlen(str) + 1; + if (!buffer || len > bufferSize) { + return -len; + } + + strcpy((char *)buffer, str); + return len; +} + +static EGLint rcGetNumConfigs(uint32_t* numAttribs) +{ + if (numAttribs) { + *numAttribs = FBConfig::getNumAttribs(); + } + return FBConfig::getNumConfigs(); +} + +static EGLint rcGetConfigs(uint32_t bufSize, GLuint* buffer) +{ + int configSize = FBConfig::getNumAttribs(); + int nConfigs = FBConfig::getNumConfigs(); + uint32_t neededSize = (nConfigs + 1) * configSize * sizeof(GLuint); + if (!buffer || bufSize < neededSize) { + return -neededSize; + } + FBConfig::packConfigsInfo(buffer); + return nConfigs; +} + +static EGLint rcChooseConfig(EGLint *attribs, uint32_t attribs_size, uint32_t *configs, uint32_t configs_size) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return 0; + } + + return FBConfig::chooseConfig(fb, attribs, configs, configs_size); +} + +static EGLint rcGetFBParam(EGLint param) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return 0; + } + + EGLint ret = 0; + + switch(param) { + case FB_WIDTH: + ret = fb->getWidth(); + break; + case FB_HEIGHT: + ret = fb->getHeight(); + break; + case FB_XDPI: + ret = 72; // XXX: should be implemented + break; + case FB_YDPI: + ret = 72; // XXX: should be implemented + break; + case FB_FPS: + ret = 60; + break; + case FB_MIN_SWAP_INTERVAL: + ret = 1; // XXX: should be implemented + break; + case FB_MAX_SWAP_INTERVAL: + ret = 1; // XXX: should be implemented + break; + default: + break; + } + + return ret; +} + +static uint32_t rcCreateContext(uint32_t config, + uint32_t share, uint32_t glVersion) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return 0; + } + + HandleType ret = fb->createRenderContext(config, share, glVersion == 2); + return ret; +} + +static void rcDestroyContext(uint32_t context) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return; + } + + fb->DestroyRenderContext(context); +} + +static uint32_t rcCreateWindowSurface(uint32_t config, + uint32_t width, uint32_t height) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return 0; + } + + return fb->createWindowSurface(config, width, height); +} + +static void rcDestroyWindowSurface(uint32_t windowSurface) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return; + } + + fb->DestroyWindowSurface( windowSurface ); +} + +static uint32_t rcCreateColorBuffer(uint32_t width, + uint32_t height, GLenum internalFormat) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return 0; + } + + return fb->createColorBuffer(width, height, internalFormat); +} + +static void rcOpenColorBuffer(uint32_t colorbuffer) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return; + } + fb->openColorBuffer( colorbuffer ); +} + +static void rcCloseColorBuffer(uint32_t colorbuffer) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return; + } + fb->closeColorBuffer( colorbuffer ); +} + +static int rcFlushWindowColorBuffer(uint32_t windowSurface) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return -1; + } + fb->flushWindowSurfaceColorBuffer(windowSurface); + return 0; +} + +static void rcSetWindowColorBuffer(uint32_t windowSurface, + uint32_t colorBuffer) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return; + } + fb->setWindowSurfaceColorBuffer(windowSurface, colorBuffer); +} + +static EGLint rcMakeCurrent(uint32_t context, + uint32_t drawSurf, uint32_t readSurf) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return EGL_FALSE; + } + + bool ret = fb->bindContext(context, drawSurf, readSurf); + + return (ret ? EGL_TRUE : EGL_FALSE); +} + +static void rcFBPost(uint32_t colorBuffer) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return; + } + + fb->post(colorBuffer); +} + +static void rcFBSetSwapInterval(EGLint interval) +{ + // XXX: TBD - should be implemented +} + +static void rcBindTexture(uint32_t colorBuffer) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return; + } + + fb->bindColorBufferToTexture(colorBuffer); +} + +static void rcBindRenderbuffer(uint32_t colorBuffer) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return; + } + + fb->bindColorBufferToRenderbuffer(colorBuffer); +} + +static EGLint rcColorBufferCacheFlush(uint32_t colorBuffer, + EGLint postCount, int forRead) +{ + // XXX: TBD - should be implemented + return 0; +} + +static void rcReadColorBuffer(uint32_t colorBuffer, + GLint x, GLint y, + GLint width, GLint height, + GLenum format, GLenum type, void* pixels) +{ + // XXX: TBD - should be implemented +} + +static int rcUpdateColorBuffer(uint32_t colorBuffer, + GLint x, GLint y, + GLint width, GLint height, + GLenum format, GLenum type, void* pixels) +{ + FrameBuffer *fb = FrameBuffer::getFB(); + if (!fb) { + return -1; + } + + fb->updateColorBuffer(colorBuffer, x, y, width, height, format, type, pixels); + return 0; +} + +void initRenderControlContext(renderControl_decoder_context_t *dec) +{ + dec->set_rcGetRendererVersion(rcGetRendererVersion); + dec->set_rcGetEGLVersion(rcGetEGLVersion); + dec->set_rcQueryEGLString(rcQueryEGLString); + dec->set_rcGetGLString(rcGetGLString); + dec->set_rcGetNumConfigs(rcGetNumConfigs); + dec->set_rcGetConfigs(rcGetConfigs); + dec->set_rcChooseConfig(rcChooseConfig); + dec->set_rcGetFBParam(rcGetFBParam); + dec->set_rcCreateContext(rcCreateContext); + dec->set_rcDestroyContext(rcDestroyContext); + dec->set_rcCreateWindowSurface(rcCreateWindowSurface); + dec->set_rcDestroyWindowSurface(rcDestroyWindowSurface); + dec->set_rcCreateColorBuffer(rcCreateColorBuffer); + dec->set_rcOpenColorBuffer(rcOpenColorBuffer); + dec->set_rcCloseColorBuffer(rcCloseColorBuffer); + dec->set_rcSetWindowColorBuffer(rcSetWindowColorBuffer); + dec->set_rcFlushWindowColorBuffer(rcFlushWindowColorBuffer); + dec->set_rcMakeCurrent(rcMakeCurrent); + dec->set_rcFBPost(rcFBPost); + dec->set_rcFBSetSwapInterval(rcFBSetSwapInterval); + dec->set_rcBindTexture(rcBindTexture); + dec->set_rcBindRenderbuffer(rcBindRenderbuffer); + dec->set_rcColorBufferCacheFlush(rcColorBufferCacheFlush); + dec->set_rcReadColorBuffer(rcReadColorBuffer); + dec->set_rcUpdateColorBuffer(rcUpdateColorBuffer); +} diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderControl.h b/emulator/opengl/host/libs/libOpenglRender/RenderControl.h new file mode 100644 index 0000000..233e809 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/RenderControl.h @@ -0,0 +1,21 @@ +/* +* 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. +*/ +#ifndef _RENDER_CONTROL_H +#define _RENDER_CONTROL_H + +void initRenderControlContext(renderControl_decoder_context_t *dec); + +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp b/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp new file mode 100644 index 0000000..78f305c --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/RenderServer.cpp @@ -0,0 +1,142 @@ +/* +* 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 "RenderServer.h" +#include "TcpStream.h" +#ifdef _WIN32 +#include "Win32PipeStream.h" +#else +#include "UnixStream.h" +#endif +#include "RenderThread.h" +#include "FrameBuffer.h" +#include <set> + +typedef std::set<RenderThread *> RenderThreadsSet; + +RenderServer::RenderServer() : + m_listenSock(NULL), + m_exiting(false) +{ +} + +extern "C" int gRendererStreamMode; + +RenderServer *RenderServer::create(int port) +{ + RenderServer *server = new RenderServer(); + if (!server) { + return NULL; + } + + if (gRendererStreamMode == STREAM_MODE_TCP) { + server->m_listenSock = new TcpStream(); + } else { +#ifdef _WIN32 + server->m_listenSock = new Win32PipeStream(); +#else + server->m_listenSock = new UnixStream(); +#endif + } + + if (server->m_listenSock->listen(port) < 0) { + ERR("RenderServer::create failed to listen on port %d\n", port); + delete server; + return NULL; + } + + return server; +} + +int RenderServer::Main() +{ + RenderThreadsSet threads; + + while(1) { + SocketStream *stream = m_listenSock->accept(); + if (!stream) { + fprintf(stderr,"Error accepting connection, aborting\n"); + 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"); + // check if we have been requested to exit while waiting on accept + if ((clientFlags & IOSTREAM_CLIENT_EXIT_SERVER) != 0) { + m_exiting = true; + break; + } + + RenderThread *rt = RenderThread::create(stream); + if (!rt) { + fprintf(stderr,"Failed to create RenderThread\n"); + delete stream; + } + + if (!rt->start()) { + fprintf(stderr,"Failed to start RenderThread\n"); + 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); + + DBG("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; +} diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderServer.h b/emulator/opengl/host/libs/libOpenglRender/RenderServer.h new file mode 100644 index 0000000..98e9890 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/RenderServer.h @@ -0,0 +1,38 @@ +/* +* 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. +*/ +#ifndef _LIB_OPENGL_RENDER_RENDER_SERVER_H +#define _LIB_OPENGL_RENDER_RENDER_SERVER_H + +#include "SocketStream.h" +#include "osThread.h" + +class RenderServer : public osUtils::Thread +{ +public: + static RenderServer *create(int port); + virtual int Main(); + + bool isExiting() const { return m_exiting; } + +private: + RenderServer(); + +private: + SocketStream *m_listenSock; + bool m_exiting; +}; + +#endif 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; +} diff --git a/emulator/opengl/host/libs/libOpenglRender/RenderThread.h b/emulator/opengl/host/libs/libOpenglRender/RenderThread.h new file mode 100644 index 0000000..67d423f --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/RenderThread.h @@ -0,0 +1,41 @@ +/* +* 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. +*/ +#ifndef _LIB_OPENGL_RENDER_RENDER_THREAD_H +#define _LIB_OPENGL_RENDER_RENDER_THREAD_H + +#include "IOStream.h" +#include "GLDecoder.h" +#include "renderControl_dec.h" +#include "osThread.h" + +class RenderThread : public osUtils::Thread +{ +public: + static RenderThread *create(IOStream *p_stream); + + bool isFinished() const { return m_finished; } + +private: + RenderThread(); + virtual int Main(); + +private: + IOStream *m_stream; + renderControl_decoder_context_t m_rcDec; + bool m_finished; +}; + +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.cpp b/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.cpp new file mode 100644 index 0000000..2f2a962 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.cpp @@ -0,0 +1,53 @@ +/* +* 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 "ThreadInfo.h" + +#ifdef __linux__ + +static __thread RenderThreadInfo *tinfo = NULL; + +RenderThreadInfo *getRenderThreadInfo() +{ + if (!tinfo) { + tinfo = new RenderThreadInfo(); + } + return tinfo; +} + +#else + +#include <cutils/threads.h> +static thread_store_t s_tls = THREAD_STORE_INITIALIZER; + +static void tlsDestruct(void *ptr) +{ + if (ptr) { + RenderThreadInfo *ti = (RenderThreadInfo *)ptr; + delete ti; + } +} + +RenderThreadInfo *getRenderThreadInfo() +{ + RenderThreadInfo *ti = (RenderThreadInfo *)thread_store_get(&s_tls); + if (!ti) { + ti = new RenderThreadInfo(); + thread_store_set(&s_tls, ti, tlsDestruct); + } + return ti; +} +#endif + diff --git a/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h b/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h new file mode 100644 index 0000000..b147290 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/ThreadInfo.h @@ -0,0 +1,35 @@ +/* +* 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. +*/ +#ifndef _LIB_OPENGL_RENDER_THREAD_INFO_H +#define _LIB_OPENGL_RENDER_THREAD_INFO_H + +#include "RenderContext.h" +#include "WindowSurface.h" +#include "GLDecoder.h" +#include "GL2Decoder.h" + +struct RenderThreadInfo +{ + RenderContextPtr currContext; + WindowSurfacePtr currDrawSurf; + WindowSurfacePtr currReadSurf; + GLDecoder m_glDec; + GL2Decoder m_gl2Dec; +}; + +RenderThreadInfo *getRenderThreadInfo(); + +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp b/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp new file mode 100644 index 0000000..3674120 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/WindowSurface.cpp @@ -0,0 +1,236 @@ +/* +* 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 "WindowSurface.h" +#include "FBConfig.h" +#include "FrameBuffer.h" +#include <GLES/glext.h> +#include "EGLDispatch.h" +#include "GLDispatch.h" +#include "GL2Dispatch.h" +#include <stdio.h> +#include <string.h> +#include "GLErrorLog.h" + +WindowSurface::WindowSurface() : + m_fbObj(0), + m_depthRB(0), + m_stencilRB(0), + m_eglSurface(NULL), + m_attachedColorBuffer(NULL), + m_readContext(NULL), + m_drawContext(NULL), + m_width(0), + m_height(0), + m_pbufWidth(0), + m_pbufHeight(0) +{ +} + +WindowSurface::~WindowSurface() +{ + s_egl.eglDestroySurface(FrameBuffer::getFB()->getDisplay(), m_eglSurface); +} + +WindowSurface *WindowSurface::create(int p_config, int p_width, int p_height) +{ + const FBConfig *fbconf = FBConfig::get(p_config); + if (!fbconf) { + return NULL; + } + + // allocate space for the WindowSurface object + WindowSurface *win = new WindowSurface(); + if (!win) { + return NULL; + } + win->m_fbconf = fbconf; + + FrameBuffer *fb = FrameBuffer::getFB(); + const FrameBufferCaps &caps = fb->getCaps(); + + // + // Create a pbuffer to be used as the egl surface + // for that window. + // + if (!win->resizePbuffer(p_width, p_height)) { + delete win; + return NULL; + } + + win->m_width = p_width; + win->m_height = p_height; + + return win; +} + +// +// 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::flushColorBuffer() +{ + if (m_attachedColorBuffer.Ptr() != NULL) { + blitToColorBuffer(); + } +} + +// +// 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; + + // + // resize the window if the attached color buffer is of different + // size + // + unsigned int cbWidth = m_attachedColorBuffer->getWidth(); + unsigned int cbHeight = m_attachedColorBuffer->getHeight(); + + if (cbWidth != m_width || cbHeight != m_height) { + + if (m_pbufWidth && m_pbufHeight) { + // if we use pbuffer, need to resize it + resizePbuffer(cbWidth, cbHeight); + } + + m_width = cbWidth; + m_height = cbHeight; + } +} + +// +// This function is called after the context and eglSurface is already +// bound in the current thread (eglMakeCurrent has been called). +// This function should take actions required on the other surface objects +// when being bind/unbound +// +void WindowSurface::bind(RenderContextPtr p_ctx, SurfaceBindType p_bindType) +{ + if (p_bindType == SURFACE_BIND_READ) { + m_readContext = p_ctx; + } + else if (p_bindType == SURFACE_BIND_DRAW) { + m_drawContext = p_ctx; + } + else if (p_bindType == SURFACE_BIND_READDRAW) { + m_readContext = p_ctx; + m_drawContext = p_ctx; + } + else { + return; // bad param + } + +} + +void WindowSurface::blitToColorBuffer() +{ + if (!m_width && !m_height) return; + + if (m_attachedColorBuffer->getWidth() != m_width || + m_attachedColorBuffer->getHeight() != m_height) { + // XXX: should never happen - how this needs to be handled? + return; + } + + // + // Make the surface current + // + EGLContext prevContext = s_egl.eglGetCurrentContext(); + EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); + EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); + FrameBuffer *fb = FrameBuffer::getFB(); + if (!s_egl.eglMakeCurrent(fb->getDisplay(), m_eglSurface, + m_eglSurface, m_drawContext->getEGLContext())) { + return; + } + + m_attachedColorBuffer->blitFromCurrentReadBuffer(); + + // restore current context/surface + s_egl.eglMakeCurrent(fb->getDisplay(), prevDrawSurf, + prevReadSurf, prevContext); + +} + +bool WindowSurface::resizePbuffer(unsigned int p_width, unsigned int p_height) +{ + if (m_eglSurface && + m_pbufWidth == p_width && + m_pbufHeight == p_height) { + // no need to resize + return true; + } + + FrameBuffer *fb = FrameBuffer::getFB(); + + EGLContext prevContext = s_egl.eglGetCurrentContext(); + EGLSurface prevReadSurf = s_egl.eglGetCurrentSurface(EGL_READ); + EGLSurface prevDrawSurf = s_egl.eglGetCurrentSurface(EGL_DRAW); + EGLSurface prevPbuf = m_eglSurface; + bool needRebindContext = m_eglSurface && + (prevReadSurf == m_eglSurface || + prevDrawSurf == m_eglSurface); + + if (needRebindContext) { + s_egl.eglMakeCurrent(fb->getDisplay(), EGL_NO_SURFACE, + EGL_NO_SURFACE, EGL_NO_CONTEXT); + } + + // + // Destroy previous surface + // + if (m_eglSurface) { + s_egl.eglDestroySurface(fb->getDisplay(), m_eglSurface); + m_eglSurface = NULL; + } + + const FrameBufferCaps &caps = fb->getCaps(); + + // + // Create pbuffer surface. + // + EGLint pbufAttribs[5]; + pbufAttribs[0] = EGL_WIDTH; + pbufAttribs[1] = p_width; + pbufAttribs[2] = EGL_HEIGHT; + pbufAttribs[3] = p_height; + pbufAttribs[4] = EGL_NONE; + + m_eglSurface = s_egl.eglCreatePbufferSurface(fb->getDisplay(), + m_fbconf->getEGLConfig(), + pbufAttribs); + if (m_eglSurface == EGL_NO_SURFACE) { + fprintf(stderr, "Renderer error: failed to create/resize pbuffer!!\n"); + return false; + } + + m_pbufWidth = p_width; + m_pbufHeight = p_height; + + if (needRebindContext) { + s_egl.eglMakeCurrent(fb->getDisplay(), + (prevDrawSurf==prevPbuf) ? m_eglSurface : prevDrawSurf, + (prevReadSurf==prevPbuf) ? m_eglSurface : prevReadSurf, + prevContext); + } + + return true; +} diff --git a/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h b/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h new file mode 100644 index 0000000..1b655c9 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/WindowSurface.h @@ -0,0 +1,71 @@ +/* +* 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. +*/ +#ifndef _LIBRENDER_WINDOWSURFACE_H +#define _LIBRENDER_WINDOWSURFACE_H + +#include "ColorBuffer.h" +#include "RenderContext.h" +#include "FBConfig.h" +#include "SmartPtr.h" +#include "FixedBuffer.h" +#include <EGL/egl.h> +#include <GLES/gl.h> + +enum SurfaceBindType { + SURFACE_BIND_READ, + SURFACE_BIND_DRAW, + SURFACE_BIND_READDRAW +}; + +class WindowSurface +{ +public: + static WindowSurface *create(int p_config, int p_width, int p_height); + ~WindowSurface(); + EGLSurface getEGLSurface() const { return m_eglSurface; } + + void setColorBuffer(ColorBufferPtr p_colorBuffer); + void flushColorBuffer(); + void bind(RenderContextPtr p_ctx, SurfaceBindType p_bindType); + +private: + WindowSurface(); + + void blitToColorBuffer(); // copy pbuffer content with texload and blit + bool resizePbuffer(unsigned int p_width, unsigned int p_height); + +private: + GLuint m_fbObj; // GLES Framebuffer object (when EGLimage is used) + GLuint m_depthRB; + GLuint m_stencilRB; + EGLSurface m_eglSurface; + ColorBufferPtr m_attachedColorBuffer; + RenderContextPtr m_readContext; + RenderContextPtr m_drawContext; + GLuint m_width; + GLuint m_height; + GLuint m_pbufWidth; + GLuint m_pbufHeight; + bool m_useEGLImage; + bool m_useBindToTexture; + FixedBuffer m_xferBuffer; + FixedBuffer m_xUpdateBuf; + const FBConfig *m_fbconf; +}; + +typedef SmartPtr<WindowSurface> WindowSurfacePtr; + +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/egl_proc.h b/emulator/opengl/host/libs/libOpenglRender/egl_proc.h new file mode 100644 index 0000000..01dc4ae --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/egl_proc.h @@ -0,0 +1,68 @@ +/* +* 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. +*/ +#ifndef _EGL_PROC_H +#define _EGL_PROC_H + +#include <EGL/egl.h> +#define EGL_EGLEXT_PROTOTYPES +#include <EGL/eglext.h> + +typedef EGLint (EGLAPIENTRY *eglGetError_t) (); +typedef EGLDisplay (EGLAPIENTRY *eglGetDisplay_t) (EGLNativeDisplayType); +typedef EGLBoolean (EGLAPIENTRY *eglInitialize_t) (EGLDisplay, EGLint*, EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglTerminate_t) (EGLDisplay); +typedef char* (EGLAPIENTRY *eglQueryString_t) (EGLDisplay, EGLint); +typedef EGLBoolean (EGLAPIENTRY *eglGetConfigs_t) (EGLDisplay, EGLConfig*, EGLint, EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglChooseConfig_t) (EGLDisplay, const EGLint*, EGLConfig*, EGLint, EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglGetConfigAttrib_t) (EGLDisplay, EGLConfig, EGLint, EGLint*); +typedef EGLSurface (EGLAPIENTRY *eglCreateWindowSurface_t) (EGLDisplay, EGLConfig, EGLNativeWindowType, const EGLint*); +typedef EGLSurface (EGLAPIENTRY *eglCreatePbufferSurface_t) (EGLDisplay, EGLConfig, const EGLint*); +typedef EGLSurface (EGLAPIENTRY *eglCreatePixmapSurface_t) (EGLDisplay, EGLConfig, EGLNativePixmapType, const EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglDestroySurface_t) (EGLDisplay, EGLSurface); +typedef EGLBoolean (EGLAPIENTRY *eglQuerySurface_t) (EGLDisplay, EGLSurface, EGLint, EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglBindAPI_t) (EGLenum); +typedef EGLenum (* eglQueryAPI_t) (); +typedef EGLBoolean (EGLAPIENTRY *eglWaitClient_t) (); +typedef EGLBoolean (EGLAPIENTRY *eglReleaseThread_t) (); +typedef EGLSurface (EGLAPIENTRY *eglCreatePbufferFromClientBuffer_t) (EGLDisplay, EGLenum, EGLClientBuffer, EGLConfig, const EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglSurfaceAttrib_t) (EGLDisplay, EGLSurface, EGLint, EGLint); +typedef EGLBoolean (EGLAPIENTRY *eglBindTexImage_t) (EGLDisplay, EGLSurface, EGLint); +typedef EGLBoolean (EGLAPIENTRY *eglReleaseTexImage_t) (EGLDisplay, EGLSurface, EGLint); +typedef EGLBoolean (EGLAPIENTRY *eglSwapInterval_t) (EGLDisplay, EGLint); +typedef EGLContext (EGLAPIENTRY *eglCreateContext_t) (EGLDisplay, EGLConfig, EGLContext, const EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglDestroyContext_t) (EGLDisplay, EGLContext); +typedef EGLBoolean (EGLAPIENTRY *eglMakeCurrent_t) (EGLDisplay, EGLSurface, EGLSurface, EGLContext); +typedef EGLContext (EGLAPIENTRY *eglGetCurrentContext_t) (); +typedef EGLSurface (EGLAPIENTRY *eglGetCurrentSurface_t) (EGLint); +typedef EGLDisplay (EGLAPIENTRY *eglGetCurrentDisplay_t) (); +typedef EGLBoolean (EGLAPIENTRY *eglQueryContext_t) (EGLDisplay, EGLContext, EGLint, EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglWaitGL_t) (); +typedef EGLBoolean (EGLAPIENTRY *eglWaitNative_t) (EGLint); +typedef EGLBoolean (EGLAPIENTRY *eglSwapBuffers_t) (EGLDisplay, EGLSurface); +typedef EGLBoolean (EGLAPIENTRY *eglCopyBuffers_t) (EGLDisplay, EGLSurface, EGLNativePixmapType); +typedef __eglMustCastToProperFunctionPointerType (EGLAPIENTRY *eglGetProcAddress_t) (const char*); +typedef EGLBoolean (EGLAPIENTRY *eglLockSurfaceKHR_t) (EGLDisplay, EGLSurface, const EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglUnlockSurfaceKHR_t) (EGLDisplay, EGLSurface); +typedef EGLImageKHR (EGLAPIENTRY *eglCreateImageKHR_t) (EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglDestroyImageKHR_t) (EGLDisplay, EGLImageKHR image); +typedef EGLSyncKHR (EGLAPIENTRY *eglCreateSyncKHR_t) (EGLDisplay, EGLenum, const EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglDestroySyncKHR_t) (EGLDisplay, EGLSyncKHR sync); +typedef EGLint (EGLAPIENTRY *eglClientWaitSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR timeout); +typedef EGLBoolean (EGLAPIENTRY *eglSignalSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLenum); +typedef EGLBoolean (EGLAPIENTRY *eglGetSyncAttribKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLint*); +typedef EGLBoolean (EGLAPIENTRY *eglSetSwapRectangleANDROID_t) (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint); + +#endif // of _EGL_PROC_H diff --git a/emulator/opengl/host/libs/libOpenglRender/gl_proc.h b/emulator/opengl/host/libs/libOpenglRender/gl_proc.h new file mode 100644 index 0000000..465a10d --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/gl_proc.h @@ -0,0 +1,296 @@ +/* +* 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. +*/ +#ifndef _GLES_PROC_H +#define _GLES_PROC_H + +#include <GLES/gl.h> +#define GL_GLEXT_PROTOTYPES +#include <GLES/glext.h> + +typedef void (GL_APIENTRY *glAlphaFunc_t) (GLenum, GLclampf); +typedef void (GL_APIENTRY *glClearColor_t) (GLclampf, GLclampf, GLclampf, GLclampf); +typedef void (GL_APIENTRY *glClearDepthf_t) (GLclampf); +typedef void (GL_APIENTRY *glClipPlanef_t) (GLenum, const GLfloat*); +typedef void (GL_APIENTRY *glColor4f_t) (GLfloat, GLfloat, GLfloat, GLfloat); +typedef void (GL_APIENTRY *glDepthRangef_t) (GLclampf, GLclampf); +typedef void (GL_APIENTRY *glFogf_t) (GLenum, GLfloat); +typedef void (GL_APIENTRY *glFogfv_t) (GLenum, const GLfloat*); +typedef void (GL_APIENTRY *glFrustumf_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +typedef void (GL_APIENTRY *glGetClipPlanef_t) (GLenum, GLfloat); +typedef void (GL_APIENTRY *glGetFloatv_t) (GLenum, GLfloat*); +typedef void (GL_APIENTRY *glGetLightfv_t) (GLenum, GLenum, GLfloat*); +typedef void (GL_APIENTRY *glGetMaterialfv_t) (GLenum, GLenum, GLfloat*); +typedef void (GL_APIENTRY *glGetTexEnvfv_t) (GLenum, GLenum, GLfloat*); +typedef void (GL_APIENTRY *glGetTexParameterfv_t) (GLenum, GLenum, GLfloat*); +typedef void (GL_APIENTRY *glLightModelf_t) (GLenum, GLfloat); +typedef void (GL_APIENTRY *glLightModelfv_t) (GLenum, const GLfloat*); +typedef void (GL_APIENTRY *glLightf_t) (GLenum, GLenum, GLfloat); +typedef void (GL_APIENTRY *glLightfv_t) (GLenum, GLenum, const GLfloat*); +typedef void (GL_APIENTRY *glLineWidth_t) (GLfloat); +typedef void (GL_APIENTRY *glLoadMatrixf_t) (const GLfloat*); +typedef void (GL_APIENTRY *glMaterialf_t) (GLenum, GLenum, GLfloat); +typedef void (GL_APIENTRY *glMaterialfv_t) (GLenum, GLenum, const GLfloat*); +typedef void (GL_APIENTRY *glMultMatrixf_t) (const GLfloat*); +typedef void (GL_APIENTRY *glMultiTexCoord4f_t) (GLenum, GLfloat, GLfloat, GLfloat, GLfloat); +typedef void (GL_APIENTRY *glNormal3f_t) (GLfloat, GLfloat, GLfloat); +typedef void (GL_APIENTRY *glOrthof_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +typedef void (GL_APIENTRY *glPointParameterf_t) (GLenum, GLfloat); +typedef void (GL_APIENTRY *glPointParameterfv_t) (GLenum, const GLfloat*); +typedef void (GL_APIENTRY *glPointSize_t) (GLfloat); +typedef void (GL_APIENTRY *glPolygonOffset_t) (GLfloat, GLfloat); +typedef void (GL_APIENTRY *glRotatef_t) (GLfloat, GLfloat, GLfloat, GLfloat); +typedef void (GL_APIENTRY *glScalef_t) (GLfloat, GLfloat, GLfloat); +typedef void (GL_APIENTRY *glTexEnvf_t) (GLenum, GLenum, GLfloat); +typedef void (GL_APIENTRY *glTexEnvfv_t) (GLenum, GLenum, const GLfloat*); +typedef void (GL_APIENTRY *glTexParameterf_t) (GLenum, GLenum, GLfloat); +typedef void (GL_APIENTRY *glTexParameterfv_t) (GLenum, GLenum, const GLfloat*); +typedef void (GL_APIENTRY *glTranslatef_t) (GLfloat, GLfloat, GLfloat); +typedef void (GL_APIENTRY *glActiveTexture_t) (GLenum); +typedef void (GL_APIENTRY *glAlphaFuncx_t) (GLenum, GLclampx); +typedef void (GL_APIENTRY *glBindBuffer_t) (GLenum, GLuint); +typedef void (GL_APIENTRY *glBindTexture_t) (GLenum, GLuint); +typedef void (GL_APIENTRY *glBlendFunc_t) (GLenum, GLenum); +typedef void (GL_APIENTRY *glBufferData_t) (GLenum, GLsizeiptr, const GLvoid*, GLenum); +typedef void (GL_APIENTRY *glBufferSubData_t) (GLenum, GLintptr, GLsizeiptr, const GLvoid*); +typedef void (GL_APIENTRY *glClear_t) (GLbitfield); +typedef void (GL_APIENTRY *glClearColorx_t) (GLclampx, GLclampx, GLclampx, GLclampx); +typedef void (GL_APIENTRY *glClearDepthx_t) (GLclampx); +typedef void (GL_APIENTRY *glClearStencil_t) (GLint); +typedef void (GL_APIENTRY *glClientActiveTexture_t) (GLenum); +typedef void (GL_APIENTRY *glClipPlanex_t) (GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glColor4ub_t) (GLubyte, GLubyte, GLubyte, GLubyte); +typedef void (GL_APIENTRY *glColor4x_t) (GLfixed, GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glColorMask_t) (GLboolean, GLboolean, GLboolean, GLboolean); +typedef void (GL_APIENTRY *glColorPointer_t) (GLint, GLenum, GLsizei, const GLvoid*); +typedef void (GL_APIENTRY *glCompressedTexImage2D_t) (GLenum, GLint, GLenum, GLsizei, GLsizei, GLint, GLsizei, const GLvoid*); +typedef void (GL_APIENTRY *glCompressedTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLsizei, const GLvoid*); +typedef void (GL_APIENTRY *glCopyTexImage2D_t) (GLenum, GLint, GLenum, GLint, GLint, GLsizei, GLsizei, GLint); +typedef void (GL_APIENTRY *glCopyTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLint, GLint, GLsizei, GLsizei); +typedef void (GL_APIENTRY *glCullFace_t) (GLenum); +typedef void (GL_APIENTRY *glDeleteBuffers_t) (GLsizei, const GLuint*); +typedef void (GL_APIENTRY *glDeleteTextures_t) (GLsizei, const GLuint*); +typedef void (GL_APIENTRY *glDepthFunc_t) (GLenum); +typedef void (GL_APIENTRY *glDepthMask_t) (GLboolean); +typedef void (GL_APIENTRY *glDepthRangex_t) (GLclampx, GLclampx); +typedef void (GL_APIENTRY *glDisable_t) (GLenum); +typedef void (GL_APIENTRY *glDisableClientState_t) (GLenum); +typedef void (GL_APIENTRY *glDrawArrays_t) (GLenum, GLint, GLsizei); +typedef void (GL_APIENTRY *glDrawElements_t) (GLenum, GLsizei, GLenum, const GLvoid*); +typedef void (GL_APIENTRY *glEnable_t) (GLenum); +typedef void (GL_APIENTRY *glEnableClientState_t) (GLenum); +typedef void (GL_APIENTRY *glFinish_t) (); +typedef void (GL_APIENTRY *glFlush_t) (); +typedef void (GL_APIENTRY *glFogx_t) (GLenum, GLfixed); +typedef void (GL_APIENTRY *glFogxv_t) (GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glFrontFace_t) (GLenum); +typedef void (GL_APIENTRY *glFrustumx_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glGetBooleanv_t) (GLenum, GLboolean*); +typedef void (GL_APIENTRY *glGetBufferParameteriv_t) (GLenum, GLenum, GLint*); +typedef void (GL_APIENTRY *glGetClipPlanex_t) (GLenum, GLfixed); +typedef void (GL_APIENTRY *glGenBuffers_t) (GLsizei, GLuint*); +typedef void (GL_APIENTRY *glGenTextures_t) (GLsizei, GLuint*); +typedef GLenum (GL_APIENTRY *glGetError_t) (); +typedef void (GL_APIENTRY *glGetFixedv_t) (GLenum, GLfixed*); +typedef void (GL_APIENTRY *glGetIntegerv_t) (GLenum, GLint*); +typedef void (GL_APIENTRY *glGetLightxv_t) (GLenum, GLenum, GLfixed*); +typedef void (GL_APIENTRY *glGetMaterialxv_t) (GLenum, GLenum, GLfixed*); +typedef void (GL_APIENTRY *glGetPointerv_t) (GLenum, GLvoid*); +typedef const GLubyte* (GL_APIENTRY *glGetString_t) (GLenum); +typedef void (GL_APIENTRY *glGetTexEnviv_t) (GLenum, GLenum, GLint*); +typedef void (GL_APIENTRY *glGetTexEnvxv_t) (GLenum, GLenum, GLfixed*); +typedef void (GL_APIENTRY *glGetTexParameteriv_t) (GLenum, GLenum, GLint*); +typedef void (GL_APIENTRY *glGetTexParameterxv_t) (GLenum, GLenum, GLfixed*); +typedef void (GL_APIENTRY *glHint_t) (GLenum, GLenum); +typedef GLboolean (GL_APIENTRY *glIsBuffer_t) (GLuint); +typedef GLboolean (GL_APIENTRY *glIsEnabled_t) (GLenum); +typedef GLboolean (GL_APIENTRY *glIsTexture_t) (GLuint); +typedef void (GL_APIENTRY *glLightModelx_t) (GLenum, GLfixed); +typedef void (GL_APIENTRY *glLightModelxv_t) (GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glLightx_t) (GLenum, GLenum, GLfixed); +typedef void (GL_APIENTRY *glLightxv_t) (GLenum, GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glLineWidthx_t) (GLfixed); +typedef void (GL_APIENTRY *glLoadIdentity_t) (); +typedef void (GL_APIENTRY *glLoadMatrixx_t) (const GLfixed*); +typedef void (GL_APIENTRY *glLogicOp_t) (GLenum); +typedef void (GL_APIENTRY *glMaterialx_t) (GLenum, GLenum, GLfixed); +typedef void (GL_APIENTRY *glMaterialxv_t) (GLenum, GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glMatrixMode_t) (GLenum); +typedef void (GL_APIENTRY *glMultMatrixx_t) (const GLfixed*); +typedef void (GL_APIENTRY *glMultiTexCoord4x_t) (GLenum, GLfixed, GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glNormal3x_t) (GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glNormalPointer_t) (GLenum, GLsizei, const GLvoid*); +typedef void (GL_APIENTRY *glOrthox_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glPixelStorei_t) (GLenum, GLint); +typedef void (GL_APIENTRY *glPointParameterx_t) (GLenum, GLfixed); +typedef void (GL_APIENTRY *glPointParameterxv_t) (GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glPointSizex_t) (GLfixed); +typedef void (GL_APIENTRY *glPolygonOffsetx_t) (GLfixed, GLfixed); +typedef void (GL_APIENTRY *glPopMatrix_t) (); +typedef void (GL_APIENTRY *glPushMatrix_t) (); +typedef void (GL_APIENTRY *glReadPixels_t) (GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, GLvoid*); +typedef void (GL_APIENTRY *glRotatex_t) (GLfixed, GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glSampleCoverage_t) (GLclampf, GLboolean); +typedef void (GL_APIENTRY *glSampleCoveragex_t) (GLclampx, GLboolean); +typedef void (GL_APIENTRY *glScalex_t) (GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glScissor_t) (GLint, GLint, GLsizei, GLsizei); +typedef void (GL_APIENTRY *glShadeModel_t) (GLenum); +typedef void (GL_APIENTRY *glStencilFunc_t) (GLenum, GLint, GLuint); +typedef void (GL_APIENTRY *glStencilMask_t) (GLuint); +typedef void (GL_APIENTRY *glStencilOp_t) (GLenum, GLenum, GLenum); +typedef void (GL_APIENTRY *glTexCoordPointer_t) (GLint, GLenum, GLsizei, const GLvoid*); +typedef void (GL_APIENTRY *glTexEnvi_t) (GLenum, GLenum, GLint); +typedef void (GL_APIENTRY *glTexEnvx_t) (GLenum, GLenum, GLfixed); +typedef void (GL_APIENTRY *glTexEnviv_t) (GLenum, GLenum, const GLint*); +typedef void (GL_APIENTRY *glTexEnvxv_t) (GLenum, GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glTexImage2D_t) (GLenum, GLint, GLint, GLsizei, GLsizei, GLint, GLenum, GLenum, const GLvoid*); +typedef void (GL_APIENTRY *glTexParameteri_t) (GLenum, GLenum, GLint); +typedef void (GL_APIENTRY *glTexParameterx_t) (GLenum, GLenum, GLfixed); +typedef void (GL_APIENTRY *glTexParameteriv_t) (GLenum, GLenum, const GLint*); +typedef void (GL_APIENTRY *glTexParameterxv_t) (GLenum, GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glTexSubImage2D_t) (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid*); +typedef void (GL_APIENTRY *glTranslatex_t) (GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glVertexPointer_t) (GLint, GLenum, GLsizei, const GLvoid*); +typedef void (GL_APIENTRY *glViewport_t) (GLint, GLint, GLsizei, GLsizei); +typedef void (GL_APIENTRY *glPointSizePointerOES_t) (GLenum, GLsizei, const GLvoid*); +typedef void (GL_APIENTRY *glBlendEquationSeparateOES_t) (GLenum, GLenum); +typedef void (GL_APIENTRY *glBlendFuncSeparateOES_t) (GLenum, GLenum, GLenum, GLenum); +typedef void (GL_APIENTRY *glBlendEquationOES_t) (GLenum); +typedef void (GL_APIENTRY *glDrawTexsOES_t) (GLshort, GLshort, GLshort, GLshort, GLshort); +typedef void (GL_APIENTRY *glDrawTexiOES_t) (GLint, GLint, GLint, GLint, GLint); +typedef void (GL_APIENTRY *glDrawTexxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glDrawTexsvOES_t) (const GLshort*); +typedef void (GL_APIENTRY *glDrawTexivOES_t) (const GLint*); +typedef void (GL_APIENTRY *glDrawTexxvOES_t) (const GLfixed*); +typedef void (GL_APIENTRY *glDrawTexfOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +typedef void (GL_APIENTRY *glDrawTexfvOES_t) (const GLfloat*); +typedef void (GL_APIENTRY *glEGLImageTargetTexture2DOES_t) (GLenum, GLeglImageOES); +typedef void (GL_APIENTRY *glEGLImageTargetRenderbufferStorageOES_t) (GLenum, GLeglImageOES); +typedef void (GL_APIENTRY *glAlphaFuncxOES_t) (GLenum, GLclampx); +typedef void (GL_APIENTRY *glClearColorxOES_t) (GLclampx, GLclampx, GLclampx, GLclampx); +typedef void (GL_APIENTRY *glClearDepthxOES_t) (GLclampx); +typedef void (GL_APIENTRY *glClipPlanexOES_t) (GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glColor4xOES_t) (GLfixed, GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glDepthRangexOES_t) (GLclampx, GLclampx); +typedef void (GL_APIENTRY *glFogxOES_t) (GLenum, GLfixed); +typedef void (GL_APIENTRY *glFogxvOES_t) (GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glFrustumxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glGetClipPlanexOES_t) (GLenum, GLfixed); +typedef void (GL_APIENTRY *glGetFixedvOES_t) (GLenum, GLfixed*); +typedef void (GL_APIENTRY *glGetLightxvOES_t) (GLenum, GLenum, GLfixed*); +typedef void (GL_APIENTRY *glGetMaterialxvOES_t) (GLenum, GLenum, GLfixed*); +typedef void (GL_APIENTRY *glGetTexEnvxvOES_t) (GLenum, GLenum, GLfixed*); +typedef void (GL_APIENTRY *glGetTexParameterxvOES_t) (GLenum, GLenum, GLfixed*); +typedef void (GL_APIENTRY *glLightModelxOES_t) (GLenum, GLfixed); +typedef void (GL_APIENTRY *glLightModelxvOES_t) (GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glLightxOES_t) (GLenum, GLenum, GLfixed); +typedef void (GL_APIENTRY *glLightxvOES_t) (GLenum, GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glLineWidthxOES_t) (GLfixed); +typedef void (GL_APIENTRY *glLoadMatrixxOES_t) (const GLfixed*); +typedef void (GL_APIENTRY *glMaterialxOES_t) (GLenum, GLenum, GLfixed); +typedef void (GL_APIENTRY *glMaterialxvOES_t) (GLenum, GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glMultMatrixxOES_t) (const GLfixed*); +typedef void (GL_APIENTRY *glMultiTexCoord4xOES_t) (GLenum, GLfixed, GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glNormal3xOES_t) (GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glOrthoxOES_t) (GLfixed, GLfixed, GLfixed, GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glPointParameterxOES_t) (GLenum, GLfixed); +typedef void (GL_APIENTRY *glPointParameterxvOES_t) (GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glPointSizexOES_t) (GLfixed); +typedef void (GL_APIENTRY *glPolygonOffsetxOES_t) (GLfixed, GLfixed); +typedef void (GL_APIENTRY *glRotatexOES_t) (GLfixed, GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glSampleCoveragexOES_t) (GLclampx, GLboolean); +typedef void (GL_APIENTRY *glScalexOES_t) (GLfixed, GLfixed, GLfixed); +typedef void (GL_APIENTRY *glTexEnvxOES_t) (GLenum, GLenum, GLfixed); +typedef void (GL_APIENTRY *glTexEnvxvOES_t) (GLenum, GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glTexParameterxOES_t) (GLenum, GLenum, GLfixed); +typedef void (GL_APIENTRY *glTexParameterxvOES_t) (GLenum, GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glTranslatexOES_t) (GLfixed, GLfixed, GLfixed); +typedef GLboolean (GL_APIENTRY *glIsRenderbufferOES_t) (GLuint); +typedef void (GL_APIENTRY *glBindRenderbufferOES_t) (GLenum, GLuint); +typedef void (GL_APIENTRY *glDeleteRenderbuffersOES_t) (GLsizei, const GLuint*); +typedef void (GL_APIENTRY *glGenRenderbuffersOES_t) (GLsizei, GLuint*); +typedef void (GL_APIENTRY *glRenderbufferStorageOES_t) (GLenum, GLenum, GLsizei, GLsizei); +typedef void (GL_APIENTRY *glGetRenderbufferParameterivOES_t) (GLenum, GLenum, GLint*); +typedef GLboolean (GL_APIENTRY *glIsFramebufferOES_t) (GLuint); +typedef void (GL_APIENTRY *glBindFramebufferOES_t) (GLenum, GLuint); +typedef void (GL_APIENTRY *glDeleteFramebuffersOES_t) (GLsizei, const GLuint*); +typedef void (GL_APIENTRY *glGenFramebuffersOES_t) (GLsizei, GLuint*); +typedef GLenum (GL_APIENTRY *glCheckFramebufferStatusOES_t) (GLenum); +typedef void (GL_APIENTRY *glFramebufferRenderbufferOES_t) (GLenum, GLenum, GLenum, GLuint); +typedef void (GL_APIENTRY *glFramebufferTexture2DOES_t) (GLenum, GLenum, GLenum, GLuint, GLint); +typedef void (GL_APIENTRY *glGetFramebufferAttachmentParameterivOES_t) (GLenum, GLenum, GLenum, GLint*); +typedef void (GL_APIENTRY *glGenerateMipmapOES_t) (GLenum); +typedef void* (GL_APIENTRY *glMapBufferOES_t) (GLenum, GLenum); +typedef GLboolean (GL_APIENTRY *glUnmapBufferOES_t) (GLenum); +typedef void (GL_APIENTRY *glGetBufferPointervOES_t) (GLenum, GLenum, GLvoid*); +typedef void (GL_APIENTRY *glCurrentPaletteMatrixOES_t) (GLuint); +typedef void (GL_APIENTRY *glLoadPaletteFromModelViewMatrixOES_t) (); +typedef void (GL_APIENTRY *glMatrixIndexPointerOES_t) (GLint, GLenum, GLsizei, const GLvoid*); +typedef void (GL_APIENTRY *glWeightPointerOES_t) (GLint, GLenum, GLsizei, const GLvoid*); +typedef GLbitfield (GL_APIENTRY *glQueryMatrixxOES_t) (GLfixed, GLint); +typedef void (GL_APIENTRY *glDepthRangefOES_t) (GLclampf, GLclampf); +typedef void (GL_APIENTRY *glFrustumfOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +typedef void (GL_APIENTRY *glOrthofOES_t) (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat, GLfloat); +typedef void (GL_APIENTRY *glClipPlanefOES_t) (GLenum, const GLfloat*); +typedef void (GL_APIENTRY *glGetClipPlanefOES_t) (GLenum, GLfloat); +typedef void (GL_APIENTRY *glClearDepthfOES_t) (GLclampf); +typedef void (GL_APIENTRY *glTexGenfOES_t) (GLenum, GLenum, GLfloat); +typedef void (GL_APIENTRY *glTexGenfvOES_t) (GLenum, GLenum, const GLfloat*); +typedef void (GL_APIENTRY *glTexGeniOES_t) (GLenum, GLenum, GLint); +typedef void (GL_APIENTRY *glTexGenivOES_t) (GLenum, GLenum, const GLint*); +typedef void (GL_APIENTRY *glTexGenxOES_t) (GLenum, GLenum, GLfixed); +typedef void (GL_APIENTRY *glTexGenxvOES_t) (GLenum, GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glGetTexGenfvOES_t) (GLenum, GLenum, GLfloat*); +typedef void (GL_APIENTRY *glGetTexGenivOES_t) (GLenum, GLenum, GLint*); +typedef void (GL_APIENTRY *glGetTexGenxvOES_t) (GLenum, GLenum, GLfixed*); +typedef void (GL_APIENTRY *glBindVertexArrayOES_t) (GLuint); +typedef void (GL_APIENTRY *glDeleteVertexArraysOES_t) (GLsizei, const GLuint*); +typedef void (GL_APIENTRY *glGenVertexArraysOES_t) (GLsizei, GLuint*); +typedef GLboolean (GL_APIENTRY *glIsVertexArrayOES_t) (GLuint); +typedef void (GL_APIENTRY *glDiscardFramebufferEXT_t) (GLenum, GLsizei, const GLenum*); +typedef void (GL_APIENTRY *glMultiDrawArraysEXT_t) (GLenum, GLint*, GLsizei*, GLsizei); +typedef void (GL_APIENTRY *glMultiDrawElementsEXT_t) (GLenum, const GLsizei*, GLenum, const GLvoid**, GLsizei); +typedef void (GL_APIENTRY *glClipPlanefIMG_t) (GLenum, const GLfloat*); +typedef void (GL_APIENTRY *glClipPlanexIMG_t) (GLenum, const GLfixed*); +typedef void (GL_APIENTRY *glRenderbufferStorageMultisampleIMG_t) (GLenum, GLsizei, GLenum, GLsizei, GLsizei); +typedef void (GL_APIENTRY *glFramebufferTexture2DMultisampleIMG_t) (GLenum, GLenum, GLenum, GLuint, GLint, GLsizei); +typedef void (GL_APIENTRY *glDeleteFencesNV_t) (GLsizei, const GLuint*); +typedef void (GL_APIENTRY *glGenFencesNV_t) (GLsizei, GLuint*); +typedef GLboolean (GL_APIENTRY *glIsFenceNV_t) (GLuint); +typedef GLboolean (GL_APIENTRY *glTestFenceNV_t) (GLuint); +typedef void (GL_APIENTRY *glGetFenceivNV_t) (GLuint, GLenum, GLint*); +typedef void (GL_APIENTRY *glFinishFenceNV_t) (GLuint); +typedef void (GL_APIENTRY *glSetFenceNV_t) (GLuint, GLenum); +typedef void (GL_APIENTRY *glGetDriverControlsQCOM_t) (GLint*, GLsizei, GLuint*); +typedef void (GL_APIENTRY *glGetDriverControlStringQCOM_t) (GLuint, GLsizei, GLsizei*, GLchar*); +typedef void (GL_APIENTRY *glEnableDriverControlQCOM_t) (GLuint); +typedef void (GL_APIENTRY *glDisableDriverControlQCOM_t) (GLuint); +typedef void (GL_APIENTRY *glExtGetTexturesQCOM_t) (GLuint*, GLint, GLint*); +typedef void (GL_APIENTRY *glExtGetBuffersQCOM_t) (GLuint*, GLint, GLint*); +typedef void (GL_APIENTRY *glExtGetRenderbuffersQCOM_t) (GLuint*, GLint, GLint*); +typedef void (GL_APIENTRY *glExtGetFramebuffersQCOM_t) (GLuint*, GLint, GLint*); +typedef void (GL_APIENTRY *glExtGetTexLevelParameterivQCOM_t) (GLuint, GLenum, GLint, GLenum, GLint*); +typedef void (GL_APIENTRY *glExtTexObjectStateOverrideiQCOM_t) (GLenum, GLenum, GLint); +typedef void (GL_APIENTRY *glExtGetTexSubImageQCOM_t) (GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei, GLenum, GLenum, GLvoid*); +typedef void (GL_APIENTRY *glExtGetBufferPointervQCOM_t) (GLenum, GLvoid*); +typedef void (GL_APIENTRY *glExtGetShadersQCOM_t) (GLuint*, GLint, GLint*); +typedef void (GL_APIENTRY *glExtGetProgramsQCOM_t) (GLuint*, GLint, GLint*); +typedef GLboolean (GL_APIENTRY *glExtIsProgramBinaryQCOM_t) (GLuint); +typedef void (GL_APIENTRY *glExtGetProgramBinarySourceQCOM_t) (GLuint, GLenum, GLchar*, GLint*); +typedef void (GL_APIENTRY *glStartTilingQCOM_t) (GLuint, GLuint, GLuint, GLuint, GLbitfield); +typedef void (GL_APIENTRY *glEndTilingQCOM_t) (GLbitfield); + + +#endif diff --git a/emulator/opengl/host/libs/libOpenglRender/render_api.cpp b/emulator/opengl/host/libs/libOpenglRender/render_api.cpp new file mode 100644 index 0000000..c8d3e06 --- /dev/null +++ b/emulator/opengl/host/libs/libOpenglRender/render_api.cpp @@ -0,0 +1,359 @@ +/* +* 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 "libOpenglRender/render_api.h" +#include "IOStream.h" +#include "FrameBuffer.h" +#include "RenderServer.h" +#include "osProcess.h" +#include "TimeUtils.h" + +#include "TcpStream.h" +#ifdef _WIN32 +#include "Win32PipeStream.h" +#else +#include "UnixStream.h" +#endif + +#include "EGLDispatch.h" +#include "GLDispatch.h" +#include "GL2Dispatch.h" + +static osUtils::childProcess *s_renderProc = NULL; +static RenderServer *s_renderThread = NULL; +static int s_renderPort = 0; + +static IOStream *createRenderThread(int p_stream_buffer_size, + unsigned int clientFlags); + +// +// For now run the renderer as a thread inside the calling +// process instead as running it in a separate process for all +// platforms. +// at the future we want it to run as a seperate process except for +// Mac OS X since it is imposibble on this platform to make one process +// render to a window created by another process. +// +//#ifdef __APPLE__ +#define RENDER_API_USE_THREAD +//#endif + +bool initLibrary(void) +{ + // + // Load EGL Plugin + // + if (!init_egl_dispatch()) { + // Failed to load EGL + printf("Failed to init_egl_dispatch\n"); + return false; + } + + // + // Load GLES Plugin + // + if (!init_gl_dispatch()) { + // Failed to load GLES + ERR("Failed to init_gl_dispatch\n"); + return false; + } + + /* failure to init the GLES2 dispatch table is not fatal */ + init_gl2_dispatch(); + + return true; +} + +bool initOpenGLRenderer(int width, int height, int portNum, + OnPostFn onPost, void* onPostContext) +{ + + // + // Fail if renderer is already initialized + // + if (s_renderProc || s_renderThread) { + return false; + } + + s_renderPort = portNum; + +#ifdef RENDER_API_USE_THREAD // should be defined for mac + // + // initialize the renderer and listen to connections + // on a thread in the current process. + // + bool inited = FrameBuffer::initialize(width, height, onPost, onPostContext); + if (!inited) { + return false; + } + + s_renderThread = RenderServer::create(portNum); + if (!s_renderThread) { + return false; + } + + s_renderThread->start(); + +#else + if (onPost) { + // onPost callback not supported with separate renderer process. + // + // If we ever revive separate process support, we could make the choice + // between thread and process at runtime instead of compile time, and + // choose the thread path if an onPost callback is requested. Or, the + // callback could be supported with a separate process using shmem or + // other IPC mechanism. + return false; + } + + // + // Launch emulator_renderer + // + char cmdLine[128]; + snprintf(cmdLine, 128, "emulator_renderer -windowid %d -port %d -x %d -y %d -width %d -height %d", + (int)window, portNum, x, y, width, height); + + s_renderProc = osUtils::childProcess::create(cmdLine, NULL); + if (!s_renderProc) { + return false; + } + + // + // try to connect to the renderer in order to check it + // was successfully initialized. + // + int nTrys = 0; + IOStream *dummy = NULL; + do { + ++nTrys; + + // + // Wait a bit to make the renderer process a chance to be + // initialized. + // On Windows we need during this time to handle windows + // events since the renderer generates a subwindow of this + // process's window, we need to be responsive for windows + // during this time to let the renderer generates this subwindow. + // +#ifndef _WIN32 + TimeSleepMS(300); +#else + long long t0 = GetCurrentTimeMS(); + while( (GetCurrentTimeMS() - t0) < 300 ) { + MSG msg; + int n = 0; + while( PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ) + { + n++; + TranslateMessage( &msg ); + DispatchMessage( &msg ); + } + if (n == 0) TimeSleepMS(10); + } +#endif + + dummy = createRenderThread(8, 0); + + if (!dummy) { + // stop if the process is no longer running + if (!osUtils::isProcessRunning(s_renderProc->getPID())) { + break; + } + } + } while(!dummy && nTrys < 10); // give up after 3 seconds, XXX: ??? + + if (!dummy) { + // + // Failed - make sure the process is killed + // + osUtils::KillProcess(s_renderProc->getPID(), true); + delete s_renderProc; + s_renderProc = NULL; + return false; + } + + // destroy the dummy connection + delete dummy; +#endif + + return true; +} + +bool stopOpenGLRenderer() +{ + 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) { + // + // wait for the process to exit + // + int exitStatus; + ret = s_renderProc->wait(&exitStatus); + + delete s_renderProc; + s_renderProc = NULL; + } + else if (s_renderThread) { + + // wait for the thread to exit + int status; + ret = s_renderThread->wait(&status); + + delete s_renderThread; + s_renderThread = NULL; + } + + return ret; +} + +bool createOpenGLSubwindow(FBNativeWindowType window, + int x, int y, int width, int height, float zRot) +{ + if (s_renderThread) { + return FrameBuffer::setupSubWindow(window,x,y,width,height, zRot); + } + else { + // + // XXX: should be implemented by sending the renderer process + // a request + ERR("%s not implemented for separate renderer process !!!\n", + __FUNCTION__); + } + return false; +} + +bool destroyOpenGLSubwindow() +{ + if (s_renderThread) { + return FrameBuffer::removeSubWindow(); + } + else { + // + // XXX: should be implemented by sending the renderer process + // a request + ERR("%s not implemented for separate renderer process !!!\n", + __FUNCTION__); + return false; + } +} + +void setOpenGLDisplayRotation(float zRot) +{ + if (s_renderThread) { + FrameBuffer *fb = FrameBuffer::getFB(); + if (fb) { + fb->setDisplayRotation(zRot); + } + } + else { + // + // XXX: should be implemented by sending the renderer process + // a request + ERR("%s not implemented for separate renderer process !!!\n", + __FUNCTION__); + } +} + +void repaintOpenGLDisplay() +{ + if (s_renderThread) { + FrameBuffer *fb = FrameBuffer::getFB(); + if (fb) { + fb->repost(); + } + } + else { + // + // XXX: should be implemented by sending the renderer process + // a request + ERR("%s not implemented for separate renderer process !!!\n", + __FUNCTION__); + } +} + + +/* NOTE: For now, always use TCP mode by default, until the emulator + * has been updated to support Unix and Win32 pipes + */ +#define DEFAULT_STREAM_MODE STREAM_MODE_TCP + +int gRendererStreamMode = DEFAULT_STREAM_MODE; + +IOStream *createRenderThread(int p_stream_buffer_size, unsigned int clientFlags) +{ + SocketStream* stream = NULL; + + if (gRendererStreamMode == STREAM_MODE_TCP) { + stream = new TcpStream(p_stream_buffer_size); + } else { +#ifdef _WIN32 + stream = new Win32PipeStream(p_stream_buffer_size); +#else /* !_WIN32 */ + stream = new UnixStream(p_stream_buffer_size); +#endif + } + + if (!stream) { + ERR("createRenderThread failed to create stream\n"); + return NULL; + } + if (stream->connect(s_renderPort) < 0) { + ERR("createRenderThread failed to connect\n"); + delete stream; + 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; +} + +int +setStreamMode(int mode) +{ + switch (mode) { + case STREAM_MODE_DEFAULT: + mode = DEFAULT_STREAM_MODE; + break; + + case STREAM_MODE_TCP: + break; + +#ifndef _WIN32 + case STREAM_MODE_UNIX: + break; +#else /* _WIN32 */ + case STREAM_MODE_PIPE: + break; +#endif /* _WIN32 */ + default: + // Invalid stream mode + return -1; + } + gRendererStreamMode = mode; + return 0; +} |