diff --git a/tools/emulator/opengl/host/include/libOpenglRender/render_api.h b/tools/emulator/opengl/host/include/libOpenglRender/render_api.h index 7ad1ae426..26b843b59 100644 --- a/tools/emulator/opengl/host/include/libOpenglRender/render_api.h +++ b/tools/emulator/opengl/host/include/libOpenglRender/render_api.h @@ -31,6 +31,10 @@ typedef HWND FBNativeWindowType; typedef Window FBNativeWindowType; +#elif defined(__APPLE__) + +typedef void* FBNativeWindowType; + #else #warning "Unsupported platform" #endif diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/Android.mk b/tools/emulator/opengl/host/libs/libOpenglRender/Android.mk index 3f69f63d2..53ff2a0b4 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/Android.mk +++ b/tools/emulator/opengl/host/libs/libOpenglRender/Android.mk @@ -7,7 +7,24 @@ $(call emugl-begin-host-shared-library,libOpenglRender) $(call emugl-import,libGLESv1_dec libGLESv2_dec lib_renderControl_dec libOpenglCodecCommon libOpenglOsUtils) +OS_SRCS:= + +ifeq ($(HOST_OS),linux) + OS_SRCS = NativeLinuxSubWindow.cpp + LOCAL_LDLIBS += -lX11 +endif + +ifeq ($(HOST_OS),darwin) + OS_SRCS = NativeMacSubWindow.m + LOCAL_LDLIBS += -Wl,-framework,AppKit +endif + +ifeq ($(HOST_OS),windows) + OS_SRCS = NativeWindowsSubWindow.cpp +endif + LOCAL_SRC_FILES := \ + $(OS_SRCS) \ render_api.cpp \ ColorBuffer.cpp \ EGLDispatch.cpp \ diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp index d5f00ce9b..81007424c 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ #include "FrameBuffer.h" +#include "NativeSubWindow.h" #include "FBConfig.h" #include "EGLDispatch.h" #include "GLDispatch.h" @@ -84,6 +85,16 @@ static const char *getGLES2ExtensionString(EGLDisplay p_dpy, } #endif +void FrameBuffer::finalize(){ + if(s_theFrameBuffer){ + s_egl.eglMakeCurrent(s_theFrameBuffer->m_eglDisplay, NULL, NULL, NULL); + s_egl.eglDestroySurface(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_eglSurface); + s_egl.eglDestroyContext(s_theFrameBuffer->m_eglDisplay,s_theFrameBuffer->m_eglContext); + delete s_theFrameBuffer; + s_theFrameBuffer = NULL; + } +} + bool FrameBuffer::initialize(FBNativeWindowType p_window, int p_x, int p_y, int p_width, int p_height) @@ -197,16 +208,16 @@ bool FrameBuffer::initialize(FBNativeWindowType p_window, return false; } -#if defined(__linux__) || defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) + EGLNativeDisplayType dpy; + fb->m_subWin = createSubWindow(p_window,&fb->m_subWinDisplay,p_x,p_y,p_width,p_height); fb->m_eglSurface = s_egl.eglCreateWindowSurface(fb->m_eglDisplay, eglConfig, - (EGLNativeWindowType)p_window, + fb->m_subWin, NULL); if (fb->m_eglSurface == EGL_NO_SURFACE) { ERR("Failed to create surface\n"); delete fb; return false; } -#endif GLint glContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 1, @@ -333,7 +344,9 @@ FrameBuffer::FrameBuffer(int p_x, int p_y, int p_width, int p_height) : m_eglContext(EGL_NO_CONTEXT), m_prevContext(EGL_NO_CONTEXT), m_prevReadSurf(EGL_NO_SURFACE), - m_prevDrawSurf(EGL_NO_SURFACE) + m_prevDrawSurf(EGL_NO_SURFACE), + m_subWin(NULL), + m_subWinDisplay(NULL) { } diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h index 128d73f60..acc2ba3d1 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h +++ b/tools/emulator/opengl/host/libs/libOpenglRender/FrameBuffer.h @@ -51,6 +51,7 @@ public: static bool initialize(FBNativeWindowType p_window, int x, int y, int width, int height); + static void finalize(); static FrameBuffer *getFB() { return s_theFrameBuffer; } const FrameBufferCaps &getCaps() const { return m_caps; } @@ -107,5 +108,7 @@ private: EGLContext m_prevContext; EGLSurface m_prevReadSurf; EGLSurface m_prevDrawSurf; + EGLNativeWindowType m_subWin; + EGLNativeDisplayType m_subWinDisplay; }; #endif diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/NativeLinuxSubWindow.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/NativeLinuxSubWindow.cpp new file mode 100644 index 000000000..6e2636ed2 --- /dev/null +++ b/tools/emulator/opengl/host/libs/libOpenglRender/NativeLinuxSubWindow.cpp @@ -0,0 +1,31 @@ +/* +* 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" + + +EGLNativeWindowType createSubWindow(FBNativeWindowType p_window, + EGLNativeDisplayType* display_out, + int x, int y,int width, int height){ + *display_out = XOpenDisplay(NULL); + Window win = XCreateWindow(*display_out,p_window,x,y, width,height,0,CopyFromParent,CopyFromParent,CopyFromParent,0,NULL); + XMapWindow(*display_out,win); + XSync(*display_out,False); + return win; +} + +void destroySubWindow(EGLNativeDisplayType dis,EGLNativeWindowType win){ + XCloseDisplay(dis); +} diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/NativeMacSubWindow.m b/tools/emulator/opengl/host/libs/libOpenglRender/NativeMacSubWindow.m new file mode 100644 index 000000000..9ed3ae685 --- /dev/null +++ b/tools/emulator/opengl/host/libs/libOpenglRender/NativeMacSubWindow.m @@ -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. +*/ +#include "NativeSubWindow.h" +#include + + +EGLNativeWindowType createSubWindow(FBNativeWindowType p_window, + EGLNativeDisplayType* display_out, + int x, int y,int width, int height){ + NSRect contentRect = NSMakeRect(x, y, width, height); + NSView *glView = [[NSView alloc] initWithFrame:contentRect]; + if (glView) { + NSWindow *win = (NSWindow *)p_window; + [[win contentView] addSubview:glView]; + [win makeKeyAndOrderFront:nil]; + } + return (EGLNativeWindowType)glView; +} + +void destroySubWindow(EGLNativeDisplayType dis,EGLNativeWindowType win){ + if(win){ + delete win; + } +} diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/NativeSubWindow.h b/tools/emulator/opengl/host/libs/libOpenglRender/NativeSubWindow.h new file mode 100644 index 000000000..da94e5e26 --- /dev/null +++ b/tools/emulator/opengl/host/libs/libOpenglRender/NativeSubWindow.h @@ -0,0 +1,29 @@ +/* +* 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 +#include "libOpenglRender/render_api.h" + +EGLNativeWindowType createSubWindow(FBNativeWindowType p_window, + EGLNativeDisplayType* display_out, + int x, int y,int width, int height); + + +void destroySubWindow(EGLNativeDisplayType dis,EGLNativeWindowType win); + +#endif diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/NativeWindowsSubWindow.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/NativeWindowsSubWindow.cpp new file mode 100644 index 000000000..4ff3943d3 --- /dev/null +++ b/tools/emulator/opengl/host/libs/libOpenglRender/NativeWindowsSubWindow.cpp @@ -0,0 +1,55 @@ +/* +* 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 + +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 = CreateWindow("subWin", + "sub", + WS_CHILD, + x,y,width,height, + p_window, + NULL, + NULL, + NULL); + ShowWindow(ret,SW_SHOW); + return ret; +} + +void destroySubWindow(EGLNativeDisplayType dis,EGLNativeWindowType win){ + DestroyWindow(win); +} diff --git a/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp b/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp index da9682b41..a9237af31 100644 --- a/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp +++ b/tools/emulator/opengl/host/libs/libOpenglRender/render_api.cpp @@ -23,6 +23,10 @@ static osUtils::childProcess *s_renderProc = NULL; static RenderServer *s_renderThread = NULL; static int s_renderPort = 0; +#ifdef __APPLE__ +#define RENDER_API_USE_THREAD +#endif + bool initOpenGLRenderer(FBNativeWindowType window, int x, int y, int width, int height, int portNum) @@ -75,7 +79,32 @@ bool initOpenGLRenderer(FBNativeWindowType window, 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); if (!dummy) { diff --git a/tools/emulator/opengl/shared/OpenglOsUtils/Android.mk b/tools/emulator/opengl/shared/OpenglOsUtils/Android.mk index 5a53a2314..35da4cfb5 100644 --- a/tools/emulator/opengl/shared/OpenglOsUtils/Android.mk +++ b/tools/emulator/opengl/shared/OpenglOsUtils/Android.mk @@ -32,7 +32,7 @@ $(call emugl-begin-host-static-library,libOpenglOsUtils) osProcessWin.cpp \ osThreadWin.cpp - $(call emugl-export,LDLIBS,-lws2_32) + $(call emugl-export,LDLIBS,-lws2_32 -lpsapi) else LOCAL_SRC_FILES += \ osProcessUnix.cpp \