From: bohu Date: Tue, 25 Apr 2017 03:38:01 +0000 (-0700) Subject: Emulator: update opengl to bb8d138b X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fdevice-generic-goldfish-opengl.git;a=commitdiff_plain;h=dcacca1449afecd0604a16c8dc97e2a67c47ce56 Emulator: update opengl to bb8d138b Bug: 37302997 Test: Build and run sdk_google_aw_x86-userdebug emulator To commit bb8d138b3e83567d68810d059d69654fa5e8a303 Merge: 7c53152 bb1f88a Author: Josh Gao Date: Fri Apr 14 23:08:26 2017 +0000 Rename socket_loopback_server to _socket_loopback_server. Change-Id: Id602f0c1df3be423e37af5f6c91d037d713c3b7a (cherry picked from commit 588c0a94e384e07c8d38185710a1a968823594ba) (cherry picked from commit 1b5d5a70fe49f2826a225878ddcd8d6ad561c886) --- diff --git a/shared/OpenglCodecCommon/TcpStream.cpp b/shared/OpenglCodecCommon/TcpStream.cpp index 4da2cec..2090ae0 100644 --- a/shared/OpenglCodecCommon/TcpStream.cpp +++ b/shared/OpenglCodecCommon/TcpStream.cpp @@ -28,6 +28,38 @@ #include #endif +static int _socket_loopback_server(int port, int type) +{ + struct sockaddr_in addr; + + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + + int s = socket(AF_INET, type, 0); + if (s < 0) + return -1; + + int n = 1; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof(n)); + + if (bind(s, reinterpret_cast(&addr), sizeof(addr)) < 0) { + close(s); + return -1; + } + + if (type == SOCK_STREAM) { + if (listen(s, 4) < 0) { + close(s); + return -1; + } + } + + return s; +} + TcpStream::TcpStream(size_t bufSize) : SocketStream(bufSize) { @@ -49,7 +81,7 @@ TcpStream::TcpStream(int sock, size_t bufSize) : int TcpStream::listen(unsigned short port) { - m_sock = socket_loopback_server(port, SOCK_STREAM); + m_sock = _socket_loopback_server(port, SOCK_STREAM); if (!valid()) return int(ERR_INVALID_SOCKET); return 0; diff --git a/system/OpenglSystemCommon/HostConnection.cpp b/system/OpenglSystemCommon/HostConnection.cpp index 022a6f9..ce89021 100644 --- a/system/OpenglSystemCommon/HostConnection.cpp +++ b/system/OpenglSystemCommon/HostConnection.cpp @@ -50,12 +50,15 @@ HostConnection::~HostConnection() } HostConnection *HostConnection::get() { + return getWithThreadInfo(getEGLThreadInfo()); +} + +HostConnection *HostConnection::getWithThreadInfo(EGLThreadInfo* tinfo) { /* TODO: Make this configurable with a system property */ const int useQemuPipe = USE_QEMU_PIPE; // Get thread info - EGLThreadInfo *tinfo = getEGLThreadInfo(); if (!tinfo) { return NULL; } diff --git a/system/OpenglSystemCommon/HostConnection.h b/system/OpenglSystemCommon/HostConnection.h index 2c81517..25d42d6 100644 --- a/system/OpenglSystemCommon/HostConnection.h +++ b/system/OpenglSystemCommon/HostConnection.h @@ -107,10 +107,13 @@ private: GLESMaxVersion m_glesMaxVersion; }; +struct EGLThreadInfo; + class HostConnection { public: static HostConnection *get(); + static HostConnection *getWithThreadInfo(EGLThreadInfo* tInfo); static void exit(); ~HostConnection(); diff --git a/system/OpenglSystemCommon/ThreadInfo.cpp b/system/OpenglSystemCommon/ThreadInfo.cpp index 04ce508..9e11624 100644 --- a/system/OpenglSystemCommon/ThreadInfo.cpp +++ b/system/OpenglSystemCommon/ThreadInfo.cpp @@ -18,19 +18,30 @@ thread_store_t s_tls = THREAD_STORE_INITIALIZER; +static bool sDefaultTlsDestructorCallback(void* ptr) { return true; } +static bool (*sTlsDestructorCallback)(void*) = sDefaultTlsDestructorCallback; + static void tlsDestruct(void *ptr) { + sTlsDestructorCallback(ptr); if (ptr) { EGLThreadInfo *ti = (EGLThreadInfo *)ptr; delete ti->hostConn; delete ti; +#ifdef __ANDROID__ ((void **)__get_tls())[TLS_SLOT_OPENGL] = NULL; +#endif } } -EGLThreadInfo *slow_getEGLThreadInfo() +void setTlsDestructor(tlsDtorCallback func) { + sTlsDestructorCallback = func; +} + +EGLThreadInfo *goldfish_get_egl_tls() { - EGLThreadInfo *ti = (EGLThreadInfo *)thread_store_get(&s_tls); + EGLThreadInfo* ti = (EGLThreadInfo*)thread_store_get(&s_tls); + if (ti) return ti; ti = new EGLThreadInfo(); diff --git a/system/OpenglSystemCommon/ThreadInfo.h b/system/OpenglSystemCommon/ThreadInfo.h index 9a5dc88..06d9267 100644 --- a/system/OpenglSystemCommon/ThreadInfo.h +++ b/system/OpenglSystemCommon/ThreadInfo.h @@ -18,15 +18,14 @@ #include "HostConnection.h" #include -#ifdef __ANDROID__ -#include -#endif +#include struct EGLContext_t; +struct HostConnection; struct EGLThreadInfo { - EGLThreadInfo() : currentContext(NULL), hostConn(NULL), eglError(EGL_SUCCESS) {} + EGLThreadInfo() : currentContext(NULL), hostConn(NULL), eglError(EGL_SUCCESS) { } EGLContext_t *currentContext; HostConnection *hostConn; @@ -34,26 +33,23 @@ struct EGLThreadInfo }; -EGLThreadInfo *slow_getEGLThreadInfo(); +typedef bool (*tlsDtorCallback)(void*); +void setTlsDestructor(tlsDtorCallback); + +extern "C" __attribute__((visibility("default"))) EGLThreadInfo *goldfish_get_egl_tls(); +inline EGLThreadInfo* getEGLThreadInfo() { #ifdef __ANDROID__ - // We have a dedicated TLS slot in bionic - inline EGLThreadInfo* getEGLThreadInfo() { - EGLThreadInfo *tInfo = - (EGLThreadInfo *)(((uintptr_t *)__get_tls())[TLS_SLOT_OPENGL]); - if (!tInfo) { - tInfo = slow_getEGLThreadInfo(); - ((uintptr_t *)__get_tls())[TLS_SLOT_OPENGL] = (uintptr_t)tInfo; - } - return tInfo; + EGLThreadInfo *tInfo = + (EGLThreadInfo *)(((uintptr_t *)__get_tls())[TLS_SLOT_OPENGL]); + if (!tInfo) { + tInfo = goldfish_get_egl_tls(); + ((uintptr_t *)__get_tls())[TLS_SLOT_OPENGL] = (uintptr_t)tInfo; } + return tInfo; #else - inline EGLThreadInfo* getEGLThreadInfo() { - return slow_getEGLThreadInfo(); - } + return goldfish_get_egl_tls(); #endif - - - +} #endif // of _THREAD_INFO_H diff --git a/system/egl/egl.cpp b/system/egl/egl.cpp index c00d380..b22e116 100644 --- a/system/egl/egl.cpp +++ b/system/egl/egl.cpp @@ -144,6 +144,18 @@ const char * eglStrError(EGLint err) return ret; \ } +#define DEFINE_AND_VALIDATE_HOST_CONNECTION_FOR_TLS(ret, tls) \ + HostConnection *hostCon = HostConnection::getWithThreadInfo(tls); \ + if (!hostCon) { \ + ALOGE("egl: Failed to get host connection\n"); \ + return ret; \ + } \ + ExtendedRCEncoderContext *rcEnc = hostCon->rcEncoder(); \ + if (!rcEnc) { \ + ALOGE("egl: Failed to get renderControl encoder context\n"); \ + return ret; \ + } + #define VALIDATE_CONTEXT_RETURN(context,ret) \ if (!(context)) { \ RETURN_ERROR(ret,EGL_BAD_CONTEXT); \ @@ -1112,41 +1124,40 @@ EGLBoolean eglWaitClient() return eglWaitGL(); } -EGLBoolean eglReleaseThread() -{ - EGLThreadInfo *tInfo = getEGLThreadInfo(); - if (tInfo) { - tInfo->eglError = EGL_SUCCESS; - EGLContext_t* context = tInfo->currentContext; - if (context) { - // The following code is doing pretty much the same thing as - // eglMakeCurrent(&s_display, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE) - // with the only issue that we do not require a valid display here. - DEFINE_AND_VALIDATE_HOST_CONNECTION(EGL_FALSE); - rcEnc->rcMakeCurrent(rcEnc, 0, 0, 0); - if (context->majorVersion > 1) { - hostCon->gl2Encoder()->setClientState(NULL); - hostCon->gl2Encoder()->setSharedGroup(GLSharedGroupPtr()); - } - else { - hostCon->glEncoder()->setClientState(NULL); - hostCon->glEncoder()->setSharedGroup(GLSharedGroupPtr()); - } - context->flags &= ~EGLContext_t::IS_CURRENT; +// We may need to trigger this directly from the TLS destructor. +static EGLBoolean s_eglReleaseThreadImpl(EGLThreadInfo* tInfo) { + if (!tInfo) return EGL_TRUE; - if (context->deletePending) { - if (context->rcContext) { - rcEnc->rcDestroyContext(rcEnc, context->rcContext); - context->rcContext = 0; - } - delete context; - } - tInfo->currentContext = 0; + tInfo->eglError = EGL_SUCCESS; + EGLContext_t* context = tInfo->currentContext; + + if (!context) return EGL_TRUE; + + // The following code is doing pretty much the same thing as + // eglMakeCurrent(&s_display, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE) + // with the only issue that we do not require a valid display here. + DEFINE_AND_VALIDATE_HOST_CONNECTION_FOR_TLS(EGL_FALSE, tInfo); + // We are going to call makeCurrent on the null context and surface + // anyway once we are on the host, so skip rcMakeCurrent here. + // rcEnc->rcMakeCurrent(rcEnc, 0, 0, 0); + context->flags &= ~EGLContext_t::IS_CURRENT; + if (context->deletePending) { + if (context->rcContext) { + rcEnc->rcDestroyContext(rcEnc, context->rcContext); + context->rcContext = 0; } + delete context; } + tInfo->currentContext = 0; + return EGL_TRUE; } +EGLBoolean eglReleaseThread() +{ + return s_eglReleaseThreadImpl(getEGLThreadInfo()); +} + EGLSurface eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) { //TODO @@ -1464,6 +1475,10 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC VALIDATE_SURFACE_RETURN(draw, EGL_FALSE); VALIDATE_SURFACE_RETURN(read, EGL_FALSE); + // Only place to initialize the TLS destructor; any + // thread can suddenly jump in any eglMakeCurrent + setTlsDestructor((tlsDtorCallback)s_eglReleaseThreadImpl); + if ((read == EGL_NO_SURFACE && draw == EGL_NO_SURFACE) && (ctx != EGL_NO_CONTEXT)) setErrorReturn(EGL_BAD_MATCH, EGL_FALSE); if ((read != EGL_NO_SURFACE || draw != EGL_NO_SURFACE) && (ctx == EGL_NO_CONTEXT)) @@ -1496,7 +1511,8 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC } if (context && (context->flags & EGLContext_t::IS_CURRENT) && (context != tInfo->currentContext)) { - //context is current to another thread + // context is current to another thread + ALOGE("%s: error: EGL_BAD_ACCESS: context %p current to another thread!\n", __FUNCTION__, context); setErrorReturn(EGL_BAD_ACCESS, EGL_FALSE); } @@ -1509,7 +1525,7 @@ EGLBoolean eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLC //Now make the local bind if (context) { - ALOGD("%s: %p: ver %d %d", __FUNCTION__, context, context->majorVersion, context->minorVersion); + ALOGD("%s: %p: ver %d %d (tinfo %p)", __FUNCTION__, context, context->majorVersion, context->minorVersion, tInfo); // This is a nontrivial context. // The thread cannot be gralloc-only anymore. hostCon->setGrallocOnly(false); diff --git a/system/egl/eglDisplay.cpp b/system/egl/eglDisplay.cpp index 2239e99..890eb50 100644 --- a/system/egl/eglDisplay.cpp +++ b/system/egl/eglDisplay.cpp @@ -430,6 +430,9 @@ EGLBoolean eglDisplay::getAttribValue(EGLConfig config, EGLint attribIdx, EGLint return EGL_TRUE; } +#define EGL_COLOR_COMPONENT_TYPE_EXT 0x3339 +#define EGL_COLOR_COMPONENT_TYPE_FIXED_EXT 0x333A + EGLBoolean eglDisplay::getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * value) { if (attrib == EGL_FRAMEBUFFER_TARGET_ANDROID) { @@ -445,6 +448,10 @@ EGLBoolean eglDisplay::getConfigAttrib(EGLConfig config, EGLint attrib, EGLint * *value = EGL_DEPTH_ENCODING_NONE_NV; return EGL_TRUE; } + if (attrib == EGL_COLOR_COMPONENT_TYPE_EXT) { + *value = EGL_COLOR_COMPONENT_TYPE_FIXED_EXT; + return EGL_TRUE; + } //Though it seems that valueFor() is thread-safe, we don't take chanses pthread_mutex_lock(&m_lock); EGLBoolean ret = getAttribValue(config, m_attribs.valueFor(attrib), value); diff --git a/system/gralloc/gralloc.cpp b/system/gralloc/gralloc.cpp index 236f633..4e63b00 100644 --- a/system/gralloc/gralloc.cpp +++ b/system/gralloc/gralloc.cpp @@ -30,6 +30,10 @@ #include #include +#include +#include +#include + /* Set to 1 or 2 to enable debug traces */ #define DEBUG 0 @@ -63,13 +67,26 @@ static pthread_once_t sFallbackOnce = PTHREAD_ONCE_INIT; static void fallback_init(void); // forward - typedef struct _alloc_list_node { buffer_handle_t handle; _alloc_list_node *next; _alloc_list_node *prev; } AllocListNode; +struct MemRegionInfo { + void* ashmemBase; + mutable uint32_t refCount; +}; + +struct MemRegionInfoCmp { + bool operator()(const MemRegionInfo& a, const MemRegionInfo& b) const { + return a.ashmemBase < b.ashmemBase; + } +}; + +typedef std::set MemRegionSet; +typedef MemRegionSet::iterator mem_region_handle_t; + // // Our gralloc device structure (alloc interface) // @@ -77,9 +94,161 @@ struct gralloc_device_t { alloc_device_t device; AllocListNode *allocListHead; // double linked list of allocated buffers + MemRegionSet ashmemRegions; // to track allocations of each ashmem region pthread_mutex_t lock; }; +struct gralloc_memregions_t { + MemRegionSet ashmemRegions; +}; + +#define INITIAL_DMA_REGION_SIZE 4096 +struct gralloc_dmaregion_t { + goldfish_dma_context goldfish_dma; + uint32_t sz; + uint32_t refcount; + pthread_mutex_t lock; +}; + +// global device instance +static gralloc_memregions_t* s_grdev = NULL; +static gralloc_dmaregion_t* s_grdma = NULL; + +void init_gralloc_memregions() { + if (s_grdev) return; + s_grdev = new gralloc_memregions_t; +} + +void init_gralloc_dmaregion() { + D("%s: call\n", __FUNCTION__); + if (s_grdma) return; + + s_grdma = new gralloc_dmaregion_t; + s_grdma->sz = INITIAL_DMA_REGION_SIZE; + s_grdma->refcount = 0; + + pthread_mutex_init(&s_grdma->lock, NULL); + pthread_mutex_lock(&s_grdma->lock); + goldfish_dma_create_region(s_grdma->sz, &s_grdma->goldfish_dma); + pthread_mutex_unlock(&s_grdma->lock); +} + +void get_gralloc_dmaregion() { + if (!s_grdma) return; + pthread_mutex_lock(&s_grdma->lock); + s_grdma->refcount++; + D("%s: call. refcount: %u\n", __FUNCTION__, s_grdma->refcount); + pthread_mutex_unlock(&s_grdma->lock); +} + +static void resize_gralloc_dmaregion_locked(uint32_t new_sz) { + if (!s_grdma) return; + if (s_grdma->goldfish_dma.mapped) { + goldfish_dma_unmap(&s_grdma->goldfish_dma); + } + close(s_grdma->goldfish_dma.fd); + goldfish_dma_create_region(new_sz, &s_grdma->goldfish_dma); + s_grdma->sz = new_sz; +} + +bool put_gralloc_dmaregion() { + if (!s_grdma) return false; + pthread_mutex_lock(&s_grdma->lock); + D("%s: call. refcount before: %u\n", __FUNCTION__, s_grdma->refcount); + s_grdma->refcount--; + bool shouldDelete = !s_grdma->refcount; + if (shouldDelete) { + D("%s: should delete!\n", __FUNCTION__); + resize_gralloc_dmaregion_locked(INITIAL_DMA_REGION_SIZE); + D("%s: done\n", __FUNCTION__); + } + pthread_mutex_unlock(&s_grdma->lock); + D("%s: exit\n", __FUNCTION__); + return shouldDelete; +} + +void gralloc_dmaregion_register_ashmem(uint32_t sz) { + if (!s_grdma) return; + pthread_mutex_lock(&s_grdma->lock); + D("%s: for sz %u, refcount %u", __FUNCTION__, sz, s_grdma->refcount); + uint32_t new_sz = std::max(s_grdma->sz, sz); + if (new_sz != s_grdma->sz) { + D("%s: change sz from %u to %u", __FUNCTION__, s_grdma->sz, sz); + resize_gralloc_dmaregion_locked(new_sz); + } + if (!s_grdma->goldfish_dma.mapped) { + goldfish_dma_map(&s_grdma->goldfish_dma); + } + pthread_mutex_unlock(&s_grdma->lock); +} + +void get_mem_region(void* ashmemBase) { + init_gralloc_memregions(); + D("%s: call for %p", __FUNCTION__, ashmemBase); + MemRegionInfo lookup; + lookup.ashmemBase = ashmemBase; + mem_region_handle_t handle = s_grdev->ashmemRegions.find(lookup); + if (handle == s_grdev->ashmemRegions.end()) { + MemRegionInfo newRegion; + newRegion.ashmemBase = ashmemBase; + newRegion.refCount = 1; + s_grdev->ashmemRegions.insert(newRegion); + } else { + handle->refCount++; + } +} + +bool put_mem_region(void* ashmemBase) { + init_gralloc_memregions(); + D("%s: call for %p", __FUNCTION__, ashmemBase); + MemRegionInfo lookup; + lookup.ashmemBase = ashmemBase; + mem_region_handle_t handle = s_grdev->ashmemRegions.find(lookup); + if (handle == s_grdev->ashmemRegions.end()) { + ALOGE("%s: error: tried to put nonexistent mem region!", __FUNCTION__); + return true; + } else { + handle->refCount--; + bool shouldRemove = !handle->refCount; + if (shouldRemove) { + s_grdev->ashmemRegions.erase(lookup); + } + return shouldRemove; + } +} + +void dump_regions() { + init_gralloc_memregions(); + mem_region_handle_t curr = s_grdev->ashmemRegions.begin(); + std::stringstream res; + for (; curr != s_grdev->ashmemRegions.end(); curr++) { + res << "\tashmem base " << curr->ashmemBase << " refcount " << curr->refCount << "\n"; + } + ALOGD("ashmem region dump [\n%s]", res.str().c_str()); +} + +#if DEBUG + +#define GET_ASHMEM_REGION(cb) \ + dump_regions(); \ + get_mem_region((void*)cb->ashmemBase); \ + dump_regions(); \ + +#define PUT_ASHMEM_REGION(cb) \ + dump_regions(); \ + bool SHOULD_UNMAP = put_mem_region((void*)cb->ashmemBase); \ + dump_regions(); \ + +#else + +#define GET_ASHMEM_REGION(cb) \ + get_mem_region((void*)cb->ashmemBase); \ + +#define PUT_ASHMEM_REGION(cb) \ + bool SHOULD_UNMAP = put_mem_region((void*)cb->ashmemBase); \ + +#endif + // // Our framebuffer device structure // @@ -102,6 +271,8 @@ static int map_buffer(cb_handle_t *cb, void **vaddr) cb->ashmemBase = intptr_t(addr); cb->ashmemBasePid = getpid(); + D("%s: %p mapped ashmem base %p size %d\n", __FUNCTION__, + cb, cb->ashmemBase, cb->ashmemSize); *vaddr = addr; return 0; @@ -148,7 +319,7 @@ static void updateHostColorBuffer(cb_handle_t* cb, char* convertedBuf = NULL; if ((doLocked && is_rgb_format) || - (cb->goldfish_dma.fd < 0 && + (!s_grdma && (doLocked || !is_rgb_format))) { convertedBuf = new char[rgbSz]; to_send = convertedBuf; @@ -162,7 +333,7 @@ static void updateHostColorBuffer(cb_handle_t* cb, width, height, top, left, bpp); } - if (cb->goldfish_dma.fd > 0) { + if (s_grdma) { if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) { get_yv12_offsets(width, height, NULL, NULL, &send_buffer_size); @@ -172,12 +343,14 @@ static void updateHostColorBuffer(cb_handle_t* cb, &send_buffer_size); } - rcEnc->bindDmaContext(&cb->goldfish_dma); + rcEnc->bindDmaContext(&s_grdma->goldfish_dma); D("%s: call. dma update with sz=%u", __FUNCTION__, send_buffer_size); + pthread_mutex_lock(&s_grdma->lock); rcEnc->rcUpdateColorBufferDMA(rcEnc, cb->hostHandle, left, top, width, height, cb->glFormat, cb->glType, to_send, send_buffer_size); + pthread_mutex_unlock(&s_grdma->lock); } else { if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12) { yv12_to_rgb888(to_send, pixels, @@ -340,8 +513,6 @@ static int gralloc_alloc(alloc_device_t* dev, selectedEmuFrameworkFormat = FRAMEWORK_FORMAT_YV12; break; case HAL_PIXEL_FORMAT_YCbCr_420_888: - ALOGD("%s: 420_888 format experimental path. " - "Initialize rgb565 gl format\n", __FUNCTION__); align = 1; bpp = 1; // per-channel bpp yuv_format = true; @@ -418,14 +589,8 @@ static int gralloc_alloc(alloc_device_t* dev, if (rcEnc->getDmaVersion() > 0) { D("%s: creating goldfish dma region of size %lu (cb fd %d)\n", __FUNCTION__, ashmem_size, cb->fd); - err = goldfish_dma_create_region(ashmem_size, &cb->goldfish_dma); - if (err) { - ALOGE("%s: Failed to create goldfish DMA region", __FUNCTION__); - } else { - goldfish_dma_map(&cb->goldfish_dma); - cb->setDmaFd(cb->goldfish_dma.fd); - D("%s: done, cbfd %d dmafd1 %d dmafd2 %d", __FUNCTION__, cb->fd, cb->goldfish_dma.fd, cb->dmafd); - } + init_gralloc_dmaregion(); + get_gralloc_dmaregion(); } else { cb->goldfish_dma.fd = -1; } @@ -454,7 +619,7 @@ static int gralloc_alloc(alloc_device_t* dev, GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_SW_READ_MASK) ) { #endif // PLATFORM_SDK_VERSION if (hostCon && rcEnc) { - if (cb->goldfish_dma.fd > 0) { + if (s_grdma) { cb->hostHandle = rcEnc->rcCreateColorBufferDMA(rcEnc, w, h, glFormat, cb->emuFrameworkFormat); } else { cb->hostHandle = rcEnc->rcCreateColorBuffer(rcEnc, w, h, glFormat); @@ -487,6 +652,8 @@ static int gralloc_alloc(alloc_device_t* dev, pthread_mutex_unlock(&grdev->lock); *pHandle = cb; + D("%s: alloc succeded, new ashmem base and size: %p %d handle: %p", + __FUNCTION__, cb->ashmemBase, cb->ashmemSize, cb); switch (frameworkFormat) { case HAL_PIXEL_FORMAT_YCbCr_420_888: *pStride = 0; @@ -501,14 +668,16 @@ static int gralloc_alloc(alloc_device_t* dev, static int gralloc_free(alloc_device_t* dev, buffer_handle_t handle) { - D("%s: start", __FUNCTION__); cb_handle_t *cb = (cb_handle_t *)handle; if (!cb_handle_t::validate((cb_handle_t*)cb)) { ERR("gralloc_free: invalid handle"); return -EINVAL; } - if (cb->hostHandle != 0) { + D("%s: for buf %p ptr %p size %d\n", + __FUNCTION__, handle, cb->ashmemBase, cb->ashmemSize); + + if (cb->hostHandle) { DEFINE_AND_VALIDATE_HOST_CONNECTION; D("Closing host ColorBuffer 0x%x\n", cb->hostHandle); rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle); @@ -519,19 +688,12 @@ static int gralloc_free(alloc_device_t* dev, // if (cb->fd > 0) { if (cb->ashmemSize > 0 && cb->ashmemBase) { + D("%s: unmapped %p", __FUNCTION__, cb->ashmemBase); munmap((void *)cb->ashmemBase, cb->ashmemSize); + put_gralloc_dmaregion(); } close(cb->fd); } - if (cb->dmafd > 0) { - D("%s: unmap and free dma fd %d\n", __FUNCTION__, cb->dmafd); - cb->goldfish_dma.fd = cb->dmafd; - if (cb->ashmemSize > 0 && cb->ashmemBase) { - goldfish_dma_unmap(&cb->goldfish_dma); - } - goldfish_dma_free(&cb->goldfish_dma); - D("%s: closed dma fd %d\n", __FUNCTION__, cb->dmafd); - } D("%s: done", __FUNCTION__); // remove it from the allocated list @@ -675,6 +837,7 @@ static int fb_close(struct hw_device_t *dev) static int gralloc_register_buffer(gralloc_module_t const* module, buffer_handle_t handle) { + D("%s: start", __FUNCTION__); pthread_once(&sFallbackOnce, fallback_init); if (sFallback != NULL) { @@ -685,6 +848,7 @@ static int gralloc_register_buffer(gralloc_module_t const* module, private_module_t *gr = (private_module_t *)module; cb_handle_t *cb = (cb_handle_t *)handle; + if (!gr || !cb_handle_t::validate(cb)) { ERR("gralloc_register_buffer(%p): invalid buffer", cb); return -EINVAL; @@ -708,18 +872,18 @@ static int gralloc_register_buffer(gralloc_module_t const* module, return -err; } cb->mappedPid = getpid(); - D("%s: checking to map goldfish dma", __FUNCTION__); - if (cb->dmafd > 0) { - D("%s: attempting to goldfish dma mmap. cbfd %d dmafd1 %d dmafd2 %d", __FUNCTION__, cb->fd, cb->goldfish_dma.fd, cb->dmafd); - D("cxt=%p curr pid %d mapped pid %d", - &cb->goldfish_dma, - (int)getpid(), - cb->mappedPid); - if (cb->goldfish_dma.fd != cb->dmafd) { - cb->goldfish_dma.fd = cb->dmafd; - } - goldfish_dma_map(&cb->goldfish_dma); + + DEFINE_AND_VALIDATE_HOST_CONNECTION; + if (rcEnc->getDmaVersion() > 0) { + init_gralloc_dmaregion(); + gralloc_dmaregion_register_ashmem(cb->ashmemSize); } + + } + + if (cb->ashmemSize > 0) { + GET_ASHMEM_REGION(cb); + get_gralloc_dmaregion(); } return 0; @@ -728,21 +892,22 @@ static int gralloc_register_buffer(gralloc_module_t const* module, static int gralloc_unregister_buffer(gralloc_module_t const* module, buffer_handle_t handle) { - D("%s: call", __FUNCTION__); if (sFallback != NULL) { return sFallback->unregisterBuffer(sFallback, handle); } private_module_t *gr = (private_module_t *)module; cb_handle_t *cb = (cb_handle_t *)handle; + if (!gr || !cb_handle_t::validate(cb)) { ERR("gralloc_unregister_buffer(%p): invalid buffer", cb); return -EINVAL; } - if (cb->hostHandle != 0) { - DEFINE_AND_VALIDATE_HOST_CONNECTION; + + if (cb->hostHandle) { D("Closing host ColorBuffer 0x%x\n", cb->hostHandle); + DEFINE_AND_VALIDATE_HOST_CONNECTION; rcEnc->rcCloseColorBuffer(rcEnc, cb->hostHandle); } @@ -751,7 +916,14 @@ static int gralloc_unregister_buffer(gralloc_module_t const* module, // (through register_buffer) // if (cb->ashmemSize > 0 && cb->mappedPid == getpid()) { + + PUT_ASHMEM_REGION(cb); + put_gralloc_dmaregion(); + + if (!SHOULD_UNMAP) goto done; + DEFINE_AND_VALIDATE_HOST_CONNECTION; + void *vaddr; int err = munmap((void *)cb->ashmemBase, cb->ashmemSize); if (err) { @@ -761,14 +933,9 @@ static int gralloc_unregister_buffer(gralloc_module_t const* module, cb->ashmemBase = 0; cb->mappedPid = 0; D("%s: Unregister buffer previous mapped to pid %d", __FUNCTION__, getpid()); - if (cb->dmafd > 0) { - cb->goldfish_dma.fd = cb->dmafd; - D("%s: Unmap dma fd %d (%d)", __FUNCTION__, cb->dmafd, cb->goldfish_dma.fd); - goldfish_dma_unmap(&cb->goldfish_dma); - } } - +done: D("gralloc_unregister_buffer(%p) done\n", cb); return 0; } @@ -786,6 +953,7 @@ static int gralloc_lock(gralloc_module_t const* module, private_module_t *gr = (private_module_t *)module; cb_handle_t *cb = (cb_handle_t *)handle; + if (!gr || !cb_handle_t::validate(cb)) { ALOGE("gralloc_lock bad handle\n"); return -EINVAL; @@ -883,11 +1051,12 @@ static int gralloc_lock(gralloc_module_t const* module, char* tmpBuf = 0; if (cb->frameworkFormat == HAL_PIXEL_FORMAT_YV12 || cb->frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888) { - // We are using RGB88 + // We are using RGB888 tmpBuf = new char[cb->width * cb->height * 3]; rgb_addr = tmpBuf; } - D("gralloc_lock read back color buffer %d %d\n", cb->width, cb->height); + D("gralloc_lock read back color buffer %d %d ashmem base %p sz %d\n", + cb->width, cb->height, cb->ashmemBase, cb->ashmemSize); rcEnc->rcReadColorBuffer(rcEnc, cb->hostHandle, 0, 0, cb->width, cb->height, cb->glFormat, cb->glType, rgb_addr); if (tmpBuf) { @@ -933,6 +1102,7 @@ static int gralloc_unlock(gralloc_module_t const* module, private_module_t *gr = (private_module_t *)module; cb_handle_t *cb = (cb_handle_t *)handle; + if (!gr || !cb_handle_t::validate(cb)) { ALOGD("%s: invalid gr or cb handle. -EINVAL", __FUNCTION__); return -EINVAL; @@ -1121,6 +1291,7 @@ static int gralloc_device_open(const hw_module_t* module, if (NULL == dev) { return -ENOMEM; } + memset(dev, 0, sizeof(gralloc_device_t)); // Initialize our device structure //