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; +} + +