diff options
author | Jesse Hall <jessehall@google.com> | 2012-04-16 12:49:39 -0700 |
---|---|---|
committer | Jesse Hall <jessehall@google.com> | 2012-04-16 15:54:18 -0700 |
commit | ce6c3389061fb9fcdefc94fab2044a8e11600b52 (patch) | |
tree | fedd1a11cbd21ec14bf00be83b8712054f8c5506 /emulator/opengl/host/libs/libOpenglRender | |
parent | ad0111a77b0f0908cc945dc6e8e8949b75cb8886 (diff) | |
download | sdk-ce6c3389061fb9fcdefc94fab2044a8e11600b52.zip sdk-ce6c3389061fb9fcdefc94fab2044a8e11600b52.tar.gz sdk-ce6c3389061fb9fcdefc94fab2044a8e11600b52.tar.bz2 |
Move emulator GLES from development.git to sdk.git
The emulator GLES support has two interfaces: a host shared library
interface used by QEMU, and a protocol between the platform and the
host. The host library interface is not versioned; QEMU and the GLES
renderer must match. The protocol on the other hand must be backwards
compatible: a new GLES renderer must support an older platform image.
Thus for branching purposes it makes more sense to put the GLES
renderer in sdk.git, which is branched along with qemu.git for SDK
releases. Platform images will be built against the protocol version
in the platform branch of sdk.git.
Change-Id: I2c3bce627ecfd0a4b3e688d1839fe10755a21e58
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; +} |