diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/Android.mk b/tools/emulator/opengl/tests/EGL_host_wrapper/Android.mk new file mode 100644 index 000000000..d22be8118 --- /dev/null +++ b/tools/emulator/opengl/tests/EGL_host_wrapper/Android.mk @@ -0,0 +1,20 @@ +ifeq ($(HOST_OS),linux) + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := \ + egl.cpp \ + egl_dispatch.cpp + +LOCAL_MODULE := libEGL_host_wrapper +LOCAL_MODULE_TAGS := debug + +OS_LDLIBS := -ldl -lpthread + +LOCAL_LDLIBS := $(OS_LDLIBS) + +include $(BUILD_HOST_SHARED_LIBRARY) + +endif # HOST_OS == linux \ No newline at end of file diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/egl.cpp b/tools/emulator/opengl/tests/EGL_host_wrapper/egl.cpp new file mode 100644 index 000000000..6fa27acb8 --- /dev/null +++ b/tools/emulator/opengl/tests/EGL_host_wrapper/egl.cpp @@ -0,0 +1,277 @@ +/* +* 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 +#include +#include +#include "egl_dispatch.h" +#include "egl_ftable.h" +#include + +#define EGL_LIB "ANDROID_EGL_LIB" + +static struct egl_dispatch *s_dispatch = NULL; +static pthread_once_t eglDispatchInitialized = PTHREAD_ONCE_INIT; + +void initEglDispatch() +{ + // + // Load back-end EGL implementation library + // + char *eglLib = (char *) "libEGL.so"; + if (getenv(EGL_LIB) != NULL) { + eglLib = getenv(EGL_LIB); + } + + s_dispatch = loadEGL(eglLib); + if (!s_dispatch) { + fprintf(stderr,"FATAL ERROR: Could not load EGL lib [%s]\n", eglLib); + exit(-1); + } +} + +static struct egl_dispatch *getDispatch() +{ + pthread_once(&eglDispatchInitialized, initEglDispatch); + return s_dispatch; +} + +__eglMustCastToProperFunctionPointerType eglGetProcAddress(const char *procname) +{ + for (int i=0; ieglGetProcAddress(procname); +} + +//////////////// Path through functions ////////// + +EGLint eglGetError() +{ + return getDispatch()->eglGetError(); +} + +EGLDisplay eglGetDisplay(EGLNativeDisplayType display_id) +{ + return getDispatch()->eglGetDisplay(display_id); +} + +EGLBoolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) +{ + return getDispatch()->eglInitialize(dpy, major, minor); +} + +EGLBoolean eglTerminate(EGLDisplay dpy) +{ + return getDispatch()->eglTerminate(dpy); +} + +const char* eglQueryString(EGLDisplay dpy, EGLint name) +{ + return getDispatch()->eglQueryString(dpy, name); +} + +EGLBoolean eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) +{ + return getDispatch()->eglGetConfigs(dpy, configs, config_size, num_config); +} + +EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) +{ + return getDispatch()->eglChooseConfig(dpy, attrib_list, configs, config_size, num_config); +} + +EGLBoolean eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) +{ + return getDispatch()->eglGetConfigAttrib(dpy, config, attribute, value); +} + +EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) +{ + return getDispatch()->eglCreateWindowSurface(dpy, config, win, attrib_list); +} + +EGLSurface eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) +{ + return getDispatch()->eglCreatePbufferSurface(dpy, config, attrib_list); +} + +EGLSurface eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) +{ + return getDispatch()->eglCreatePixmapSurface(dpy, config, pixmap, attrib_list); +} + +EGLBoolean eglDestroySurface(EGLDisplay dpy, EGLSurface surface) +{ + return getDispatch()->eglDestroySurface(dpy, surface); +} + +EGLBoolean eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) +{ + return getDispatch()->eglQuerySurface(dpy, surface, attribute, value); +} + +EGLBoolean eglBindAPI(EGLenum api) +{ + return getDispatch()->eglBindAPI(api); +} + +EGLenum eglQueryAPI() +{ + return getDispatch()->eglQueryAPI(); +} + +EGLBoolean eglWaitClient() +{ + return getDispatch()->eglWaitClient(); +} + +EGLBoolean eglReleaseThread() +{ + return getDispatch()->eglReleaseThread(); +} + +EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) +{ + return getDispatch()->eglCreatePbufferFromClientBuffer(dpy, buftype, buffer, config, attrib_list); +} + +EGLBoolean eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) +{ + return getDispatch()->eglSurfaceAttrib(dpy, surface, attribute, value); +} + +EGLBoolean eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) +{ + return getDispatch()->eglBindTexImage(dpy, surface, buffer); +} + +EGLBoolean eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) +{ + return getDispatch()->eglReleaseTexImage(dpy, surface, buffer); +} + +EGLBoolean eglSwapInterval(EGLDisplay dpy, EGLint interval) +{ + return getDispatch()->eglSwapInterval(dpy, interval); +} + +EGLContext eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) +{ + return getDispatch()->eglCreateContext(dpy, config, share_context, attrib_list); +} + +EGLBoolean eglDestroyContext(EGLDisplay dpy, EGLContext ctx) +{ + return getDispatch()->eglDestroyContext(dpy, ctx); +} + +EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) +{ + return getDispatch()->eglMakeCurrent(dpy, draw, read, ctx); +} + +EGLContext eglGetCurrentContext() +{ + return getDispatch()->eglGetCurrentContext(); +} + +EGLSurface eglGetCurrentSurface(EGLint readdraw) +{ + return getDispatch()->eglGetCurrentSurface(readdraw); +} + +EGLDisplay eglGetCurrentDisplay() +{ + return getDispatch()->eglGetCurrentDisplay(); +} + +EGLBoolean eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) +{ + return getDispatch()->eglQueryContext(dpy, ctx, attribute, value); +} + +EGLBoolean eglWaitGL() +{ + return getDispatch()->eglWaitGL(); +} + +EGLBoolean eglWaitNative(EGLint engine) +{ + return getDispatch()->eglWaitNative(engine); +} + +EGLBoolean eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) +{ + return getDispatch()->eglSwapBuffers(dpy, surface); +} + +EGLBoolean eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) +{ + return getDispatch()->eglCopyBuffers(dpy, surface, target); +} + +EGLBoolean eglLockSurfaceKHR(EGLDisplay display, EGLSurface surface, const EGLint *attrib_list) +{ + return getDispatch()->eglLockSurfaceKHR(display, surface, attrib_list); +} + +EGLBoolean eglUnlockSurfaceKHR(EGLDisplay display, EGLSurface surface) +{ + return getDispatch()->eglUnlockSurfaceKHR(display, surface); +} + +EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list) +{ + return getDispatch()->eglCreateImageKHR(dpy, ctx, target, buffer, attrib_list); +} + +EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) +{ + return getDispatch()->eglDestroyImageKHR(dpy, image); +} + +EGLSyncKHR eglCreateSyncKHR(EGLDisplay dpy, EGLenum type, const EGLint *attrib_list) +{ + return getDispatch()->eglCreateSyncKHR(dpy, type, attrib_list); +} + +EGLBoolean eglDestroySyncKHR(EGLDisplay dpy, EGLSyncKHR sync) +{ + return getDispatch()->eglDestroySyncKHR(dpy, sync); +} + +EGLint eglClientWaitSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint flags, EGLTimeKHR timeout) +{ + return getDispatch()->eglClientWaitSyncKHR(dpy, sync, flags, timeout); +} + +EGLBoolean eglSignalSyncKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLenum mode) +{ + return getDispatch()->eglSignalSyncKHR(dpy, sync, mode); +} + +EGLBoolean eglGetSyncAttribKHR(EGLDisplay dpy, EGLSyncKHR sync, EGLint attribute, EGLint *value) +{ + return getDispatch()->eglGetSyncAttribKHR(dpy, sync, attribute, value); +} + +EGLBoolean eglSetSwapRectangleANDROID(EGLDisplay dpy, EGLSurface draw, EGLint left, EGLint top, EGLint width, EGLint height) +{ + return getDispatch()->eglSetSwapRectangleANDROID(dpy, draw, left, top, width, height); +} diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.cpp b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.cpp new file mode 100644 index 000000000..a9b8214d3 --- /dev/null +++ b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.cpp @@ -0,0 +1,77 @@ +/* +* 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 +#include +#include "egl_dispatch.h" + + +egl_dispatch *loadEGL(const char *p_eglPath) +{ + void *libEGL = dlopen(p_eglPath, RTLD_NOW); + if (!libEGL) { + return NULL; + } + + egl_dispatch *disp = new egl_dispatch; + + void *ptr; + ptr = dlsym(libEGL,"eglGetError"); disp->set_eglGetError((eglGetError_t)ptr); + ptr = dlsym(libEGL,"eglGetDisplay"); disp->set_eglGetDisplay((eglGetDisplay_t)ptr); + ptr = dlsym(libEGL,"eglInitialize"); disp->set_eglInitialize((eglInitialize_t)ptr); + ptr = dlsym(libEGL,"eglTerminate"); disp->set_eglTerminate((eglTerminate_t)ptr); + ptr = dlsym(libEGL,"eglQueryString"); disp->set_eglQueryString((eglQueryString_t)ptr); + ptr = dlsym(libEGL,"eglGetConfigs"); disp->set_eglGetConfigs((eglGetConfigs_t)ptr); + ptr = dlsym(libEGL,"eglChooseConfig"); disp->set_eglChooseConfig((eglChooseConfig_t)ptr); + ptr = dlsym(libEGL,"eglGetConfigAttrib"); disp->set_eglGetConfigAttrib((eglGetConfigAttrib_t)ptr); + ptr = dlsym(libEGL,"eglCreateWindowSurface"); disp->set_eglCreateWindowSurface((eglCreateWindowSurface_t)ptr); + ptr = dlsym(libEGL,"eglCreatePbufferSurface"); disp->set_eglCreatePbufferSurface((eglCreatePbufferSurface_t)ptr); + ptr = dlsym(libEGL,"eglCreatePixmapSurface"); disp->set_eglCreatePixmapSurface((eglCreatePixmapSurface_t)ptr); + ptr = dlsym(libEGL,"eglDestroySurface"); disp->set_eglDestroySurface((eglDestroySurface_t)ptr); + ptr = dlsym(libEGL,"eglQuerySurface"); disp->set_eglQuerySurface((eglQuerySurface_t)ptr); + ptr = dlsym(libEGL,"eglBindAPI"); disp->set_eglBindAPI((eglBindAPI_t)ptr); + ptr = dlsym(libEGL,"eglQueryAPI"); disp->set_eglQueryAPI((eglQueryAPI_t)ptr); + ptr = dlsym(libEGL,"eglWaitClient"); disp->set_eglWaitClient((eglWaitClient_t)ptr); + ptr = dlsym(libEGL,"eglReleaseThread"); disp->set_eglReleaseThread((eglReleaseThread_t)ptr); + ptr = dlsym(libEGL,"eglCreatePbufferFromClientBuffer"); disp->set_eglCreatePbufferFromClientBuffer((eglCreatePbufferFromClientBuffer_t)ptr); + ptr = dlsym(libEGL,"eglSurfaceAttrib"); disp->set_eglSurfaceAttrib((eglSurfaceAttrib_t)ptr); + ptr = dlsym(libEGL,"eglBindTexImage"); disp->set_eglBindTexImage((eglBindTexImage_t)ptr); + ptr = dlsym(libEGL,"eglReleaseTexImage"); disp->set_eglReleaseTexImage((eglReleaseTexImage_t)ptr); + ptr = dlsym(libEGL,"eglSwapInterval"); disp->set_eglSwapInterval((eglSwapInterval_t)ptr); + ptr = dlsym(libEGL,"eglCreateContext"); disp->set_eglCreateContext((eglCreateContext_t)ptr); + ptr = dlsym(libEGL,"eglDestroyContext"); disp->set_eglDestroyContext((eglDestroyContext_t)ptr); + ptr = dlsym(libEGL,"eglMakeCurrent"); disp->set_eglMakeCurrent((eglMakeCurrent_t)ptr); + ptr = dlsym(libEGL,"eglGetCurrentContext"); disp->set_eglGetCurrentContext((eglGetCurrentContext_t)ptr); + ptr = dlsym(libEGL,"eglGetCurrentSurface"); disp->set_eglGetCurrentSurface((eglGetCurrentSurface_t)ptr); + ptr = dlsym(libEGL,"eglGetCurrentDisplay"); disp->set_eglGetCurrentDisplay((eglGetCurrentDisplay_t)ptr); + ptr = dlsym(libEGL,"eglQueryContext"); disp->set_eglQueryContext((eglQueryContext_t)ptr); + ptr = dlsym(libEGL,"eglWaitGL"); disp->set_eglWaitGL((eglWaitGL_t)ptr); + ptr = dlsym(libEGL,"eglWaitNative"); disp->set_eglWaitNative((eglWaitNative_t)ptr); + ptr = dlsym(libEGL,"eglSwapBuffers"); disp->set_eglSwapBuffers((eglSwapBuffers_t)ptr); + ptr = dlsym(libEGL,"eglCopyBuffers"); disp->set_eglCopyBuffers((eglCopyBuffers_t)ptr); + ptr = dlsym(libEGL,"eglGetProcAddress"); disp->set_eglGetProcAddress((eglGetProcAddress_t)ptr); + ptr = dlsym(libEGL,"eglLockSurfaceKHR"); disp->set_eglLockSurfaceKHR((eglLockSurfaceKHR_t)ptr); + ptr = dlsym(libEGL,"eglUnlockSurfaceKHR"); disp->set_eglUnlockSurfaceKHR((eglUnlockSurfaceKHR_t)ptr); + ptr = dlsym(libEGL,"eglCreateImageKHR"); disp->set_eglCreateImageKHR((eglCreateImageKHR_t)ptr); + ptr = dlsym(libEGL,"eglDestroyImageKHR"); disp->set_eglDestroyImageKHR((eglDestroyImageKHR_t)ptr); + ptr = dlsym(libEGL,"eglCreateSyncKHR"); disp->set_eglCreateSyncKHR((eglCreateSyncKHR_t)ptr); + ptr = dlsym(libEGL,"eglDestroySyncKHR"); disp->set_eglDestroySyncKHR((eglDestroySyncKHR_t)ptr); + ptr = dlsym(libEGL,"eglClientWaitSyncKHR"); disp->set_eglClientWaitSyncKHR((eglClientWaitSyncKHR_t)ptr); + ptr = dlsym(libEGL,"eglSignalSyncKHR"); disp->set_eglSignalSyncKHR((eglSignalSyncKHR_t)ptr); + ptr = dlsym(libEGL,"eglGetSyncAttribKHR"); disp->set_eglGetSyncAttribKHR((eglGetSyncAttribKHR_t)ptr); + ptr = dlsym(libEGL,"eglSetSwapRectangleANDROID"); disp->set_eglSetSwapRectangleANDROID((eglSetSwapRectangleANDROID_t)ptr); + + return disp; +} diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.h b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.h new file mode 100644 index 000000000..e5f67c98a --- /dev/null +++ b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_dispatch.h @@ -0,0 +1,115 @@ +/* +* 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 egl_dispatch { + 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; + //Accessors + eglGetError_t set_eglGetError(eglGetError_t f) { eglGetError_t retval = eglGetError; eglGetError = f; return retval;} + eglGetDisplay_t set_eglGetDisplay(eglGetDisplay_t f) { eglGetDisplay_t retval = eglGetDisplay; eglGetDisplay = f; return retval;} + eglInitialize_t set_eglInitialize(eglInitialize_t f) { eglInitialize_t retval = eglInitialize; eglInitialize = f; return retval;} + eglTerminate_t set_eglTerminate(eglTerminate_t f) { eglTerminate_t retval = eglTerminate; eglTerminate = f; return retval;} + eglQueryString_t set_eglQueryString(eglQueryString_t f) { eglQueryString_t retval = eglQueryString; eglQueryString = f; return retval;} + eglGetConfigs_t set_eglGetConfigs(eglGetConfigs_t f) { eglGetConfigs_t retval = eglGetConfigs; eglGetConfigs = f; return retval;} + eglChooseConfig_t set_eglChooseConfig(eglChooseConfig_t f) { eglChooseConfig_t retval = eglChooseConfig; eglChooseConfig = f; return retval;} + eglGetConfigAttrib_t set_eglGetConfigAttrib(eglGetConfigAttrib_t f) { eglGetConfigAttrib_t retval = eglGetConfigAttrib; eglGetConfigAttrib = f; return retval;} + eglCreateWindowSurface_t set_eglCreateWindowSurface(eglCreateWindowSurface_t f) { eglCreateWindowSurface_t retval = eglCreateWindowSurface; eglCreateWindowSurface = f; return retval;} + eglCreatePbufferSurface_t set_eglCreatePbufferSurface(eglCreatePbufferSurface_t f) { eglCreatePbufferSurface_t retval = eglCreatePbufferSurface; eglCreatePbufferSurface = f; return retval;} + eglCreatePixmapSurface_t set_eglCreatePixmapSurface(eglCreatePixmapSurface_t f) { eglCreatePixmapSurface_t retval = eglCreatePixmapSurface; eglCreatePixmapSurface = f; return retval;} + eglDestroySurface_t set_eglDestroySurface(eglDestroySurface_t f) { eglDestroySurface_t retval = eglDestroySurface; eglDestroySurface = f; return retval;} + eglQuerySurface_t set_eglQuerySurface(eglQuerySurface_t f) { eglQuerySurface_t retval = eglQuerySurface; eglQuerySurface = f; return retval;} + eglBindAPI_t set_eglBindAPI(eglBindAPI_t f) { eglBindAPI_t retval = eglBindAPI; eglBindAPI = f; return retval;} + eglQueryAPI_t set_eglQueryAPI(eglQueryAPI_t f) { eglQueryAPI_t retval = eglQueryAPI; eglQueryAPI = f; return retval;} + eglWaitClient_t set_eglWaitClient(eglWaitClient_t f) { eglWaitClient_t retval = eglWaitClient; eglWaitClient = f; return retval;} + eglReleaseThread_t set_eglReleaseThread(eglReleaseThread_t f) { eglReleaseThread_t retval = eglReleaseThread; eglReleaseThread = f; return retval;} + eglCreatePbufferFromClientBuffer_t set_eglCreatePbufferFromClientBuffer(eglCreatePbufferFromClientBuffer_t f) { eglCreatePbufferFromClientBuffer_t retval = eglCreatePbufferFromClientBuffer; eglCreatePbufferFromClientBuffer = f; return retval;} + eglSurfaceAttrib_t set_eglSurfaceAttrib(eglSurfaceAttrib_t f) { eglSurfaceAttrib_t retval = eglSurfaceAttrib; eglSurfaceAttrib = f; return retval;} + eglBindTexImage_t set_eglBindTexImage(eglBindTexImage_t f) { eglBindTexImage_t retval = eglBindTexImage; eglBindTexImage = f; return retval;} + eglReleaseTexImage_t set_eglReleaseTexImage(eglReleaseTexImage_t f) { eglReleaseTexImage_t retval = eglReleaseTexImage; eglReleaseTexImage = f; return retval;} + eglSwapInterval_t set_eglSwapInterval(eglSwapInterval_t f) { eglSwapInterval_t retval = eglSwapInterval; eglSwapInterval = f; return retval;} + eglCreateContext_t set_eglCreateContext(eglCreateContext_t f) { eglCreateContext_t retval = eglCreateContext; eglCreateContext = f; return retval;} + eglDestroyContext_t set_eglDestroyContext(eglDestroyContext_t f) { eglDestroyContext_t retval = eglDestroyContext; eglDestroyContext = f; return retval;} + eglMakeCurrent_t set_eglMakeCurrent(eglMakeCurrent_t f) { eglMakeCurrent_t retval = eglMakeCurrent; eglMakeCurrent = f; return retval;} + eglGetCurrentContext_t set_eglGetCurrentContext(eglGetCurrentContext_t f) { eglGetCurrentContext_t retval = eglGetCurrentContext; eglGetCurrentContext = f; return retval;} + eglGetCurrentSurface_t set_eglGetCurrentSurface(eglGetCurrentSurface_t f) { eglGetCurrentSurface_t retval = eglGetCurrentSurface; eglGetCurrentSurface = f; return retval;} + eglGetCurrentDisplay_t set_eglGetCurrentDisplay(eglGetCurrentDisplay_t f) { eglGetCurrentDisplay_t retval = eglGetCurrentDisplay; eglGetCurrentDisplay = f; return retval;} + eglQueryContext_t set_eglQueryContext(eglQueryContext_t f) { eglQueryContext_t retval = eglQueryContext; eglQueryContext = f; return retval;} + eglWaitGL_t set_eglWaitGL(eglWaitGL_t f) { eglWaitGL_t retval = eglWaitGL; eglWaitGL = f; return retval;} + eglWaitNative_t set_eglWaitNative(eglWaitNative_t f) { eglWaitNative_t retval = eglWaitNative; eglWaitNative = f; return retval;} + eglSwapBuffers_t set_eglSwapBuffers(eglSwapBuffers_t f) { eglSwapBuffers_t retval = eglSwapBuffers; eglSwapBuffers = f; return retval;} + eglCopyBuffers_t set_eglCopyBuffers(eglCopyBuffers_t f) { eglCopyBuffers_t retval = eglCopyBuffers; eglCopyBuffers = f; return retval;} + eglGetProcAddress_t set_eglGetProcAddress(eglGetProcAddress_t f) { eglGetProcAddress_t retval = eglGetProcAddress; eglGetProcAddress = f; return retval;} + eglLockSurfaceKHR_t set_eglLockSurfaceKHR(eglLockSurfaceKHR_t f) { eglLockSurfaceKHR_t retval = eglLockSurfaceKHR; eglLockSurfaceKHR = f; return retval;} + eglUnlockSurfaceKHR_t set_eglUnlockSurfaceKHR(eglUnlockSurfaceKHR_t f) { eglUnlockSurfaceKHR_t retval = eglUnlockSurfaceKHR; eglUnlockSurfaceKHR = f; return retval;} + eglCreateImageKHR_t set_eglCreateImageKHR(eglCreateImageKHR_t f) { eglCreateImageKHR_t retval = eglCreateImageKHR; eglCreateImageKHR = f; return retval;} + eglDestroyImageKHR_t set_eglDestroyImageKHR(eglDestroyImageKHR_t f) { eglDestroyImageKHR_t retval = eglDestroyImageKHR; eglDestroyImageKHR = f; return retval;} + eglCreateSyncKHR_t set_eglCreateSyncKHR(eglCreateSyncKHR_t f) { eglCreateSyncKHR_t retval = eglCreateSyncKHR; eglCreateSyncKHR = f; return retval;} + eglDestroySyncKHR_t set_eglDestroySyncKHR(eglDestroySyncKHR_t f) { eglDestroySyncKHR_t retval = eglDestroySyncKHR; eglDestroySyncKHR = f; return retval;} + eglClientWaitSyncKHR_t set_eglClientWaitSyncKHR(eglClientWaitSyncKHR_t f) { eglClientWaitSyncKHR_t retval = eglClientWaitSyncKHR; eglClientWaitSyncKHR = f; return retval;} + eglSignalSyncKHR_t set_eglSignalSyncKHR(eglSignalSyncKHR_t f) { eglSignalSyncKHR_t retval = eglSignalSyncKHR; eglSignalSyncKHR = f; return retval;} + eglGetSyncAttribKHR_t set_eglGetSyncAttribKHR(eglGetSyncAttribKHR_t f) { eglGetSyncAttribKHR_t retval = eglGetSyncAttribKHR; eglGetSyncAttribKHR = f; return retval;} + eglSetSwapRectangleANDROID_t set_eglSetSwapRectangleANDROID(eglSetSwapRectangleANDROID_t f) { eglSetSwapRectangleANDROID_t retval = eglSetSwapRectangleANDROID; eglSetSwapRectangleANDROID = f; return retval;} +}; + +egl_dispatch *loadEGL(const char *p_eglPath); + +#endif diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/egl_ftable.h b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_ftable.h new file mode 100644 index 000000000..ee4058590 --- /dev/null +++ b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_ftable.h @@ -0,0 +1,66 @@ +/* +* 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. +*/ +static struct _egl_funcs_by_name { + const char *name; + void *proc; +} egl_funcs_by_name[] = { + {"eglGetError", (void *)eglGetError}, + {"eglGetDisplay", (void *)eglGetDisplay}, + {"eglInitialize", (void *)eglInitialize}, + {"eglTerminate", (void *)eglTerminate}, + {"eglQueryString", (void *)eglQueryString}, + {"eglGetConfigs", (void *)eglGetConfigs}, + {"eglChooseConfig", (void *)eglChooseConfig}, + {"eglGetConfigAttrib", (void *)eglGetConfigAttrib}, + {"eglCreateWindowSurface", (void *)eglCreateWindowSurface}, + {"eglCreatePbufferSurface", (void *)eglCreatePbufferSurface}, + {"eglCreatePixmapSurface", (void *)eglCreatePixmapSurface}, + {"eglDestroySurface", (void *)eglDestroySurface}, + {"eglQuerySurface", (void *)eglQuerySurface}, + {"eglBindAPI", (void *)eglBindAPI}, + {"eglQueryAPI", (void *)eglQueryAPI}, + {"eglWaitClient", (void *)eglWaitClient}, + {"eglReleaseThread", (void *)eglReleaseThread}, + {"eglCreatePbufferFromClientBuffer", (void *)eglCreatePbufferFromClientBuffer}, + {"eglSurfaceAttrib", (void *)eglSurfaceAttrib}, + {"eglBindTexImage", (void *)eglBindTexImage}, + {"eglReleaseTexImage", (void *)eglReleaseTexImage}, + {"eglSwapInterval", (void *)eglSwapInterval}, + {"eglCreateContext", (void *)eglCreateContext}, + {"eglDestroyContext", (void *)eglDestroyContext}, + {"eglMakeCurrent", (void *)eglMakeCurrent}, + {"eglGetCurrentContext", (void *)eglGetCurrentContext}, + {"eglGetCurrentSurface", (void *)eglGetCurrentSurface}, + {"eglGetCurrentDisplay", (void *)eglGetCurrentDisplay}, + {"eglQueryContext", (void *)eglQueryContext}, + {"eglWaitGL", (void *)eglWaitGL}, + {"eglWaitNative", (void *)eglWaitNative}, + {"eglSwapBuffers", (void *)eglSwapBuffers}, + {"eglCopyBuffers", (void *)eglCopyBuffers}, + {"eglGetProcAddress", (void *)eglGetProcAddress}, + {"eglLockSurfaceKHR", (void *)eglLockSurfaceKHR}, + {"eglUnlockSurfaceKHR", (void *)eglUnlockSurfaceKHR}, + {"eglCreateImageKHR", (void *)eglCreateImageKHR}, + {"eglDestroyImageKHR", (void *)eglDestroyImageKHR}, + {"eglCreateSyncKHR", (void *)eglCreateSyncKHR}, + {"eglDestroySyncKHR", (void *)eglDestroySyncKHR}, + {"eglClientWaitSyncKHR", (void *)eglClientWaitSyncKHR}, + {"eglSignalSyncKHR", (void *)eglSignalSyncKHR}, + {"eglGetSyncAttribKHR", (void *)eglGetSyncAttribKHR}, + {"eglSetSwapRectangleANDROID", (void *)eglSetSwapRectangleANDROID} +}; + +static int egl_num_funcs = sizeof(egl_funcs_by_name) / sizeof(struct _egl_funcs_by_name); diff --git a/tools/emulator/opengl/tests/EGL_host_wrapper/egl_proc.h b/tools/emulator/opengl/tests/EGL_host_wrapper/egl_proc.h new file mode 100644 index 000000000..140c0309e --- /dev/null +++ b/tools/emulator/opengl/tests/EGL_host_wrapper/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 +#define EGL_EGLEXT_PROTOTYPES +#include + +typedef EGLint (* eglGetError_t) (); +typedef EGLDisplay (* eglGetDisplay_t) (EGLNativeDisplayType); +typedef EGLBoolean (* eglInitialize_t) (EGLDisplay, EGLint*, EGLint*); +typedef EGLBoolean (* eglTerminate_t) (EGLDisplay); +typedef char* (* eglQueryString_t) (EGLDisplay, EGLint); +typedef EGLBoolean (* eglGetConfigs_t) (EGLDisplay, EGLConfig*, EGLint, EGLint*); +typedef EGLBoolean (* eglChooseConfig_t) (EGLDisplay, const EGLint*, EGLConfig*, EGLint, EGLint*); +typedef EGLBoolean (* eglGetConfigAttrib_t) (EGLDisplay, EGLConfig, EGLint, EGLint*); +typedef EGLSurface (* eglCreateWindowSurface_t) (EGLDisplay, EGLConfig, EGLNativeWindowType, const EGLint*); +typedef EGLSurface (* eglCreatePbufferSurface_t) (EGLDisplay, EGLConfig, const EGLint*); +typedef EGLSurface (* eglCreatePixmapSurface_t) (EGLDisplay, EGLConfig, EGLNativePixmapType, const EGLint*); +typedef EGLBoolean (* eglDestroySurface_t) (EGLDisplay, EGLSurface); +typedef EGLBoolean (* eglQuerySurface_t) (EGLDisplay, EGLSurface, EGLint, EGLint*); +typedef EGLBoolean (* eglBindAPI_t) (EGLenum); +typedef EGLenum (* eglQueryAPI_t) (); +typedef EGLBoolean (* eglWaitClient_t) (); +typedef EGLBoolean (* eglReleaseThread_t) (); +typedef EGLSurface (* eglCreatePbufferFromClientBuffer_t) (EGLDisplay, EGLenum, EGLClientBuffer, EGLConfig, const EGLint*); +typedef EGLBoolean (* eglSurfaceAttrib_t) (EGLDisplay, EGLSurface, EGLint, EGLint); +typedef EGLBoolean (* eglBindTexImage_t) (EGLDisplay, EGLSurface, EGLint); +typedef EGLBoolean (* eglReleaseTexImage_t) (EGLDisplay, EGLSurface, EGLint); +typedef EGLBoolean (* eglSwapInterval_t) (EGLDisplay, EGLint); +typedef EGLContext (* eglCreateContext_t) (EGLDisplay, EGLConfig, EGLContext, const EGLint*); +typedef EGLBoolean (* eglDestroyContext_t) (EGLDisplay, EGLContext); +typedef EGLBoolean (* eglMakeCurrent_t) (EGLDisplay, EGLSurface, EGLSurface, EGLContext); +typedef EGLContext (* eglGetCurrentContext_t) (); +typedef EGLSurface (* eglGetCurrentSurface_t) (EGLint); +typedef EGLDisplay (* eglGetCurrentDisplay_t) (); +typedef EGLBoolean (* eglQueryContext_t) (EGLDisplay, EGLContext, EGLint, EGLint*); +typedef EGLBoolean (* eglWaitGL_t) (); +typedef EGLBoolean (* eglWaitNative_t) (EGLint); +typedef EGLBoolean (* eglSwapBuffers_t) (EGLDisplay, EGLSurface); +typedef EGLBoolean (* eglCopyBuffers_t) (EGLDisplay, EGLSurface, EGLNativePixmapType); +typedef __eglMustCastToProperFunctionPointerType (* eglGetProcAddress_t) (const char*); +typedef EGLBoolean (* eglLockSurfaceKHR_t) (EGLDisplay, EGLSurface, const EGLint*); +typedef EGLBoolean (* eglUnlockSurfaceKHR_t) (EGLDisplay, EGLSurface); +typedef EGLImageKHR (* eglCreateImageKHR_t) (EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, const EGLint*); +typedef EGLBoolean (* eglDestroyImageKHR_t) (EGLDisplay, EGLImageKHR image); +typedef EGLSyncKHR (* eglCreateSyncKHR_t) (EGLDisplay, EGLenum, const EGLint*); +typedef EGLBoolean (* eglDestroySyncKHR_t) (EGLDisplay, EGLSyncKHR sync); +typedef EGLint (* eglClientWaitSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLTimeKHR timeout); +typedef EGLBoolean (* eglSignalSyncKHR_t) (EGLDisplay, EGLSyncKHR, EGLenum); +typedef EGLBoolean (* eglGetSyncAttribKHR_t) (EGLDisplay, EGLSyncKHR, EGLint, EGLint*); +typedef EGLBoolean (* eglSetSwapRectangleANDROID_t) (EGLDisplay, EGLSurface, EGLint, EGLint, EGLint, EGLint); + +#endif // of _EGL_PROC_H diff --git a/tools/emulator/opengl/tests/ut_renderer/Android.mk b/tools/emulator/opengl/tests/ut_renderer/Android.mk new file mode 100644 index 000000000..1fe2d078c --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/Android.mk @@ -0,0 +1,52 @@ + +LOCAL_PATH:=$(call my-dir) + +# ut_renderer test program ########################### + +include $(CLEAR_VARS) + +ifeq ($(HOST_OS), linux) + +emulatorOpengl := $(LOCAL_PATH)/../.. + +LOCAL_MODULE := ut_renderer +LOCAL_MODULE_TAGS := debug + +# add additional depencies to ensure that the generated code that we depend on +# is generated +LOCAL_ADDITIONAL_DEPENDENCIES := \ + $(HOST_OUT_SHARED_LIBRARIES)/libut_rendercontrol_dec$(HOST_SHLIB_SUFFIX) \ + $(HOST_OUT_SHARED_LIBRARIES)/libGLESv1_dec$(HOST_SHLIB_SUFFIX) + +LOCAL_SRC_FILES := ut_renderer.cpp \ + RenderingThread.cpp \ + ReadBuffer.cpp \ + Renderer.cpp \ + RendererContext.cpp \ + RendererSurface.cpp \ + X11Windowing.cpp \ + TimeUtils.cpp + +# define PVR_WAR to support imgtec PVR opengl-ES implementation +# +# specifically this MACRO enables code that work arounds a bug +# in the implementation where glTextureParameter(...,GL_TEXTURE_RECT,...) +# is called would cause a crash if the texture dimensions have not been +# defined yet. + +LOCAL_CFLAGS := -DPVR_WAR +#LOCAL_CFLAGS += -g -O0 + +LOCAL_C_INCLUDES := $(emulatorOpengl)/system/OpenglCodecCommon \ + $(call intermediates-dir-for, SHARED_LIBRARIES, libut_rendercontrol_dec, HOST) \ + $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_dec, HOST) \ + $(emulatorOpengl)/host/libs/GLESv1_dec \ + $(emulatorOpengl)/system/GLESv1_enc \ + $(emulatorOpengl)/tests/ut_rendercontrol_enc + +LOCAL_SHARED_LIBRARIES := libut_rendercontrol_dec libGLESv1_dec libEGL_host_wrapper +LOCAL_STATIC_LIBRARIES := libOpenglCodecCommon +LOCAL_LDLIBS := -lpthread -lX11 -lrt +include $(BUILD_HOST_EXECUTABLE) + +endif # HOST_OS == linux diff --git a/tools/emulator/opengl/tests/ut_renderer/NativeWindowing.h b/tools/emulator/opengl/tests/ut_renderer/NativeWindowing.h new file mode 100644 index 000000000..946806693 --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/NativeWindowing.h @@ -0,0 +1,28 @@ +/* +* 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_WINDOWING_H +#define _NATIVE_WINDOWING_H + +#include + +class NativeWindowing { +public: + virtual NativeDisplayType getNativeDisplay() = 0; + virtual NativeWindowType createNativeWindow(NativeDisplayType dpy, int width, int height) = 0; + virtual int destroyNativeWindow(NativeDisplayType dpy, NativeWindowType win) = 0; +}; + +#endif diff --git a/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.cpp b/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.cpp new file mode 100644 index 000000000..661b4cc26 --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.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 "ReadBuffer.h" +#include +#include + +ReadBuffer::ReadBuffer(TcpStream *stream, size_t bufsize) +{ + m_size = bufsize; + m_stream = stream; + m_buf = new unsigned char[m_size]; + m_validData = 0; + m_readPtr = m_buf; +} + +ReadBuffer::~ReadBuffer() +{ + delete m_buf; +} + +int ReadBuffer::getData() +{ + if (m_validData > 0) { + memcpy(m_buf, m_readPtr, m_validData); + } + m_readPtr = m_buf; + // get fresh data into the buffer; + int stat = m_stream->recv(m_buf + m_validData, m_size - m_validData); + if (stat > 0) { + m_validData += (size_t) stat; + } + return stat; +} + +void ReadBuffer::consume(size_t amount) +{ + assert(amount <= m_validData); + m_validData -= amount; + m_readPtr += amount; +} diff --git a/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.h b/tools/emulator/opengl/tests/ut_renderer/ReadBuffer.h new file mode 100644 index 000000000..1b8f6fd66 --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/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 "TcpStream.h" + +class ReadBuffer { +public: + ReadBuffer(TcpStream *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; + TcpStream *m_stream; +}; +#endif diff --git a/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp b/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp new file mode 100644 index 000000000..3228df6f9 --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/Renderer.cpp @@ -0,0 +1,181 @@ +/* +* 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 +#include +#include +#include "RenderingThread.h" +#include "Renderer.h" + +// include operating-system dependent windowing system impelemntation +#ifdef _WIN32 +# error "WINDOWS IS NOT SUPPORTED AT THE MOMENT" +#elif defined __APPLE__ +# error "Apple OS-X IS NOT SUPPORTED" +#elif defined (__unix__) +# include "X11Windowing.h" +#endif + + + + + +Renderer * Renderer::m_instance = NULL; + +Renderer * Renderer::instance() +{ + if (m_instance == NULL) m_instance = new Renderer; + return m_instance; +} + +Renderer::Renderer() +{ + // Unix specific, use your platform specific windowing implementation +#ifdef __unix__ + m_nw = new X11Windowing; +#endif + + m_dpy = eglGetDisplay(m_nw->getNativeDisplay()); + EGLint major, minor; + eglInitialize(m_dpy, &major, &minor); + fprintf(stderr, "egl initialized : %d.%d\n", major, minor); +} + +int Renderer::createSurface(RenderingThread *thread, const ClientHandle & handle) +{ + android::Mutex::Autolock(this->m_mutex); + + assert(m_surfaces.find(handle) == m_surfaces.end()); + if (handle.handle == 0) { + fprintf(stderr, "trying to create surface for EGL_NO_SURFACE !!!\n"); + return -1; + } else { + RendererSurface *surface = RendererSurface::create(m_dpy, RendererSurface::CONFIG_DEPTH, m_nw); + if (surface == NULL) { + printf("failed to create surface !!\n"); + return -1; + } + m_surfaces.insert(SurfaceMap::value_type(handle, surface)); + } + return 0; +} + +int Renderer::destroySurface(RenderingThread *thread, const ClientHandle &handle) +{ + android::Mutex::Autolock(this->m_mutex); + + SurfaceMap::iterator i = m_surfaces.find(handle); + if (i == m_surfaces.end()) { + printf("removing surface that doesn't exists\n"); + return -1; + } + if (i->second->destroy(m_nw)) { + m_surfaces.erase(handle); + } + return 0; +} + +int Renderer::createContext(RenderingThread *thread, const ClientHandle &handle, ClientHandle shareCtx) +{ + android::Mutex::Autolock(this->m_mutex); + + assert(m_ctxs.find(handle) == m_ctxs.end()); + RendererContext *shared = NULL; + if (shareCtx.handle != 0) { + ContextMap::iterator sctx = m_ctxs.find(shareCtx); + if (sctx != m_ctxs.end()) { + shared = sctx->second; + } + } + + RendererContext *ctx = + RendererContext::create(m_dpy, + RendererSurface::getEglConfig(m_dpy, RendererSurface::CONFIG_DEPTH), + shared); + if (ctx == NULL) { + fprintf(stderr, "failed to create context\n"); + return -1; + } + m_ctxs.insert(ContextMap::value_type(handle, ctx)); + return 0; +} + +int Renderer::destroyContext(RenderingThread *thread, const ClientHandle &handle) +{ + android::Mutex::Autolock(this->m_mutex); + + ContextMap::iterator i = m_ctxs.find(handle); + if (i == m_ctxs.end()) { + printf("removing context that doesn't exists\n"); + return -1; + } + if (i->second->destroy()) { + m_ctxs.erase(handle); + } + return 0; +} + +int Renderer::makeCurrent(RenderingThread *thread, + const ClientHandle &drawSurface, + const ClientHandle &readSurface, + const ClientHandle & ctx) +{ + android::Mutex::Autolock(this->m_mutex); + + RendererContext *currentContext = thread->currentContext(); + + ContextMap::iterator c = m_ctxs.find(ctx); + EGLContext eglContext; + if (ctx.handle != 0 && c != m_ctxs.end()) { + if (c->second != currentContext) { + // new context is set + if (currentContext != NULL) currentContext->unref(); + c->second->ref(); + eglContext = c->second->eglContext(); + thread->setCurrentContext(c->second); + thread->glDecoder().setContextData(&c->second->decoderContextData()); + } else { + // same context is already set + eglContext = c->second->eglContext(); + } + } else { + eglContext = EGL_NO_CONTEXT; + if (currentContext != NULL) currentContext->unref(); + thread->setCurrentContext(NULL); + thread->glDecoder().setContextData(NULL); + } + + EGLSurface draw = EGL_NO_SURFACE; + EGLSurface read = EGL_NO_SURFACE; + SurfaceMap::iterator i; + i = m_surfaces.find(drawSurface); if (i != m_surfaces.end()) draw = i->second->eglSurface(); + i = m_surfaces.find(readSurface); if (i != m_surfaces.end()) read = i->second->eglSurface(); + + return eglMakeCurrent(m_dpy, draw, read, eglContext); +} + +int Renderer::swapBuffers(RenderingThread *thread, + const ClientHandle &surface) +{ + android::Mutex::Autolock(this->m_mutex); + + SurfaceMap::iterator s = m_surfaces.find(surface); + if (s == m_surfaces.end()) { + fprintf(stderr, "swapping buffers for non existing surface\n"); + return -1; + } + return eglSwapBuffers(m_dpy, s->second->eglSurface()); +} diff --git a/tools/emulator/opengl/tests/ut_renderer/Renderer.h b/tools/emulator/opengl/tests/ut_renderer/Renderer.h new file mode 100644 index 000000000..49be147aa --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/Renderer.h @@ -0,0 +1,62 @@ +/* +* 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 _RENDERER_H_ +#define _RENDERER_H_ +#include +#include "RendererSurface.h" +#include "RendererContext.h" +#include "NativeWindowing.h" +#include + +class RenderingThread; + +class Renderer { +public: + + class ClientHandle { + public: + unsigned int pid; + unsigned int handle; + ClientHandle(unsigned int _pid, unsigned int _handle) : pid(_pid), handle(_handle) {} + + bool operator< (const ClientHandle & p) const { + bool val = (pid == p.pid) ? handle < p.handle : pid < p.pid; + return val; + } + }; + + static Renderer *instance(); + int createSurface(RenderingThread *thread, const ClientHandle & handle); + int destroySurface(RenderingThread *thread, const ClientHandle &handle); + int createContext(RenderingThread *thread, const ClientHandle & ctx, const ClientHandle shareCtx); + int destroyContext(RenderingThread *thread,const ClientHandle & ctx); + int makeCurrent(RenderingThread *thread, + const ClientHandle & drawSurface, const ClientHandle & readSurface, const ClientHandle & ctx); + int swapBuffers(RenderingThread *thread, const ClientHandle & surface); + +private: + typedef std::map SurfaceMap; + typedef std::map ContextMap; + static Renderer *m_instance; + Renderer(); + SurfaceMap m_surfaces; + ContextMap m_ctxs; + NativeWindowing *m_nw; + EGLDisplay m_dpy; + + android::Mutex m_mutex; // single global mutex for the renderer class; +}; +#endif diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererContext.cpp b/tools/emulator/opengl/tests/ut_renderer/RendererContext.cpp new file mode 100644 index 000000000..271494d27 --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/RendererContext.cpp @@ -0,0 +1,62 @@ +/* +* 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 "RendererContext.h" +#include +#include + +RendererContext * RendererContext::create(EGLDisplay dpy, EGLConfig config, RendererContext *shareCtx) +{ + EGLContext ctx; + EGLContext shared = shareCtx == NULL ? EGL_NO_CONTEXT : shareCtx->eglContext(); + ctx = eglCreateContext(dpy, config, shared, NULL); + if (eglGetError() != EGL_SUCCESS) return NULL; + + return new RendererContext(dpy, ctx); +} + +int RendererContext::destroy() +{ + if (count() <= 0) { + eglDestroyContext(m_dpy, m_ctx); + return 1; + } + return 0; +} + +#ifdef PVR_WAR +void RendererContext::setActiveTexture(GLenum texture) +{ + m_activeTexture = texture - GL_TEXTURE0; +} + +void RendererContext::setTex2DBind(GLuint texture) +{ + m_tex2DBind[m_activeTexture] = texture; +} + +GLuint RendererContext::getTex2DBind() +{ + return m_tex2DBind[m_activeTexture]; +} + +void RendererContext::addPendingCropRect(int *rect) +{ + PendingCropRect *r = new PendingCropRect; + r->texture = m_tex2DBind[m_activeTexture]; + memcpy(r->rect, rect, 4*sizeof(int)); + m_pendingCropRects.insert(r); +} +#endif diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererContext.h b/tools/emulator/opengl/tests/ut_renderer/RendererContext.h new file mode 100644 index 000000000..c0fd6dc8b --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/RendererContext.h @@ -0,0 +1,125 @@ +/* +* 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 _RENDERER_CONTEXT_H_ +#define _RENDERER_CONTEXT_H_ + +#include "RendererObject.h" +#include "GLDecoderContextData.h" + +#include +#define GL_API +#define GL_APIENTRY +#include +#include + +#ifdef PVR_WAR +#include +struct PendingCropRect +{ + GLuint texture; + int rect[4]; +}; + +typedef std::set PendingCropRectSet; +#endif + +class RendererContext : public RendererObject { +public: + static RendererContext *create(EGLDisplay dpy, EGLConfig config, RendererContext *shareCtx); + EGLContext eglContext() { return m_ctx; } + int destroy(); + GLDecoderContextData & decoderContextData() { return m_contextData; } +#ifdef PVR_WAR + void setActiveTexture(GLenum texture); + GLenum getActiveTexture() { return GL_TEXTURE0 + m_activeTexture; } + void setTex2DBind(GLuint texture); + void setTex2DEnable(bool enable) { + m_tex2DEnable[m_activeTexture] = enable; + } + bool isTex2DEnable(int texunit) { return m_tex2DEnable[texunit]; } + GLuint getTex2DBind(); + void addPendingCropRect(int *rect); + PendingCropRectSet &getPendingCropRects() { return m_pendingCropRects; } + + void setClientActiveTexture(GLenum texture) { m_clientActiveTexture = texture - GL_TEXTURE0; } + GLenum getClientActiveTexture() { return m_clientActiveTexture + GL_TEXTURE0; } + void enableClientState(GLenum cap, bool enable) { + switch(cap) { + case GL_VERTEX_ARRAY: + m_clientStateEnable[0] = enable; + break; + case GL_NORMAL_ARRAY: + m_clientStateEnable[1] = enable; + break; + case GL_COLOR_ARRAY: + m_clientStateEnable[2] = enable; + break; + case GL_POINT_SIZE_ARRAY_OES: + m_clientStateEnable[3] = enable; + break; + case GL_TEXTURE_COORD_ARRAY: + m_clientStateEnable[4 + m_clientActiveTexture] = enable; + break; + } + } + + bool getClientState(GLenum cap, int texUnit) { + switch(cap) { + case GL_VERTEX_ARRAY: + return m_clientStateEnable[0]; + case GL_NORMAL_ARRAY: + return m_clientStateEnable[1]; + case GL_COLOR_ARRAY: + return m_clientStateEnable[2]; + case GL_POINT_SIZE_ARRAY_OES: + return m_clientStateEnable[3]; + break; + case GL_TEXTURE_COORD_ARRAY: + return m_clientStateEnable[4 + texUnit]; + break; + } + return false; + } +#endif + +private: + EGLDisplay m_dpy; + EGLContext m_ctx; + GLDecoderContextData m_contextData; + + RendererContext(EGLDisplay dpy, EGLContext ctx) : + m_dpy(dpy), + m_ctx(ctx) + { +#ifdef PVR_WAR + m_activeTexture = 0; + m_clientActiveTexture = 0; + memset(m_tex2DBind, 0, 8*sizeof(GLuint)); + memset(m_tex2DEnable, 0, 8*sizeof(bool)); + memset(m_clientStateEnable, 0, 16*sizeof(bool)); +#endif + } + +#ifdef PVR_WAR + int m_tex2DBind[8]; + bool m_tex2DEnable[8]; + int m_activeTexture; + int m_clientActiveTexture; + bool m_clientStateEnable[16]; + PendingCropRectSet m_pendingCropRects; +#endif +}; +#endif diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererObject.h b/tools/emulator/opengl/tests/ut_renderer/RendererObject.h new file mode 100644 index 000000000..18c89beac --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/RendererObject.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 _RENDERER_OBJECT_H_ +#define _RENDERER_OBJECT_H_ + +class RendererObject { +public: + RendererObject() { m_count = 0; } + + int count() { return m_count; } + void ref() { m_count++; } + void unref() { m_count--; } +private: + int m_count; +}; +#endif diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererSurface.cpp b/tools/emulator/opengl/tests/ut_renderer/RendererSurface.cpp new file mode 100644 index 000000000..2a8dc81ef --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/RendererSurface.cpp @@ -0,0 +1,91 @@ +/* +* 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 "RendererSurface.h" +#include +#include + +#include "NativeWindowing.h" + +#define MAX_ATTRIB 100 + + +EGLConfig RendererSurface::getEglConfig(EGLDisplay eglDisplay, SurfaceConfig config) +{ + EGLConfig eglConfig; + int nConfigs; + + EGLint attrib[MAX_ATTRIB]; + int pos =0; + + attrib[pos++] = EGL_SURFACE_TYPE; attrib[pos++] = EGL_WINDOW_BIT; + if (config & CONFIG_DEPTH) {attrib[pos++] = EGL_DEPTH_SIZE; attrib[pos++] = 1;} + attrib[pos++] = EGL_NONE; + + if (!eglChooseConfig(eglDisplay, attrib, &eglConfig, 1, &nConfigs)) { + return 0; + } + /***/ + int ibuf; + if (eglGetConfigAttrib(eglDisplay, eglConfig, EGL_BUFFER_SIZE, &ibuf)) { + fprintf(stderr, "EGL COLOR Buffer size: %d\n", ibuf); + } else { + fprintf(stderr, "eglGetConfigAttrib error: %d\n", eglGetError()); + } + if (eglGetConfigAttrib(eglDisplay, eglConfig, EGL_DEPTH_SIZE, &ibuf)) { + fprintf(stderr, "EGL DEPTH Buffer size: %d\n", ibuf); + } else { + fprintf(stderr, "eglGetConfigAttrib error: %d\n", eglGetError()); + } + /***/ + + + if (nConfigs != 1) { + return 0; + } + return eglConfig; +} + +RendererSurface * RendererSurface::create(EGLDisplay eglDisplay, SurfaceConfig config, NativeWindowing *nw) +{ + + EGLConfig eglConfig = getEglConfig(eglDisplay, config); + if (eglConfig == 0) { + return NULL; + } + + NativeWindowType window = nw->createNativeWindow(nw->getNativeDisplay(), DEFAULT_WIDTH, DEFAULT_HEIGHT); + if (window == 0) { + return NULL; + } + + EGLSurface eglSurface = eglCreateWindowSurface(eglDisplay, + eglConfig, + window, NULL); + + if (eglGetError() != EGL_SUCCESS) { + return NULL; + } + + return new RendererSurface(eglDisplay, window, eglSurface, eglConfig); +} + +int RendererSurface::destroy(NativeWindowing *nw) +{ + eglDestroySurface(m_eglDisplay, m_eglSurface); + nw->destroyNativeWindow(nw->getNativeDisplay(), m_window); + return 1; +} + diff --git a/tools/emulator/opengl/tests/ut_renderer/RendererSurface.h b/tools/emulator/opengl/tests/ut_renderer/RendererSurface.h new file mode 100644 index 000000000..4f6709cde --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/RendererSurface.h @@ -0,0 +1,52 @@ +/* +* 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 _RENDERER_SURFACE_H_ +#define _RENDERER_SURFACE_H_ + +#include +#include "NativeWindowing.h" +#include "RendererObject.h" + +#define DEFAULT_HEIGHT 480 +#define DEFAULT_WIDTH 320 + +class RendererSurface : public RendererObject { +public: + typedef enum { CONFIG_DEPTH = 1 << 0 } SurfaceConfig; + + EGLSurface eglSurface() { return m_eglSurface; } + EGLConfig eglConfig() { return m_config; } + EGLDisplay eglDisplay() { return m_eglDisplay; } + + static RendererSurface * create(EGLDisplay eglDisplay, SurfaceConfig config, NativeWindowing *nw); + static EGLConfig getEglConfig(EGLDisplay eglDisplay, SurfaceConfig config); + + int destroy(NativeWindowing *nw); + +private: + RendererSurface(EGLDisplay display, NativeWindowType window, EGLSurface surface, EGLConfig config) : + m_eglDisplay(display), + m_config(config), + m_window(window), + m_eglSurface(surface) + {} + + EGLDisplay m_eglDisplay; + EGLConfig m_config; + NativeWindowType m_window; + EGLSurface m_eglSurface; +}; +#endif diff --git a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp new file mode 100644 index 000000000..a7bd939af --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.cpp @@ -0,0 +1,376 @@ +/* +* 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 "RenderingThread.h" +#include +#include +#include +#include +#include "ReadBuffer.h" +#include "Renderer.h" +#include "TimeUtils.h" + +#include + +__thread RenderingThread * RenderingThread::m_tls; + +#ifdef PVR_WAR +void RenderingThread::s_glTexParameteriv(GLenum target, GLenum param, int *p) +{ + if (target == GL_TEXTURE_2D && param == GL_TEXTURE_CROP_RECT_OES) { + m_tls->m_currentContext->addPendingCropRect(p); + } else { + m_tls->m_glTexParameteriv(target, param, p); + } +} + +void RenderingThread::s_glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h) +{ + m_tls->applyPendingCropRects(); + m_tls->m_glDrawTexfOES(x, y, z, w, h); + m_tls->fixTextureEnable(); +} + +void RenderingThread::s_glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort w, GLshort h) +{ + m_tls->applyPendingCropRects(); + m_tls->m_glDrawTexsOES(x, y, z, w, h); + m_tls->fixTextureEnable(); +} + +void RenderingThread::s_glDrawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h) +{ + m_tls->applyPendingCropRects(); + m_tls->m_glDrawTexiOES(x, y, z, w, h); + m_tls->fixTextureEnable(); +} + +void RenderingThread::s_glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h) +{ + m_tls->applyPendingCropRects(); + m_tls->m_glDrawTexxOES(x, y, z, w, h); + m_tls->fixTextureEnable(); +} + +void RenderingThread::s_glDrawTexfvOES(GLfloat *coords) +{ + m_tls->applyPendingCropRects(); + m_tls->m_glDrawTexfvOES(coords); + m_tls->fixTextureEnable(); +} + +void RenderingThread::s_glDrawTexsvOES(GLshort *coords) +{ + m_tls->applyPendingCropRects(); + m_tls->m_glDrawTexsvOES(coords); + m_tls->fixTextureEnable(); +} + +void RenderingThread::s_glDrawTexivOES(GLint *coords) +{ + m_tls->applyPendingCropRects(); + m_tls->m_glDrawTexivOES(coords); + m_tls->fixTextureEnable(); +} + +void RenderingThread::s_glDrawTexxvOES(GLfixed *coords) +{ + m_tls->applyPendingCropRects(); + m_tls->m_glDrawTexxvOES(coords); + m_tls->fixTextureEnable(); +} + + +void RenderingThread::s_glActiveTexture(GLenum texture) +{ + if (texture - GL_TEXTURE0 >= m_tls->m_backendCaps.maxTextureUnits) return; + + m_tls->m_currentContext->setActiveTexture(texture); + m_tls->m_glActiveTexture(texture); +} + +void RenderingThread::s_glBindTexture(GLenum target, GLuint texture) +{ + if (target == GL_TEXTURE_2D) m_tls->m_currentContext->setTex2DBind(texture); + m_tls->m_glBindTexture(target, texture); +} + +void RenderingThread::s_glEnable(GLenum cap) +{ + if (cap == GL_TEXTURE_2D) m_tls->m_currentContext->setTex2DEnable(true); + m_tls->m_glEnable(cap); +} + +void RenderingThread::s_glDisable(GLenum cap) +{ + if (cap == GL_TEXTURE_2D) m_tls->m_currentContext->setTex2DEnable(false); + m_tls->m_glDisable(cap); +} + +void RenderingThread::s_glClientActiveTexture(GLenum texture) +{ + if (texture - GL_TEXTURE0 >= m_tls->m_backendCaps.maxTextureUnits) return; + m_tls->m_currentContext->setClientActiveTexture(texture); + m_tls->m_glClientActiveTexture(texture); +} + +void RenderingThread::s_glEnableClientState(GLenum cap) +{ + m_tls->m_currentContext->enableClientState(cap, true); + m_tls->m_glEnableClientState(cap); +} + +void RenderingThread::s_glDisableClientState(GLenum cap) +{ + m_tls->m_currentContext->enableClientState(cap, false); + m_tls->m_glDisableClientState(cap); +} + +void RenderingThread::applyPendingCropRects() +{ + PendingCropRectSet &rset = m_currentContext->getPendingCropRects(); + if (rset.size() > 0) { + GLuint currBindedTex = m_currentContext->getTex2DBind(); + for (PendingCropRectSet::iterator i = rset.begin(); + i != rset.end(); + i++) { + m_glBindTexture(GL_TEXTURE_2D, (*i)->texture); + m_glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, (int *)(*i)->rect); + delete (*i); + } + m_glBindTexture(GL_TEXTURE_2D, currBindedTex); + rset.clear(); + } +} + +void RenderingThread::fixTextureEnable() +{ + // restore texture units enable state + for (unsigned int i=0; iisTex2DEnable(i)) { + m_glEnable(GL_TEXTURE_2D); + } + else { + m_glDisable(GL_TEXTURE_2D); + } + m_glClientActiveTexture(GL_TEXTURE0 + i); + if (m_currentContext->getClientState(GL_TEXTURE_COORD_ARRAY, i)) { + m_glEnableClientState(GL_TEXTURE_COORD_ARRAY); + } + else { + m_glDisableClientState(GL_TEXTURE_COORD_ARRAY); + } + } + // restore current active texture + m_glActiveTexture(m_currentContext->getActiveTexture()); + m_glClientActiveTexture(m_currentContext->getClientActiveTexture()); + + // restore other client state enable bits + if (m_currentContext->getClientState(GL_VERTEX_ARRAY, 0)) { + m_glEnableClientState(GL_VERTEX_ARRAY); + } + else { + m_glDisableClientState(GL_VERTEX_ARRAY); + } + + if (m_currentContext->getClientState(GL_NORMAL_ARRAY, 0)) { + m_glEnableClientState(GL_NORMAL_ARRAY); + } + else { + m_glDisableClientState(GL_NORMAL_ARRAY); + } + + if (m_currentContext->getClientState(GL_COLOR_ARRAY, 0)) { + m_glEnableClientState(GL_COLOR_ARRAY); + } + else { + m_glDisableClientState(GL_COLOR_ARRAY); + } + + if (m_currentContext->getClientState(GL_POINT_SIZE_ARRAY_OES, 0)) { + m_glEnableClientState(GL_POINT_SIZE_ARRAY_OES); + } + else { + m_glDisableClientState(GL_POINT_SIZE_ARRAY_OES); + } +} +#endif + + +int RenderingThread::s_createContext(uint32_t pid, uint32_t handle, uint32_t shareCtx) +{ + return Renderer::instance()->createContext(m_tls, Renderer::ClientHandle(pid, handle), + Renderer::ClientHandle(pid, shareCtx)); + +} + + +int RenderingThread::s_createSurface(uint32_t pid, uint32_t handle) +{ + return Renderer::instance()->createSurface(m_tls, Renderer::ClientHandle(pid, handle)); +} + +int RenderingThread::s_destroySurface(uint32_t pid, uint32_t handle) +{ + return Renderer::instance()->destroySurface(m_tls, Renderer::ClientHandle(pid, handle)); +} + +int RenderingThread::s_destroyContext(uint32_t pid, uint32_t handle) +{ + return Renderer::instance()->destroyContext(m_tls, Renderer::ClientHandle(pid, handle)); +} + + +int RenderingThread::s_makeCurrent(uint32_t pid, uint32_t drawSurface, uint32_t readSurface, uint32_t ctx) +{ + int ret = Renderer::instance()->makeCurrent(m_tls, + Renderer::ClientHandle(pid, drawSurface), + Renderer::ClientHandle(pid, readSurface), + Renderer::ClientHandle(pid, ctx)); + + if (ret && ctx) { + m_tls->initBackendCaps(); + } + + return ret; +} + +void RenderingThread::s_swapBuffers(uint32_t pid, uint32_t surface) +{ + Renderer::instance()->swapBuffers(m_tls, Renderer::ClientHandle(pid, surface)); +} + + +RenderingThread::RenderingThread(TcpStream *stream) : + m_stream(stream), + m_currentContext(NULL) +{ + m_backendCaps.initialized = false; +} + +int RenderingThread::start(void) +{ + if (pthread_create(&m_thread, NULL, s_thread, this) < 0) { + perror("pthread_create"); + return -1; + } + return 0; +} + + +void * RenderingThread::s_thread(void *data) +{ + RenderingThread *self = (RenderingThread *)data; + m_tls = self; + return self->thread(); +} + +void RenderingThread::initBackendCaps() +{ + if (m_backendCaps.initialized) return; + + m_glDec.glGetIntegerv(GL_MAX_TEXTURE_UNITS, (GLint *)&m_backendCaps.maxTextureUnits); + m_backendCaps.initialized = true; +} + +void *RenderingThread::thread() +{ + + // initialize our decoders; + m_glDec.initGL(); + +#ifdef PVR_WAR + m_glTexParameteriv = m_glDec.set_glTexParameteriv(s_glTexParameteriv); + m_glDrawTexfOES = m_glDec.set_glDrawTexfOES(s_glDrawTexfOES); + m_glDrawTexsOES = m_glDec.set_glDrawTexsOES(s_glDrawTexsOES); + m_glDrawTexiOES = m_glDec.set_glDrawTexiOES(s_glDrawTexiOES); + m_glDrawTexxOES = m_glDec.set_glDrawTexxOES(s_glDrawTexxOES); + m_glDrawTexfvOES = m_glDec.set_glDrawTexfvOES(s_glDrawTexfvOES); + m_glDrawTexsvOES = m_glDec.set_glDrawTexsvOES(s_glDrawTexsvOES); + m_glDrawTexivOES = m_glDec.set_glDrawTexivOES(s_glDrawTexivOES); + m_glDrawTexxvOES = m_glDec.set_glDrawTexxvOES(s_glDrawTexxvOES); + m_glActiveTexture = m_glDec.set_glActiveTexture(s_glActiveTexture); + m_glBindTexture = m_glDec.set_glBindTexture(s_glBindTexture); + m_glEnable = m_glDec.set_glEnable(s_glEnable); + m_glDisable = m_glDec.set_glDisable(s_glDisable); + m_glClientActiveTexture = m_glDec.set_glClientActiveTexture(s_glClientActiveTexture); + m_glEnableClientState = m_glDec.set_glEnableClientState(s_glEnableClientState); + m_glDisableClientState = m_glDec.set_glDisableClientState(s_glDisableClientState); +#endif + + m_utDec.set_swapBuffers(s_swapBuffers); + m_utDec.set_createContext(s_createContext); + m_utDec.set_destroyContext(s_destroyContext); + m_utDec.set_createSurface(s_createSurface); + m_utDec.set_destroySurface(s_destroySurface); + m_utDec.set_makeCurrentContext(s_makeCurrent); + + ReadBuffer readBuf(m_stream, DECODER_BUF_SIZE); + + int stats_totalBytes = 0; + long long stats_t0 = GetCurrentTimeMS(); + + while (1) { + + int stat = readBuf.getData(); + if (stat == 0) { + fprintf(stderr, "client shutdown\n"); + break; + } else if (stat < 0) { + perror("getData"); + 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(); + } + + bool progress = true; + while (progress) { + progress = false; + // we need at least one header (8 bytes) in our buffer + if (readBuf.validData() >= 8) { + size_t last = m_glDec.decode(readBuf.buf(), readBuf.validData(), m_stream); + if (last > 0) { + progress = true; + readBuf.consume(last); + } + } + + if (readBuf.validData() >= 8) { + size_t last = m_utDec.decode(readBuf.buf(), readBuf.validData(), m_stream); + if (last > 0) { + readBuf.consume(last); + progress = true; + } + } + } + } + // shutdown + if (m_currentContext != NULL) { + m_currentContext->unref(); + } + + return NULL; +} diff --git a/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h new file mode 100644 index 000000000..bbc4dd38a --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/RenderingThread.h @@ -0,0 +1,113 @@ +/* +* 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 _RENDERING_THREAD_H_ +#define _RENDERING_THREAD_H_ + +#include "TcpStream.h" +#include "GLDecoder.h" +#include "ut_rendercontrol_dec.h" +#include + +#define GL_API +#define GL_APIENTRY + +#include +#include + + +#define WINDOW_WIDTH 320 +#define WINDOW_HEIGHT 480 + +#define DECODER_BUF_SIZE (4 * 1024 * 1024) + +class RendererContext; + +class RenderingThread { +public: + RenderingThread(TcpStream *stream); + int start(); + void *thread(); + RendererContext *currentContext() { return m_currentContext; } + void setCurrentContext(RendererContext *ctx) { m_currentContext = ctx; } + GLDecoder & glDecoder() { return m_glDec; } +private: + void initBackendCaps(); + +private: + GLDecoder m_glDec; + ut_rendercontrol_decoder_context_t m_utDec; + + TcpStream *m_stream; + pthread_t m_thread; + RendererContext * m_currentContext; + + struct BackendCaps { + bool initialized; + GLuint maxTextureUnits; + } m_backendCaps; + + static void * s_thread(void *data); + static __thread RenderingThread *m_tls; + + static int s_createContext(uint32_t pid, uint32_t handle, uint32_t shareCtx); + static int s_createSurface(uint32_t pid, uint32_t handle); + static int s_destroySurface(uint32_t pid, uint32_t handle); + static int s_destroyContext(uint32_t pid, uint32_t handle); + static int s_makeCurrent(uint32_t pid, uint32_t drawSurface, uint32_t readSurface, uint32_t ctx); + static void s_swapBuffers(uint32_t pid, uint32_t surface); +#ifdef PVR_WAR + static void s_glTexParameteriv(GLenum target, GLenum param, int *p); + static void s_glDrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat w, GLfloat h); + static void s_glDrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort w, GLshort h); + static void s_glDrawTexiOES(GLint x, GLint y, GLint z, GLint w, GLint h); + static void s_glDrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h); + static void s_glDrawTexfvOES(GLfloat *coords); + static void s_glDrawTexsvOES(GLshort *coords); + static void s_glDrawTexivOES(GLint *coords); + static void s_glDrawTexxvOES(GLfixed *coords); + + static void s_glActiveTexture(GLenum texture); + static void s_glBindTexture(GLenum target, GLuint texture); + static void s_glEnable(GLenum cap); + static void s_glDisable(GLenum cap); + static void s_glClientActiveTexture(GLenum texture); + static void s_glEnableClientState(GLenum cap); + static void s_glDisableClientState(GLenum cap); + + void applyPendingCropRects(); + void fixTextureEnable(); + + glTexParameteriv_server_proc_t m_glTexParameteriv; + glDrawTexfOES_server_proc_t m_glDrawTexfOES; + glDrawTexiOES_server_proc_t m_glDrawTexiOES; + glDrawTexsOES_server_proc_t m_glDrawTexsOES; + glDrawTexxOES_server_proc_t m_glDrawTexxOES; + glDrawTexfvOES_server_proc_t m_glDrawTexfvOES; + glDrawTexivOES_server_proc_t m_glDrawTexivOES; + glDrawTexsvOES_server_proc_t m_glDrawTexsvOES; + glDrawTexxvOES_server_proc_t m_glDrawTexxvOES; + glActiveTexture_server_proc_t m_glActiveTexture; + glBindTexture_server_proc_t m_glBindTexture; + glEnable_server_proc_t m_glEnable; + glDisable_server_proc_t m_glDisable; + glClientActiveTexture_server_proc_t m_glClientActiveTexture; + glEnableClientState_server_proc_t m_glEnableClientState; + glDisableClientState_server_proc_t m_glDisableClientState; +#endif + +}; + +#endif diff --git a/tools/emulator/opengl/tests/ut_renderer/TimeUtils.cpp b/tools/emulator/opengl/tests/ut_renderer/TimeUtils.cpp new file mode 100644 index 000000000..7f65cca5e --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/TimeUtils.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 "TimeUtils.h" + +#ifdef _WIN32 +#include +#include +#include +#elif defined(__linux__) +#include +#include +#include +#else +#error "Unsupported platform" +#endif + +long long GetCurrentTimeMS() +{ +#ifdef _WIN32 + static LARGE_INTEGER freq; + static bool bNotInit = true; + if ( bNotInit ) { + bNotInit = (QueryPerformanceFrequency( &freq ) == FALSE); + } + LARGE_INTEGER currVal; + QueryPerformanceCounter( &currVal ); + + return currVal.QuadPart / (freq.QuadPart / 1000); + +#elif defined(__linux__) + + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + long long iDiff = (now.tv_sec * 1000LL) + now.tv_nsec/1000000LL; + return iDiff; + +#else + +#error "Unsupported platform" + +#endif +} diff --git a/tools/emulator/opengl/tests/ut_renderer/TimeUtils.h b/tools/emulator/opengl/tests/ut_renderer/TimeUtils.h new file mode 100644 index 000000000..184a13f81 --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/TimeUtils.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 _TIME_UTILS_H +#define _TIME_UTILS_H + +long long GetCurrentTimeMS(); + +#endif diff --git a/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.cpp b/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.cpp new file mode 100644 index 000000000..121ee87c1 --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.cpp @@ -0,0 +1,69 @@ +/* +* 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 "X11RendererSurface.h" + +NativeDisplayType X11RendererSurface::getNativeDisplay() +{ + if (m_display == NULL) { + m_display = XOpenDisplay(NULL); + } + return NativeDisplayType(m_display); +} + +int X11RendererSurface::destoryNativeWindow(NativeWindowType win) +{ + if (m_display == NULL) return -1; + + Window x11Window = (Window)(win); + return XDestroyWindow(m_display, x11Window); +} + +NativeWindowType GlesX11Win::createNativeWindow() +{ + + getNativeDisplay(); + if (m_display == NULL) { + return -1; + } + + long defaultScreen = DefaultScreen( dpy ); + Window rootWindow = RootWindow(dpy, defaultScreen); + int depth = DefaultDepth(dpy, defaultScreen); + XVisualInfo *visualInfo = new XVisualInfo; + + XMatchVisualInfo(m_display, defaultScreen, , dpeth, TrueColor, visualInfo); + if (visualInfo == NULL) { + fprintf(stderr, "couldn't find matching visual\n"); + return -1; + } + + Colormap x11Colormap = XCreateColormap(m_display, rootWindow, visualInfo->visual, AllocNone); + XSetWindowAttributes sWA; + sWA.Colormap = x11Colormap; + sWA.event_mask = StructureNotifyMask | ExposureMask; + unsigned int eventMask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap; + + Window win = XCreateWindow( m_display, + rootWindow, + 0, 0, width, height, + 0, CopyFromParent, InputOutput, + CopyFromParent, eventMask, &sWA); + + XMapWindow(m_display, win); + XFlush(m_display); + return NativeWindowType(win); +} + diff --git a/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.h b/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.h new file mode 100644 index 000000000..be9bcece2 --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/X11RendererSurface.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 _X11_RENDERER_SURFACE_H_ +#define _X11_RENDERER_SURFACE_H_ + +#include +#include +#include + +include "RendererSurface.h" + +class X11RendererSurface : public RendererSurface +{ +public: + X11RendererSurface() : RendererSurface() { + m_display = NULL; + } + NativeDisplayType getNativeDisplay(); + NativeWindowType createNativeWindow(); + int destroyNativeWindow(NativeWindowType win); +private: + Display m_display; +}; +#endif diff --git a/tools/emulator/opengl/tests/ut_renderer/X11Windowing.cpp b/tools/emulator/opengl/tests/ut_renderer/X11Windowing.cpp new file mode 100644 index 000000000..4009eb421 --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/X11Windowing.cpp @@ -0,0 +1,70 @@ +/* +* 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 "X11Windowing.h" + +#include +#include +#include +#include + +NativeDisplayType X11Windowing::getNativeDisplay() +{ + Display *dpy = XOpenDisplay(NULL); + return (NativeDisplayType)dpy; +} + +NativeWindowType X11Windowing::createNativeWindow(NativeDisplayType _dpy, int width, int height) +{ + Display *dpy = (Display *) _dpy; + + long defaultScreen = DefaultScreen( dpy ); + Window rootWindow = RootWindow(dpy, defaultScreen); + int depth = DefaultDepth(dpy, defaultScreen); + XVisualInfo *visualInfo = new XVisualInfo; + + XMatchVisualInfo(dpy, defaultScreen, depth, TrueColor, visualInfo); + if (visualInfo == NULL) { + fprintf(stderr, "couldn't find matching visual\n"); + return NULL; + } + + Colormap x11Colormap = XCreateColormap(dpy, rootWindow, visualInfo->visual, AllocNone); + XSetWindowAttributes sWA; + sWA.colormap = x11Colormap; + sWA.event_mask = StructureNotifyMask | ExposureMask; + sWA.background_pixel = 0; + sWA.border_pixel = 0; + unsigned int attributes_mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap; + + Window win = XCreateWindow( dpy, + rootWindow, + 0, 0, width, height, + 0, CopyFromParent, InputOutput, + CopyFromParent, attributes_mask, &sWA); + + XMapWindow(dpy, win); + XFlush(dpy); + return NativeWindowType(win); +} + +int X11Windowing::destroyNativeWindow(NativeDisplayType _dpy, NativeWindowType _win) +{ + Display *dpy = (Display *)_dpy; + Window win = (Window)_win; + XDestroyWindow(dpy, win); + XFlush(dpy); + return 0; +} diff --git a/tools/emulator/opengl/tests/ut_renderer/X11Windowing.h b/tools/emulator/opengl/tests/ut_renderer/X11Windowing.h new file mode 100644 index 000000000..0f0c76be1 --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/X11Windowing.h @@ -0,0 +1,27 @@ +/* +* 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 _X11WINDOWING_H_ +#define _X11WINDOWING_H_ + +#include "NativeWindowing.h" + +class X11Windowing : public NativeWindowing { + NativeDisplayType getNativeDisplay(); + NativeWindowType createNativeWindow(NativeDisplayType _dpy, int width, int height); + int destroyNativeWindow(NativeDisplayType dpy, NativeWindowType win); +}; + +#endif diff --git a/tools/emulator/opengl/tests/ut_renderer/ut_renderer.cpp b/tools/emulator/opengl/tests/ut_renderer/ut_renderer.cpp new file mode 100644 index 000000000..2137a8295 --- /dev/null +++ b/tools/emulator/opengl/tests/ut_renderer/ut_renderer.cpp @@ -0,0 +1,52 @@ +/* +* 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 +#include +#include +#include +#include "codec_defs.h" +#include "RenderingThread.h" +#include "TcpStream.h" + + +int main(int argc, char **argv) +{ + + TcpStream *socket = new TcpStream; + + if (socket->listen(CODEC_SERVER_PORT) < 0) { + perror("listen"); + exit(1); + } + + printf("waiting for client connection on port: %d\n", CODEC_SERVER_PORT); + while (1) { + // wait for client connection + TcpStream *glStream = socket->accept(); + if (glStream == NULL) { + printf("failed to get client.. aborting\n"); + exit(3); + } + printf("Got client connection, creating a rendering thread;\n"); + // create a thread to handle this connection + RenderingThread *rt = new RenderingThread(glStream); + rt->start(); + } + + return 0; +} + +