am d73fbc24: Merge "emulator: opengl: Use QEMU pipe."
* commit 'd73fbc24fe703e9866a63b8950954430af46bca1': emulator: opengl: Use QEMU pipe.
This commit is contained in:
committed by
Android Git Automerger
commit
9ffa5d9043
@@ -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 {
|
||||
|
||||
@@ -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 -
|
||||
|
||||
@@ -12,6 +12,7 @@ LOCAL_ADDITIONAL_DEPENDENCIES := \
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
HostConnection.cpp \
|
||||
QemuPipeStream.cpp \
|
||||
ThreadInfo.cpp
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
|
||||
@@ -15,12 +15,16 @@
|
||||
*/
|
||||
#include "HostConnection.h"
|
||||
#include "TcpStream.h"
|
||||
#include "QemuPipeStream.h"
|
||||
#include "ThreadInfo.h"
|
||||
#include <cutils/log.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 <hardware/qemu_pipe.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -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
|
||||
* <hardware/qemu_pipe.h> for more details.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#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
|
||||
@@ -32,7 +32,8 @@ LOCAL_MODULE := gralloc.goldfish
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := \
|
||||
libOpenglSystemCommon \
|
||||
libOpenglCodecCommon
|
||||
libOpenglCodecCommon \
|
||||
libqemu
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libcutils \
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "ServerConnection.h"
|
||||
#include "TcpStream.h"
|
||||
#include "QemuPipeStream.h"
|
||||
#include <cutils/log.h>
|
||||
#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);
|
||||
|
||||
@@ -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 <pthread.h>
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user