summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/binder/BpBinder.cpp32
-rw-r--r--libs/binder/IPCThreadState.cpp12
-rw-r--r--libs/binder/Parcel.cpp64
-rw-r--r--libs/binder/ProcessState.cpp2
-rw-r--r--libs/camera/Camera.cpp52
-rw-r--r--libs/camera/ICamera.cpp72
-rw-r--r--libs/camera/ICameraClient.cpp12
-rw-r--r--libs/camera/ICameraRecordingProxy.cpp12
-rw-r--r--libs/camera/ICameraRecordingProxyListener.cpp4
-rw-r--r--libs/gui/Android.mk4
-rw-r--r--libs/gui/BitTube.cpp (renamed from libs/gui/SensorChannel.cpp)61
-rw-r--r--libs/gui/DisplayEventReceiver.cpp83
-rw-r--r--libs/gui/IDisplayEventConnection.cpp73
-rw-r--r--libs/gui/ISensorEventConnection.cpp8
-rw-r--r--libs/gui/ISurfaceComposer.cpp32
-rw-r--r--libs/gui/SensorEventQueue.cpp4
-rw-r--r--libs/gui/SurfaceComposerClient.cpp1
-rw-r--r--libs/gui/SurfaceTexture.cpp4
-rw-r--r--libs/gui/SurfaceTextureClient.cpp36
-rw-r--r--libs/gui/tests/SurfaceTexture_test.cpp36
-rw-r--r--libs/gui/tests/Surface_test.cpp2
-rw-r--r--libs/hwui/OpenGLRenderer.cpp9
-rw-r--r--libs/hwui/PathCache.cpp4
-rw-r--r--libs/rs/driver/rsdAllocation.cpp2
-rw-r--r--libs/rs/driver/rsdBcc.cpp10
-rw-r--r--libs/rs/driver/rsdCore.cpp6
-rw-r--r--libs/rs/driver/rsdGL.cpp24
-rw-r--r--libs/rs/driver/rsdProgram.cpp4
-rw-r--r--libs/rs/driver/rsdShader.cpp42
-rw-r--r--libs/rs/driver/rsdShaderCache.cpp14
-rw-r--r--libs/rs/driver/rsdVertexArray.cpp4
-rw-r--r--libs/rs/rsAllocation.cpp112
-rw-r--r--libs/rs/rsAllocation.h5
-rw-r--r--libs/rs/rsComponent.cpp7
-rw-r--r--libs/rs/rsComponent.h2
-rw-r--r--libs/rs/rsContext.cpp48
-rw-r--r--libs/rs/rsContext.h3
-rw-r--r--libs/rs/rsElement.cpp23
-rw-r--r--libs/rs/rsElement.h12
-rw-r--r--libs/rs/rsFileA3D.cpp10
-rw-r--r--libs/rs/rsFont.cpp16
-rw-r--r--libs/rs/rsFont.h3
-rw-r--r--libs/rs/rsLocklessFifo.cpp4
-rw-r--r--libs/rs/rsMatrix4x4.cpp8
-rw-r--r--libs/rs/rsObjectBase.cpp34
-rw-r--r--libs/rs/rsProgramVertex.cpp5
-rw-r--r--libs/rs/rsScript.cpp20
-rw-r--r--libs/rs/rsScript.h3
-rw-r--r--libs/rs/rsScriptC.cpp37
-rw-r--r--libs/rs/rsScriptC_LibGL.cpp5
-rw-r--r--libs/rs/rsThreadIO.cpp2
-rw-r--r--libs/rs/rsType.cpp2
-rw-r--r--libs/rs/scriptc/rs_allocation.rsh25
-rw-r--r--libs/utils/Android.mk4
-rw-r--r--libs/utils/Asset.cpp10
-rw-r--r--libs/utils/AssetManager.cpp50
-rw-r--r--libs/utils/BasicHashtable.cpp338
-rw-r--r--libs/utils/BlobCache.cpp24
-rw-r--r--libs/utils/CallStack.cpp302
-rw-r--r--libs/utils/FileMap.cpp2
-rw-r--r--libs/utils/RefBase.cpp2
-rw-r--r--libs/utils/ResourceTypes.cpp22
-rw-r--r--libs/utils/StreamingZipInflater.cpp8
-rw-r--r--libs/utils/Threads.cpp8
-rw-r--r--libs/utils/Timers.cpp2
-rw-r--r--libs/utils/VectorImpl.cpp8
-rw-r--r--libs/utils/ZipFileRO.cpp8
-rw-r--r--libs/utils/ZipUtils.cpp4
-rwxr-xr-xlibs/utils/primes.py47
-rw-r--r--libs/utils/tests/Android.mk3
-rw-r--r--libs/utils/tests/BasicHashtable_test.cpp577
71 files changed, 1872 insertions, 658 deletions
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 5de87ec7692a..e8fb1d9b7d7f 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -24,8 +24,8 @@
#include <stdio.h>
-//#undef LOGV
-//#define LOGV(...) fprintf(stderr, __VA_ARGS__)
+//#undef ALOGV
+//#define ALOGV(...) fprintf(stderr, __VA_ARGS__)
namespace android {
@@ -73,7 +73,7 @@ void BpBinder::ObjectManager::detach(const void* objectID)
void BpBinder::ObjectManager::kill()
{
const size_t N = mObjects.size();
- LOGV("Killing %d objects in manager %p", N, this);
+ ALOGV("Killing %d objects in manager %p", N, this);
for (size_t i=0; i<N; i++) {
const entry_t& e = mObjects.valueAt(i);
if (e.func != NULL) {
@@ -92,7 +92,7 @@ BpBinder::BpBinder(int32_t handle)
, mObitsSent(0)
, mObituaries(NULL)
{
- LOGV("Creating BpBinder %p handle %d\n", this, mHandle);
+ ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
extendObjectLifetime(OBJECT_LIFETIME_WEAK);
IPCThreadState::self()->incWeakHandle(handle);
@@ -190,7 +190,7 @@ status_t BpBinder::linkToDeath(
if (!mObituaries) {
return NO_MEMORY;
}
- LOGV("Requesting death notification: %p handle %d\n", this, mHandle);
+ ALOGV("Requesting death notification: %p handle %d\n", this, mHandle);
getWeakRefs()->incWeak(this);
IPCThreadState* self = IPCThreadState::self();
self->requestDeathNotification(mHandle, this);
@@ -226,7 +226,7 @@ status_t BpBinder::unlinkToDeath(
}
mObituaries->removeAt(i);
if (mObituaries->size() == 0) {
- LOGV("Clearing death notification: %p handle %d\n", this, mHandle);
+ ALOGV("Clearing death notification: %p handle %d\n", this, mHandle);
IPCThreadState* self = IPCThreadState::self();
self->clearDeathNotification(mHandle, this);
self->flushCommands();
@@ -242,7 +242,7 @@ status_t BpBinder::unlinkToDeath(
void BpBinder::sendObituary()
{
- LOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
+ ALOGV("Sending obituary for proxy %p handle %d, mObitsSent=%s\n",
this, mHandle, mObitsSent ? "true" : "false");
mAlive = 0;
@@ -251,7 +251,7 @@ void BpBinder::sendObituary()
mLock.lock();
Vector<Obituary>* obits = mObituaries;
if(obits != NULL) {
- LOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
+ ALOGV("Clearing sent death notification: %p handle %d\n", this, mHandle);
IPCThreadState* self = IPCThreadState::self();
self->clearDeathNotification(mHandle, this);
self->flushCommands();
@@ -260,7 +260,7 @@ void BpBinder::sendObituary()
mObitsSent = 1;
mLock.unlock();
- LOGV("Reporting death of proxy %p for %d recipients\n",
+ ALOGV("Reporting death of proxy %p for %d recipients\n",
this, obits ? obits->size() : 0);
if (obits != NULL) {
@@ -276,7 +276,7 @@ void BpBinder::sendObituary()
void BpBinder::reportOneDeath(const Obituary& obit)
{
sp<DeathRecipient> recipient = obit.recipient.promote();
- LOGV("Reporting death to recipient: %p\n", recipient.get());
+ ALOGV("Reporting death to recipient: %p\n", recipient.get());
if (recipient == NULL) return;
recipient->binderDied(this);
@@ -288,7 +288,7 @@ void BpBinder::attachObject(
object_cleanup_func func)
{
AutoMutex _l(mLock);
- LOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
+ ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
mObjects.attach(objectID, object, cleanupCookie, func);
}
@@ -311,7 +311,7 @@ BpBinder* BpBinder::remoteBinder()
BpBinder::~BpBinder()
{
- LOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
+ ALOGV("Destroying BpBinder %p handle %d\n", this, mHandle);
IPCThreadState* ipc = IPCThreadState::self();
@@ -338,15 +338,15 @@ BpBinder::~BpBinder()
void BpBinder::onFirstRef()
{
- LOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
+ ALOGV("onFirstRef BpBinder %p handle %d\n", this, mHandle);
IPCThreadState* ipc = IPCThreadState::self();
if (ipc) ipc->incStrongHandle(mHandle);
}
void BpBinder::onLastStrongRef(const void* id)
{
- LOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
- IF_LOGV() {
+ ALOGV("onLastStrongRef BpBinder %p handle %d\n", this, mHandle);
+ IF_ALOGV() {
printRefs();
}
IPCThreadState* ipc = IPCThreadState::self();
@@ -355,7 +355,7 @@ void BpBinder::onLastStrongRef(const void* id)
bool BpBinder::onIncStrongAttempted(uint32_t flags, const void* id)
{
- LOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
+ ALOGV("onIncStrongAttempted BpBinder %p handle %d\n", this, mHandle);
IPCThreadState* ipc = IPCThreadState::self();
return ipc ? ipc->attemptIncStrongHandle(mHandle) == NO_ERROR : false;
}
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 5ccf87f2cbd3..6965702ab098 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -56,12 +56,12 @@
#else
-#define IF_LOG_TRANSACTIONS() IF_LOG(LOG_VERBOSE, "transact")
-#define IF_LOG_COMMANDS() IF_LOG(LOG_VERBOSE, "ipc")
-#define LOG_REMOTEREFS(...) LOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
-#define IF_LOG_REMOTEREFS() IF_LOG(LOG_DEBUG, "remoterefs")
-#define LOG_THREADPOOL(...) LOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
-#define LOG_ONEWAY(...) LOG(LOG_DEBUG, "ipc", __VA_ARGS__)
+#define IF_LOG_TRANSACTIONS() IF_ALOG(LOG_VERBOSE, "transact")
+#define IF_LOG_COMMANDS() IF_ALOG(LOG_VERBOSE, "ipc")
+#define LOG_REMOTEREFS(...) ALOG(LOG_DEBUG, "remoterefs", __VA_ARGS__)
+#define IF_LOG_REMOTEREFS() IF_ALOG(LOG_DEBUG, "remoterefs")
+#define LOG_THREADPOOL(...) ALOG(LOG_DEBUG, "threadpool", __VA_ARGS__)
+#define LOG_ONEWAY(...) ALOG(LOG_DEBUG, "ipc", __VA_ARGS__)
#endif
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 6b4c1a61e4c9..6cd43aaf0ef6 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -44,7 +44,7 @@
#endif
#define LOG_REFS(...)
-//#define LOG_REFS(...) LOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
+//#define LOG_REFS(...) ALOG(LOG_DEBUG, "Parcel", __VA_ARGS__)
// ---------------------------------------------------------------------------
@@ -330,7 +330,7 @@ status_t Parcel::setDataSize(size_t size)
err = continueWrite(size);
if (err == NO_ERROR) {
mDataSize = size;
- LOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
+ ALOGV("setDataSize Setting data size of %p to %d\n", this, mDataSize);
}
return err;
}
@@ -534,10 +534,10 @@ status_t Parcel::finishWrite(size_t len)
{
//printf("Finish write of %d\n", len);
mDataPos += len;
- LOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("finishWrite Setting data pos of %p to %d\n", this, mDataPos);
if (mDataPos > mDataSize) {
mDataSize = mDataPos;
- LOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
+ ALOGV("finishWrite Setting data size of %p to %d\n", this, mDataSize);
}
//printf("New pos=%d, size=%d\n", mDataPos, mDataSize);
return NO_ERROR;
@@ -722,7 +722,15 @@ status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership)
status_t Parcel::writeDupFileDescriptor(int fd)
{
- return writeFileDescriptor(dup(fd), true /*takeOwnership*/);
+ int dupFd = dup(fd);
+ if (dupFd < 0) {
+ return -errno;
+ }
+ status_t err = writeFileDescriptor(dupFd, true /*takeOwnership*/);
+ if (err) {
+ close(dupFd);
+ }
+ return err;
}
status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
@@ -730,7 +738,7 @@ status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
status_t status;
if (!mAllowFds || len <= IN_PLACE_BLOB_LIMIT) {
- LOGV("writeBlob: write in place");
+ ALOGV("writeBlob: write in place");
status = writeInt32(0);
if (status) return status;
@@ -741,7 +749,7 @@ status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob)
return NO_ERROR;
}
- LOGV("writeBlob: write to ashmem");
+ ALOGV("writeBlob: write to ashmem");
int fd = ashmem_create_region("Parcel Blob", len);
if (fd < 0) return NO_MEMORY;
@@ -865,7 +873,7 @@ status_t Parcel::read(void* outData, size_t len) const
if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
memcpy(outData, mData+mDataPos, len);
mDataPos += PAD_SIZE(len);
- LOGV("read Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("read Setting data pos of %p to %d\n", this, mDataPos);
return NO_ERROR;
}
return NOT_ENOUGH_DATA;
@@ -876,7 +884,7 @@ const void* Parcel::readInplace(size_t len) const
if ((mDataPos+PAD_SIZE(len)) >= mDataPos && (mDataPos+PAD_SIZE(len)) <= mDataSize) {
const void* data = mData+mDataPos;
mDataPos += PAD_SIZE(len);
- LOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("readInplace Setting data pos of %p to %d\n", this, mDataPos);
return data;
}
return NULL;
@@ -987,7 +995,7 @@ const char* Parcel::readCString() const
if (eos) {
const size_t len = eos - str;
mDataPos += PAD_SIZE(len+1);
- LOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("readCString Setting data pos of %p to %d\n", this, mDataPos);
return str;
}
}
@@ -1102,7 +1110,7 @@ status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
if (status) return status;
if (!useAshmem) {
- LOGV("readBlob: read in place");
+ ALOGV("readBlob: read in place");
const void* ptr = readInplace(len);
if (!ptr) return BAD_VALUE;
@@ -1110,7 +1118,7 @@ status_t Parcel::readBlob(size_t len, ReadableBlob* outBlob) const
return NO_ERROR;
}
- LOGV("readBlob: read from ashmem");
+ ALOGV("readBlob: read from ashmem");
int fd = readFileDescriptor();
if (fd == int(BAD_TYPE)) return BAD_VALUE;
@@ -1164,7 +1172,7 @@ const flat_binder_object* Parcel::readObject(bool nullMetaData) const
// When transferring a NULL object, we don't write it into
// the object list, so we don't want to check for it when
// reading.
- LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
return obj;
}
@@ -1174,7 +1182,7 @@ const flat_binder_object* Parcel::readObject(bool nullMetaData) const
size_t opos = mNextObjectHint;
if (N > 0) {
- LOGV("Parcel %p looking for obj at %d, hint=%d\n",
+ ALOGV("Parcel %p looking for obj at %d, hint=%d\n",
this, DPOS, opos);
// Start at the current hint position, looking for an object at
@@ -1188,10 +1196,10 @@ const flat_binder_object* Parcel::readObject(bool nullMetaData) const
}
if (OBJS[opos] == DPOS) {
// Found it!
- LOGV("Parcel found obj %d at index %d with forward search",
+ ALOGV("Parcel found obj %d at index %d with forward search",
this, DPOS, opos);
mNextObjectHint = opos+1;
- LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
return obj;
}
@@ -1201,10 +1209,10 @@ const flat_binder_object* Parcel::readObject(bool nullMetaData) const
}
if (OBJS[opos] == DPOS) {
// Found it!
- LOGV("Parcel found obj %d at index %d with backward search",
+ ALOGV("Parcel found obj %d at index %d with backward search",
this, DPOS, opos);
mNextObjectHint = opos+1;
- LOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("readObject Setting data pos of %p to %d\n", this, mDataPos);
return obj;
}
}
@@ -1260,7 +1268,7 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
mDataSize = mDataCapacity = dataSize;
//LOGI("setDataReference Setting data size of %p to %lu (pid=%d)\n", this, mDataSize, getpid());
mDataPos = 0;
- LOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("setDataReference Setting data pos of %p to %d\n", this, mDataPos);
mObjects = const_cast<size_t*>(objects);
mObjectsSize = mObjectsCapacity = objectsCount;
mNextObjectHint = 0;
@@ -1370,8 +1378,8 @@ status_t Parcel::restartWrite(size_t desired)
}
mDataSize = mDataPos = 0;
- LOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
- LOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("restartWrite Setting data size of %p to %d\n", this, mDataSize);
+ ALOGV("restartWrite Setting data pos of %p to %d\n", this, mDataPos);
free(mObjects);
mObjects = NULL;
@@ -1445,7 +1453,7 @@ status_t Parcel::continueWrite(size_t desired)
mData = data;
mObjects = objects;
mDataSize = (mDataSize < desired) ? mDataSize : desired;
- LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+ ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
mDataCapacity = desired;
mObjectsSize = mObjectsCapacity = objectsSize;
mNextObjectHint = 0;
@@ -1485,11 +1493,11 @@ status_t Parcel::continueWrite(size_t desired)
} else {
if (mDataSize > desired) {
mDataSize = desired;
- LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+ ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
}
if (mDataPos > desired) {
mDataPos = desired;
- LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
}
}
@@ -1508,8 +1516,8 @@ status_t Parcel::continueWrite(size_t desired)
mData = data;
mDataSize = mDataPos = 0;
- LOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
- LOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("continueWrite Setting data size of %p to %d\n", this, mDataSize);
+ ALOGV("continueWrite Setting data pos of %p to %d\n", this, mDataPos);
mDataCapacity = desired;
}
@@ -1523,8 +1531,8 @@ void Parcel::initState()
mDataSize = 0;
mDataCapacity = 0;
mDataPos = 0;
- LOGV("initState Setting data size of %p to %d\n", this, mDataSize);
- LOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
+ ALOGV("initState Setting data size of %p to %d\n", this, mDataSize);
+ ALOGV("initState Setting data pos of %p to %d\n", this, mDataPos);
mObjects = NULL;
mObjectsSize = 0;
mObjectsCapacity = 0;
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index f5288c8c3ead..f06a59ea6656 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -288,7 +288,7 @@ void ProcessState::spawnPooledThread(bool isMain)
int32_t s = android_atomic_add(1, &mThreadPoolSeq);
char buf[32];
sprintf(buf, "Binder Thread #%d", s);
- LOGV("Spawning new pooled thread, name=%s\n", buf);
+ ALOGV("Spawning new pooled thread, name=%s\n", buf);
sp<Thread> t = new PoolThread(isMain);
t->run(buf);
}
diff --git a/libs/camera/Camera.cpp b/libs/camera/Camera.cpp
index 7ac3cc1df718..da21d1a05276 100644
--- a/libs/camera/Camera.cpp
+++ b/libs/camera/Camera.cpp
@@ -70,7 +70,7 @@ Camera::Camera()
// construct a camera client from an existing camera remote
sp<Camera> Camera::create(const sp<ICamera>& camera)
{
- LOGV("create");
+ ALOGV("create");
if (camera == 0) {
LOGE("camera remote is a NULL pointer");
return 0;
@@ -117,7 +117,7 @@ status_t Camera::getCameraInfo(int cameraId,
sp<Camera> Camera::connect(int cameraId)
{
- LOGV("connect");
+ ALOGV("connect");
sp<Camera> c = new Camera();
const sp<ICameraService>& cs = getCameraService();
if (cs != 0) {
@@ -134,7 +134,7 @@ sp<Camera> Camera::connect(int cameraId)
void Camera::disconnect()
{
- LOGV("disconnect");
+ ALOGV("disconnect");
if (mCamera != 0) {
mCamera->disconnect();
mCamera->asBinder()->unlinkToDeath(this);
@@ -144,7 +144,7 @@ void Camera::disconnect()
status_t Camera::reconnect()
{
- LOGV("reconnect");
+ ALOGV("reconnect");
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->connect(this);
@@ -172,7 +172,7 @@ status_t Camera::unlock()
// pass the buffered Surface to the camera service
status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
{
- LOGV("setPreviewDisplay(%p)", surface.get());
+ ALOGV("setPreviewDisplay(%p)", surface.get());
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
if (surface != 0) {
@@ -186,7 +186,7 @@ status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
// pass the buffered ISurfaceTexture to the camera service
status_t Camera::setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture)
{
- LOGV("setPreviewTexture(%p)", surfaceTexture.get());
+ ALOGV("setPreviewTexture(%p)", surfaceTexture.get());
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
if (surfaceTexture != 0) {
@@ -200,7 +200,7 @@ status_t Camera::setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture)
// start preview mode
status_t Camera::startPreview()
{
- LOGV("startPreview");
+ ALOGV("startPreview");
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->startPreview();
@@ -208,7 +208,7 @@ status_t Camera::startPreview()
status_t Camera::storeMetaDataInBuffers(bool enabled)
{
- LOGV("storeMetaDataInBuffers: %s",
+ ALOGV("storeMetaDataInBuffers: %s",
enabled? "true": "false");
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
@@ -218,7 +218,7 @@ status_t Camera::storeMetaDataInBuffers(bool enabled)
// start recording mode, must call setPreviewDisplay first
status_t Camera::startRecording()
{
- LOGV("startRecording");
+ ALOGV("startRecording");
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->startRecording();
@@ -227,7 +227,7 @@ status_t Camera::startRecording()
// stop preview mode
void Camera::stopPreview()
{
- LOGV("stopPreview");
+ ALOGV("stopPreview");
sp <ICamera> c = mCamera;
if (c == 0) return;
c->stopPreview();
@@ -236,7 +236,7 @@ void Camera::stopPreview()
// stop recording mode
void Camera::stopRecording()
{
- LOGV("stopRecording");
+ ALOGV("stopRecording");
{
Mutex::Autolock _l(mLock);
mRecordingProxyListener.clear();
@@ -249,7 +249,7 @@ void Camera::stopRecording()
// release a recording frame
void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
{
- LOGV("releaseRecordingFrame");
+ ALOGV("releaseRecordingFrame");
sp <ICamera> c = mCamera;
if (c == 0) return;
c->releaseRecordingFrame(mem);
@@ -258,7 +258,7 @@ void Camera::releaseRecordingFrame(const sp<IMemory>& mem)
// get preview state
bool Camera::previewEnabled()
{
- LOGV("previewEnabled");
+ ALOGV("previewEnabled");
sp <ICamera> c = mCamera;
if (c == 0) return false;
return c->previewEnabled();
@@ -267,7 +267,7 @@ bool Camera::previewEnabled()
// get recording state
bool Camera::recordingEnabled()
{
- LOGV("recordingEnabled");
+ ALOGV("recordingEnabled");
sp <ICamera> c = mCamera;
if (c == 0) return false;
return c->recordingEnabled();
@@ -275,7 +275,7 @@ bool Camera::recordingEnabled()
status_t Camera::autoFocus()
{
- LOGV("autoFocus");
+ ALOGV("autoFocus");
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->autoFocus();
@@ -283,7 +283,7 @@ status_t Camera::autoFocus()
status_t Camera::cancelAutoFocus()
{
- LOGV("cancelAutoFocus");
+ ALOGV("cancelAutoFocus");
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->cancelAutoFocus();
@@ -292,7 +292,7 @@ status_t Camera::cancelAutoFocus()
// take a picture
status_t Camera::takePicture(int msgType)
{
- LOGV("takePicture: 0x%x", msgType);
+ ALOGV("takePicture: 0x%x", msgType);
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->takePicture(msgType);
@@ -301,7 +301,7 @@ status_t Camera::takePicture(int msgType)
// set preview/capture parameters - key/value pairs
status_t Camera::setParameters(const String8& params)
{
- LOGV("setParameters");
+ ALOGV("setParameters");
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->setParameters(params);
@@ -310,7 +310,7 @@ status_t Camera::setParameters(const String8& params)
// get preview/capture parameters - key/value pairs
String8 Camera::getParameters() const
{
- LOGV("getParameters");
+ ALOGV("getParameters");
String8 params;
sp <ICamera> c = mCamera;
if (c != 0) params = mCamera->getParameters();
@@ -320,7 +320,7 @@ String8 Camera::getParameters() const
// send command to camera driver
status_t Camera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
{
- LOGV("sendCommand");
+ ALOGV("sendCommand");
sp <ICamera> c = mCamera;
if (c == 0) return NO_INIT;
return c->sendCommand(cmd, arg1, arg2);
@@ -340,7 +340,7 @@ void Camera::setRecordingProxyListener(const sp<ICameraRecordingProxyListener>&
void Camera::setPreviewCallbackFlags(int flag)
{
- LOGV("setPreviewCallbackFlags");
+ ALOGV("setPreviewCallbackFlags");
sp <ICamera> c = mCamera;
if (c == 0) return;
mCamera->setPreviewCallbackFlag(flag);
@@ -408,20 +408,20 @@ void Camera::binderDied(const wp<IBinder>& who) {
}
void Camera::DeathNotifier::binderDied(const wp<IBinder>& who) {
- LOGV("binderDied");
+ ALOGV("binderDied");
Mutex::Autolock _l(Camera::mLock);
Camera::mCameraService.clear();
LOGW("Camera server died!");
}
sp<ICameraRecordingProxy> Camera::getRecordingProxy() {
- LOGV("getProxy");
+ ALOGV("getProxy");
return new RecordingProxy(this);
}
status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyListener>& listener)
{
- LOGV("RecordingProxy::startRecording");
+ ALOGV("RecordingProxy::startRecording");
mCamera->setRecordingProxyListener(listener);
mCamera->reconnect();
return mCamera->startRecording();
@@ -429,13 +429,13 @@ status_t Camera::RecordingProxy::startRecording(const sp<ICameraRecordingProxyLi
void Camera::RecordingProxy::stopRecording()
{
- LOGV("RecordingProxy::stopRecording");
+ ALOGV("RecordingProxy::stopRecording");
mCamera->stopRecording();
}
void Camera::RecordingProxy::releaseRecordingFrame(const sp<IMemory>& mem)
{
- LOGV("RecordingProxy::releaseRecordingFrame");
+ ALOGV("RecordingProxy::releaseRecordingFrame");
mCamera->releaseRecordingFrame(mem);
}
diff --git a/libs/camera/ICamera.cpp b/libs/camera/ICamera.cpp
index 5f6e5ef4d129..70f5dbcf3f45 100644
--- a/libs/camera/ICamera.cpp
+++ b/libs/camera/ICamera.cpp
@@ -60,7 +60,7 @@ public:
// disconnect from camera service
void disconnect()
{
- LOGV("disconnect");
+ ALOGV("disconnect");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(DISCONNECT, data, &reply);
@@ -69,7 +69,7 @@ public:
// pass the buffered Surface to the camera service
status_t setPreviewDisplay(const sp<Surface>& surface)
{
- LOGV("setPreviewDisplay");
+ ALOGV("setPreviewDisplay");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
Surface::writeToParcel(surface, &data);
@@ -80,7 +80,7 @@ public:
// pass the buffered SurfaceTexture to the camera service
status_t setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture)
{
- LOGV("setPreviewTexture");
+ ALOGV("setPreviewTexture");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
sp<IBinder> b(surfaceTexture->asBinder());
@@ -93,7 +93,7 @@ public:
// preview are handled. See Camera.h for details.
void setPreviewCallbackFlag(int flag)
{
- LOGV("setPreviewCallbackFlag(%d)", flag);
+ ALOGV("setPreviewCallbackFlag(%d)", flag);
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
data.writeInt32(flag);
@@ -103,7 +103,7 @@ public:
// start preview mode, must call setPreviewDisplay first
status_t startPreview()
{
- LOGV("startPreview");
+ ALOGV("startPreview");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(START_PREVIEW, data, &reply);
@@ -113,7 +113,7 @@ public:
// start recording mode, must call setPreviewDisplay first
status_t startRecording()
{
- LOGV("startRecording");
+ ALOGV("startRecording");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(START_RECORDING, data, &reply);
@@ -123,7 +123,7 @@ public:
// stop preview mode
void stopPreview()
{
- LOGV("stopPreview");
+ ALOGV("stopPreview");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(STOP_PREVIEW, data, &reply);
@@ -132,7 +132,7 @@ public:
// stop recording mode
void stopRecording()
{
- LOGV("stopRecording");
+ ALOGV("stopRecording");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(STOP_RECORDING, data, &reply);
@@ -140,7 +140,7 @@ public:
void releaseRecordingFrame(const sp<IMemory>& mem)
{
- LOGV("releaseRecordingFrame");
+ ALOGV("releaseRecordingFrame");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
data.writeStrongBinder(mem->asBinder());
@@ -149,7 +149,7 @@ public:
status_t storeMetaDataInBuffers(bool enabled)
{
- LOGV("storeMetaDataInBuffers: %s", enabled? "true": "false");
+ ALOGV("storeMetaDataInBuffers: %s", enabled? "true": "false");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
data.writeInt32(enabled);
@@ -160,7 +160,7 @@ public:
// check preview state
bool previewEnabled()
{
- LOGV("previewEnabled");
+ ALOGV("previewEnabled");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(PREVIEW_ENABLED, data, &reply);
@@ -170,7 +170,7 @@ public:
// check recording state
bool recordingEnabled()
{
- LOGV("recordingEnabled");
+ ALOGV("recordingEnabled");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(RECORDING_ENABLED, data, &reply);
@@ -180,7 +180,7 @@ public:
// auto focus
status_t autoFocus()
{
- LOGV("autoFocus");
+ ALOGV("autoFocus");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(AUTO_FOCUS, data, &reply);
@@ -191,7 +191,7 @@ public:
// cancel focus
status_t cancelAutoFocus()
{
- LOGV("cancelAutoFocus");
+ ALOGV("cancelAutoFocus");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(CANCEL_AUTO_FOCUS, data, &reply);
@@ -202,7 +202,7 @@ public:
// take a picture - returns an IMemory (ref-counted mmap)
status_t takePicture(int msgType)
{
- LOGV("takePicture: 0x%x", msgType);
+ ALOGV("takePicture: 0x%x", msgType);
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
data.writeInt32(msgType);
@@ -214,7 +214,7 @@ public:
// set preview/capture parameters - key/value pairs
status_t setParameters(const String8& params)
{
- LOGV("setParameters");
+ ALOGV("setParameters");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
data.writeString8(params);
@@ -225,7 +225,7 @@ public:
// get preview/capture parameters - key/value pairs
String8 getParameters() const
{
- LOGV("getParameters");
+ ALOGV("getParameters");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(GET_PARAMETERS, data, &reply);
@@ -233,7 +233,7 @@ public:
}
virtual status_t sendCommand(int32_t cmd, int32_t arg1, int32_t arg2)
{
- LOGV("sendCommand");
+ ALOGV("sendCommand");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
data.writeInt32(cmd);
@@ -275,116 +275,116 @@ status_t BnCamera::onTransact(
{
switch(code) {
case DISCONNECT: {
- LOGV("DISCONNECT");
+ ALOGV("DISCONNECT");
CHECK_INTERFACE(ICamera, data, reply);
disconnect();
return NO_ERROR;
} break;
case SET_PREVIEW_DISPLAY: {
- LOGV("SET_PREVIEW_DISPLAY");
+ ALOGV("SET_PREVIEW_DISPLAY");
CHECK_INTERFACE(ICamera, data, reply);
sp<Surface> surface = Surface::readFromParcel(data);
reply->writeInt32(setPreviewDisplay(surface));
return NO_ERROR;
} break;
case SET_PREVIEW_TEXTURE: {
- LOGV("SET_PREVIEW_TEXTURE");
+ ALOGV("SET_PREVIEW_TEXTURE");
CHECK_INTERFACE(ICamera, data, reply);
sp<ISurfaceTexture> st = interface_cast<ISurfaceTexture>(data.readStrongBinder());
reply->writeInt32(setPreviewTexture(st));
return NO_ERROR;
} break;
case SET_PREVIEW_CALLBACK_FLAG: {
- LOGV("SET_PREVIEW_CALLBACK_TYPE");
+ ALOGV("SET_PREVIEW_CALLBACK_TYPE");
CHECK_INTERFACE(ICamera, data, reply);
int callback_flag = data.readInt32();
setPreviewCallbackFlag(callback_flag);
return NO_ERROR;
} break;
case START_PREVIEW: {
- LOGV("START_PREVIEW");
+ ALOGV("START_PREVIEW");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(startPreview());
return NO_ERROR;
} break;
case START_RECORDING: {
- LOGV("START_RECORDING");
+ ALOGV("START_RECORDING");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(startRecording());
return NO_ERROR;
} break;
case STOP_PREVIEW: {
- LOGV("STOP_PREVIEW");
+ ALOGV("STOP_PREVIEW");
CHECK_INTERFACE(ICamera, data, reply);
stopPreview();
return NO_ERROR;
} break;
case STOP_RECORDING: {
- LOGV("STOP_RECORDING");
+ ALOGV("STOP_RECORDING");
CHECK_INTERFACE(ICamera, data, reply);
stopRecording();
return NO_ERROR;
} break;
case RELEASE_RECORDING_FRAME: {
- LOGV("RELEASE_RECORDING_FRAME");
+ ALOGV("RELEASE_RECORDING_FRAME");
CHECK_INTERFACE(ICamera, data, reply);
sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
releaseRecordingFrame(mem);
return NO_ERROR;
} break;
case STORE_META_DATA_IN_BUFFERS: {
- LOGV("STORE_META_DATA_IN_BUFFERS");
+ ALOGV("STORE_META_DATA_IN_BUFFERS");
CHECK_INTERFACE(ICamera, data, reply);
bool enabled = data.readInt32();
reply->writeInt32(storeMetaDataInBuffers(enabled));
return NO_ERROR;
} break;
case PREVIEW_ENABLED: {
- LOGV("PREVIEW_ENABLED");
+ ALOGV("PREVIEW_ENABLED");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(previewEnabled());
return NO_ERROR;
} break;
case RECORDING_ENABLED: {
- LOGV("RECORDING_ENABLED");
+ ALOGV("RECORDING_ENABLED");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(recordingEnabled());
return NO_ERROR;
} break;
case AUTO_FOCUS: {
- LOGV("AUTO_FOCUS");
+ ALOGV("AUTO_FOCUS");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(autoFocus());
return NO_ERROR;
} break;
case CANCEL_AUTO_FOCUS: {
- LOGV("CANCEL_AUTO_FOCUS");
+ ALOGV("CANCEL_AUTO_FOCUS");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(cancelAutoFocus());
return NO_ERROR;
} break;
case TAKE_PICTURE: {
- LOGV("TAKE_PICTURE");
+ ALOGV("TAKE_PICTURE");
CHECK_INTERFACE(ICamera, data, reply);
int msgType = data.readInt32();
reply->writeInt32(takePicture(msgType));
return NO_ERROR;
} break;
case SET_PARAMETERS: {
- LOGV("SET_PARAMETERS");
+ ALOGV("SET_PARAMETERS");
CHECK_INTERFACE(ICamera, data, reply);
String8 params(data.readString8());
reply->writeInt32(setParameters(params));
return NO_ERROR;
} break;
case GET_PARAMETERS: {
- LOGV("GET_PARAMETERS");
+ ALOGV("GET_PARAMETERS");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeString8(getParameters());
return NO_ERROR;
} break;
case SEND_COMMAND: {
- LOGV("SEND_COMMAND");
+ ALOGV("SEND_COMMAND");
CHECK_INTERFACE(ICamera, data, reply);
int command = data.readInt32();
int arg1 = data.readInt32();
diff --git a/libs/camera/ICameraClient.cpp b/libs/camera/ICameraClient.cpp
index 183429ad8c7b..205c8ba1f123 100644
--- a/libs/camera/ICameraClient.cpp
+++ b/libs/camera/ICameraClient.cpp
@@ -41,7 +41,7 @@ public:
// generic callback from camera service to app
void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2)
{
- LOGV("notifyCallback");
+ ALOGV("notifyCallback");
Parcel data, reply;
data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
data.writeInt32(msgType);
@@ -54,7 +54,7 @@ public:
void dataCallback(int32_t msgType, const sp<IMemory>& imageData,
camera_frame_metadata_t *metadata)
{
- LOGV("dataCallback");
+ ALOGV("dataCallback");
Parcel data, reply;
data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
data.writeInt32(msgType);
@@ -69,7 +69,7 @@ public:
// generic data callback from camera service to app with image data
void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& imageData)
{
- LOGV("dataCallback");
+ ALOGV("dataCallback");
Parcel data, reply;
data.writeInterfaceToken(ICameraClient::getInterfaceDescriptor());
data.writeInt64(timestamp);
@@ -88,7 +88,7 @@ status_t BnCameraClient::onTransact(
{
switch(code) {
case NOTIFY_CALLBACK: {
- LOGV("NOTIFY_CALLBACK");
+ ALOGV("NOTIFY_CALLBACK");
CHECK_INTERFACE(ICameraClient, data, reply);
int32_t msgType = data.readInt32();
int32_t ext1 = data.readInt32();
@@ -97,7 +97,7 @@ status_t BnCameraClient::onTransact(
return NO_ERROR;
} break;
case DATA_CALLBACK: {
- LOGV("DATA_CALLBACK");
+ ALOGV("DATA_CALLBACK");
CHECK_INTERFACE(ICameraClient, data, reply);
int32_t msgType = data.readInt32();
sp<IMemory> imageData = interface_cast<IMemory>(data.readStrongBinder());
@@ -113,7 +113,7 @@ status_t BnCameraClient::onTransact(
return NO_ERROR;
} break;
case DATA_CALLBACK_TIMESTAMP: {
- LOGV("DATA_CALLBACK_TIMESTAMP");
+ ALOGV("DATA_CALLBACK_TIMESTAMP");
CHECK_INTERFACE(ICameraClient, data, reply);
nsecs_t timestamp = data.readInt64();
int32_t msgType = data.readInt32();
diff --git a/libs/camera/ICameraRecordingProxy.cpp b/libs/camera/ICameraRecordingProxy.cpp
index 64b6a5ceaacc..7223b6d32c32 100644
--- a/libs/camera/ICameraRecordingProxy.cpp
+++ b/libs/camera/ICameraRecordingProxy.cpp
@@ -42,7 +42,7 @@ public:
status_t startRecording(const sp<ICameraRecordingProxyListener>& listener)
{
- LOGV("startRecording");
+ ALOGV("startRecording");
Parcel data, reply;
data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
data.writeStrongBinder(listener->asBinder());
@@ -52,7 +52,7 @@ public:
void stopRecording()
{
- LOGV("stopRecording");
+ ALOGV("stopRecording");
Parcel data, reply;
data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
remote()->transact(STOP_RECORDING, data, &reply);
@@ -60,7 +60,7 @@ public:
void releaseRecordingFrame(const sp<IMemory>& mem)
{
- LOGV("releaseRecordingFrame");
+ ALOGV("releaseRecordingFrame");
Parcel data, reply;
data.writeInterfaceToken(ICameraRecordingProxy::getInterfaceDescriptor());
data.writeStrongBinder(mem->asBinder());
@@ -77,7 +77,7 @@ status_t BnCameraRecordingProxy::onTransact(
{
switch(code) {
case START_RECORDING: {
- LOGV("START_RECORDING");
+ ALOGV("START_RECORDING");
CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
sp<ICameraRecordingProxyListener> listener =
interface_cast<ICameraRecordingProxyListener>(data.readStrongBinder());
@@ -85,13 +85,13 @@ status_t BnCameraRecordingProxy::onTransact(
return NO_ERROR;
} break;
case STOP_RECORDING: {
- LOGV("STOP_RECORDING");
+ ALOGV("STOP_RECORDING");
CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
stopRecording();
return NO_ERROR;
} break;
case RELEASE_RECORDING_FRAME: {
- LOGV("RELEASE_RECORDING_FRAME");
+ ALOGV("RELEASE_RECORDING_FRAME");
CHECK_INTERFACE(ICameraRecordingProxy, data, reply);
sp<IMemory> mem = interface_cast<IMemory>(data.readStrongBinder());
releaseRecordingFrame(mem);
diff --git a/libs/camera/ICameraRecordingProxyListener.cpp b/libs/camera/ICameraRecordingProxyListener.cpp
index f8cece5e1add..cb17f190e480 100644
--- a/libs/camera/ICameraRecordingProxyListener.cpp
+++ b/libs/camera/ICameraRecordingProxyListener.cpp
@@ -37,7 +37,7 @@ public:
void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& imageData)
{
- LOGV("dataCallback");
+ ALOGV("dataCallback");
Parcel data, reply;
data.writeInterfaceToken(ICameraRecordingProxyListener::getInterfaceDescriptor());
data.writeInt64(timestamp);
@@ -56,7 +56,7 @@ status_t BnCameraRecordingProxyListener::onTransact(
{
switch(code) {
case DATA_CALLBACK_TIMESTAMP: {
- LOGV("DATA_CALLBACK_TIMESTAMP");
+ ALOGV("DATA_CALLBACK_TIMESTAMP");
CHECK_INTERFACE(ICameraRecordingProxyListener, data, reply);
nsecs_t timestamp = data.readInt64();
int32_t msgType = data.readInt32();
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index 9767568bed35..b8be67d446ce 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -2,11 +2,13 @@ LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
+ BitTube.cpp \
+ DisplayEventReceiver.cpp \
+ IDisplayEventConnection.cpp \
ISensorEventConnection.cpp \
ISensorServer.cpp \
ISurfaceTexture.cpp \
Sensor.cpp \
- SensorChannel.cpp \
SensorEventQueue.cpp \
SensorManager.cpp \
SurfaceTexture.cpp \
diff --git a/libs/gui/SensorChannel.cpp b/libs/gui/BitTube.cpp
index 147e1c2bb4d5..fa8d0eabca1d 100644
--- a/libs/gui/SensorChannel.cpp
+++ b/libs/gui/BitTube.cpp
@@ -24,12 +24,12 @@
#include <binder/Parcel.h>
-#include <gui/SensorChannel.h>
+#include <gui/BitTube.h>
namespace android {
// ----------------------------------------------------------------------------
-SensorChannel::SensorChannel()
+BitTube::BitTube()
: mSendFd(-1), mReceiveFd(-1)
{
int fds[2];
@@ -38,17 +38,26 @@ SensorChannel::SensorChannel()
mSendFd = fds[1];
fcntl(mReceiveFd, F_SETFL, O_NONBLOCK);
fcntl(mSendFd, F_SETFL, O_NONBLOCK);
+ } else {
+ mReceiveFd = -errno;
+ LOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd));
}
}
-SensorChannel::SensorChannel(const Parcel& data)
+BitTube::BitTube(const Parcel& data)
: mSendFd(-1), mReceiveFd(-1)
{
mReceiveFd = dup(data.readFileDescriptor());
- fcntl(mReceiveFd, F_SETFL, O_NONBLOCK);
+ if (mReceiveFd >= 0) {
+ fcntl(mReceiveFd, F_SETFL, O_NONBLOCK);
+ } else {
+ mReceiveFd = -errno;
+ LOGE("BitTube(Parcel): can't dup filedescriptor (%s)",
+ strerror(-mReceiveFd));
+ }
}
-SensorChannel::~SensorChannel()
+BitTube::~BitTube()
{
if (mSendFd >= 0)
close(mSendFd);
@@ -57,28 +66,46 @@ SensorChannel::~SensorChannel()
close(mReceiveFd);
}
-int SensorChannel::getFd() const
+status_t BitTube::initCheck() const
+{
+ if (mReceiveFd < 0) {
+ return status_t(mReceiveFd);
+ }
+ return NO_ERROR;
+}
+
+int BitTube::getFd() const
{
return mReceiveFd;
}
-ssize_t SensorChannel::write(void const* vaddr, size_t size)
+ssize_t BitTube::write(void const* vaddr, size_t size)
{
- ssize_t len = ::write(mSendFd, vaddr, size);
- if (len < 0)
- return -errno;
- return len;
+ ssize_t err, len;
+ do {
+ len = ::write(mSendFd, vaddr, size);
+ err = len < 0 ? errno : 0;
+ } while (err == EINTR);
+ return err == 0 ? len : -err;
+
}
-ssize_t SensorChannel::read(void* vaddr, size_t size)
+ssize_t BitTube::read(void* vaddr, size_t size)
{
- ssize_t len = ::read(mReceiveFd, vaddr, size);
- if (len < 0)
- return -errno;
- return len;
+ ssize_t err, len;
+ do {
+ len = ::read(mReceiveFd, vaddr, size);
+ err = len < 0 ? errno : 0;
+ } while (err == EINTR);
+ if (err == EAGAIN || err == EWOULDBLOCK) {
+ // EAGAIN means that we have non-blocking I/O but there was
+ // no data to be read. Nothing the client should care about.
+ return 0;
+ }
+ return err == 0 ? len : -err;
}
-status_t SensorChannel::writeToParcel(Parcel* reply) const
+status_t BitTube::writeToParcel(Parcel* reply) const
{
if (mReceiveFd < 0)
return -EINVAL;
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
new file mode 100644
index 000000000000..3b29a113e4ef
--- /dev/null
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -0,0 +1,83 @@
+/*
+ * 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 <string.h>
+
+#include <utils/Errors.h>
+
+#include <gui/BitTube.h>
+#include <gui/DisplayEventReceiver.h>
+#include <gui/IDisplayEventConnection.h>
+
+#include <private/gui/ComposerService.h>
+
+#include <surfaceflinger/ISurfaceComposer.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+DisplayEventReceiver::DisplayEventReceiver() {
+ sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+ if (sf != NULL) {
+ mEventConnection = sf->createDisplayEventConnection();
+ if (mEventConnection != NULL) {
+ mDataChannel = mEventConnection->getDataChannel();
+ }
+ }
+}
+
+DisplayEventReceiver::~DisplayEventReceiver() {
+}
+
+status_t DisplayEventReceiver::initCheck() const {
+ if (mDataChannel != NULL)
+ return NO_ERROR;
+ return NO_INIT;
+}
+
+int DisplayEventReceiver::getFd() const {
+ if (mDataChannel == NULL)
+ return NO_INIT;
+
+ return mDataChannel->getFd();
+}
+
+ssize_t DisplayEventReceiver::getEvents(DisplayEventReceiver::Event* events,
+ size_t count) {
+ ssize_t size = mDataChannel->read(events, sizeof(events[0])*count);
+ LOGE_IF(size<0,
+ "DisplayEventReceiver::getEvents error (%s)",
+ strerror(-size));
+ if (size >= 0) {
+ // Note: if (size % sizeof(events[0])) != 0, we've got a
+ // partial read. This can happen if the queue filed up (ie: if we
+ // didn't pull from it fast enough).
+ // We discard the partial event and rely on the sender to
+ // re-send the event if appropriate (some events, like VSYNC
+ // can be lost forever).
+
+ // returns number of events read
+ size /= sizeof(events[0]);
+ }
+ return size;
+}
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
diff --git a/libs/gui/IDisplayEventConnection.cpp b/libs/gui/IDisplayEventConnection.cpp
new file mode 100644
index 000000000000..44127fb4acd8
--- /dev/null
+++ b/libs/gui/IDisplayEventConnection.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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 <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+#include <binder/Parcel.h>
+#include <binder/IInterface.h>
+
+#include <gui/IDisplayEventConnection.h>
+#include <gui/BitTube.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+
+enum {
+ GET_DATA_CHANNEL = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+class BpDisplayEventConnection : public BpInterface<IDisplayEventConnection>
+{
+public:
+ BpDisplayEventConnection(const sp<IBinder>& impl)
+ : BpInterface<IDisplayEventConnection>(impl)
+ {
+ }
+
+ virtual sp<BitTube> getDataChannel() const
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
+ remote()->transact(GET_DATA_CHANNEL, data, &reply);
+ return new BitTube(reply);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(DisplayEventConnection, "android.gui.DisplayEventConnection");
+
+// ----------------------------------------------------------------------------
+
+status_t BnDisplayEventConnection::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
+{
+ switch(code) {
+ case GET_DATA_CHANNEL: {
+ CHECK_INTERFACE(IDisplayEventConnection, data, reply);
+ sp<BitTube> channel(getDataChannel());
+ channel->writeToParcel(reply);
+ return NO_ERROR;
+ } break;
+ }
+ return BBinder::onTransact(code, data, reply, flags);
+}
+
+// ----------------------------------------------------------------------------
+}; // namespace android
diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/gui/ISensorEventConnection.cpp
index a5083fed0aba..0e51e8ef0de6 100644
--- a/libs/gui/ISensorEventConnection.cpp
+++ b/libs/gui/ISensorEventConnection.cpp
@@ -25,7 +25,7 @@
#include <binder/IInterface.h>
#include <gui/ISensorEventConnection.h>
-#include <gui/SensorChannel.h>
+#include <gui/BitTube.h>
namespace android {
// ----------------------------------------------------------------------------
@@ -44,12 +44,12 @@ public:
{
}
- virtual sp<SensorChannel> getSensorChannel() const
+ virtual sp<BitTube> getSensorChannel() const
{
Parcel data, reply;
data.writeInterfaceToken(ISensorEventConnection::getInterfaceDescriptor());
remote()->transact(GET_SENSOR_CHANNEL, data, &reply);
- return new SensorChannel(reply);
+ return new BitTube(reply);
}
virtual status_t enableDisable(int handle, bool enabled)
@@ -83,7 +83,7 @@ status_t BnSensorEventConnection::onTransact(
switch(code) {
case GET_SENSOR_CHANNEL: {
CHECK_INTERFACE(ISensorEventConnection, data, reply);
- sp<SensorChannel> channel(getSensorChannel());
+ sp<BitTube> channel(getSensorChannel());
channel->writeToParcel(reply);
return NO_ERROR;
} break;
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 86bc62aa2806..db3282781ab3 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -29,6 +29,9 @@
#include <surfaceflinger/ISurfaceComposer.h>
+#include <gui/BitTube.h>
+#include <gui/IDisplayEventConnection.h>
+
#include <ui/DisplayInfo.h>
#include <gui/ISurfaceTexture.h>
@@ -44,6 +47,8 @@
namespace android {
+class IDisplayEventConnection;
+
class BpSurfaceComposer : public BpInterface<ISurfaceComposer>
{
public:
@@ -174,6 +179,27 @@ public:
}
return result != 0;
}
+
+ virtual sp<IDisplayEventConnection> createDisplayEventConnection()
+ {
+ Parcel data, reply;
+ sp<IDisplayEventConnection> result;
+ int err = data.writeInterfaceToken(
+ ISurfaceComposer::getInterfaceDescriptor());
+ if (err != NO_ERROR) {
+ return result;
+ }
+ err = remote()->transact(
+ BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION,
+ data, &reply);
+ if (err != NO_ERROR) {
+ LOGE("ISurfaceComposer::createDisplayEventConnection: error performing "
+ "transaction: %s (%d)", strerror(-err), -err);
+ return result;
+ }
+ result = interface_cast<IDisplayEventConnection>(reply.readStrongBinder());
+ return result;
+ }
};
IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
@@ -254,6 +280,12 @@ status_t BnSurfaceComposer::onTransact(
int32_t result = authenticateSurfaceTexture(surfaceTexture) ? 1 : 0;
reply->writeInt32(result);
} break;
+ case CREATE_DISPLAY_EVENT_CONNECTION: {
+ CHECK_INTERFACE(ISurfaceComposer, data, reply);
+ sp<IDisplayEventConnection> connection(createDisplayEventConnection());
+ reply->writeStrongBinder(connection->asBinder());
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
index f9355249ab92..ee21c45c5935 100644
--- a/libs/gui/SensorEventQueue.cpp
+++ b/libs/gui/SensorEventQueue.cpp
@@ -24,7 +24,7 @@
#include <utils/Looper.h>
#include <gui/Sensor.h>
-#include <gui/SensorChannel.h>
+#include <gui/BitTube.h>
#include <gui/SensorEventQueue.h>
#include <gui/ISensorEventConnection.h>
@@ -104,7 +104,7 @@ status_t SensorEventQueue::waitForEvent() const
do {
result = looper->pollOnce(-1);
if (result == ALOOPER_EVENT_ERROR) {
- LOGE("SensorChannel::waitForEvent error (errno=%d)", errno);
+ LOGE("SensorEventQueue::waitForEvent error (errno=%d)", errno);
result = -EPIPE; // unknown error, so we make up one
break;
}
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 4ad6c22c0dae..699438c0d717 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -39,6 +39,7 @@
#include <private/surfaceflinger/LayerState.h>
#include <private/surfaceflinger/SharedBufferStack.h>
+#include <private/gui/ComposerService.h>
namespace android {
// ---------------------------------------------------------------------------
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index beb23f64065a..289726bae1d9 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -29,6 +29,8 @@
#include <hardware/hardware.h>
+#include <private/gui/ComposerService.h>
+
#include <surfaceflinger/ISurfaceComposer.h>
#include <surfaceflinger/SurfaceComposerClient.h>
#include <surfaceflinger/IGraphicBufferAlloc.h>
@@ -44,7 +46,7 @@
#endif
// Macros for including the SurfaceTexture name in log messages
-#define ST_LOGV(x, ...) LOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
#define ST_LOGD(x, ...) LOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
#define ST_LOGI(x, ...) LOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
#define ST_LOGW(x, ...) LOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index 48070d67c322..691b52daf9d8 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -23,6 +23,8 @@
#include <utils/Log.h>
+#include <private/gui/ComposerService.h>
+
namespace android {
SurfaceTextureClient::SurfaceTextureClient(
@@ -136,13 +138,13 @@ int SurfaceTextureClient::setSwapInterval(int interval) {
}
int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
- LOGV("SurfaceTextureClient::dequeueBuffer");
+ ALOGV("SurfaceTextureClient::dequeueBuffer");
Mutex::Autolock lock(mMutex);
int buf = -1;
status_t result = mSurfaceTexture->dequeueBuffer(&buf, mReqWidth, mReqHeight,
mReqFormat, mReqUsage);
if (result < 0) {
- LOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"
+ ALOGV("dequeueBuffer: ISurfaceTexture::dequeueBuffer(%d, %d, %d, %d)"
"failed: %d", mReqWidth, mReqHeight, mReqFormat, mReqUsage,
result);
return result;
@@ -165,7 +167,7 @@ int SurfaceTextureClient::dequeueBuffer(android_native_buffer_t** buffer) {
}
int SurfaceTextureClient::cancelBuffer(android_native_buffer_t* buffer) {
- LOGV("SurfaceTextureClient::cancelBuffer");
+ ALOGV("SurfaceTextureClient::cancelBuffer");
Mutex::Autolock lock(mMutex);
int i = getSlotFromBufferLocked(buffer);
if (i < 0) {
@@ -205,18 +207,18 @@ int SurfaceTextureClient::getSlotFromBufferLocked(
}
int SurfaceTextureClient::lockBuffer(android_native_buffer_t* buffer) {
- LOGV("SurfaceTextureClient::lockBuffer");
+ ALOGV("SurfaceTextureClient::lockBuffer");
Mutex::Autolock lock(mMutex);
return OK;
}
int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
- LOGV("SurfaceTextureClient::queueBuffer");
+ ALOGV("SurfaceTextureClient::queueBuffer");
Mutex::Autolock lock(mMutex);
int64_t timestamp;
if (mTimestamp == NATIVE_WINDOW_TIMESTAMP_AUTO) {
timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
- LOGV("SurfaceTextureClient::queueBuffer making up timestamp: %.2f ms",
+ ALOGV("SurfaceTextureClient::queueBuffer making up timestamp: %.2f ms",
timestamp / 1000000.f);
} else {
timestamp = mTimestamp;
@@ -234,7 +236,7 @@ int SurfaceTextureClient::queueBuffer(android_native_buffer_t* buffer) {
}
int SurfaceTextureClient::query(int what, int* value) const {
- LOGV("SurfaceTextureClient::query");
+ ALOGV("SurfaceTextureClient::query");
{ // scope for the lock
Mutex::Autolock lock(mMutex);
switch (what) {
@@ -402,7 +404,7 @@ int SurfaceTextureClient::dispatchUnlockAndPost(va_list args) {
int SurfaceTextureClient::connect(int api) {
- LOGV("SurfaceTextureClient::connect");
+ ALOGV("SurfaceTextureClient::connect");
Mutex::Autolock lock(mMutex);
int err = mSurfaceTexture->connect(api,
&mDefaultWidth, &mDefaultHeight, &mTransformHint);
@@ -413,7 +415,7 @@ int SurfaceTextureClient::connect(int api) {
}
int SurfaceTextureClient::disconnect(int api) {
- LOGV("SurfaceTextureClient::disconnect");
+ ALOGV("SurfaceTextureClient::disconnect");
Mutex::Autolock lock(mMutex);
freeAllBuffers();
int err = mSurfaceTexture->disconnect(api);
@@ -431,7 +433,7 @@ int SurfaceTextureClient::disconnect(int api) {
int SurfaceTextureClient::setUsage(uint32_t reqUsage)
{
- LOGV("SurfaceTextureClient::setUsage");
+ ALOGV("SurfaceTextureClient::setUsage");
Mutex::Autolock lock(mMutex);
mReqUsage = reqUsage;
return OK;
@@ -439,7 +441,7 @@ int SurfaceTextureClient::setUsage(uint32_t reqUsage)
int SurfaceTextureClient::setCrop(Rect const* rect)
{
- LOGV("SurfaceTextureClient::setCrop");
+ ALOGV("SurfaceTextureClient::setCrop");
Mutex::Autolock lock(mMutex);
Rect realRect;
@@ -457,7 +459,7 @@ int SurfaceTextureClient::setCrop(Rect const* rect)
int SurfaceTextureClient::setBufferCount(int bufferCount)
{
- LOGV("SurfaceTextureClient::setBufferCount");
+ ALOGV("SurfaceTextureClient::setBufferCount");
Mutex::Autolock lock(mMutex);
status_t err = mSurfaceTexture->setBufferCount(bufferCount);
@@ -473,7 +475,7 @@ int SurfaceTextureClient::setBufferCount(int bufferCount)
int SurfaceTextureClient::setBuffersDimensions(int w, int h)
{
- LOGV("SurfaceTextureClient::setBuffersDimensions");
+ ALOGV("SurfaceTextureClient::setBuffersDimensions");
Mutex::Autolock lock(mMutex);
if (w<0 || h<0)
@@ -493,7 +495,7 @@ int SurfaceTextureClient::setBuffersDimensions(int w, int h)
int SurfaceTextureClient::setBuffersFormat(int format)
{
- LOGV("SurfaceTextureClient::setBuffersFormat");
+ ALOGV("SurfaceTextureClient::setBuffersFormat");
Mutex::Autolock lock(mMutex);
if (format<0)
@@ -506,7 +508,7 @@ int SurfaceTextureClient::setBuffersFormat(int format)
int SurfaceTextureClient::setScalingMode(int mode)
{
- LOGV("SurfaceTextureClient::setScalingMode(%d)", mode);
+ ALOGV("SurfaceTextureClient::setScalingMode(%d)", mode);
Mutex::Autolock lock(mMutex);
// mode is validated on the server
status_t err = mSurfaceTexture->setScalingMode(mode);
@@ -518,7 +520,7 @@ int SurfaceTextureClient::setScalingMode(int mode)
int SurfaceTextureClient::setBuffersTransform(int transform)
{
- LOGV("SurfaceTextureClient::setBuffersTransform");
+ ALOGV("SurfaceTextureClient::setBuffersTransform");
Mutex::Autolock lock(mMutex);
status_t err = mSurfaceTexture->setTransform(transform);
return err;
@@ -526,7 +528,7 @@ int SurfaceTextureClient::setBuffersTransform(int transform)
int SurfaceTextureClient::setBuffersTimestamp(int64_t timestamp)
{
- LOGV("SurfaceTextureClient::setBuffersTimestamp");
+ ALOGV("SurfaceTextureClient::setBuffersTimestamp");
Mutex::Autolock lock(mMutex);
mTimestamp = timestamp;
return NO_ERROR;
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index 6d1b95126995..c79e69a9b8a1 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -1385,12 +1385,12 @@ protected:
// test.
void waitForFrame() {
Mutex::Autolock lock(mMutex);
- LOGV("+waitForFrame");
+ ALOGV("+waitForFrame");
while (!mFrameAvailable) {
mFrameAvailableCondition.wait(mMutex);
}
mFrameAvailable = false;
- LOGV("-waitForFrame");
+ ALOGV("-waitForFrame");
}
// Allow the producer to return from its swapBuffers call and continue
@@ -1398,23 +1398,23 @@ protected:
// thread once for every frame expected by the test.
void finishFrame() {
Mutex::Autolock lock(mMutex);
- LOGV("+finishFrame");
+ ALOGV("+finishFrame");
mFrameFinished = true;
mFrameFinishCondition.signal();
- LOGV("-finishFrame");
+ ALOGV("-finishFrame");
}
// This should be called by SurfaceTexture on the producer thread.
virtual void onFrameAvailable() {
Mutex::Autolock lock(mMutex);
- LOGV("+onFrameAvailable");
+ ALOGV("+onFrameAvailable");
mFrameAvailable = true;
mFrameAvailableCondition.signal();
while (!mFrameFinished) {
mFrameFinishCondition.wait(mMutex);
}
mFrameFinished = false;
- LOGV("-onFrameAvailable");
+ ALOGV("-onFrameAvailable");
}
protected:
@@ -1500,9 +1500,9 @@ TEST_F(SurfaceTextureGLThreadToGLTest,
for (int i = 0; i < NUM_ITERATIONS; i++) {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
- LOGV("+swapBuffers");
+ ALOGV("+swapBuffers");
swapBuffers();
- LOGV("-swapBuffers");
+ ALOGV("-swapBuffers");
}
}
};
@@ -1511,9 +1511,9 @@ TEST_F(SurfaceTextureGLThreadToGLTest,
for (int i = 0; i < NUM_ITERATIONS; i++) {
mFC->waitForFrame();
- LOGV("+updateTexImage");
+ ALOGV("+updateTexImage");
mST->updateTexImage();
- LOGV("-updateTexImage");
+ ALOGV("-updateTexImage");
mFC->finishFrame();
// TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
@@ -1529,9 +1529,9 @@ TEST_F(SurfaceTextureGLThreadToGLTest,
for (int i = 0; i < NUM_ITERATIONS; i++) {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
- LOGV("+swapBuffers");
+ ALOGV("+swapBuffers");
swapBuffers();
- LOGV("-swapBuffers");
+ ALOGV("-swapBuffers");
}
}
};
@@ -1541,9 +1541,9 @@ TEST_F(SurfaceTextureGLThreadToGLTest,
for (int i = 0; i < NUM_ITERATIONS; i++) {
mFC->waitForFrame();
mFC->finishFrame();
- LOGV("+updateTexImage");
+ ALOGV("+updateTexImage");
mST->updateTexImage();
- LOGV("-updateTexImage");
+ ALOGV("-updateTexImage");
// TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported!
}
@@ -1559,9 +1559,9 @@ TEST_F(SurfaceTextureGLThreadToGLTest,
for (int i = 0; i < NUM_ITERATIONS; i++) {
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
- LOGV("+swapBuffers");
+ ALOGV("+swapBuffers");
swapBuffers();
- LOGV("-swapBuffers");
+ ALOGV("-swapBuffers");
}
}
};
@@ -1610,9 +1610,9 @@ TEST_F(SurfaceTextureGLThreadToGLTest,
for (int i = 0; i < NUM_ITERATIONS-3; i++) {
mFC->waitForFrame();
mFC->finishFrame();
- LOGV("+updateTexImage");
+ ALOGV("+updateTexImage");
mST->updateTexImage();
- LOGV("-updateTexImage");
+ ALOGV("-updateTexImage");
}
}
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 693b7b82480d..ea527504b160 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -22,6 +22,8 @@
#include <surfaceflinger/SurfaceComposerClient.h>
#include <utils/String8.h>
+#include <private/gui/ComposerService.h>
+
namespace android {
class SurfaceTest : public ::testing::Test {
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 4d226461a02a..718c1312a874 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -941,7 +941,11 @@ void OpenGLRenderer::skew(float sx, float sy) {
}
void OpenGLRenderer::setMatrix(SkMatrix* matrix) {
- mSnapshot->transform->load(*matrix);
+ if (matrix) {
+ mSnapshot->transform->load(*matrix);
+ } else {
+ mSnapshot->transform->loadIdentity();
+ }
}
void OpenGLRenderer::getMatrix(SkMatrix* matrix) {
@@ -2095,6 +2099,9 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count,
}
FontRenderer& fontRenderer = mCaches.fontRenderer.getFontRenderer(paint);
+#if DEBUG_GLYPHS
+ LOGD("OpenGLRenderer drawText() with FontID=%d", SkTypeface::UniqueID(paint->getTypeface()));
+#endif
fontRenderer.setFont(paint, SkTypeface::UniqueID(paint->getTypeface()),
paint->getTextSize());
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 367c6275c711..e893f7a95adb 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -34,8 +34,8 @@ PathCache::PathCache(): ShapeCache<PathCacheEntry>("path",
void PathCache::remove(SkPath* path) {
// TODO: Linear search...
- Vector<uint32_t> pathsToRemove;
- for (uint32_t i = 0; i < mCache.size(); i++) {
+ Vector<size_t> pathsToRemove;
+ for (size_t i = 0; i < mCache.size(); i++) {
if (mCache.getKeyAt(i).path == path) {
pathsToRemove.push(i);
removeTexture(mCache.getValueAt(i));
diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp
index 2ebfe0a1f8ad..e79cd0f3cc3a 100644
--- a/libs/rs/driver/rsdAllocation.cpp
+++ b/libs/rs/driver/rsdAllocation.cpp
@@ -256,7 +256,7 @@ void rsdAllocationDestroy(const Context *rsc, Allocation *alloc) {
if (drv->bufferID) {
// Causes a SW crash....
- //LOGV(" mBufferID %i", mBufferID);
+ //ALOGV(" mBufferID %i", mBufferID);
//glDeleteBuffers(1, &mBufferID);
//mBufferID = 0;
}
diff --git a/libs/rs/driver/rsdBcc.cpp b/libs/rs/driver/rsdBcc.cpp
index 4ecf8e84a4df..917b419fd16b 100644
--- a/libs/rs/driver/rsdBcc.cpp
+++ b/libs/rs/driver/rsdBcc.cpp
@@ -72,7 +72,7 @@ bool rsdScriptInit(const Context *rsc,
//LOGE("rsdScriptCreate %p %p %p %p %i %i %p", rsc, resName, cacheDir, bitcode, bitcodeSize, flags, lookupFunc);
pthread_mutex_lock(&rsdgInitMutex);
- char *cachePath = NULL;
+
size_t exportFuncCount = 0;
size_t exportVarCount = 0;
size_t objectSlotCount = 0;
@@ -122,8 +122,6 @@ bool rsdScriptInit(const Context *rsc,
goto error;
}
- free(cachePath);
-
drv->mRoot = reinterpret_cast<int (*)()>(bccGetFuncAddr(drv->mBccScript, "root"));
drv->mInit = reinterpret_cast<void (*)()>(bccGetFuncAddr(drv->mBccScript, "init"));
drv->mFreeChildren = reinterpret_cast<void (*)()>(bccGetFuncAddr(drv->mBccScript, ".rs.dtor"));
@@ -450,7 +448,7 @@ void rsdScriptSetGlobalVar(const Context *dc, const Script *script,
int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
if (!destPtr) {
- //LOGV("Calling setVar on slot = %i which is null", slot);
+ //ALOGV("Calling setVar on slot = %i which is null", slot);
return;
}
@@ -464,7 +462,7 @@ void rsdScriptSetGlobalBind(const Context *dc, const Script *script, uint32_t sl
int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
if (!destPtr) {
- //LOGV("Calling setVar on slot = %i which is null", slot);
+ //ALOGV("Calling setVar on slot = %i which is null", slot);
return;
}
@@ -478,7 +476,7 @@ void rsdScriptSetGlobalObj(const Context *dc, const Script *script, uint32_t slo
int32_t *destPtr = ((int32_t **)drv->mFieldAddress)[slot];
if (!destPtr) {
- //LOGV("Calling setVar on slot = %i which is null", slot);
+ //ALOGV("Calling setVar on slot = %i which is null", slot);
return;
}
diff --git a/libs/rs/driver/rsdCore.cpp b/libs/rs/driver/rsdCore.cpp
index 247f4dc163af..9292fa15a05a 100644
--- a/libs/rs/driver/rsdCore.cpp
+++ b/libs/rs/driver/rsdCore.cpp
@@ -139,7 +139,7 @@ static void * HelperThreadProc(void *vrsc) {
uint32_t idx = (uint32_t)android_atomic_inc(&dc->mWorkers.mLaunchCount);
- //LOGV("RS helperThread starting %p idx=%i", rsc, idx);
+ //ALOGV("RS helperThread starting %p idx=%i", rsc, idx);
dc->mWorkers.mLaunchSignals[idx].init();
dc->mWorkers.mNativeThreadId[idx] = gettid();
@@ -168,7 +168,7 @@ static void * HelperThreadProc(void *vrsc) {
dc->mWorkers.mCompleteSignal.set();
}
- //LOGV("RS helperThread exited %p idx=%i", rsc, idx);
+ //ALOGV("RS helperThread exited %p idx=%i", rsc, idx);
return NULL;
}
@@ -219,7 +219,7 @@ bool rsdHalInit(Context *rsc, uint32_t version_major, uint32_t version_minor) {
int cpu = sysconf(_SC_NPROCESSORS_ONLN);
- LOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
+ ALOGV("%p Launching thread(s), CPUs %i", rsc, cpu);
if (cpu < 2) cpu = 0;
dc->mWorkers.mCount = (uint32_t)cpu;
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index 98d9486a36bd..d4deefb1e475 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -101,7 +101,7 @@ static void printEGLConfiguration(EGLDisplay dpy, EGLConfig config) {
EGLint value = -1;
EGLBoolean returnVal = eglGetConfigAttrib(dpy, config, names[j].attribute, &value);
if (returnVal) {
- LOGV(" %s: %d (0x%x)", names[j].name, value, value);
+ ALOGV(" %s: %d (0x%x)", names[j].name, value, value);
}
}
}
@@ -116,12 +116,12 @@ static void DumpDebug(RsdHal *dc) {
LOGE(" GL Extensions: %s", dc->gl.gl.extensions);
LOGE(" GL int Versions %i %i", dc->gl.gl.majorVersion, dc->gl.gl.minorVersion);
- LOGV("MAX Textures %i, %i %i", dc->gl.gl.maxVertexTextureUnits,
+ ALOGV("MAX Textures %i, %i %i", dc->gl.gl.maxVertexTextureUnits,
dc->gl.gl.maxFragmentTextureImageUnits, dc->gl.gl.maxTextureImageUnits);
- LOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
- LOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
+ ALOGV("MAX Attribs %i", dc->gl.gl.maxVertexAttribs);
+ ALOGV("MAX Uniforms %i, %i", dc->gl.gl.maxVertexUniformVectors,
dc->gl.gl.maxFragmentUniformVectors);
- LOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
+ ALOGV("MAX Varyings %i", dc->gl.gl.maxVaryingVectors);
}
void rsdGLShutdown(const Context *rsc) {
@@ -199,7 +199,7 @@ bool rsdGLInit(const Context *rsc) {
configAttribsPtr[0] = EGL_NONE;
rsAssert(configAttribsPtr < (configAttribs + (sizeof(configAttribs) / sizeof(EGLint))));
- LOGV("%p initEGL start", rsc);
+ ALOGV("%p initEGL start", rsc);
rsc->setWatchdogGL("eglGetDisplay", __LINE__, __FILE__);
dc->gl.egl.display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
checkEglError("eglGetDisplay");
@@ -303,11 +303,11 @@ bool rsdGLInit(const Context *rsc) {
dc->gl.gl.renderer = glGetString(GL_RENDERER);
dc->gl.gl.extensions = glGetString(GL_EXTENSIONS);
- //LOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
- //LOGV("GL Version %s", mGL.mVersion);
- //LOGV("GL Vendor %s", mGL.mVendor);
- //LOGV("GL Renderer %s", mGL.mRenderer);
- //LOGV("GL Extensions %s", mGL.mExtensions);
+ //ALOGV("EGL Version %i %i", mEGL.mMajorVersion, mEGL.mMinorVersion);
+ //ALOGV("GL Version %s", mGL.mVersion);
+ //ALOGV("GL Vendor %s", mGL.mVendor);
+ //ALOGV("GL Renderer %s", mGL.mRenderer);
+ //ALOGV("GL Extensions %s", mGL.mExtensions);
const char *verptr = NULL;
if (strlen((const char *)dc->gl.gl.version) > 9) {
@@ -360,7 +360,7 @@ bool rsdGLInit(const Context *rsc) {
dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
dc->gl.currentFrameBuffer = NULL;
- LOGV("%p initGLThread end", rsc);
+ ALOGV("%p initGLThread end", rsc);
rsc->setWatchdogGL(NULL, 0, NULL);
return true;
}
diff --git a/libs/rs/driver/rsdProgram.cpp b/libs/rs/driver/rsdProgram.cpp
index 7556e50a37ec..54484dfced3a 100644
--- a/libs/rs/driver/rsdProgram.cpp
+++ b/libs/rs/driver/rsdProgram.cpp
@@ -68,7 +68,7 @@ void rsdProgramVertexDestroy(const Context *rsc, const ProgramVertex *pv) {
if(pv->mHal.drv) {
drv = (RsdShader*)pv->mHal.drv;
if (rsc->props.mLogShaders) {
- LOGV("Destroying vertex shader with ID %u", drv->getShaderID());
+ ALOGV("Destroying vertex shader with ID %u", drv->getShaderID());
}
if (drv->getShaderID()) {
dc->gl.shaderCache->cleanupVertex(drv->getShaderID());
@@ -99,7 +99,7 @@ void rsdProgramFragmentDestroy(const Context *rsc, const ProgramFragment *pf) {
if(pf->mHal.drv) {
drv = (RsdShader*)pf->mHal.drv;
if (rsc->props.mLogShaders) {
- LOGV("Destroying fragment shader with ID %u", drv->getShaderID());
+ ALOGV("Destroying fragment shader with ID %u", drv->getShaderID());
}
if (drv->getShaderID()) {
dc->gl.shaderCache->cleanupFragment(drv->getShaderID());
diff --git a/libs/rs/driver/rsdShader.cpp b/libs/rs/driver/rsdShader.cpp
index bdb60c24f917..e9ce7c208cd0 100644
--- a/libs/rs/driver/rsdShader.cpp
+++ b/libs/rs/driver/rsdShader.cpp
@@ -172,8 +172,8 @@ bool RsdShader::loadShader(const Context *rsc) {
rsAssert(mShaderID);
if (rsc->props.mLogShaders) {
- LOGV("Loading shader type %x, ID %i", mType, mShaderID);
- LOGV("%s", mShader.string());
+ ALOGV("Loading shader type %x, ID %i", mType, mShaderID);
+ ALOGV("%s", mShader.string());
}
if (mShaderID) {
@@ -202,7 +202,7 @@ bool RsdShader::loadShader(const Context *rsc) {
}
if (rsc->props.mLogShaders) {
- LOGV("--Shader load result %x ", glGetError());
+ ALOGV("--Shader load result %x ", glGetError());
}
mIsValid = true;
return true;
@@ -252,36 +252,36 @@ void RsdShader::logUniform(const Element *field, const float *fd, uint32_t array
uint32_t elementSize = field->getSizeBytes() / sizeof(float);
for (uint32_t i = 0; i < arraySize; i ++) {
if (arraySize > 1) {
- LOGV("Array Element [%u]", i);
+ ALOGV("Array Element [%u]", i);
}
if (dataType == RS_TYPE_MATRIX_4X4) {
- LOGV("Matrix4x4");
- LOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]);
- LOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]);
- LOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]);
- LOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
+ ALOGV("Matrix4x4");
+ ALOGV("{%f, %f, %f, %f", fd[0], fd[4], fd[8], fd[12]);
+ ALOGV(" %f, %f, %f, %f", fd[1], fd[5], fd[9], fd[13]);
+ ALOGV(" %f, %f, %f, %f", fd[2], fd[6], fd[10], fd[14]);
+ ALOGV(" %f, %f, %f, %f}", fd[3], fd[7], fd[11], fd[15]);
} else if (dataType == RS_TYPE_MATRIX_3X3) {
- LOGV("Matrix3x3");
- LOGV("{%f, %f, %f", fd[0], fd[3], fd[6]);
- LOGV(" %f, %f, %f", fd[1], fd[4], fd[7]);
- LOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
+ ALOGV("Matrix3x3");
+ ALOGV("{%f, %f, %f", fd[0], fd[3], fd[6]);
+ ALOGV(" %f, %f, %f", fd[1], fd[4], fd[7]);
+ ALOGV(" %f, %f, %f}", fd[2], fd[5], fd[8]);
} else if (dataType == RS_TYPE_MATRIX_2X2) {
- LOGV("Matrix2x2");
- LOGV("{%f, %f", fd[0], fd[2]);
- LOGV(" %f, %f}", fd[1], fd[3]);
+ ALOGV("Matrix2x2");
+ ALOGV("{%f, %f", fd[0], fd[2]);
+ ALOGV(" %f, %f}", fd[1], fd[3]);
} else {
switch (field->getComponent().getVectorSize()) {
case 1:
- LOGV("Uniform 1 = %f", fd[0]);
+ ALOGV("Uniform 1 = %f", fd[0]);
break;
case 2:
- LOGV("Uniform 2 = %f %f", fd[0], fd[1]);
+ ALOGV("Uniform 2 = %f %f", fd[0], fd[1]);
break;
case 3:
- LOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
+ ALOGV("Uniform 3 = %f %f %f", fd[0], fd[1], fd[2]);
break;
case 4:
- LOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
+ ALOGV("Uniform 4 = %f %f %f %f", fd[0], fd[1], fd[2], fd[3]);
break;
default:
rsAssert(0);
@@ -479,7 +479,7 @@ void RsdShader::setupUserConstants(const Context *rsc, RsdShaderCache *sc, bool
arraySize = sc->fragUniformSize(uidx);
}
if (rsc->props.mLogShadersUniforms) {
- LOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s",
+ ALOGV("Uniform slot=%i, offset=%i, constant=%i, field=%i, uidx=%i, name=%s",
slot, offset, ct, field, uidx, fieldName);
}
uidx ++;
diff --git a/libs/rs/driver/rsdShaderCache.cpp b/libs/rs/driver/rsdShaderCache.cpp
index d11490cef58a..2871a12231a5 100644
--- a/libs/rs/driver/rsdShaderCache.cpp
+++ b/libs/rs/driver/rsdShaderCache.cpp
@@ -54,7 +54,7 @@ void RsdShaderCache::updateUniformArrayData(const Context *rsc, RsdShader *prog,
}
if (rsc->props.mLogShaders) {
- LOGV("%s U, %s = %d, arraySize = %d\n", logTag,
+ ALOGV("%s U, %s = %d, arraySize = %d\n", logTag,
prog->getUniformName(ct).string(), data[ct].slot, data[ct].arraySize);
}
}
@@ -119,22 +119,22 @@ bool RsdShaderCache::link(const Context *rsc) {
if (!vtx->getShaderID() || !frag->getShaderID()) {
return false;
}
- //LOGV("rsdShaderCache lookup vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
+ //ALOGV("rsdShaderCache lookup vtx %i, frag %i", vtx->getShaderID(), frag->getShaderID());
uint32_t entryCount = mEntries.size();
for (uint32_t ct = 0; ct < entryCount; ct ++) {
if ((mEntries[ct]->vtx == vtx->getShaderID()) &&
(mEntries[ct]->frag == frag->getShaderID())) {
- //LOGV("SC using program %i", mEntries[ct]->program);
+ //ALOGV("SC using program %i", mEntries[ct]->program);
glUseProgram(mEntries[ct]->program);
mCurrent = mEntries[ct];
- //LOGV("RsdShaderCache hit, using %i", ct);
+ //ALOGV("RsdShaderCache hit, using %i", ct);
rsdGLCheckError(rsc, "RsdShaderCache::link (hit)");
return true;
}
}
- //LOGV("RsdShaderCache miss");
+ //ALOGV("RsdShaderCache miss");
//LOGE("e0 %x", glGetError());
ProgramEntry *e = new ProgramEntry(vtx->getAttribCount(),
vtx->getUniformCount(),
@@ -180,7 +180,7 @@ bool RsdShaderCache::link(const Context *rsc) {
e->vtxAttrs[ct].slot = glGetAttribLocation(pgm, vtx->getAttribName(ct));
e->vtxAttrs[ct].name = vtx->getAttribName(ct).string();
if (rsc->props.mLogShaders) {
- LOGV("vtx A %i, %s = %d\n", ct, vtx->getAttribName(ct).string(), e->vtxAttrs[ct].slot);
+ ALOGV("vtx A %i, %s = %d\n", ct, vtx->getAttribName(ct).string(), e->vtxAttrs[ct].slot);
}
}
@@ -229,7 +229,7 @@ bool RsdShaderCache::link(const Context *rsc) {
}
}
- //LOGV("SC made program %i", e->program);
+ //ALOGV("SC made program %i", e->program);
glUseProgram(e->program);
rsdGLCheckError(rsc, "RsdShaderCache::link (miss)");
diff --git a/libs/rs/driver/rsdVertexArray.cpp b/libs/rs/driver/rsdVertexArray.cpp
index 62ec107aec3a..1836e675fb7b 100644
--- a/libs/rs/driver/rsdVertexArray.cpp
+++ b/libs/rs/driver/rsdVertexArray.cpp
@@ -65,9 +65,9 @@ void RsdVertexArray::Attrib::set(uint32_t type, uint32_t size, uint32_t stride,
void RsdVertexArray::logAttrib(uint32_t idx, uint32_t slot) const {
if (idx == 0) {
- LOGV("Starting vertex attribute binding");
+ ALOGV("Starting vertex attribute binding");
}
- LOGV("va %i: slot=%i name=%s buf=%i ptr=%p size=%i type=0x%x stride=0x%x norm=%i offset=0x%x",
+ ALOGV("va %i: slot=%i name=%s buf=%i ptr=%p size=%i type=0x%x stride=0x%x norm=%i offset=0x%x",
idx, slot,
mAttribs[idx].name.string(),
mAttribs[idx].buffer,
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index e73263009fc6..c1192fefff7a 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -191,10 +191,85 @@ void Allocation::dumpLOGV(const char *prefix) const {
mHal.state.type->dumpLOGV(s.string());
}
- LOGV("%s allocation ptr=%p mUsageFlags=0x04%x, mMipmapControl=0x%04x",
+ ALOGV("%s allocation ptr=%p mUsageFlags=0x04%x, mMipmapControl=0x%04x",
prefix, getPtr(), mHal.state.usageFlags, mHal.state.mipmapControl);
}
+uint32_t Allocation::getPackedSize() const {
+ uint32_t numItems = mHal.state.type->getSizeBytes() / mHal.state.type->getElementSizeBytes();
+ return numItems * mHal.state.type->getElement()->getSizeBytesUnpadded();
+}
+
+void Allocation::writePackedData(const Type *type,
+ uint8_t *dst, const uint8_t *src, bool dstPadded) {
+ const Element *elem = type->getElement();
+ uint32_t unpaddedBytes = elem->getSizeBytesUnpadded();
+ uint32_t paddedBytes = elem->getSizeBytes();
+ uint32_t numItems = type->getSizeBytes() / paddedBytes;
+
+ uint32_t srcInc = !dstPadded ? paddedBytes : unpaddedBytes;
+ uint32_t dstInc = dstPadded ? paddedBytes : unpaddedBytes;
+
+ // no sub-elements
+ uint32_t fieldCount = elem->getFieldCount();
+ if (fieldCount == 0) {
+ for (uint32_t i = 0; i < numItems; i ++) {
+ memcpy(dst, src, unpaddedBytes);
+ src += srcInc;
+ dst += dstInc;
+ }
+ return;
+ }
+
+ // Cache offsets
+ uint32_t *offsetsPadded = new uint32_t[fieldCount];
+ uint32_t *offsetsUnpadded = new uint32_t[fieldCount];
+ uint32_t *sizeUnpadded = new uint32_t[fieldCount];
+
+ for (uint32_t i = 0; i < fieldCount; i++) {
+ offsetsPadded[i] = elem->getFieldOffsetBytes(i);
+ offsetsUnpadded[i] = elem->getFieldOffsetBytesUnpadded(i);
+ sizeUnpadded[i] = elem->getField(i)->getSizeBytesUnpadded();
+ }
+
+ uint32_t *srcOffsets = !dstPadded ? offsetsPadded : offsetsUnpadded;
+ uint32_t *dstOffsets = dstPadded ? offsetsPadded : offsetsUnpadded;
+
+ // complex elements, need to copy subelem after subelem
+ for (uint32_t i = 0; i < numItems; i ++) {
+ for (uint32_t fI = 0; fI < fieldCount; fI++) {
+ memcpy(dst + dstOffsets[fI], src + srcOffsets[fI], sizeUnpadded[fI]);
+ }
+ src += srcInc;
+ dst += dstInc;
+ }
+
+ delete[] offsetsPadded;
+ delete[] offsetsUnpadded;
+ delete[] sizeUnpadded;
+}
+
+void Allocation::unpackVec3Allocation(const void *data, uint32_t dataSize) {
+ const uint8_t *src = (const uint8_t*)data;
+ uint8_t *dst = (uint8_t*)getPtr();
+
+ writePackedData(getType(), dst, src, true);
+}
+
+void Allocation::packVec3Allocation(OStream *stream) const {
+ uint32_t paddedBytes = getType()->getElement()->getSizeBytes();
+ uint32_t unpaddedBytes = getType()->getElement()->getSizeBytesUnpadded();
+ uint32_t numItems = mHal.state.type->getSizeBytes() / paddedBytes;
+
+ const uint8_t *src = (const uint8_t*)getPtr();
+ uint8_t *dst = new uint8_t[numItems * unpaddedBytes];
+
+ writePackedData(getType(), dst, src, false);
+ stream->addByteArray(dst, getPackedSize());
+
+ delete[] dst;
+}
+
void Allocation::serialize(OStream *stream) const {
// Need to identify ourselves
stream->addU32((uint32_t)getClassId());
@@ -207,10 +282,17 @@ void Allocation::serialize(OStream *stream) const {
mHal.state.type->serialize(stream);
uint32_t dataSize = mHal.state.type->getSizeBytes();
+ // 3 element vectors are padded to 4 in memory, but padding isn't serialized
+ uint32_t packedSize = getPackedSize();
// Write how much data we are storing
- stream->addU32(dataSize);
- // Now write the data
- stream->addByteArray(getPtr(), dataSize);
+ stream->addU32(packedSize);
+ if (dataSize == packedSize) {
+ // Now write the data
+ stream->addByteArray(getPtr(), dataSize);
+ } else {
+ // Now write the data
+ packVec3Allocation(stream);
+ }
}
Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
@@ -230,22 +312,30 @@ Allocation *Allocation::createFromStream(Context *rsc, IStream *stream) {
}
type->compute();
+ Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
+ type->decUserRef();
+
// Number of bytes we wrote out for this allocation
uint32_t dataSize = stream->loadU32();
- if (dataSize != type->getSizeBytes()) {
+ // 3 element vectors are padded to 4 in memory, but padding isn't serialized
+ uint32_t packedSize = alloc->getPackedSize();
+ if (dataSize != type->getSizeBytes() &&
+ dataSize != packedSize) {
LOGE("failed to read allocation because numbytes written is not the same loaded type wants\n");
+ ObjectBase::checkDelete(alloc);
ObjectBase::checkDelete(type);
return NULL;
}
- Allocation *alloc = Allocation::createAllocation(rsc, type, RS_ALLOCATION_USAGE_SCRIPT);
alloc->setName(name.string(), name.size());
- type->decUserRef();
- uint32_t count = dataSize / type->getElementSizeBytes();
-
- // Read in all of our allocation data
- alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
+ if (dataSize == type->getSizeBytes()) {
+ uint32_t count = dataSize / type->getElementSizeBytes();
+ // Read in all of our allocation data
+ alloc->data(rsc, 0, 0, count, stream->getPtr() + stream->getPos(), dataSize);
+ } else {
+ alloc->unpackVec3Allocation(stream->getPtr() + stream->getPos(), dataSize);
+ }
stream->reset(stream->getPos() + dataSize);
return alloc;
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index 714798aa1e0c..4ce863ab927f 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -135,6 +135,11 @@ protected:
private:
void freeChildrenUnlocked();
Allocation(Context *rsc, const Type *, uint32_t usages, RsAllocationMipmapControl mc);
+
+ uint32_t getPackedSize() const;
+ static void writePackedData(const Type *type, uint8_t *dst, const uint8_t *src, bool dstPadded);
+ void unpackVec3Allocation(const void *data, uint32_t dataSize);
+ void packVec3Allocation(OStream *stream) const;
};
}
diff --git a/libs/rs/rsComponent.cpp b/libs/rs/rsComponent.cpp
index ce06306a1ef0..21b98f6193a2 100644
--- a/libs/rs/rsComponent.cpp
+++ b/libs/rs/rsComponent.cpp
@@ -169,7 +169,8 @@ void Component::set(RsDataType dt, RsDataKind dk, bool norm, uint32_t vecSize) {
break;
}
- mBits = mTypeBits * mVectorSize;
+ mBitsUnpadded = mTypeBits * mVectorSize;
+ mBits = mTypeBits * rsHigherPow2(mVectorSize);
}
bool Component::isReference() const {
@@ -228,10 +229,10 @@ static const char * gKindStrings[] = {
void Component::dumpLOGV(const char *prefix) const {
if (mType >= RS_TYPE_ELEMENT) {
- LOGV("%s Component: %s, %s, vectorSize=%i, bits=%i",
+ ALOGV("%s Component: %s, %s, vectorSize=%i, bits=%i",
prefix, gTypeObjStrings[mType - RS_TYPE_ELEMENT], gKindStrings[mKind], mVectorSize, mBits);
} else {
- LOGV("%s Component: %s, %s, vectorSize=%i, bits=%i",
+ ALOGV("%s Component: %s, %s, vectorSize=%i, bits=%i",
prefix, gTypeBasicStrings[mType], gKindStrings[mKind], mVectorSize, mBits);
}
}
diff --git a/libs/rs/rsComponent.h b/libs/rs/rsComponent.h
index 6ddc990b2486..8629d0d9d6b9 100644
--- a/libs/rs/rsComponent.h
+++ b/libs/rs/rsComponent.h
@@ -41,6 +41,7 @@ public:
bool getIsFloat() const {return mIsFloat;}
bool getIsSigned() const {return mIsSigned;}
uint32_t getBits() const {return mBits;}
+ uint32_t getBitsUnpadded() const {return mBitsUnpadded;}
// Helpers for reading / writing this class out
void serialize(OStream *stream) const;
@@ -56,6 +57,7 @@ protected:
// derived
uint32_t mBits;
+ uint32_t mBitsUnpadded;
uint32_t mTypeBits;
bool mIsFloat;
bool mIsSigned;
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 5291a1f73f2e..293fc3ad953b 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -152,7 +152,7 @@ void Context::timerPrint() {
if (props.mLogTimes) {
- LOGV("RS: Frame (%i), Script %2.1f%% (%i), Swap %2.1f%% (%i), Idle %2.1f%% (%lli), Internal %2.1f%% (%lli), Avg fps: %u",
+ ALOGV("RS: Frame (%i), Script %2.1f%% (%i), Swap %2.1f%% (%i), Idle %2.1f%% (%lli), Internal %2.1f%% (%lli), Avg fps: %u",
mTimeMSLastFrame,
100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimeMSLastScript,
100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimeMSLastSwap,
@@ -284,7 +284,7 @@ void * Context::threadProc(void *vrsc) {
}
}
- LOGV("%p RS Thread exiting", rsc);
+ ALOGV("%p RS Thread exiting", rsc);
if (rsc->mIsGraphicsContext) {
pthread_mutex_lock(&gInitMutex);
@@ -292,12 +292,12 @@ void * Context::threadProc(void *vrsc) {
pthread_mutex_unlock(&gInitMutex);
}
- LOGV("%p RS Thread exited", rsc);
+ ALOGV("%p RS Thread exited", rsc);
return NULL;
}
void Context::destroyWorkerThreadResources() {
- //LOGV("destroyWorkerThreadResources 1");
+ //ALOGV("destroyWorkerThreadResources 1");
ObjectBase::zeroAllUserRef(this);
if (mIsGraphicsContext) {
mRaster.clear();
@@ -315,7 +315,7 @@ void Context::destroyWorkerThreadResources() {
mFBOCache.deinit(this);
}
ObjectBase::freeAllChildren(this);
- //LOGV("destroyWorkerThreadResources 2");
+ //ALOGV("destroyWorkerThreadResources 2");
mExit = true;
}
@@ -431,7 +431,7 @@ bool Context::initContext(Device *dev, const RsSurfaceConfig *sc) {
}
Context::~Context() {
- LOGV("%p Context::~Context", this);
+ ALOGV("%p Context::~Context", this);
if (!mIsContextLite) {
mIO.coreFlush();
@@ -455,7 +455,7 @@ Context::~Context() {
}
pthread_mutex_unlock(&gInitMutex);
}
- LOGV("%p Context::~Context done", this);
+ ALOGV("%p Context::~Context done", this);
}
void Context::setSurface(uint32_t w, uint32_t h, RsNativeWindow sur) {
@@ -472,6 +472,30 @@ void Context::setSurface(uint32_t w, uint32_t h, RsNativeWindow sur) {
}
}
+uint32_t Context::getCurrentSurfaceWidth() const {
+ for (uint32_t i = 0; i < mFBOCache.mHal.state.colorTargetsCount; i ++) {
+ if (mFBOCache.mHal.state.colorTargets[i] != NULL) {
+ return mFBOCache.mHal.state.colorTargets[i]->getType()->getDimX();
+ }
+ }
+ if (mFBOCache.mHal.state.depthTarget != NULL) {
+ return mFBOCache.mHal.state.depthTarget->getType()->getDimX();
+ }
+ return mWidth;
+}
+
+uint32_t Context::getCurrentSurfaceHeight() const {
+ for (uint32_t i = 0; i < mFBOCache.mHal.state.colorTargetsCount; i ++) {
+ if (mFBOCache.mHal.state.colorTargets[i] != NULL) {
+ return mFBOCache.mHal.state.colorTargets[i]->getType()->getDimY();
+ }
+ }
+ if (mFBOCache.mHal.state.depthTarget != NULL) {
+ return mFBOCache.mHal.state.depthTarget->getType()->getDimY();
+ }
+ return mHeight;
+}
+
void Context::pause() {
rsAssert(mIsGraphicsContext);
mPaused = true;
@@ -672,10 +696,10 @@ void rsi_ContextDestroyWorker(Context *rsc) {
}
void rsi_ContextDestroy(Context *rsc) {
- LOGV("%p rsContextDestroy", rsc);
+ ALOGV("%p rsContextDestroy", rsc);
rsContextDestroyWorker(rsc);
delete rsc;
- LOGV("%p rsContextDestroy done", rsc);
+ ALOGV("%p rsContextDestroy done", rsc);
}
@@ -706,7 +730,7 @@ void rsi_ContextDeinitToClient(Context *rsc) {
RsContext rsContextCreate(RsDevice vdev, uint32_t version,
uint32_t sdkVersion) {
- LOGV("rsContextCreate dev=%p", vdev);
+ ALOGV("rsContextCreate dev=%p", vdev);
Device * dev = static_cast<Device *>(vdev);
Context *rsc = Context::createContext(dev, NULL);
if (rsc) {
@@ -718,14 +742,14 @@ RsContext rsContextCreate(RsDevice vdev, uint32_t version,
RsContext rsContextCreateGL(RsDevice vdev, uint32_t version,
uint32_t sdkVersion, RsSurfaceConfig sc,
uint32_t dpi) {
- LOGV("rsContextCreateGL dev=%p", vdev);
+ ALOGV("rsContextCreateGL dev=%p", vdev);
Device * dev = static_cast<Device *>(vdev);
Context *rsc = Context::createContext(dev, &sc);
if (rsc) {
rsc->setTargetSdkVersion(sdkVersion);
rsc->setDPI(dpi);
}
- LOGV("%p rsContextCreateGL ret", rsc);
+ ALOGV("%p rsContextCreateGL ret", rsc);
return rsc;
}
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 199cc5a36051..c6582c9dffbc 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -164,6 +164,9 @@ public:
uint32_t getWidth() const {return mWidth;}
uint32_t getHeight() const {return mHeight;}
+ uint32_t getCurrentSurfaceWidth() const;
+ uint32_t getCurrentSurfaceHeight() const;
+
mutable ThreadIO mIO;
// Timers
diff --git a/libs/rs/rsElement.cpp b/libs/rs/rsElement.cpp
index 71e1b91c6371..56c31b66405d 100644
--- a/libs/rs/rsElement.cpp
+++ b/libs/rs/rsElement.cpp
@@ -23,6 +23,7 @@ using namespace android::renderscript;
Element::Element(Context *rsc) : ObjectBase(rsc) {
mBits = 0;
+ mBitsUnpadded = 0;
mFields = NULL;
mFieldCount = 0;
mHasReference = false;
@@ -60,13 +61,25 @@ size_t Element::getSizeBits() const {
return total;
}
+size_t Element::getSizeBitsUnpadded() const {
+ if (!mFieldCount) {
+ return mBitsUnpadded;
+ }
+
+ size_t total = 0;
+ for (size_t ct=0; ct < mFieldCount; ct++) {
+ total += mFields[ct].e->mBitsUnpadded * mFields[ct].arraySize;
+ }
+ return total;
+}
+
void Element::dumpLOGV(const char *prefix) const {
ObjectBase::dumpLOGV(prefix);
- LOGV("%s Element: fieldCount: %zu, size bytes: %zu", prefix, mFieldCount, getSizeBytes());
+ ALOGV("%s Element: fieldCount: %zu, size bytes: %zu", prefix, mFieldCount, getSizeBytes());
mComponent.dumpLOGV(prefix);
for (uint32_t ct = 0; ct < mFieldCount; ct++) {
- LOGV("%s Element field index: %u ------------------", prefix, ct);
- LOGV("%s name: %s, offsetBits: %u, arraySize: %u",
+ ALOGV("%s Element field index: %u ------------------", prefix, ct);
+ ALOGV("%s name: %s, offsetBits: %u, arraySize: %u",
prefix, mFields[ct].name.string(), mFields[ct].offsetBits, mFields[ct].arraySize);
mFields[ct].e->dumpLOGV(prefix);
}
@@ -146,14 +159,18 @@ Element *Element::createFromStream(Context *rsc, IStream *stream) {
void Element::compute() {
if (mFieldCount == 0) {
mBits = mComponent.getBits();
+ mBitsUnpadded = mComponent.getBitsUnpadded();
mHasReference = mComponent.isReference();
return;
}
size_t bits = 0;
+ size_t bitsUnpadded = 0;
for (size_t ct=0; ct < mFieldCount; ct++) {
mFields[ct].offsetBits = bits;
+ mFields[ct].offsetBitsUnpadded = bitsUnpadded;
bits += mFields[ct].e->getSizeBits() * mFields[ct].arraySize;
+ bitsUnpadded += mFields[ct].e->getSizeBitsUnpadded() * mFields[ct].arraySize;
if (mFields[ct].e->mHasReference) {
mHasReference = true;
diff --git a/libs/rs/rsElement.h b/libs/rs/rsElement.h
index bfdec53b9982..04010faafac8 100644
--- a/libs/rs/rsElement.h
+++ b/libs/rs/rsElement.h
@@ -43,6 +43,11 @@ public:
uint32_t getGLType() const;
uint32_t getGLFormat() const;
+ size_t getSizeBitsUnpadded() const;
+ size_t getSizeBytesUnpadded() const {
+ return (getSizeBitsUnpadded() + 7) >> 3;
+ }
+
size_t getSizeBits() const;
size_t getSizeBytes() const {
return (getSizeBits() + 7) >> 3;
@@ -55,6 +60,10 @@ public:
return mFields[componentNumber].offsetBits >> 3;
}
+ size_t getFieldOffsetBytesUnpadded(uint32_t componentNumber) const {
+ return mFields[componentNumber].offsetBitsUnpadded >> 3;
+ }
+
uint32_t getFieldCount() const {return mFieldCount;}
const Element * getField(uint32_t idx) const {return mFields[idx].e.get();}
const char * getFieldName(uint32_t idx) const {return mFields[idx].name.string();}
@@ -64,6 +73,7 @@ public:
RsDataType getType() const {return mComponent.getType();}
RsDataKind getKind() const {return mComponent.getKind();}
uint32_t getBits() const {return mBits;}
+ uint32_t getBitsUnpadded() const {return mBitsUnpadded;}
void dumpLOGV(const char *prefix) const;
virtual void serialize(OStream *stream) const;
@@ -112,6 +122,7 @@ protected:
String8 name;
ObjectBaseRef<const Element> e;
uint32_t offsetBits;
+ uint32_t offsetBitsUnpadded;
uint32_t arraySize;
} ElementField_t;
ElementField_t *mFields;
@@ -123,6 +134,7 @@ protected:
Element(Context *);
Component mComponent;
+ uint32_t mBitsUnpadded;
uint32_t mBits;
void compute();
diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp
index df5dc128061b..530e79e2b0c8 100644
--- a/libs/rs/rsFileA3D.cpp
+++ b/libs/rs/rsFileA3D.cpp
@@ -68,7 +68,7 @@ void FileA3D::parseHeader(IStream *headerStream) {
for (uint32_t i = 0; i < numIndexEntries; i ++) {
A3DIndexEntry *entry = new A3DIndexEntry();
headerStream->loadString(&entry->mObjectName);
- //LOGV("Header data, entry name = %s", entry->mObjectName.string());
+ //ALOGV("Header data, entry name = %s", entry->mObjectName.string());
entry->mType = (RsA3DClassID)headerStream->loadU32();
if (mUse64BitOffsets){
entry->mOffset = headerStream->loadOffset();
@@ -145,7 +145,7 @@ bool FileA3D::load(FILE *f) {
char magicString[12];
size_t len;
- LOGV("file open 1");
+ ALOGV("file open 1");
len = fread(magicString, 1, 12, f);
if ((len != 12) ||
memcmp(magicString, "Android3D_ff", 12)) {
@@ -181,7 +181,7 @@ bool FileA3D::load(FILE *f) {
return false;
}
- LOGV("file open size = %lli", mDataSize);
+ ALOGV("file open size = %lli", mDataSize);
// We should know enough to read the file in at this point.
mAlloc = malloc(mDataSize);
@@ -196,7 +196,7 @@ bool FileA3D::load(FILE *f) {
mReadStream = new IStream(mData, mUse64BitOffsets);
- LOGV("Header is read an stream initialized");
+ ALOGV("Header is read an stream initialized");
return true;
}
@@ -369,7 +369,7 @@ RsObjectBase rsaFileA3DGetEntryByIndex(RsContext con, uint32_t index, RsFile fil
}
ObjectBase *obj = fa3d->initializeFromEntry(index);
- //LOGV("Returning object with name %s", obj->getName());
+ //ALOGV("Returning object with name %s", obj->getName());
return obj;
}
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 7efed9d9f948..7b3aa70a9f94 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -651,14 +651,10 @@ void FontState::appendMeshQuad(float x1, float y1, float z1,
float x4, float y4, float z4,
float u4, float v4) {
const uint32_t vertsPerQuad = 4;
- const uint32_t floatsPerVert = 5;
+ const uint32_t floatsPerVert = 6;
float *currentPos = mTextMeshPtr + mCurrentQuadIndex * vertsPerQuad * floatsPerVert;
- // Cull things that are off the screen
- float width = (float)mRSC->getWidth();
- float height = (float)mRSC->getHeight();
-
- if (x1 > width || y1 < 0.0f || x2 < 0 || y4 > height) {
+ if (x1 > mSurfaceWidth || y1 < 0.0f || x2 < 0 || y4 > mSurfaceHeight) {
return;
}
@@ -670,24 +666,28 @@ void FontState::appendMeshQuad(float x1, float y1, float z1,
(*currentPos++) = x1;
(*currentPos++) = y1;
(*currentPos++) = z1;
+ (*currentPos++) = 0;
(*currentPos++) = u1;
(*currentPos++) = v1;
(*currentPos++) = x2;
(*currentPos++) = y2;
(*currentPos++) = z2;
+ (*currentPos++) = 0;
(*currentPos++) = u2;
(*currentPos++) = v2;
(*currentPos++) = x3;
(*currentPos++) = y3;
(*currentPos++) = z3;
+ (*currentPos++) = 0;
(*currentPos++) = u3;
(*currentPos++) = v3;
(*currentPos++) = x4;
(*currentPos++) = y4;
(*currentPos++) = z4;
+ (*currentPos++) = 0;
(*currentPos++) = u4;
(*currentPos++) = v4;
@@ -746,6 +746,10 @@ void FontState::renderText(const char *text, uint32_t len, int32_t x, int32_t y,
return;
}
+ // Cull things that are off the screen
+ mSurfaceWidth = (float)mRSC->getCurrentSurfaceWidth();
+ mSurfaceHeight = (float)mRSC->getCurrentSurfaceHeight();
+
currentFont->renderUTF(text, len, x, y, startIndex, numGlyphs,
mode, bounds, bitmap, bitmapW, bitmapH);
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index 679591ca434f..4ca794dcee1c 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -160,6 +160,9 @@ public:
protected:
+ float mSurfaceWidth;
+ float mSurfaceHeight;
+
friend class Font;
struct CacheTextureLine {
diff --git a/libs/rs/rsLocklessFifo.cpp b/libs/rs/rsLocklessFifo.cpp
index 88798058d1a8..ce69a603f353 100644
--- a/libs/rs/rsLocklessFifo.cpp
+++ b/libs/rs/rsLocklessFifo.cpp
@@ -231,7 +231,7 @@ void LocklessCommandFifo::makeSpace(uint32_t bytes) {
}
void LocklessCommandFifo::dumpState(const char *s) const {
- LOGV("%s %p put %p, get %p, buf %p, end %p", s, this, mPut, mGet, mBuffer, mEnd);
+ ALOGV("%s %p put %p, get %p, buf %p, end %p", s, this, mPut, mGet, mBuffer, mEnd);
}
void LocklessCommandFifo::printDebugData() const {
@@ -244,7 +244,7 @@ void LocklessCommandFifo::printDebugData() const {
for (int ct=0; ct < 16; ct++) {
- LOGV("fifo %p = 0x%08x 0x%08x 0x%08x 0x%08x", pptr, pptr[0], pptr[1], pptr[2], pptr[3]);
+ ALOGV("fifo %p = 0x%08x 0x%08x 0x%08x 0x%08x", pptr, pptr[0], pptr[1], pptr[2], pptr[3]);
pptr += 4;
}
diff --git a/libs/rs/rsMatrix4x4.cpp b/libs/rs/rsMatrix4x4.cpp
index f34af471cc8c..c6f96d8d2fe0 100644
--- a/libs/rs/rsMatrix4x4.cpp
+++ b/libs/rs/rsMatrix4x4.cpp
@@ -307,8 +307,8 @@ void Matrix4x4::vectorMultiply(float *out, const float *in) const {
}
void Matrix4x4::logv(const char *s) const {
- LOGV("%s {%f, %f, %f, %f", s, m[0], m[4], m[8], m[12]);
- LOGV("%s %f, %f, %f, %f", s, m[1], m[5], m[9], m[13]);
- LOGV("%s %f, %f, %f, %f", s, m[2], m[6], m[10], m[14]);
- LOGV("%s %f, %f, %f, %f}", s, m[3], m[7], m[11], m[15]);
+ ALOGV("%s {%f, %f, %f, %f", s, m[0], m[4], m[8], m[12]);
+ ALOGV("%s %f, %f, %f, %f", s, m[1], m[5], m[9], m[13]);
+ ALOGV("%s %f, %f, %f, %f", s, m[2], m[6], m[10], m[14]);
+ ALOGV("%s %f, %f, %f, %f}", s, m[3], m[7], m[11], m[15]);
}
diff --git a/libs/rs/rsObjectBase.cpp b/libs/rs/rsObjectBase.cpp
index f5ced26e657c..addf932a8e67 100644
--- a/libs/rs/rsObjectBase.cpp
+++ b/libs/rs/rsObjectBase.cpp
@@ -35,11 +35,11 @@ ObjectBase::ObjectBase(Context *rsc) {
rsAssert(rsc);
add();
- //LOGV("ObjectBase %p con", this);
+ //ALOGV("ObjectBase %p con", this);
}
ObjectBase::~ObjectBase() {
- //LOGV("~ObjectBase %p ref %i,%i", this, mUserRefCount, mSysRefCount);
+ //ALOGV("~ObjectBase %p ref %i,%i", this, mUserRefCount, mSysRefCount);
#if RS_OBJECT_DEBUG
mStack.dump();
#endif
@@ -60,22 +60,22 @@ ObjectBase::~ObjectBase() {
void ObjectBase::dumpLOGV(const char *op) const {
if (mName.size()) {
- LOGV("%s RSobj %p, name %s, refs %i,%i links %p,%p,%p",
+ ALOGV("%s RSobj %p, name %s, refs %i,%i links %p,%p,%p",
op, this, mName.string(), mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
} else {
- LOGV("%s RSobj %p, no-name, refs %i,%i links %p,%p,%p",
+ ALOGV("%s RSobj %p, no-name, refs %i,%i links %p,%p,%p",
op, this, mUserRefCount, mSysRefCount, mNext, mPrev, mRSC);
}
}
void ObjectBase::incUserRef() const {
android_atomic_inc(&mUserRefCount);
- //LOGV("ObjectBase %p incU ref %i, %i", this, mUserRefCount, mSysRefCount);
+ //ALOGV("ObjectBase %p incU ref %i, %i", this, mUserRefCount, mSysRefCount);
}
void ObjectBase::incSysRef() const {
android_atomic_inc(&mSysRefCount);
- //LOGV("ObjectBase %p incS ref %i, %i", this, mUserRefCount, mSysRefCount);
+ //ALOGV("ObjectBase %p incS ref %i, %i", this, mUserRefCount, mSysRefCount);
}
void ObjectBase::preDestroy() const {
@@ -111,7 +111,7 @@ bool ObjectBase::checkDelete(const ObjectBase *ref) {
bool ObjectBase::decUserRef() const {
rsAssert(mUserRefCount > 0);
#if RS_OBJECT_DEBUG
- LOGV("ObjectBase %p decU ref %i, %i", this, mUserRefCount, mSysRefCount);
+ ALOGV("ObjectBase %p decU ref %i, %i", this, mUserRefCount, mSysRefCount);
if (mUserRefCount <= 0) {
mStack.dump();
}
@@ -126,7 +126,7 @@ bool ObjectBase::decUserRef() const {
}
bool ObjectBase::zeroUserRef() const {
- //LOGV("ObjectBase %p zeroU ref %i, %i", this, mUserRefCount, mSysRefCount);
+ //ALOGV("ObjectBase %p zeroU ref %i, %i", this, mUserRefCount, mSysRefCount);
android_atomic_acquire_store(0, &mUserRefCount);
if (android_atomic_acquire_load(&mSysRefCount) <= 0) {
return checkDelete(this);
@@ -135,7 +135,7 @@ bool ObjectBase::zeroUserRef() const {
}
bool ObjectBase::decSysRef() const {
- //LOGV("ObjectBase %p decS ref %i, %i", this, mUserRefCount, mSysRefCount);
+ //ALOGV("ObjectBase %p decS ref %i, %i", this, mUserRefCount, mSysRefCount);
rsAssert(mSysRefCount > 0);
if ((android_atomic_dec(&mSysRefCount) <= 1) &&
(android_atomic_acquire_load(&mUserRefCount) <= 0)) {
@@ -165,7 +165,7 @@ void ObjectBase::add() const {
rsAssert(!mNext);
rsAssert(!mPrev);
- //LOGV("calling add rsc %p", mRSC);
+ //ALOGV("calling add rsc %p", mRSC);
mNext = mRSC->mObjHead;
if (mRSC->mObjHead) {
mRSC->mObjHead->mPrev = this;
@@ -176,7 +176,7 @@ void ObjectBase::add() const {
}
void ObjectBase::remove() const {
- //LOGV("calling remove rsc %p", mRSC);
+ //ALOGV("calling remove rsc %p", mRSC);
if (!mRSC) {
rsAssert(!mPrev);
rsAssert(!mNext);
@@ -198,7 +198,7 @@ void ObjectBase::remove() const {
void ObjectBase::zeroAllUserRef(Context *rsc) {
if (rsc->props.mLogObjects) {
- LOGV("Forcing release of all outstanding user refs.");
+ ALOGV("Forcing release of all outstanding user refs.");
}
// This operation can be slow, only to be called during context cleanup.
@@ -216,14 +216,14 @@ void ObjectBase::zeroAllUserRef(Context *rsc) {
}
if (rsc->props.mLogObjects) {
- LOGV("Objects remaining.");
+ ALOGV("Objects remaining.");
dumpAll(rsc);
}
}
void ObjectBase::freeAllChildren(Context *rsc) {
if (rsc->props.mLogObjects) {
- LOGV("Forcing release of all child objects.");
+ ALOGV("Forcing release of all child objects.");
}
// This operation can be slow, only to be called during context cleanup.
@@ -238,7 +238,7 @@ void ObjectBase::freeAllChildren(Context *rsc) {
}
if (rsc->props.mLogObjects) {
- LOGV("Objects remaining.");
+ ALOGV("Objects remaining.");
dumpAll(rsc);
}
}
@@ -246,10 +246,10 @@ void ObjectBase::freeAllChildren(Context *rsc) {
void ObjectBase::dumpAll(Context *rsc) {
asyncLock();
- LOGV("Dumping all objects");
+ ALOGV("Dumping all objects");
const ObjectBase * o = rsc->mObjHead;
while (o) {
- LOGV(" Object %p", o);
+ ALOGV(" Object %p", o);
o->dumpLOGV(" ");
o = o->mNext;
}
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 4a1362254b0b..871caacd6f66 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -206,8 +206,11 @@ void ProgramVertexState::init(Context *rsc) {
void ProgramVertexState::updateSize(Context *rsc) {
float *f = static_cast<float *>(mDefaultAlloc->getPtr());
+ float surfaceWidth = (float)rsc->getCurrentSurfaceWidth();
+ float surfaceHeight = (float)rsc->getCurrentSurfaceHeight();
+
Matrix4x4 m;
- m.loadOrtho(0,rsc->getWidth(), rsc->getHeight(),0, -1,1);
+ m.loadOrtho(0, surfaceWidth, surfaceHeight, 0, -1, 1);
memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m.m, sizeof(m));
memcpy(&f[RS_PROGRAM_VERTEX_MVP_OFFSET], m.m, sizeof(m));
diff --git a/libs/rs/rsScript.cpp b/libs/rs/rsScript.cpp
index 93513fe3e6a5..7fc128e8d243 100644
--- a/libs/rs/rsScript.cpp
+++ b/libs/rs/rsScript.cpp
@@ -15,6 +15,7 @@
*/
#include "rsContext.h"
+#include <time.h>
using namespace android;
using namespace android::renderscript;
@@ -25,6 +26,7 @@ Script::Script(Context *rsc) : ObjectBase(rsc) {
mSlots = NULL;
mTypes = NULL;
+ mInitialized = false;
}
Script::~Script() {
@@ -89,8 +91,22 @@ void rsi_ScriptBindAllocation(Context * rsc, RsScript vs, RsAllocation va, uint3
}
void rsi_ScriptSetTimeZone(Context * rsc, RsScript vs, const char * timeZone, size_t length) {
- Script *s = static_cast<Script *>(vs);
- s->mEnviroment.mTimeZone = timeZone;
+ // We unfortunately need to make a new copy of the string, since it is
+ // not NULL-terminated. We then use setenv(), which properly handles
+ // freeing/duplicating the actual string for the environment.
+ char *tz = (char *) malloc(length + 1);
+ if (!tz) {
+ LOGE("Couldn't allocate memory for timezone buffer");
+ return;
+ }
+ strncpy(tz, timeZone, length);
+ tz[length] = '\0';
+ if (setenv("TZ", tz, 1) == 0) {
+ tzset();
+ } else {
+ LOGE("Error setting timezone");
+ }
+ free(tz);
}
void rsi_ScriptForEach(Context *rsc, RsScript vs, uint32_t slot,
diff --git a/libs/rs/rsScript.h b/libs/rs/rsScript.h
index d645421ad165..99dceafaba37 100644
--- a/libs/rs/rsScript.h
+++ b/libs/rs/rsScript.h
@@ -59,7 +59,6 @@ public:
struct Enviroment_t {
int64_t mStartTimeMillis;
int64_t mLastDtTime;
- const char* mTimeZone;
ObjectBaseRef<ProgramVertex> mVertex;
ObjectBaseRef<ProgramFragment> mFragment;
@@ -68,7 +67,6 @@ public:
};
Enviroment_t mEnviroment;
- void initSlots();
void setSlot(uint32_t slot, Allocation *a);
void setVar(uint32_t slot, const void *val, size_t len);
void setVarObj(uint32_t slot, ObjectBase *val);
@@ -86,6 +84,7 @@ public:
virtual void setupScript(Context *rsc) = 0;
virtual uint32_t run(Context *) = 0;
protected:
+ bool mInitialized;
ObjectBaseRef<Allocation> *mSlots;
ObjectBaseRef<const Type> *mTypes;
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 2e7f2134fbaa..ce3c643c32a3 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -21,6 +21,7 @@
#ifndef ANDROID_RS_SERIALIZE
#include <bcinfo/BitcodeTranslator.h>
+#include <bcinfo/BitcodeWrapper.h>
#endif
using namespace android;
@@ -44,8 +45,10 @@ ScriptC::~ScriptC() {
BT = NULL;
}
#endif
- mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this);
- mRSC->mHal.funcs.script.destroy(mRSC, this);
+ if (mInitialized) {
+ mRSC->mHal.funcs.script.invokeFreeChildren(mRSC, this);
+ mRSC->mHal.funcs.script.destroy(mRSC, this);
+ }
}
void ScriptC::setupScript(Context *rsc) {
@@ -111,13 +114,13 @@ uint32_t ScriptC::run(Context *rsc) {
uint32_t ret = 0;
if (rsc->props.mLogScripts) {
- LOGV("%p ScriptC::run invoking root, ptr %p", rsc, mHal.info.root);
+ ALOGV("%p ScriptC::run invoking root, ptr %p", rsc, mHal.info.root);
}
ret = rsc->mHal.funcs.script.invokeRoot(rsc, this);
if (rsc->props.mLogScripts) {
- LOGV("%p ScriptC::run invoking complete, ret=%i", rsc, ret);
+ ALOGV("%p ScriptC::run invoking complete, ret=%i", rsc, ret);
}
return ret;
@@ -146,7 +149,7 @@ void ScriptC::Invoke(Context *rsc, uint32_t slot, const void *data, size_t len)
setupScript(rsc);
if (rsc->props.mLogScripts) {
- LOGV("%p ScriptC::Invoke invoking slot %i, ptr %p", rsc, slot, this);
+ ALOGV("%p ScriptC::Invoke invoking slot %i, ptr %p", rsc, slot, this);
}
rsc->mHal.funcs.script.invokeFunction(rsc, this, slot, data, len);
}
@@ -196,7 +199,24 @@ bool ScriptC::runCompiler(Context *rsc,
//LOGE("runCompiler %p %p %p %p %p %i", rsc, this, resName, cacheDir, bitcode, bitcodeLen);
#ifndef ANDROID_RS_SERIALIZE
- uint32_t sdkVersion = rsc->getTargetSdkVersion();
+ uint32_t sdkVersion = 0;
+ bcinfo::BitcodeWrapper bcWrapper((const char *)bitcode, bitcodeLen);
+ if (!bcWrapper.unwrap()) {
+ LOGE("Bitcode is not in proper container format (raw or wrapper)");
+ return false;
+ }
+
+ rsAssert(bcWrapper.getHeaderVersion() == 0);
+ if (bcWrapper.getBCFileType() == bcinfo::BC_WRAPPER) {
+ sdkVersion = bcWrapper.getTargetAPI();
+ }
+
+ if (sdkVersion == 0) {
+ // This signals that we didn't have a wrapper containing information
+ // about the bitcode.
+ sdkVersion = rsc->getTargetSdkVersion();
+ }
+
if (BT) {
delete BT;
}
@@ -212,8 +232,11 @@ bool ScriptC::runCompiler(Context *rsc,
bitcodeLen = BT->getTranslatedBitcodeSize();
#endif
- rsc->mHal.funcs.script.init(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0);
+ if (!rsc->mHal.funcs.script.init(rsc, this, resName, cacheDir, bitcode, bitcodeLen, 0)) {
+ return false;
+ }
+ mInitialized = true;
mEnviroment.mFragment.set(rsc->getDefaultProgramFragment());
mEnviroment.mVertex.set(rsc->getDefaultProgramVertex());
mEnviroment.mFragmentStore.set(rsc->getDefaultProgramStore());
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index 7862f3c7d1d3..26e2374719ce 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -79,23 +79,28 @@ void rsrBindProgramRaster(Context *rsc, Script *sc, ProgramRaster *pr) {
void rsrBindFrameBufferObjectColorTarget(Context *rsc, Script *sc, Allocation *a, uint32_t slot) {
CHECK_OBJ(va);
rsc->mFBOCache.bindColorTarget(rsc, a, slot);
+ rsc->mStateVertex.updateSize(rsc);
}
void rsrBindFrameBufferObjectDepthTarget(Context *rsc, Script *sc, Allocation *a) {
CHECK_OBJ(va);
rsc->mFBOCache.bindDepthTarget(rsc, a);
+ rsc->mStateVertex.updateSize(rsc);
}
void rsrClearFrameBufferObjectColorTarget(Context *rsc, Script *sc, uint32_t slot) {
rsc->mFBOCache.bindColorTarget(rsc, NULL, slot);
+ rsc->mStateVertex.updateSize(rsc);
}
void rsrClearFrameBufferObjectDepthTarget(Context *rsc, Script *sc) {
rsc->mFBOCache.bindDepthTarget(rsc, NULL);
+ rsc->mStateVertex.updateSize(rsc);
}
void rsrClearFrameBufferObjectTargets(Context *rsc, Script *sc) {
rsc->mFBOCache.resetAll(rsc);
+ rsc->mStateVertex.updateSize(rsc);
}
//////////////////////////////////////////////////////////////////////////////
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index b1a579a1bea3..13e789dabd34 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -145,7 +145,7 @@ bool ThreadIO::playCoreCommands(Context *con, bool waitForCommand, uint64_t time
con->timerSet(Context::RS_TIMER_INTERNAL);
}
waitForCommand = false;
- //LOGV("playCoreCommands 3 %i %i", cmdID, cmdSize);
+ //ALOGV("playCoreCommands 3 %i %i", cmdID, cmdSize);
if (cmdID >= (sizeof(gPlaybackFuncs) / sizeof(void *))) {
rsAssert(cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index 9a6a31b4f89f..271c9e2361a4 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -141,7 +141,7 @@ uint32_t Type::getLODFaceOffset(uint32_t lod, RsAllocationCubemapFace face, uint
void Type::dumpLOGV(const char *prefix) const {
char buf[1024];
ObjectBase::dumpLOGV(prefix);
- LOGV("%s Type: x=%zu y=%zu z=%zu mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
+ ALOGV("%s Type: x=%zu y=%zu z=%zu mip=%i face=%i", prefix, mDimX, mDimY, mDimZ, mDimLOD, mFaces);
snprintf(buf, sizeof(buf), "%s element: ", prefix);
mElement->dumpLOGV(buf);
}
diff --git a/libs/rs/scriptc/rs_allocation.rsh b/libs/rs/scriptc/rs_allocation.rsh
index 154a09910e5a..1cb3a99a7f89 100644
--- a/libs/rs/scriptc/rs_allocation.rsh
+++ b/libs/rs/scriptc/rs_allocation.rsh
@@ -14,6 +14,31 @@
* limitations under the License.
*/
+/*! \mainpage notitle
+ *
+ * Renderscript is a high-performance runtime that provides graphics rendering and
+ * compute operations at the native level. Renderscript code is compiled on devices
+ * at runtime to allow platform-independence as well.
+ * This reference documentation describes the Renderscript runtime APIs, which you
+ * can utilize to write Renderscript code in C99. The Renderscript header
+ * files are automatically included for you, except for the rs_graphics.rsh header. If
+ * you are doing graphics rendering, include the graphics header file like this:
+ *
+ * <code>#include "rs_graphics.rsh"</code>
+ *
+ * To use Renderscript, you need to utilize the Renderscript runtime APIs documented here
+ * as well as the Android framework APIs for Renderscript.
+ * For documentation on the Android framework APIs, see the <a href=
+ * "http://developer.android.com/reference/android/renderscript/package-summary.html">
+ * android.renderscript</a> package reference.
+ * For more information on how to develop with Renderscript and how the runtime and
+ * Android framework APIs interact, see the <a href=
+ * "http://developer.android.com/guide/topics/renderscript/index.html">Renderscript
+ * developer guide</a> and the <a href=
+ * "http://developer.android.com/resources/samples/RenderScript/index.html">
+ * Renderscript samples</a>.
+ */
+
/** @file rs_allocation.rsh
* \brief Allocation routines
*
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index 831d9e37890c..544ab744e33a 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -21,6 +21,7 @@ commonSources:= \
Asset.cpp \
AssetDir.cpp \
AssetManager.cpp \
+ BasicHashtable.cpp \
BlobCache.cpp \
BufferedTextOutput.cpp \
CallStack.cpp \
@@ -105,7 +106,8 @@ LOCAL_SHARED_LIBRARIES := \
libz \
liblog \
libcutils \
- libdl
+ libdl \
+ libcorkscrew
LOCAL_MODULE:= libutils
include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp
index a18294b18c8b..7fd2c8731475 100644
--- a/libs/utils/Asset.cpp
+++ b/libs/utils/Asset.cpp
@@ -585,7 +585,7 @@ const void* _FileAsset::getBuffer(bool wordAligned)
return NULL;
}
- LOGV("Asset %p allocating buffer size %d (smaller than threshold)", this, (int)allocLen);
+ ALOGV("Asset %p allocating buffer size %d (smaller than threshold)", this, (int)allocLen);
if (mLength > 0) {
long oldPosn = ftell(mFp);
fseek(mFp, mStart, SEEK_SET);
@@ -597,7 +597,7 @@ const void* _FileAsset::getBuffer(bool wordAligned)
fseek(mFp, oldPosn, SEEK_SET);
}
- LOGV(" getBuffer: loaded into buffer\n");
+ ALOGV(" getBuffer: loaded into buffer\n");
mBuf = buf;
return mBuf;
@@ -610,7 +610,7 @@ const void* _FileAsset::getBuffer(bool wordAligned)
return NULL;
}
- LOGV(" getBuffer: mapped\n");
+ ALOGV(" getBuffer: mapped\n");
mMap = map;
if (!wordAligned) {
@@ -648,13 +648,13 @@ const void* _FileAsset::ensureAlignment(FileMap* map)
if ((((size_t)data)&0x3) == 0) {
// We can return this directly if it is aligned on a word
// boundary.
- LOGV("Returning aligned FileAsset %p (%s).", this,
+ ALOGV("Returning aligned FileAsset %p (%s).", this,
getAssetSource());
return data;
}
// If not aligned on a word boundary, then we need to copy it into
// our own buffer.
- LOGV("Copying FileAsset %p (%s) to buffer size %d to make it aligned.", this,
+ ALOGV("Copying FileAsset %p (%s) to buffer size %d to make it aligned.", this,
getAssetSource(), (int)mLength);
unsigned char* buf = new unsigned char[mLength];
if (buf == NULL) {
diff --git a/libs/utils/AssetManager.cpp b/libs/utils/AssetManager.cpp
index 22034c593545..203e6fa37dee 100644
--- a/libs/utils/AssetManager.cpp
+++ b/libs/utils/AssetManager.cpp
@@ -167,7 +167,7 @@ bool AssetManager::addAssetPath(const String8& path, void** cookie)
}
}
- LOGV("In %p Asset %s path: %s", this,
+ ALOGV("In %p Asset %s path: %s", this,
ap.type == kFileTypeDirectory ? "dir" : "zip", ap.path.string());
mAssetPaths.add(ap);
@@ -498,7 +498,7 @@ Asset* AssetManager::open(const char* fileName, AccessMode mode)
size_t i = mAssetPaths.size();
while (i > 0) {
i--;
- LOGV("Looking for asset '%s' in '%s'\n",
+ ALOGV("Looking for asset '%s' in '%s'\n",
assetName.string(), mAssetPaths.itemAt(i).path.string());
Asset* pAsset = openNonAssetInPathLocked(assetName.string(), mode, mAssetPaths.itemAt(i));
if (pAsset != NULL) {
@@ -532,7 +532,7 @@ Asset* AssetManager::openNonAsset(const char* fileName, AccessMode mode)
size_t i = mAssetPaths.size();
while (i > 0) {
i--;
- LOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string());
+ ALOGV("Looking for non-asset '%s' in '%s'\n", fileName, mAssetPaths.itemAt(i).path.string());
Asset* pAsset = openNonAssetInPathLocked(
fileName, mode, mAssetPaths.itemAt(i));
if (pAsset != NULL) {
@@ -556,7 +556,7 @@ Asset* AssetManager::openNonAsset(void* cookie, const char* fileName, AccessMode
loadFileNameCacheLocked();
if (which < mAssetPaths.size()) {
- LOGV("Looking for non-asset '%s' in '%s'\n", fileName,
+ ALOGV("Looking for non-asset '%s' in '%s'\n", fileName,
mAssetPaths.itemAt(which).path.string());
Asset* pAsset = openNonAssetInPathLocked(
fileName, mode, mAssetPaths.itemAt(which));
@@ -621,7 +621,7 @@ const ResTable* AssetManager::getResTable(bool required) const
bool shared = true;
const asset_path& ap = mAssetPaths.itemAt(i);
Asset* idmap = openIdmapLocked(ap);
- LOGV("Looking for resource asset in '%s'\n", ap.path.string());
+ ALOGV("Looking for resource asset in '%s'\n", ap.path.string());
if (ap.type != kFileTypeDirectory) {
if (i == 0) {
// The first item is typically the framework resources,
@@ -633,7 +633,7 @@ const ResTable* AssetManager::getResTable(bool required) const
ass = const_cast<AssetManager*>(this)->
mZipSet.getZipResourceTableAsset(ap.path);
if (ass == NULL) {
- LOGV("loading resource table %s\n", ap.path.string());
+ ALOGV("loading resource table %s\n", ap.path.string());
ass = const_cast<AssetManager*>(this)->
openNonAssetInPathLocked("resources.arsc",
Asset::ACCESS_BUFFER,
@@ -648,7 +648,7 @@ const ResTable* AssetManager::getResTable(bool required) const
// If this is the first resource table in the asset
// manager, then we are going to cache it so that we
// can quickly copy it out for others.
- LOGV("Creating shared resources for %s", ap.path.string());
+ ALOGV("Creating shared resources for %s", ap.path.string());
sharedRes = new ResTable();
sharedRes->add(ass, (void*)(i+1), false, idmap);
sharedRes = const_cast<AssetManager*>(this)->
@@ -656,7 +656,7 @@ const ResTable* AssetManager::getResTable(bool required) const
}
}
} else {
- LOGV("loading resource table %s\n", ap.path.string());
+ ALOGV("loading resource table %s\n", ap.path.string());
Asset* ass = const_cast<AssetManager*>(this)->
openNonAssetInPathLocked("resources.arsc",
Asset::ACCESS_BUFFER,
@@ -668,12 +668,12 @@ const ResTable* AssetManager::getResTable(bool required) const
mResources = rt = new ResTable();
updateResourceParamsLocked();
}
- LOGV("Installing resource asset %p in to table %p\n", ass, mResources);
+ ALOGV("Installing resource asset %p in to table %p\n", ass, mResources);
if (sharedRes != NULL) {
- LOGV("Copying existing resources for %s", ap.path.string());
+ ALOGV("Copying existing resources for %s", ap.path.string());
rt->add(sharedRes);
} else {
- LOGV("Parsing resources for %s", ap.path.string());
+ ALOGV("Parsing resources for %s", ap.path.string());
rt->add(ass, (void*)(i+1), !shared, idmap);
}
@@ -725,7 +725,7 @@ Asset* AssetManager::openIdmapLocked(const struct asset_path& ap) const
ass = const_cast<AssetManager*>(this)->
openAssetFromFileLocked(ap.idmap, Asset::ACCESS_BUFFER);
if (ass) {
- LOGV("loading idmap %s\n", ap.idmap.string());
+ ALOGV("loading idmap %s\n", ap.idmap.string());
} else {
LOGW("failed to load idmap %s\n", ap.idmap.string());
}
@@ -1019,7 +1019,7 @@ String8 AssetManager::createPathNameLocked(const asset_path& ap, const char* roo
*/
ZipFileRO* AssetManager::getZipFileLocked(const asset_path& ap)
{
- LOGV("getZipFileLocked() in %p\n", this);
+ ALOGV("getZipFileLocked() in %p\n", this);
return mZipSet.getZip(ap.path);
}
@@ -1086,12 +1086,12 @@ Asset* AssetManager::openAssetFromZipLocked(const ZipFileRO* pZipFile,
if (method == ZipFileRO::kCompressStored) {
pAsset = Asset::createFromUncompressedMap(dataMap, mode);
- LOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(),
+ ALOGV("Opened uncompressed entry %s in zip %s mode %d: %p", entryName.string(),
dataMap->getFileName(), mode, pAsset);
} else {
pAsset = Asset::createFromCompressedMap(dataMap, method,
uncompressedLen, mode);
- LOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(),
+ ALOGV("Opened compressed entry %s in zip %s mode %d: %p", entryName.string(),
dataMap->getFileName(), mode, pAsset);
}
if (pAsset == NULL) {
@@ -1146,10 +1146,10 @@ AssetDir* AssetManager::openDir(const char* dirName)
i--;
const asset_path& ap = mAssetPaths.itemAt(i);
if (ap.type == kFileTypeRegular) {
- LOGV("Adding directory %s from zip %s", dirName, ap.path.string());
+ ALOGV("Adding directory %s from zip %s", dirName, ap.path.string());
scanAndMergeZipLocked(pMergedInfo, ap, kAssetsRoot, dirName);
} else {
- LOGV("Adding directory %s from dir %s", dirName, ap.path.string());
+ ALOGV("Adding directory %s from dir %s", dirName, ap.path.string());
scanAndMergeDirLocked(pMergedInfo, ap, kAssetsRoot, dirName);
}
}
@@ -1200,10 +1200,10 @@ AssetDir* AssetManager::openNonAssetDir(void* cookie, const char* dirName)
if (which < mAssetPaths.size()) {
const asset_path& ap = mAssetPaths.itemAt(which);
if (ap.type == kFileTypeRegular) {
- LOGV("Adding directory %s from zip %s", dirName, ap.path.string());
+ ALOGV("Adding directory %s from zip %s", dirName, ap.path.string());
scanAndMergeZipLocked(pMergedInfo, ap, NULL, dirName);
} else {
- LOGV("Adding directory %s from dir %s", dirName, ap.path.string());
+ ALOGV("Adding directory %s from dir %s", dirName, ap.path.string());
scanAndMergeDirLocked(pMergedInfo, ap, NULL, dirName);
}
}
@@ -1325,7 +1325,7 @@ bool AssetManager::scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMerg
matchIdx = AssetDir::FileInfo::findEntry(pMergedInfo, match);
if (matchIdx > 0) {
- LOGV("Excluding '%s' [%s]\n",
+ ALOGV("Excluding '%s' [%s]\n",
pMergedInfo->itemAt(matchIdx).getFileName().string(),
pMergedInfo->itemAt(matchIdx).getSourceName().string());
pMergedInfo->removeAt(matchIdx);
@@ -1365,7 +1365,7 @@ SortedVector<AssetDir::FileInfo>* AssetManager::scanDirLocked(const String8& pat
struct dirent* entry;
FileType fileType;
- LOGV("Scanning dir '%s'\n", path.string());
+ ALOGV("Scanning dir '%s'\n", path.string());
dir = opendir(path.string());
if (dir == NULL)
@@ -1782,7 +1782,7 @@ AssetManager::SharedZip::SharedZip(const String8& path, time_t modWhen)
{
//LOGI("Creating SharedZip %p %s\n", this, (const char*)mPath);
mZipFile = new ZipFileRO;
- LOGV("+++ opening zip '%s'\n", mPath.string());
+ ALOGV("+++ opening zip '%s'\n", mPath.string());
if (mZipFile->open(mPath.string()) != NO_ERROR) {
LOGD("failed to open Zip archive '%s'\n", mPath.string());
delete mZipFile;
@@ -1811,7 +1811,7 @@ ZipFileRO* AssetManager::SharedZip::getZip()
Asset* AssetManager::SharedZip::getResourceTableAsset()
{
- LOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
+ ALOGV("Getting from SharedZip %p resource asset %p\n", this, mResourceTableAsset);
return mResourceTableAsset;
}
@@ -1833,7 +1833,7 @@ Asset* AssetManager::SharedZip::setResourceTableAsset(Asset* asset)
ResTable* AssetManager::SharedZip::getResourceTable()
{
- LOGV("Getting from SharedZip %p resource table %p\n", this, mResourceTable);
+ ALOGV("Getting from SharedZip %p resource table %p\n", this, mResourceTable);
return mResourceTable;
}
@@ -1867,7 +1867,7 @@ AssetManager::SharedZip::~SharedZip()
}
if (mZipFile != NULL) {
delete mZipFile;
- LOGV("Closed '%s'\n", mPath.string());
+ ALOGV("Closed '%s'\n", mPath.string());
}
}
diff --git a/libs/utils/BasicHashtable.cpp b/libs/utils/BasicHashtable.cpp
new file mode 100644
index 000000000000..fb8ec9f83f16
--- /dev/null
+++ b/libs/utils/BasicHashtable.cpp
@@ -0,0 +1,338 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BasicHashtable"
+
+#include <math.h>
+
+#include <utils/Log.h>
+#include <utils/BasicHashtable.h>
+#include <utils/misc.h>
+
+namespace android {
+
+BasicHashtableImpl::BasicHashtableImpl(size_t entrySize, bool hasTrivialDestructor,
+ size_t minimumInitialCapacity, float loadFactor) :
+ mBucketSize(entrySize + sizeof(Bucket)), mHasTrivialDestructor(hasTrivialDestructor),
+ mLoadFactor(loadFactor), mSize(0),
+ mFilledBuckets(0), mBuckets(NULL) {
+ determineCapacity(minimumInitialCapacity, mLoadFactor, &mBucketCount, &mCapacity);
+}
+
+BasicHashtableImpl::BasicHashtableImpl(const BasicHashtableImpl& other) :
+ mBucketSize(other.mBucketSize), mHasTrivialDestructor(other.mHasTrivialDestructor),
+ mCapacity(other.mCapacity), mLoadFactor(other.mLoadFactor),
+ mSize(other.mSize), mFilledBuckets(other.mFilledBuckets),
+ mBucketCount(other.mBucketCount), mBuckets(other.mBuckets) {
+ if (mBuckets) {
+ SharedBuffer::bufferFromData(mBuckets)->acquire();
+ }
+}
+
+void BasicHashtableImpl::dispose() {
+ if (mBuckets) {
+ releaseBuckets(mBuckets, mBucketCount);
+ }
+}
+
+void BasicHashtableImpl::clone() {
+ if (mBuckets) {
+ void* newBuckets = allocateBuckets(mBucketCount);
+ copyBuckets(mBuckets, newBuckets, mBucketCount);
+ releaseBuckets(mBuckets, mBucketCount);
+ mBuckets = newBuckets;
+ }
+}
+
+void BasicHashtableImpl::setTo(const BasicHashtableImpl& other) {
+ if (mBuckets) {
+ releaseBuckets(mBuckets, mBucketCount);
+ }
+
+ mCapacity = other.mCapacity;
+ mLoadFactor = other.mLoadFactor;
+ mSize = other.mSize;
+ mFilledBuckets = other.mFilledBuckets;
+ mBucketCount = other.mBucketCount;
+ mBuckets = other.mBuckets;
+
+ if (mBuckets) {
+ SharedBuffer::bufferFromData(mBuckets)->acquire();
+ }
+}
+
+void BasicHashtableImpl::clear() {
+ if (mBuckets) {
+ if (mFilledBuckets) {
+ SharedBuffer* sb = SharedBuffer::bufferFromData(mBuckets);
+ if (sb->onlyOwner()) {
+ destroyBuckets(mBuckets, mBucketCount);
+ for (size_t i = 0; i < mSize; i++) {
+ Bucket& bucket = bucketAt(mBuckets, i);
+ bucket.cookie = 0;
+ }
+ } else {
+ releaseBuckets(mBuckets, mBucketCount);
+ mBuckets = NULL;
+ }
+ mFilledBuckets = 0;
+ }
+ mSize = 0;
+ }
+}
+
+ssize_t BasicHashtableImpl::next(ssize_t index) const {
+ if (mSize) {
+ while (size_t(++index) < mBucketCount) {
+ const Bucket& bucket = bucketAt(mBuckets, index);
+ if (bucket.cookie & Bucket::PRESENT) {
+ return index;
+ }
+ }
+ }
+ return -1;
+}
+
+ssize_t BasicHashtableImpl::find(ssize_t index, hash_t hash,
+ const void* __restrict__ key) const {
+ if (!mSize) {
+ return -1;
+ }
+
+ hash = trimHash(hash);
+ if (index < 0) {
+ index = chainStart(hash, mBucketCount);
+
+ const Bucket& bucket = bucketAt(mBuckets, size_t(index));
+ if (bucket.cookie & Bucket::PRESENT) {
+ if (compareBucketKey(bucket, key)) {
+ return index;
+ }
+ } else {
+ if (!(bucket.cookie & Bucket::COLLISION)) {
+ return -1;
+ }
+ }
+ }
+
+ size_t inc = chainIncrement(hash, mBucketCount);
+ for (;;) {
+ index = chainSeek(index, inc, mBucketCount);
+
+ const Bucket& bucket = bucketAt(mBuckets, size_t(index));
+ if (bucket.cookie & Bucket::PRESENT) {
+ if ((bucket.cookie & Bucket::HASH_MASK) == hash
+ && compareBucketKey(bucket, key)) {
+ return index;
+ }
+ }
+ if (!(bucket.cookie & Bucket::COLLISION)) {
+ return -1;
+ }
+ }
+}
+
+size_t BasicHashtableImpl::add(hash_t hash, const void* entry) {
+ if (!mBuckets) {
+ mBuckets = allocateBuckets(mBucketCount);
+ } else {
+ edit();
+ }
+
+ hash = trimHash(hash);
+ for (;;) {
+ size_t index = chainStart(hash, mBucketCount);
+ Bucket* bucket = &bucketAt(mBuckets, size_t(index));
+ if (bucket->cookie & Bucket::PRESENT) {
+ size_t inc = chainIncrement(hash, mBucketCount);
+ do {
+ bucket->cookie |= Bucket::COLLISION;
+ index = chainSeek(index, inc, mBucketCount);
+ bucket = &bucketAt(mBuckets, size_t(index));
+ } while (bucket->cookie & Bucket::PRESENT);
+ }
+
+ uint32_t collision = bucket->cookie & Bucket::COLLISION;
+ if (!collision) {
+ if (mFilledBuckets >= mCapacity) {
+ rehash(mCapacity * 2, mLoadFactor);
+ continue;
+ }
+ mFilledBuckets += 1;
+ }
+
+ bucket->cookie = collision | Bucket::PRESENT | hash;
+ mSize += 1;
+ initializeBucketEntry(*bucket, entry);
+ return index;
+ }
+}
+
+void BasicHashtableImpl::removeAt(size_t index) {
+ edit();
+
+ Bucket& bucket = bucketAt(mBuckets, index);
+ bucket.cookie &= ~Bucket::PRESENT;
+ if (!(bucket.cookie & Bucket::COLLISION)) {
+ mFilledBuckets -= 1;
+ }
+ mSize -= 1;
+ if (!mHasTrivialDestructor) {
+ destroyBucketEntry(bucket);
+ }
+}
+
+void BasicHashtableImpl::rehash(size_t minimumCapacity, float loadFactor) {
+ if (minimumCapacity < mSize) {
+ minimumCapacity = mSize;
+ }
+ size_t newBucketCount, newCapacity;
+ determineCapacity(minimumCapacity, loadFactor, &newBucketCount, &newCapacity);
+
+ if (newBucketCount != mBucketCount || newCapacity != mCapacity) {
+ if (mBuckets) {
+ void* newBuckets;
+ if (mSize) {
+ newBuckets = allocateBuckets(newBucketCount);
+ for (size_t i = 0; i < mBucketCount; i++) {
+ const Bucket& fromBucket = bucketAt(mBuckets, i);
+ if (fromBucket.cookie & Bucket::PRESENT) {
+ hash_t hash = fromBucket.cookie & Bucket::HASH_MASK;
+ size_t index = chainStart(hash, newBucketCount);
+ Bucket* toBucket = &bucketAt(newBuckets, size_t(index));
+ if (toBucket->cookie & Bucket::PRESENT) {
+ size_t inc = chainIncrement(hash, newBucketCount);
+ do {
+ toBucket->cookie |= Bucket::COLLISION;
+ index = chainSeek(index, inc, newBucketCount);
+ toBucket = &bucketAt(newBuckets, size_t(index));
+ } while (toBucket->cookie & Bucket::PRESENT);
+ }
+ toBucket->cookie = Bucket::PRESENT | hash;
+ initializeBucketEntry(*toBucket, fromBucket.entry);
+ }
+ }
+ } else {
+ newBuckets = NULL;
+ }
+ releaseBuckets(mBuckets, mBucketCount);
+ mBuckets = newBuckets;
+ mFilledBuckets = mSize;
+ }
+ mBucketCount = newBucketCount;
+ mCapacity = newCapacity;
+ }
+ mLoadFactor = loadFactor;
+}
+
+void* BasicHashtableImpl::allocateBuckets(size_t count) const {
+ size_t bytes = count * mBucketSize;
+ SharedBuffer* sb = SharedBuffer::alloc(bytes);
+ LOG_ALWAYS_FATAL_IF(!sb, "Could not allocate %u bytes for hashtable with %u buckets.",
+ uint32_t(bytes), uint32_t(count));
+ void* buckets = sb->data();
+ for (size_t i = 0; i < count; i++) {
+ Bucket& bucket = bucketAt(buckets, i);
+ bucket.cookie = 0;
+ }
+ return buckets;
+}
+
+void BasicHashtableImpl::releaseBuckets(void* __restrict__ buckets, size_t count) const {
+ SharedBuffer* sb = SharedBuffer::bufferFromData(buckets);
+ if (sb->release(SharedBuffer::eKeepStorage) == 1) {
+ destroyBuckets(buckets, count);
+ SharedBuffer::dealloc(sb);
+ }
+}
+
+void BasicHashtableImpl::destroyBuckets(void* __restrict__ buckets, size_t count) const {
+ if (!mHasTrivialDestructor) {
+ for (size_t i = 0; i < count; i++) {
+ Bucket& bucket = bucketAt(buckets, i);
+ if (bucket.cookie & Bucket::PRESENT) {
+ destroyBucketEntry(bucket);
+ }
+ }
+ }
+}
+
+void BasicHashtableImpl::copyBuckets(const void* __restrict__ fromBuckets,
+ void* __restrict__ toBuckets, size_t count) const {
+ for (size_t i = 0; i < count; i++) {
+ const Bucket& fromBucket = bucketAt(fromBuckets, i);
+ Bucket& toBucket = bucketAt(toBuckets, i);
+ toBucket.cookie = fromBucket.cookie;
+ if (fromBucket.cookie & Bucket::PRESENT) {
+ initializeBucketEntry(toBucket, fromBucket.entry);
+ }
+ }
+}
+
+// Table of 31-bit primes where each prime is no less than twice as large
+// as the previous one. Generated by "primes.py".
+static size_t PRIMES[] = {
+ 5,
+ 11,
+ 23,
+ 47,
+ 97,
+ 197,
+ 397,
+ 797,
+ 1597,
+ 3203,
+ 6421,
+ 12853,
+ 25717,
+ 51437,
+ 102877,
+ 205759,
+ 411527,
+ 823117,
+ 1646237,
+ 3292489,
+ 6584983,
+ 13169977,
+ 26339969,
+ 52679969,
+ 105359939,
+ 210719881,
+ 421439783,
+ 842879579,
+ 1685759167,
+ 0,
+};
+
+void BasicHashtableImpl::determineCapacity(size_t minimumCapacity, float loadFactor,
+ size_t* __restrict__ outBucketCount, size_t* __restrict__ outCapacity) {
+ LOG_ALWAYS_FATAL_IF(loadFactor <= 0.0f || loadFactor > 1.0f,
+ "Invalid load factor %0.3f. Must be in the range (0, 1].", loadFactor);
+
+ size_t count = ceilf(minimumCapacity / loadFactor) + 1;
+ size_t i = 0;
+ while (count > PRIMES[i] && i < NELEM(PRIMES)) {
+ i++;
+ }
+ count = PRIMES[i];
+ LOG_ALWAYS_FATAL_IF(!count, "Could not determine required number of buckets for "
+ "hashtable with minimum capacity %u and load factor %0.3f.",
+ uint32_t(minimumCapacity), loadFactor);
+ *outBucketCount = count;
+ *outCapacity = ceilf((count - 1) * loadFactor);
+}
+
+}; // namespace android
diff --git a/libs/utils/BlobCache.cpp b/libs/utils/BlobCache.cpp
index d38aae9cd4e3..497082869268 100644
--- a/libs/utils/BlobCache.cpp
+++ b/libs/utils/BlobCache.cpp
@@ -48,23 +48,23 @@ BlobCache::BlobCache(size_t maxKeySize, size_t maxValueSize, size_t maxTotalSize
mRandState[1] = (now >> 16) & 0xFFFF;
mRandState[2] = (now >> 32) & 0xFFFF;
#endif
- LOGV("initializing random seed using %lld", now);
+ ALOGV("initializing random seed using %lld", now);
}
void BlobCache::set(const void* key, size_t keySize, const void* value,
size_t valueSize) {
if (mMaxKeySize < keySize) {
- LOGV("set: not caching because the key is too large: %d (limit: %d)",
+ ALOGV("set: not caching because the key is too large: %d (limit: %d)",
keySize, mMaxKeySize);
return;
}
if (mMaxValueSize < valueSize) {
- LOGV("set: not caching because the value is too large: %d (limit: %d)",
+ ALOGV("set: not caching because the value is too large: %d (limit: %d)",
valueSize, mMaxValueSize);
return;
}
if (mMaxTotalSize < keySize + valueSize) {
- LOGV("set: not caching because the combined key/value size is too "
+ ALOGV("set: not caching because the combined key/value size is too "
"large: %d (limit: %d)", keySize + valueSize, mMaxTotalSize);
return;
}
@@ -93,7 +93,7 @@ void BlobCache::set(const void* key, size_t keySize, const void* value,
clean();
continue;
} else {
- LOGV("set: not caching new key/value pair because the "
+ ALOGV("set: not caching new key/value pair because the "
"total cache size limit would be exceeded: %d "
"(limit: %d)",
keySize + valueSize, mMaxTotalSize);
@@ -102,7 +102,7 @@ void BlobCache::set(const void* key, size_t keySize, const void* value,
}
mCacheEntries.add(CacheEntry(keyBlob, valueBlob));
mTotalSize = newTotalSize;
- LOGV("set: created new cache entry with %d byte key and %d byte value",
+ ALOGV("set: created new cache entry with %d byte key and %d byte value",
keySize, valueSize);
} else {
// Update the existing cache entry.
@@ -115,7 +115,7 @@ void BlobCache::set(const void* key, size_t keySize, const void* value,
clean();
continue;
} else {
- LOGV("set: not caching new value because the total cache "
+ ALOGV("set: not caching new value because the total cache "
"size limit would be exceeded: %d (limit: %d)",
keySize + valueSize, mMaxTotalSize);
break;
@@ -123,7 +123,7 @@ void BlobCache::set(const void* key, size_t keySize, const void* value,
}
mCacheEntries.editItemAt(index).setValue(valueBlob);
mTotalSize = newTotalSize;
- LOGV("set: updated existing cache entry with %d byte key and %d byte "
+ ALOGV("set: updated existing cache entry with %d byte key and %d byte "
"value", keySize, valueSize);
}
break;
@@ -133,7 +133,7 @@ void BlobCache::set(const void* key, size_t keySize, const void* value,
size_t BlobCache::get(const void* key, size_t keySize, void* value,
size_t valueSize) {
if (mMaxKeySize < keySize) {
- LOGV("get: not searching because the key is too large: %d (limit %d)",
+ ALOGV("get: not searching because the key is too large: %d (limit %d)",
keySize, mMaxKeySize);
return 0;
}
@@ -141,7 +141,7 @@ size_t BlobCache::get(const void* key, size_t keySize, void* value,
CacheEntry dummyEntry(dummyKey, NULL);
ssize_t index = mCacheEntries.indexOf(dummyEntry);
if (index < 0) {
- LOGV("get: no cache entry found for key of size %d", keySize);
+ ALOGV("get: no cache entry found for key of size %d", keySize);
return 0;
}
@@ -150,10 +150,10 @@ size_t BlobCache::get(const void* key, size_t keySize, void* value,
sp<Blob> valueBlob(mCacheEntries[index].getValue());
size_t valueBlobSize = valueBlob->getSize();
if (valueBlobSize <= valueSize) {
- LOGV("get: copying %d bytes to caller's buffer", valueBlobSize);
+ ALOGV("get: copying %d bytes to caller's buffer", valueBlobSize);
memcpy(value, valueBlob->getData(), valueBlobSize);
} else {
- LOGV("get: caller's buffer is too small for value: %d (needs %d)",
+ ALOGV("get: caller's buffer is too small for value: %d (needs %d)",
valueSize, valueBlobSize);
}
return valueBlobSize;
diff --git a/libs/utils/CallStack.cpp b/libs/utils/CallStack.cpp
index 55b6024f6315..c2a5e5534f3a 100644
--- a/libs/utils/CallStack.cpp
+++ b/libs/utils/CallStack.cpp
@@ -17,218 +17,33 @@
#define LOG_TAG "CallStack"
#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#if HAVE_DLADDR
-#include <dlfcn.h>
-#endif
-
-#if HAVE_CXXABI
-#include <cxxabi.h>
-#endif
-
-#include <unwind.h>
#include <utils/Log.h>
#include <utils/Errors.h>
#include <utils/CallStack.h>
-#include <utils/threads.h>
-
+#include <corkscrew/backtrace.h>
/*****************************************************************************/
namespace android {
-
-typedef struct {
- size_t count;
- size_t ignore;
- const void** addrs;
-} stack_crawl_state_t;
-
-static
-_Unwind_Reason_Code trace_function(_Unwind_Context *context, void *arg)
-{
- stack_crawl_state_t* state = (stack_crawl_state_t*)arg;
- if (state->count) {
- void* ip = (void*)_Unwind_GetIP(context);
- if (ip) {
- if (state->ignore) {
- state->ignore--;
- } else {
- state->addrs[0] = ip;
- state->addrs++;
- state->count--;
- }
- }
- }
- return _URC_NO_REASON;
-}
-
-static
-int backtrace(const void** addrs, size_t ignore, size_t size)
-{
- stack_crawl_state_t state;
- state.count = size;
- state.ignore = ignore;
- state.addrs = addrs;
- _Unwind_Backtrace(trace_function, (void*)&state);
- return size - state.count;
-}
-
-/*****************************************************************************/
-
-static
-const char *lookup_symbol(const void* addr, void **offset, char* name, size_t bufSize)
-{
-#if HAVE_DLADDR
- Dl_info info;
- if (dladdr(addr, &info)) {
- *offset = info.dli_saddr;
- return info.dli_sname;
- }
-#endif
- return NULL;
-}
-
-static
-int32_t linux_gcc_demangler(const char *mangled_name, char *unmangled_name, size_t buffersize)
-{
- size_t out_len = 0;
-#if HAVE_CXXABI
- int status = 0;
- char *demangled = abi::__cxa_demangle(mangled_name, 0, &out_len, &status);
- if (status == 0) {
- // OK
- if (out_len < buffersize) memcpy(unmangled_name, demangled, out_len);
- else out_len = 0;
- free(demangled);
- } else {
- out_len = 0;
- }
-#endif
- return out_len;
-}
-
-/*****************************************************************************/
-
-class MapInfo {
- struct mapinfo {
- struct mapinfo *next;
- uint64_t start;
- uint64_t end;
- char name[];
- };
-
- const char *map_to_name(uint64_t pc, const char* def, uint64_t* start) {
- mapinfo* mi = getMapInfoList();
- while(mi) {
- if ((pc >= mi->start) && (pc < mi->end)) {
- if (start)
- *start = mi->start;
- return mi->name;
- }
- mi = mi->next;
- }
- if (start)
- *start = 0;
- return def;
- }
-
- mapinfo *parse_maps_line(char *line) {
- mapinfo *mi;
- int len = strlen(line);
- if (len < 1) return 0;
- line[--len] = 0;
- if (len < 50) return 0;
- if (line[20] != 'x') return 0;
- mi = (mapinfo*)malloc(sizeof(mapinfo) + (len - 47));
- if (mi == 0) return 0;
- mi->start = strtoull(line, 0, 16);
- mi->end = strtoull(line + 9, 0, 16);
- mi->next = 0;
- strcpy(mi->name, line + 49);
- return mi;
- }
-
- mapinfo* getMapInfoList() {
- Mutex::Autolock _l(mLock);
- if (milist == 0) {
- char data[1024];
- FILE *fp;
- sprintf(data, "/proc/%d/maps", getpid());
- fp = fopen(data, "r");
- if (fp) {
- while(fgets(data, 1024, fp)) {
- mapinfo *mi = parse_maps_line(data);
- if(mi) {
- mi->next = milist;
- milist = mi;
- }
- }
- fclose(fp);
- }
- }
- return milist;
- }
- mapinfo* milist;
- Mutex mLock;
- static MapInfo sMapInfo;
-
-public:
- MapInfo()
- : milist(0) {
- }
-
- ~MapInfo() {
- while (milist) {
- mapinfo *next = milist->next;
- free(milist);
- milist = next;
- }
- }
-
- static const char *mapAddressToName(const void* pc, const char* def,
- void const** start)
- {
- uint64_t s;
- char const* name = sMapInfo.map_to_name(uint64_t(uintptr_t(pc)), def, &s);
- if (start) {
- *start = (void*)s;
- }
- return name;
- }
-
-};
-
-/*****************************************************************************/
-
-MapInfo MapInfo::sMapInfo;
-
-/*****************************************************************************/
-
-CallStack::CallStack()
- : mCount(0)
-{
+CallStack::CallStack() :
+ mCount(0) {
}
-CallStack::CallStack(const CallStack& rhs)
- : mCount(rhs.mCount)
-{
+CallStack::CallStack(const CallStack& rhs) :
+ mCount(rhs.mCount) {
if (mCount) {
- memcpy(mStack, rhs.mStack, mCount*sizeof(void*));
+ memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
}
}
-CallStack::~CallStack()
-{
+CallStack::~CallStack() {
}
-CallStack& CallStack::operator = (const CallStack& rhs)
-{
+CallStack& CallStack::operator = (const CallStack& rhs) {
mCount = rhs.mCount;
if (mCount) {
- memcpy(mStack, rhs.mStack, mCount*sizeof(void*));
+ memcpy(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t));
}
return *this;
}
@@ -236,7 +51,7 @@ CallStack& CallStack::operator = (const CallStack& rhs)
bool CallStack::operator == (const CallStack& rhs) const {
if (mCount != rhs.mCount)
return false;
- return !mCount || (memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) == 0);
+ return !mCount || memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) == 0;
}
bool CallStack::operator != (const CallStack& rhs) const {
@@ -246,7 +61,7 @@ bool CallStack::operator != (const CallStack& rhs) const {
bool CallStack::operator < (const CallStack& rhs) const {
if (mCount != rhs.mCount)
return mCount < rhs.mCount;
- return memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) < 0;
+ return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) < 0;
}
bool CallStack::operator >= (const CallStack& rhs) const {
@@ -256,7 +71,7 @@ bool CallStack::operator >= (const CallStack& rhs) const {
bool CallStack::operator > (const CallStack& rhs) const {
if (mCount != rhs.mCount)
return mCount > rhs.mCount;
- return memcmp(mStack, rhs.mStack, mCount*sizeof(void*)) > 0;
+ return memcmp(mStack, rhs.mStack, mCount * sizeof(backtrace_frame_t)) > 0;
}
bool CallStack::operator <= (const CallStack& rhs) const {
@@ -266,84 +81,49 @@ bool CallStack::operator <= (const CallStack& rhs) const {
const void* CallStack::operator [] (int index) const {
if (index >= int(mCount))
return 0;
- return mStack[index];
+ return reinterpret_cast<const void*>(mStack[index].absolute_pc);
}
-
-void CallStack::clear()
-{
+void CallStack::clear() {
mCount = 0;
}
-void CallStack::update(int32_t ignoreDepth, int32_t maxDepth)
-{
- if (maxDepth > MAX_DEPTH)
+void CallStack::update(int32_t ignoreDepth, int32_t maxDepth) {
+ if (maxDepth > MAX_DEPTH) {
maxDepth = MAX_DEPTH;
- mCount = backtrace(mStack, ignoreDepth, maxDepth);
-}
-
-// Return the stack frame name on the designated level
-String8 CallStack::toStringSingleLevel(const char* prefix, int32_t level) const
-{
- String8 res;
- char namebuf[1024];
- char tmp[256];
- char tmp1[32];
- char tmp2[32];
- void *offs;
-
- const void* ip = mStack[level];
- if (!ip) return res;
-
- if (prefix) res.append(prefix);
- snprintf(tmp1, 32, "#%02d ", level);
- res.append(tmp1);
-
- const char* name = lookup_symbol(ip, &offs, namebuf, sizeof(namebuf));
- if (name) {
- if (linux_gcc_demangler(name, tmp, 256) != 0)
- name = tmp;
- snprintf(tmp1, 32, "0x%p: <", ip);
- snprintf(tmp2, 32, ">+0x%p", offs);
- res.append(tmp1);
- res.append(name);
- res.append(tmp2);
- } else {
- void const* start = 0;
- name = MapInfo::mapAddressToName(ip, "<unknown>", &start);
- snprintf(tmp, 256, "pc %08lx %s",
- long(uintptr_t(ip)-uintptr_t(start)), name);
- res.append(tmp);
}
- res.append("\n");
-
- return res;
+ ssize_t count = unwind_backtrace(mStack, ignoreDepth + 1, maxDepth);
+ mCount = count > 0 ? count : 0;
}
-// Dump a stack trace to the log
-void CallStack::dump(const char* prefix) const
-{
- /*
- * Sending a single long log may be truncated since the stack levels can
- * get very deep. So we request function names of each frame individually.
- */
- for (int i=0; i<int(mCount); i++) {
- LOGD("%s", toStringSingleLevel(prefix, i).string());
+void CallStack::dump(const char* prefix) const {
+ backtrace_symbol_t symbols[mCount];
+
+ get_backtrace_symbols(mStack, mCount, symbols);
+ for (size_t i = 0; i < mCount; i++) {
+ char line[MAX_BACKTRACE_LINE_LENGTH];
+ format_backtrace_line(i, &mStack[i], &symbols[i],
+ line, MAX_BACKTRACE_LINE_LENGTH);
+ LOGD("%s%s", prefix, line);
}
+ free_backtrace_symbols(symbols, mCount);
}
-// Return a string (possibly very long) containing the complete stack trace
-String8 CallStack::toString(const char* prefix) const
-{
- String8 res;
+String8 CallStack::toString(const char* prefix) const {
+ String8 str;
+ backtrace_symbol_t symbols[mCount];
- for (int i=0; i<int(mCount); i++) {
- res.append(toStringSingleLevel(prefix, i).string());
+ get_backtrace_symbols(mStack, mCount, symbols);
+ for (size_t i = 0; i < mCount; i++) {
+ char line[MAX_BACKTRACE_LINE_LENGTH];
+ format_backtrace_line(i, &mStack[i], &symbols[i],
+ line, MAX_BACKTRACE_LINE_LENGTH);
+ str.append(prefix);
+ str.append(line);
+ str.append("\n");
}
-
- return res;
+ free_backtrace_symbols(symbols, mCount);
+ return str;
}
-/*****************************************************************************/
-
}; // namespace android
diff --git a/libs/utils/FileMap.cpp b/libs/utils/FileMap.cpp
index c220a9016f79..294f7b6b2ac4 100644
--- a/libs/utils/FileMap.cpp
+++ b/libs/utils/FileMap.cpp
@@ -190,7 +190,7 @@ try_again:
assert(mBasePtr != NULL);
- LOGV("MAP: base %p/%d data %p/%d\n",
+ ALOGV("MAP: base %p/%d data %p/%d\n",
mBasePtr, (int) mBaseLength, mDataPtr, (int) mDataLength);
return true;
diff --git a/libs/utils/RefBase.cpp b/libs/utils/RefBase.cpp
index 37d061cb3cbb..959b3823574f 100644
--- a/libs/utils/RefBase.cpp
+++ b/libs/utils/RefBase.cpp
@@ -421,7 +421,7 @@ void RefBase::weakref_type::decWeak(const void* id)
// destroy the object now.
delete impl->mBase;
} else {
- // LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
+ // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase);
delete impl;
}
} else {
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index 6cf01c8d6887..6a9e91d2b39f 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -69,7 +69,7 @@ namespace android {
static void printToLogFunc(void* cookie, const char* txt)
{
- LOGV("%s", txt);
+ ALOGV("%s", txt);
}
// Standard C isspace() is only required to look at the low byte of its input, so
@@ -1867,7 +1867,7 @@ status_t ResTable::add(const void* data, size_t size, void* cookie,
const bool notDeviceEndian = htods(0xf0) != 0xf0;
LOAD_TABLE_NOISY(
- LOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d "
+ ALOGV("Adding resources to ResTable: data=%p, size=0x%x, cookie=%p, asset=%p, copy=%d "
"idmap=%p\n", data, size, cookie, asset, copyData, idmap));
if (copyData || notDeviceEndian) {
@@ -2122,7 +2122,7 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag
resID, &overlayResID);
if (retval == NO_ERROR && overlayResID != 0x0) {
// for this loop iteration, this is the type and entry we really want
- LOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID);
+ ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID);
T = Res_GETTYPE(overlayResID);
E = Res_GETENTRY(overlayResID);
} else {
@@ -2401,7 +2401,7 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
resID, &overlayResID);
if (retval == NO_ERROR && overlayResID != 0x0) {
// for this loop iteration, this is the type and entry we really want
- LOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID);
+ ALOGV("resource map 0x%08x -> 0x%08x\n", resID, overlayResID);
T = Res_GETTYPE(overlayResID);
E = Res_GETENTRY(overlayResID);
} else {
@@ -2413,9 +2413,9 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag,
const ResTable_type* type;
const ResTable_entry* entry;
const Type* typeClass;
- LOGV("Getting entry pkg=%p, t=%d, e=%d\n", package, T, E);
+ ALOGV("Getting entry pkg=%p, t=%d, e=%d\n", package, T, E);
ssize_t offset = getEntry(package, T, E, &mParams, &type, &entry, &typeClass);
- LOGV("Resulting offset=%d\n", offset);
+ ALOGV("Resulting offset=%d\n", offset);
if (offset <= 0) {
// No {entry, appropriate config} pair found in package. If this
// package is an overlay package (ip != 0), this simply means the
@@ -3898,9 +3898,9 @@ void ResTable::getConfigurations(Vector<ResTable_config>* configs) const
void ResTable::getLocales(Vector<String8>* locales) const
{
Vector<ResTable_config> configs;
- LOGV("calling getConfigurations");
+ ALOGV("calling getConfigurations");
getConfigurations(&configs);
- LOGV("called getConfigurations size=%d", (int)configs.size());
+ ALOGV("called getConfigurations size=%d", (int)configs.size());
const size_t I = configs.size();
for (size_t i=0; i<I; i++) {
char locale[6];
@@ -3924,13 +3924,13 @@ ssize_t ResTable::getEntry(
const ResTable_type** outType, const ResTable_entry** outEntry,
const Type** outTypeClass) const
{
- LOGV("Getting entry from package %p\n", package);
+ ALOGV("Getting entry from package %p\n", package);
const ResTable_package* const pkg = package->package;
const Type* allTypes = package->getType(typeIndex);
- LOGV("allTypes=%p\n", allTypes);
+ ALOGV("allTypes=%p\n", allTypes);
if (allTypes == NULL) {
- LOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex);
+ ALOGV("Skipping entry type index 0x%02x because type is NULL!\n", typeIndex);
return 0;
}
diff --git a/libs/utils/StreamingZipInflater.cpp b/libs/utils/StreamingZipInflater.cpp
index 00498bd1fcb8..59a46f977c7f 100644
--- a/libs/utils/StreamingZipInflater.cpp
+++ b/libs/utils/StreamingZipInflater.cpp
@@ -77,7 +77,7 @@ StreamingZipInflater::~StreamingZipInflater() {
}
void StreamingZipInflater::initInflateState() {
- LOGV("Initializing inflate state");
+ ALOGV("Initializing inflate state");
memset(&mInflateState, 0, sizeof(mInflateState));
mInflateState.zalloc = Z_NULL;
@@ -152,13 +152,13 @@ ssize_t StreamingZipInflater::read(void* outBuf, size_t count) {
mInflateState.avail_out = mOutBufSize;
/*
- LOGV("Inflating to outbuf: avail_in=%u avail_out=%u next_in=%p next_out=%p",
+ ALOGV("Inflating to outbuf: avail_in=%u avail_out=%u next_in=%p next_out=%p",
mInflateState.avail_in, mInflateState.avail_out,
mInflateState.next_in, mInflateState.next_out);
*/
int result = Z_OK;
if (mStreamNeedsInit) {
- LOGV("Initializing zlib to inflate");
+ ALOGV("Initializing zlib to inflate");
result = inflateInit2(&mInflateState, -MAX_WBITS);
mStreamNeedsInit = false;
}
@@ -192,7 +192,7 @@ int StreamingZipInflater::readNextChunk() {
size_t toRead = min_of(mInBufSize, mInTotalSize - mInNextChunkOffset);
if (toRead > 0) {
ssize_t didRead = ::read(mFd, mInBuf, toRead);
- //LOGV("Reading input chunk, size %08x didread %08x", toRead, didRead);
+ //ALOGV("Reading input chunk, size %08x didread %08x", toRead, didRead);
if (didRead < 0) {
// TODO: error
LOGE("Error reading asset data");
diff --git a/libs/utils/Threads.cpp b/libs/utils/Threads.cpp
index 5dbcb75b0616..fe4b8e62b2ca 100644
--- a/libs/utils/Threads.cpp
+++ b/libs/utils/Threads.cpp
@@ -205,7 +205,7 @@ static __stdcall unsigned int threadIntermediary(void* vDetails)
delete pDetails;
- LOG(LOG_VERBOSE, "thread", "thread exiting\n");
+ ALOG(LOG_VERBOSE, "thread", "thread exiting\n");
return (unsigned int) result;
}
@@ -232,7 +232,7 @@ static bool doCreateThread(android_thread_func_t fn, void* arg, android_thread_i
if (hThread == NULL)
#endif
{
- LOG(LOG_WARN, "thread", "WARNING: thread create failed\n");
+ ALOG(LOG_WARN, "thread", "WARNING: thread create failed\n");
return false;
}
@@ -470,7 +470,7 @@ status_t Mutex::lock()
void Mutex::unlock()
{
if (!ReleaseMutex((HANDLE) mState))
- LOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n");
+ ALOG(LOG_WARN, "thread", "WARNING: bad result from unlocking mutex\n");
}
status_t Mutex::tryLock()
@@ -479,7 +479,7 @@ status_t Mutex::tryLock()
dwWaitResult = WaitForSingleObject((HANDLE) mState, 0);
if (dwWaitResult != WAIT_OBJECT_0 && dwWaitResult != WAIT_TIMEOUT)
- LOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n");
+ ALOG(LOG_WARN, "thread", "WARNING: bad result from try-locking mutex\n");
return (dwWaitResult == WAIT_OBJECT_0) ? 0 : -1;
}
diff --git a/libs/utils/Timers.cpp b/libs/utils/Timers.cpp
index 64a29f58776a..64b470181ad9 100644
--- a/libs/utils/Timers.cpp
+++ b/libs/utils/Timers.cpp
@@ -113,7 +113,7 @@ long long DurationTimer::durationUsecs(void) const
/*static*/ void DurationTimer::addToTimeval(struct timeval* ptv, long usec)
{
if (usec < 0) {
- LOG(LOG_WARN, "", "Negative values not supported in addToTimeval\n");
+ ALOG(LOG_WARN, "", "Negative values not supported in addToTimeval\n");
return;
}
diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp
index bfb37a60d718..4a9029671ce5 100644
--- a/libs/utils/VectorImpl.cpp
+++ b/libs/utils/VectorImpl.cpp
@@ -346,7 +346,7 @@ void VectorImpl::release_storage()
void* VectorImpl::_grow(size_t where, size_t amount)
{
-// LOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
+// ALOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
// this, (int)where, (int)amount, (int)mCount, (int)capacity());
LOG_ASSERT(where <= mCount,
@@ -356,7 +356,7 @@ void* VectorImpl::_grow(size_t where, size_t amount)
const size_t new_size = mCount + amount;
if (capacity() < new_size) {
const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2);
-// LOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity);
+// ALOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity);
if ((mStorage) &&
(mCount==where) &&
(mFlags & HAS_TRIVIAL_COPY) &&
@@ -399,7 +399,7 @@ void VectorImpl::_shrink(size_t where, size_t amount)
if (!mStorage)
return;
-// LOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
+// ALOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d",
// this, (int)where, (int)amount, (int)mCount, (int)capacity());
LOG_ASSERT(where + amount <= mCount,
@@ -409,7 +409,7 @@ void VectorImpl::_shrink(size_t where, size_t amount)
const size_t new_size = mCount - amount;
if (new_size*3 < capacity()) {
const size_t new_capacity = max(kMinVectorCapacity, new_size*2);
-// LOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity);
+// ALOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity);
if ((where == new_size) &&
(mFlags & HAS_TRIVIAL_COPY) &&
(mFlags & HAS_TRIVIAL_DTOR))
diff --git a/libs/utils/ZipFileRO.cpp b/libs/utils/ZipFileRO.cpp
index b18c383aeeaf..d880f550cb5d 100644
--- a/libs/utils/ZipFileRO.cpp
+++ b/libs/utils/ZipFileRO.cpp
@@ -222,7 +222,7 @@ bool ZipFileRO::mapCentralDirectory(void)
free(scanBuf);
return false;
} else if (header != kLFHSignature) {
- LOGV("Not a Zip archive (found 0x%08x)\n", header);
+ ALOGV("Not a Zip archive (found 0x%08x)\n", header);
free(scanBuf);
return false;
}
@@ -264,7 +264,7 @@ bool ZipFileRO::mapCentralDirectory(void)
int i;
for (i = readAmount - kEOCDLen; i >= 0; i--) {
if (scanBuf[i] == 0x50 && get4LE(&scanBuf[i]) == kEOCDSignature) {
- LOGV("+++ Found EOCD at buf+%d\n", i);
+ ALOGV("+++ Found EOCD at buf+%d\n", i);
break;
}
}
@@ -299,7 +299,7 @@ bool ZipFileRO::mapCentralDirectory(void)
return false;
}
- LOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
+ ALOGV("+++ numEntries=%d dirSize=%d dirOffset=%d\n",
numEntries, dirSize, dirOffset);
mDirectoryMap = new FileMap();
@@ -372,7 +372,7 @@ bool ZipFileRO::parseZipArchive(void)
goto bail;
}
}
- LOGV("+++ zip good scan %d entries\n", numEntries);
+ ALOGV("+++ zip good scan %d entries\n", numEntries);
result = true;
bail:
diff --git a/libs/utils/ZipUtils.cpp b/libs/utils/ZipUtils.cpp
index 9138878ff776..76725b4e2ad4 100644
--- a/libs/utils/ZipUtils.cpp
+++ b/libs/utils/ZipUtils.cpp
@@ -95,7 +95,7 @@ using namespace android;
if (zstream.avail_in == 0) {
getSize = (compRemaining > kReadBufSize) ?
kReadBufSize : compRemaining;
- LOGV("+++ reading %ld bytes (%ld left)\n",
+ ALOGV("+++ reading %ld bytes (%ld left)\n",
getSize, compRemaining);
int cc = read(fd, readBuf, getSize);
@@ -207,7 +207,7 @@ bail:
if (zstream.avail_in == 0) {
getSize = (compRemaining > kReadBufSize) ?
kReadBufSize : compRemaining;
- LOGV("+++ reading %ld bytes (%ld left)\n",
+ ALOGV("+++ reading %ld bytes (%ld left)\n",
getSize, compRemaining);
int cc = fread(readBuf, 1, getSize, fp);
diff --git a/libs/utils/primes.py b/libs/utils/primes.py
new file mode 100755
index 000000000000..e161dd801ed9
--- /dev/null
+++ b/libs/utils/primes.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python2.6
+#
+# 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.
+#
+
+#
+# Generates a table of prime numbers for use in BasicHashtable.cpp.
+#
+# Each prime is chosen such that it is a little more than twice as large as
+# the previous prime in the table. This makes it easier to choose a new
+# hashtable size when the underlying array is grown by as nominal factor
+# of two each time.
+#
+
+def is_odd_prime(n):
+ limit = (n - 1) / 2
+ d = 3
+ while d <= limit:
+ if n % d == 0:
+ return False
+ d += 2
+ return True
+
+print "static size_t PRIMES[] = {"
+
+n = 5
+max = 2**31 - 1
+while n < max:
+ print " %d," % (n)
+ n = n * 2 + 1
+ while not is_odd_prime(n):
+ n += 2
+
+print " 0,"
+print "};"
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
index b97f52f5b892..58230f429ed0 100644
--- a/libs/utils/tests/Android.mk
+++ b/libs/utils/tests/Android.mk
@@ -4,9 +4,10 @@ include $(CLEAR_VARS)
# Build the unit tests.
test_src_files := \
+ BasicHashtable_test.cpp \
BlobCache_test.cpp \
- ObbFile_test.cpp \
Looper_test.cpp \
+ ObbFile_test.cpp \
String8_test.cpp \
Unicode_test.cpp \
ZipFileRO_test.cpp \
diff --git a/libs/utils/tests/BasicHashtable_test.cpp b/libs/utils/tests/BasicHashtable_test.cpp
new file mode 100644
index 000000000000..764082dc04e1
--- /dev/null
+++ b/libs/utils/tests/BasicHashtable_test.cpp
@@ -0,0 +1,577 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "BasicHashtable_test"
+
+#include <utils/BasicHashtable.h>
+#include <cutils/log.h>
+#include <gtest/gtest.h>
+#include <unistd.h>
+
+namespace android {
+
+typedef int SimpleKey;
+typedef int SimpleValue;
+typedef key_value_pair_t<SimpleKey, SimpleValue> SimpleEntry;
+typedef BasicHashtable<SimpleKey, SimpleEntry> SimpleHashtable;
+
+struct ComplexKey {
+ int k;
+
+ explicit ComplexKey(int k) : k(k) {
+ instanceCount += 1;
+ }
+
+ ComplexKey(const ComplexKey& other) : k(other.k) {
+ instanceCount += 1;
+ }
+
+ ~ComplexKey() {
+ instanceCount -= 1;
+ }
+
+ bool operator ==(const ComplexKey& other) const {
+ return k == other.k;
+ }
+
+ bool operator !=(const ComplexKey& other) const {
+ return k != other.k;
+ }
+
+ static ssize_t instanceCount;
+};
+
+ssize_t ComplexKey::instanceCount = 0;
+
+template<> inline hash_t hash_type(const ComplexKey& value) {
+ return hash_type(value.k);
+}
+
+struct ComplexValue {
+ int v;
+
+ explicit ComplexValue(int v) : v(v) {
+ instanceCount += 1;
+ }
+
+ ComplexValue(const ComplexValue& other) : v(other.v) {
+ instanceCount += 1;
+ }
+
+ ~ComplexValue() {
+ instanceCount -= 1;
+ }
+
+ static ssize_t instanceCount;
+};
+
+ssize_t ComplexValue::instanceCount = 0;
+
+typedef key_value_pair_t<ComplexKey, ComplexValue> ComplexEntry;
+typedef BasicHashtable<ComplexKey, ComplexEntry> ComplexHashtable;
+
+class BasicHashtableTest : public testing::Test {
+protected:
+ virtual void SetUp() {
+ ComplexKey::instanceCount = 0;
+ ComplexValue::instanceCount = 0;
+ }
+
+ virtual void TearDown() {
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+ }
+
+ void assertInstanceCount(ssize_t keys, ssize_t values) {
+ if (keys != ComplexKey::instanceCount || values != ComplexValue::instanceCount) {
+ FAIL() << "Expected " << keys << " keys and " << values << " values "
+ "but there were actually " << ComplexKey::instanceCount << " keys and "
+ << ComplexValue::instanceCount << " values";
+ }
+ }
+
+public:
+ template <typename TKey, typename TEntry>
+ static void cookieAt(const BasicHashtable<TKey, TEntry>& h, size_t index,
+ bool* collision, bool* present, hash_t* hash) {
+ uint32_t cookie = h.cookieAt(index);
+ *collision = cookie & BasicHashtable<TKey, TEntry>::Bucket::COLLISION;
+ *present = cookie & BasicHashtable<TKey, TEntry>::Bucket::PRESENT;
+ *hash = cookie & BasicHashtable<TKey, TEntry>::Bucket::HASH_MASK;
+ }
+
+ template <typename TKey, typename TEntry>
+ static const void* getBuckets(const BasicHashtable<TKey, TEntry>& h) {
+ return h.mBuckets;
+ }
+};
+
+template <typename TKey, typename TValue>
+static size_t add(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h,
+ const TKey& key, const TValue& value) {
+ return h.add(hash_type(key), key_value_pair_t<TKey, TValue>(key, value));
+}
+
+template <typename TKey, typename TValue>
+static ssize_t find(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h,
+ ssize_t index, const TKey& key) {
+ return h.find(index, hash_type(key), key);
+}
+
+template <typename TKey, typename TValue>
+static bool remove(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h,
+ const TKey& key) {
+ ssize_t index = find(h, -1, key);
+ if (index >= 0) {
+ h.removeAt(index);
+ return true;
+ }
+ return false;
+}
+
+template <typename TEntry>
+static void getKeyValue(const TEntry& entry, int* key, int* value);
+
+template <> void getKeyValue(const SimpleEntry& entry, int* key, int* value) {
+ *key = entry.key;
+ *value = entry.value;
+}
+
+template <> void getKeyValue(const ComplexEntry& entry, int* key, int* value) {
+ *key = entry.key.k;
+ *value = entry.value.v;
+}
+
+template <typename TKey, typename TValue>
+static void dump(BasicHashtable<TKey, key_value_pair_t<TKey, TValue> >& h) {
+ LOGD("hashtable %p, size=%u, capacity=%u, bucketCount=%u",
+ &h, h.size(), h.capacity(), h.bucketCount());
+ for (size_t i = 0; i < h.bucketCount(); i++) {
+ bool collision, present;
+ hash_t hash;
+ BasicHashtableTest::cookieAt(h, i, &collision, &present, &hash);
+ if (present) {
+ int key, value;
+ getKeyValue(h.entryAt(i), &key, &value);
+ LOGD(" [%3u] = collision=%d, present=%d, hash=0x%08x, key=%3d, value=%3d, "
+ "hash_type(key)=0x%08x",
+ i, collision, present, hash, key, value, hash_type(key));
+ } else {
+ LOGD(" [%3u] = collision=%d, present=%d",
+ i, collision, present);
+ }
+ }
+}
+
+TEST_F(BasicHashtableTest, DefaultConstructor_WithDefaultProperties) {
+ SimpleHashtable h;
+
+ EXPECT_EQ(0U, h.size());
+ EXPECT_EQ(3U, h.capacity());
+ EXPECT_EQ(5U, h.bucketCount());
+ EXPECT_EQ(0.75f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Constructor_WithNonUnityLoadFactor) {
+ SimpleHashtable h(52, 0.8f);
+
+ EXPECT_EQ(0U, h.size());
+ EXPECT_EQ(77U, h.capacity());
+ EXPECT_EQ(97U, h.bucketCount());
+ EXPECT_EQ(0.8f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Constructor_WithUnityLoadFactorAndExactCapacity) {
+ SimpleHashtable h(46, 1.0f);
+
+ EXPECT_EQ(0U, h.size());
+ EXPECT_EQ(46U, h.capacity()); // must be one less than bucketCount because loadFactor == 1.0f
+ EXPECT_EQ(47U, h.bucketCount());
+ EXPECT_EQ(1.0f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Constructor_WithUnityLoadFactorAndInexactCapacity) {
+ SimpleHashtable h(42, 1.0f);
+
+ EXPECT_EQ(0U, h.size());
+ EXPECT_EQ(46U, h.capacity()); // must be one less than bucketCount because loadFactor == 1.0f
+ EXPECT_EQ(47U, h.bucketCount());
+ EXPECT_EQ(1.0f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, FindAddFindRemoveFind_OneEntry) {
+ SimpleHashtable h;
+ ssize_t index = find(h, -1, 8);
+ ASSERT_EQ(-1, index);
+
+ index = add(h, 8, 1);
+ ASSERT_EQ(1U, h.size());
+
+ ASSERT_EQ(index, find(h, -1, 8));
+ ASSERT_EQ(8, h.entryAt(index).key);
+ ASSERT_EQ(1, h.entryAt(index).value);
+
+ index = find(h, index, 8);
+ ASSERT_EQ(-1, index);
+
+ ASSERT_TRUE(remove(h, 8));
+ ASSERT_EQ(0U, h.size());
+
+ index = find(h, -1, 8);
+ ASSERT_EQ(-1, index);
+}
+
+TEST_F(BasicHashtableTest, FindAddFindRemoveFind_MultipleEntryWithUniqueKey) {
+ const size_t N = 11;
+
+ SimpleHashtable h;
+ for (size_t i = 0; i < N; i++) {
+ ssize_t index = find(h, -1, int(i));
+ ASSERT_EQ(-1, index);
+
+ index = add(h, int(i), int(i * 10));
+ ASSERT_EQ(i + 1, h.size());
+
+ ASSERT_EQ(index, find(h, -1, int(i)));
+ ASSERT_EQ(int(i), h.entryAt(index).key);
+ ASSERT_EQ(int(i * 10), h.entryAt(index).value);
+
+ index = find(h, index, int(i));
+ ASSERT_EQ(-1, index);
+ }
+
+ for (size_t i = N; --i > 0; ) {
+ ASSERT_TRUE(remove(h, int(i))) << "i = " << i;
+ ASSERT_EQ(i, h.size());
+
+ ssize_t index = find(h, -1, int(i));
+ ASSERT_EQ(-1, index);
+ }
+}
+
+TEST_F(BasicHashtableTest, FindAddFindRemoveFind_MultipleEntryWithDuplicateKey) {
+ const size_t N = 11;
+ const int K = 1;
+
+ SimpleHashtable h;
+ for (size_t i = 0; i < N; i++) {
+ ssize_t index = find(h, -1, K);
+ if (i == 0) {
+ ASSERT_EQ(-1, index);
+ } else {
+ ASSERT_NE(-1, index);
+ }
+
+ add(h, K, int(i));
+ ASSERT_EQ(i + 1, h.size());
+
+ index = -1;
+ int values = 0;
+ for (size_t j = 0; j <= i; j++) {
+ index = find(h, index, K);
+ ASSERT_GE(index, 0);
+ ASSERT_EQ(K, h.entryAt(index).key);
+ values |= 1 << h.entryAt(index).value;
+ }
+ ASSERT_EQ(values, (1 << (i + 1)) - 1);
+
+ index = find(h, index, K);
+ ASSERT_EQ(-1, index);
+ }
+
+ for (size_t i = N; --i > 0; ) {
+ ASSERT_TRUE(remove(h, K)) << "i = " << i;
+ ASSERT_EQ(i, h.size());
+
+ ssize_t index = -1;
+ for (size_t j = 0; j < i; j++) {
+ index = find(h, index, K);
+ ASSERT_GE(index, 0);
+ ASSERT_EQ(K, h.entryAt(index).key);
+ }
+
+ index = find(h, index, K);
+ ASSERT_EQ(-1, index);
+ }
+}
+
+TEST_F(BasicHashtableTest, Clear_WhenAlreadyEmpty_DoesNothing) {
+ SimpleHashtable h;
+ h.clear();
+
+ EXPECT_EQ(0U, h.size());
+ EXPECT_EQ(3U, h.capacity());
+ EXPECT_EQ(5U, h.bucketCount());
+ EXPECT_EQ(0.75f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Clear_AfterElementsAdded_RemovesThem) {
+ SimpleHashtable h;
+ add(h, 0, 0);
+ add(h, 1, 0);
+ h.clear();
+
+ EXPECT_EQ(0U, h.size());
+ EXPECT_EQ(3U, h.capacity());
+ EXPECT_EQ(5U, h.bucketCount());
+ EXPECT_EQ(0.75f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Clear_AfterElementsAdded_DestroysThem) {
+ ComplexHashtable h;
+ add(h, ComplexKey(0), ComplexValue(0));
+ add(h, ComplexKey(1), ComplexValue(0));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+
+ h.clear();
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+
+ EXPECT_EQ(0U, h.size());
+ EXPECT_EQ(3U, h.capacity());
+ EXPECT_EQ(5U, h.bucketCount());
+ EXPECT_EQ(0.75f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Remove_AfterElementsAdded_DestroysThem) {
+ ComplexHashtable h;
+ add(h, ComplexKey(0), ComplexValue(0));
+ add(h, ComplexKey(1), ComplexValue(0));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+
+ ASSERT_TRUE(remove(h, ComplexKey(0)));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1));
+
+ ASSERT_TRUE(remove(h, ComplexKey(1)));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+
+ EXPECT_EQ(0U, h.size());
+ EXPECT_EQ(3U, h.capacity());
+ EXPECT_EQ(5U, h.bucketCount());
+ EXPECT_EQ(0.75f, h.loadFactor());
+}
+
+TEST_F(BasicHashtableTest, Destructor_AfterElementsAdded_DestroysThem) {
+ {
+ ComplexHashtable h;
+ add(h, ComplexKey(0), ComplexValue(0));
+ add(h, ComplexKey(1), ComplexValue(0));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+ } // h is destroyed here
+
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+}
+
+TEST_F(BasicHashtableTest, Next_WhenEmpty_ReturnsMinusOne) {
+ SimpleHashtable h;
+
+ ASSERT_EQ(-1, h.next(-1));
+}
+
+TEST_F(BasicHashtableTest, Next_WhenNonEmpty_IteratesOverAllEntries) {
+ const int N = 88;
+
+ SimpleHashtable h;
+ for (int i = 0; i < N; i++) {
+ add(h, i, i * 10);
+ }
+
+ bool set[N];
+ memset(set, 0, sizeof(bool) * N);
+ int count = 0;
+ for (ssize_t index = -1; (index = h.next(index)) != -1; ) {
+ ASSERT_GE(index, 0);
+ ASSERT_LT(size_t(index), h.bucketCount());
+
+ const SimpleEntry& entry = h.entryAt(index);
+ ASSERT_GE(entry.key, 0);
+ ASSERT_LT(entry.key, N);
+ ASSERT_EQ(false, set[entry.key]);
+ ASSERT_EQ(entry.key * 10, entry.value);
+
+ set[entry.key] = true;
+ count += 1;
+ }
+ ASSERT_EQ(N, count);
+}
+
+TEST_F(BasicHashtableTest, Add_RehashesOnDemand) {
+ SimpleHashtable h;
+ size_t initialCapacity = h.capacity();
+ size_t initialBucketCount = h.bucketCount();
+
+ for (size_t i = 0; i < initialCapacity; i++) {
+ add(h, int(i), 0);
+ }
+
+ EXPECT_EQ(initialCapacity, h.size());
+ EXPECT_EQ(initialCapacity, h.capacity());
+ EXPECT_EQ(initialBucketCount, h.bucketCount());
+
+ add(h, -1, -1);
+
+ EXPECT_EQ(initialCapacity + 1, h.size());
+ EXPECT_GT(h.capacity(), initialCapacity);
+ EXPECT_GT(h.bucketCount(), initialBucketCount);
+ EXPECT_GT(h.bucketCount(), h.capacity());
+}
+
+TEST_F(BasicHashtableTest, Rehash_WhenCapacityAndBucketCountUnchanged_DoesNothing) {
+ ComplexHashtable h;
+ add(h, ComplexKey(0), ComplexValue(0));
+ const void* oldBuckets = getBuckets(h);
+ ASSERT_NE((void*)NULL, oldBuckets);
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1));
+
+ h.rehash(h.capacity(), h.loadFactor());
+
+ ASSERT_EQ(oldBuckets, getBuckets(h));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(1, 1));
+}
+
+TEST_F(BasicHashtableTest, Rehash_WhenEmptyAndHasNoBuckets_ButDoesNotAllocateBuckets) {
+ ComplexHashtable h;
+ ASSERT_EQ((void*)NULL, getBuckets(h));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+
+ h.rehash(9, 1.0f);
+
+ EXPECT_EQ(0U, h.size());
+ EXPECT_EQ(10U, h.capacity());
+ EXPECT_EQ(11U, h.bucketCount());
+ EXPECT_EQ(1.0f, h.loadFactor());
+ EXPECT_EQ((void*)NULL, getBuckets(h));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+}
+
+TEST_F(BasicHashtableTest, Rehash_WhenEmptyAndHasBuckets_ReleasesBucketsAndSetsCapacity) {
+ ComplexHashtable h(10);
+ add(h, ComplexKey(0), ComplexValue(0));
+ ASSERT_TRUE(remove(h, ComplexKey(0)));
+ ASSERT_NE((void*)NULL, getBuckets(h));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+
+ h.rehash(0, 0.75f);
+
+ EXPECT_EQ(0U, h.size());
+ EXPECT_EQ(3U, h.capacity());
+ EXPECT_EQ(5U, h.bucketCount());
+ EXPECT_EQ(0.75f, h.loadFactor());
+ EXPECT_EQ((void*)NULL, getBuckets(h));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(0, 0));
+}
+
+TEST_F(BasicHashtableTest, Rehash_WhenLessThanCurrentCapacity_ShrinksBuckets) {
+ ComplexHashtable h(10);
+ add(h, ComplexKey(0), ComplexValue(0));
+ add(h, ComplexKey(1), ComplexValue(1));
+ const void* oldBuckets = getBuckets(h);
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+
+ h.rehash(0, 0.75f);
+
+ EXPECT_EQ(2U, h.size());
+ EXPECT_EQ(3U, h.capacity());
+ EXPECT_EQ(5U, h.bucketCount());
+ EXPECT_EQ(0.75f, h.loadFactor());
+ EXPECT_NE(oldBuckets, getBuckets(h));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+}
+
+TEST_F(BasicHashtableTest, CopyOnWrite) {
+ ComplexHashtable h1;
+ add(h1, ComplexKey(0), ComplexValue(0));
+ add(h1, ComplexKey(1), ComplexValue(1));
+ const void* originalBuckets = getBuckets(h1);
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+ ssize_t index0 = find(h1, -1, ComplexKey(0));
+ EXPECT_GE(index0, 0);
+
+ // copy constructor acquires shared reference
+ ComplexHashtable h2(h1);
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+ ASSERT_EQ(originalBuckets, getBuckets(h2));
+ EXPECT_EQ(h1.size(), h2.size());
+ EXPECT_EQ(h1.capacity(), h2.capacity());
+ EXPECT_EQ(h1.bucketCount(), h2.bucketCount());
+ EXPECT_EQ(h1.loadFactor(), h2.loadFactor());
+ EXPECT_EQ(index0, find(h2, -1, ComplexKey(0)));
+
+ // operator= acquires shared reference
+ ComplexHashtable h3;
+ h3 = h2;
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+ ASSERT_EQ(originalBuckets, getBuckets(h3));
+ EXPECT_EQ(h1.size(), h3.size());
+ EXPECT_EQ(h1.capacity(), h3.capacity());
+ EXPECT_EQ(h1.bucketCount(), h3.bucketCount());
+ EXPECT_EQ(h1.loadFactor(), h3.loadFactor());
+ EXPECT_EQ(index0, find(h3, -1, ComplexKey(0)));
+
+ // editEntryAt copies shared contents
+ h1.editEntryAt(index0).value.v = 42;
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4));
+ ASSERT_NE(originalBuckets, getBuckets(h1));
+ EXPECT_EQ(42, h1.entryAt(index0).value.v);
+ EXPECT_EQ(0, h2.entryAt(index0).value.v);
+ EXPECT_EQ(0, h3.entryAt(index0).value.v);
+
+ // clear releases reference to shared contents
+ h2.clear();
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4));
+ EXPECT_EQ(0U, h2.size());
+ ASSERT_NE(originalBuckets, getBuckets(h2));
+
+ // operator= acquires shared reference, destroys unshared contents
+ h1 = h3;
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+ ASSERT_EQ(originalBuckets, getBuckets(h1));
+ EXPECT_EQ(h3.size(), h1.size());
+ EXPECT_EQ(h3.capacity(), h1.capacity());
+ EXPECT_EQ(h3.bucketCount(), h1.bucketCount());
+ EXPECT_EQ(h3.loadFactor(), h1.loadFactor());
+ EXPECT_EQ(index0, find(h1, -1, ComplexKey(0)));
+
+ // add copies shared contents
+ add(h1, ComplexKey(2), ComplexValue(2));
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(5, 5));
+ ASSERT_NE(originalBuckets, getBuckets(h1));
+ EXPECT_EQ(3U, h1.size());
+ EXPECT_EQ(0U, h2.size());
+ EXPECT_EQ(2U, h3.size());
+
+ // remove copies shared contents
+ h1 = h3;
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+ ASSERT_EQ(originalBuckets, getBuckets(h1));
+ h1.removeAt(index0);
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(3, 3));
+ ASSERT_NE(originalBuckets, getBuckets(h1));
+ EXPECT_EQ(1U, h1.size());
+ EXPECT_EQ(0U, h2.size());
+ EXPECT_EQ(2U, h3.size());
+
+ // rehash copies shared contents
+ h1 = h3;
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(2, 2));
+ ASSERT_EQ(originalBuckets, getBuckets(h1));
+ h1.rehash(10, 1.0f);
+ ASSERT_NO_FATAL_FAILURE(assertInstanceCount(4, 4));
+ ASSERT_NE(originalBuckets, getBuckets(h1));
+ EXPECT_EQ(2U, h1.size());
+ EXPECT_EQ(0U, h2.size());
+ EXPECT_EQ(2U, h3.size());
+}
+
+} // namespace android