diff --git a/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp b/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp index fdccc1533..e774c62fe 100644 --- a/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp +++ b/tools/emulator/opengl/shared/OpenglCodecCommon/TcpStream.cpp @@ -134,7 +134,7 @@ int TcpStream::writeFully(const void *buf, size_t len) if (stat < 0) { if (errno != EINTR) { retval = stat; - ERR("TcpStream::writeFully failed, errno = %d\n", errno); + ERR("TcpStream::writeFully failed: %s\n", strerror(errno)); break; } } else { @@ -161,7 +161,7 @@ const unsigned char *TcpStream::readFully(void *buf, size_t len) if (errno == EINTR) { continue; } else { - ERR("TcpStream::readFully failed, errno = %d 0x%x \n", errno,buf); + ERR("TcpStream::readFully failed (buf 0x%x): %s\n", buf, strerror(errno)); return NULL; } } else { diff --git a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp index dea34c81f..2095af50e 100644 --- a/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp +++ b/tools/emulator/opengl/system/GLESv1_enc/GLEncoder.cpp @@ -428,7 +428,7 @@ void GLEncoder::s_glDrawElements(void *self, GLenum mode, GLsizei count, GLenum count * glSizeof(type)); // XXX - OPTIMIZATION (see the other else branch) should be implemented if(!has_indirect_arrays) { - LOGD("unoptimized drawelements !!!\n"); + //LOGD("unoptimized drawelements !!!\n"); } } else { // we are all direct arrays and immidate mode index array - diff --git a/tools/emulator/opengl/system/OpenglSystemCommon/Android.mk b/tools/emulator/opengl/system/OpenglSystemCommon/Android.mk index ff14f1a8f..760bb7212 100644 --- a/tools/emulator/opengl/system/OpenglSystemCommon/Android.mk +++ b/tools/emulator/opengl/system/OpenglSystemCommon/Android.mk @@ -12,6 +12,7 @@ LOCAL_ADDITIONAL_DEPENDENCIES := \ LOCAL_SRC_FILES := \ HostConnection.cpp \ + QemuPipeStream.cpp \ ThreadInfo.cpp LOCAL_C_INCLUDES += \ diff --git a/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp b/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp index c87724700..bfb43f99e 100644 --- a/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp +++ b/tools/emulator/opengl/system/OpenglSystemCommon/HostConnection.cpp @@ -15,12 +15,16 @@ */ #include "HostConnection.h" #include "TcpStream.h" +#include "QemuPipeStream.h" #include "ThreadInfo.h" #include #define STREAM_BUFFER_SIZE 4*1024*1024 #define STREAM_PORT_NUM 4141 +/* Set to 1 to use a QEMU pipe, or 0 for a TCP connection */ +#define USE_QEMU_PIPE 1 + HostConnection::HostConnection() : m_stream(NULL), m_glEnc(NULL), @@ -37,36 +41,52 @@ HostConnection::~HostConnection() HostConnection *HostConnection::get() { + /* TODO: Make this configurable with a system property */ + const int useQemuPipe = USE_QEMU_PIPE; + // Get thread info EGLThreadInfo *tinfo = getEGLThreadInfo(); if (!tinfo) { return NULL; } - // - // create new host connection for that thread if needed - // if (tinfo->hostConn == NULL) { HostConnection *con = new HostConnection(); if (NULL == con) { return NULL; } - TcpStream *stream = new TcpStream(STREAM_BUFFER_SIZE); - if (!stream) { - LOGE("Failed to create TcpStream for host connection!!!\n"); - delete con; - return NULL; + if (useQemuPipe) { + QemuPipeStream *stream = new QemuPipeStream(STREAM_BUFFER_SIZE); + if (!stream) { + LOGE("Failed to create QemuPipeStream for host connection!!!\n"); + delete con; + return NULL; + } + if (stream->connect() < 0) { + LOGE("Failed to connect to host !!!\n"); + delete con; + return NULL; + } + con->m_stream = stream; } + else /* !useQemuPipe */ + { + TcpStream *stream = new TcpStream(STREAM_BUFFER_SIZE); + if (!stream) { + LOGE("Failed to create TcpStream for host connection!!!\n"); + delete con; + return NULL; + } - if (stream->connect("10.0.2.2", STREAM_PORT_NUM) < 0) { - LOGE("Failed to connect to host !!!\n"); - delete con; - return NULL; + if (stream->connect("10.0.2.2", STREAM_PORT_NUM) < 0) { + LOGE("Failed to connect to host !!!\n"); + delete con; + return NULL; + } + con->m_stream = stream; } LOGD("Host Connection established \n"); - - con->m_stream = stream; tinfo->hostConn = con; } diff --git a/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp b/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp new file mode 100644 index 000000000..1a339ba29 --- /dev/null +++ b/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp @@ -0,0 +1,184 @@ +/* +* 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 "QemuPipeStream.h" +#include +#include +#include +#include +#include +#include + +QemuPipeStream::QemuPipeStream(size_t bufSize) : + IOStream(bufSize), + m_sock(-1), + m_bufsize(bufSize), + m_buf(NULL) +{ +} + +QemuPipeStream::QemuPipeStream(int sock, size_t bufSize) : + IOStream(bufSize), + m_sock(sock), + m_bufsize(bufSize), + m_buf(NULL) +{ +} + +QemuPipeStream::~QemuPipeStream() +{ + if (m_sock >= 0) { + ::close(m_sock); + } + if (m_buf != NULL) { + free(m_buf); + } +} + + +int QemuPipeStream::connect(void) +{ + m_sock = qemu_pipe_open("opengles"); + if (!valid()) return -1; + return 0; +} + +void *QemuPipeStream::allocBuffer(size_t minSize) +{ + size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize); + if (!m_buf) { + m_buf = (unsigned char *)malloc(allocSize); + } + else if (m_bufsize < allocSize) { + unsigned char *p = (unsigned char *)realloc(m_buf, allocSize); + if (p != NULL) { + m_buf = p; + m_bufsize = allocSize; + } else { + ERR("realloc (%d) failed\n", allocSize); + free(m_buf); + m_buf = NULL; + m_bufsize = 0; + } + } + + return m_buf; +}; + +int QemuPipeStream::commitBuffer(size_t size) +{ + return writeFully(m_buf, size); +} + +int QemuPipeStream::writeFully(const void *buf, size_t len) +{ + if (!valid()) return -1; + + size_t res = len; + int retval = 0; + + while (res > 0) { + ssize_t stat = ::write(m_sock, (const char *)(buf) + (len - res), res); + if (stat > 0) { + res -= stat; + continue; + } + if (stat == 0) { /* EOF */ + ERR("QemuPipeStream::writeFully failed: premature EOF\n"); + retval = -1; + break; + } + if (errno == EINTR) { + continue; + } + retval = stat; + ERR("QemuPipeStream::writeFully failed: %s\n", strerror(errno)); + break; + } + return retval; +} + +const unsigned char *QemuPipeStream::readFully(void *buf, size_t len) +{ + if (!valid()) return NULL; + if (!buf) { + ERR("QemuPipeStream::readFully failed, buf=NULL"); + return NULL; // do not allow NULL buf in that implementation + } + size_t res = len; + while (res > 0) { + ssize_t stat = ::read(m_sock, (char *)(buf) + len - res, len); + if (stat == 0) { + // client shutdown; + return NULL; + } else if (stat < 0) { + if (errno == EINTR) { + continue; + } else { + ERR("QemuPipeStream::readFully failed (buf %p): %s\n", + buf, strerror(errno)); + return NULL; + } + } else { + res -= stat; + } + } + return (const unsigned char *)buf; +} + +const unsigned char *QemuPipeStream::read( void *buf, size_t *inout_len) +{ + if (!valid()) return NULL; + if (!buf) { + ERR("QemuPipeStream::read failed, buf=NULL"); + return NULL; // do not allow NULL buf in that implementation + } + + int n = recv(buf, *inout_len); + + if (n > 0) { + *inout_len = n; + return (const unsigned char *)buf; + } + + return NULL; +} + +int QemuPipeStream::recv(void *buf, size_t len) +{ + if (!valid()) return int(ERR_INVALID_SOCKET); + char* p = (char *)buf; + int ret = 0; + while(len > 0) { + int res = ::read(m_sock, p, len); + if (res > 0) { + p += res; + ret += res; + len -= res; + continue; + } + if (res == 0) { /* EOF */ + break; + } + if (errno == EINTR) + continue; + + /* A real error */ + if (ret == 0) + ret = -1; + break; + } + return ret; +} diff --git a/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.h b/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.h new file mode 100644 index 000000000..db362867a --- /dev/null +++ b/tools/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.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 __QEMU_PIPE_STREAM_H +#define __QEMU_PIPE_STREAM_H + +/* This file implements an IOStream that uses a QEMU fast-pipe + * to communicate with the emulator's 'opengles' service. See + * for more details. + */ +#include +#include "IOStream.h" + +class QemuPipeStream : public IOStream { +public: + typedef enum { ERR_INVALID_SOCKET = -1000 } QemuPipeStreamError; + + explicit QemuPipeStream(size_t bufsize = 10000); + ~QemuPipeStream(); + int connect(void); + + virtual void *allocBuffer(size_t minSize); + virtual int commitBuffer(size_t size); + virtual const unsigned char *readFully( void *buf, size_t len); + virtual const unsigned char *read( void *buf, size_t *inout_len); + + bool valid() { return m_sock >= 0; } + int recv(void *buf, size_t len); + +private: + int writeFully(const void *buf, size_t len); + +private: + int m_sock; + size_t m_bufsize; + unsigned char *m_buf; + QemuPipeStream(int sock, size_t bufSize); +}; + +#endif diff --git a/tools/emulator/opengl/system/gralloc/Android.mk b/tools/emulator/opengl/system/gralloc/Android.mk index 7b8dbea6f..7a7c340b9 100644 --- a/tools/emulator/opengl/system/gralloc/Android.mk +++ b/tools/emulator/opengl/system/gralloc/Android.mk @@ -32,7 +32,8 @@ LOCAL_MODULE := gralloc.goldfish LOCAL_STATIC_LIBRARIES := \ libOpenglSystemCommon \ - libOpenglCodecCommon + libOpenglCodecCommon \ + libqemu LOCAL_SHARED_LIBRARIES := \ libcutils \ diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/Android.mk b/tools/emulator/opengl/tests/gles_android_wrapper/Android.mk index 0cda39af7..ad850361a 100644 --- a/tools/emulator/opengl/tests/gles_android_wrapper/Android.mk +++ b/tools/emulator/opengl/tests/gles_android_wrapper/Android.mk @@ -36,7 +36,7 @@ $(GEN_GLESv1_emul) : PRIVATE_CUSTOM_TOOL := \ $(GEN_GLESv1_emul) : $(EMUGEN) \ $(emulatorOpengl)/system/GLESv1_enc/gl.in \ $(emulatorOpengl)/system/GLESv1_enc/gl.attrib \ - $(emulatorOpengl)/system/GLESv1_enc/gl.types + $(emulatorOpengl)/system/GLESv1_enc/gl.types $(transform-generated-source) LOCAL_GENERATED_SOURCES += $(GEN_GLESv1_emul) @@ -72,7 +72,7 @@ $(GEN_GLESv2_emul) : PRIVATE_CUSTOM_TOOL := \ $(GEN_GLESv2_emul) : $(EMUGEN) \ $(emulatorOpengl)/system/GLESv2_enc/gl2.in \ $(emulatorOpengl)/system/GLESv2_enc/gl2.attrib \ - $(emulatorOpengl)/system/GLESv2_enc/gl2.types + $(emulatorOpengl)/system/GLESv2_enc/gl2.types $(transform-generated-source) LOCAL_GENERATED_SOURCES += $(GEN_GLESv2_emul) @@ -102,6 +102,7 @@ LOCAL_ADDITIONAL_DEPENDENCIES := \ LOCAL_C_INCLUDES := $(emulatorOpengl)/shared/OpenglCodecCommon \ $(emulatorOpengl)/host/include/libOpenglRender \ + $(emulatorOpengl)/system/OpenglSystemCommon \ $(call intermediates-dir-for, SHARED_LIBRARIES, libut_rendercontrol_enc) \ $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv1_enc) \ $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv2_enc) \ @@ -109,7 +110,7 @@ LOCAL_C_INCLUDES := $(emulatorOpengl)/shared/OpenglCodecCommon \ $(call intermediates-dir-for, SHARED_LIBRARIES, libGLESv2_emul) \ $(emulatorOpengl)/system/GLESv1_enc \ $(emulatorOpengl)/system/GLESv2_enc \ - $(emulatorOpengl)/tests/ut_rendercontrol_enc + $(emulatorOpengl)/tests/ut_rendercontrol_enc LOCAL_CFLAGS := $(logTag) @@ -127,7 +128,7 @@ LOCAL_SHARED_LIBRARIES := libdl \ libGLESv1_enc \ libGLESv2_enc \ libut_rendercontrol_enc -LOCAL_STATIC_LIBRARIES := libOpenglCodecCommon +LOCAL_STATIC_LIBRARIES := libOpenglCodecCommon libOpenglSystemCommon libqemu include $(BUILD_SHARED_LIBRARY) diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.cpp b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.cpp index ea36c72ba..1204264b0 100644 --- a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.cpp +++ b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.cpp @@ -16,6 +16,8 @@ #include #include #include "ServerConnection.h" +#include "TcpStream.h" +#include "QemuPipeStream.h" #include #include "ThreadInfo.h" @@ -72,24 +74,44 @@ ServerConnection::~ServerConnection() int ServerConnection::create(size_t bufsize, const char *defaultServer) { + /* XXX: Make configurable through system property */ + int useQemuPipe = 1; + if (m_stream != NULL) delete(m_stream); - m_stream = new TcpStream(bufsize); - char *s = getenv(ENV_RGL_SERVER); - char *hostname; - if (s == NULL) { - hostname = strdup(defaultServer); - } else { - hostname = strdup(s); + if (useQemuPipe) { + QemuPipeStream* pipeStream = new QemuPipeStream(bufsize); + + if (pipeStream->connect() < 0) { + LOGE("couldn't connect to host server\n"); + delete pipeStream; + return -1; + } + m_stream = pipeStream; } + else /* !useQemuPipe */ + { + TcpStream* tcpStream = new TcpStream(bufsize); - if (m_stream->connect(hostname, CODEC_SERVER_PORT) < 0) { - LOGE("couldn't connect to %s\n", hostname); + char *s = getenv(ENV_RGL_SERVER); + char *hostname; + if (s == NULL) { + hostname = strdup(defaultServer); + } else { + hostname = strdup(s); + } + + if (tcpStream->connect(hostname, CODEC_SERVER_PORT) < 0) { + LOGE("couldn't connect to %s\n", hostname); + free(hostname); + delete tcpStream; + return -1; + } + LOGI("connecting to server %s\n", hostname); free(hostname); - return -1; + + m_stream = tcpStream; } - LOGI("connecting to server %s\n", hostname); - free(hostname); m_glEnc = new GLEncoder(m_stream); m_glEnc->setContextAccessor(s_getGlContext); diff --git a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h index 0a39afe3f..84f40d84d 100644 --- a/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h +++ b/tools/emulator/opengl/tests/gles_android_wrapper/ServerConnection.h @@ -18,7 +18,7 @@ #include "GLEncoder.h" #include "GL2Encoder.h" -#include "TcpStream.h" +#include "IOStream.h" #include "codec_defs.h" #include "ut_rendercontrol_enc.h" #include @@ -44,7 +44,7 @@ private: static pthread_key_t s_glKey; static pthread_key_t s_connectionKey; static void s_initKeys(); - TcpStream *m_stream; + IOStream *m_stream; GLEncoder *m_glEnc; GL2Encoder *m_gl2Enc; ut_rendercontrol_encoder_context_t *m_ut_enc;