summaryrefslogtreecommitdiffstats
path: root/libs
diff options
context:
space:
mode:
Diffstat (limited to 'libs')
-rw-r--r--libs/binder/AppOpsManager.cpp2
-rw-r--r--libs/binder/Binder.cpp12
-rw-r--r--libs/binder/BpBinder.cpp1
-rw-r--r--libs/binder/Debug.cpp5
-rw-r--r--libs/binder/IAppOpsService.cpp4
-rw-r--r--libs/binder/IInterface.cpp12
-rw-r--r--libs/binder/IMemory.cpp13
-rw-r--r--libs/binder/IPCThreadState.cpp66
-rw-r--r--libs/binder/IServiceManager.cpp2
-rw-r--r--libs/binder/Parcel.cpp19
-rw-r--r--libs/binder/tests/Android.mk34
-rw-r--r--libs/binder/tests/binderDriverInterfaceTest.cpp353
-rw-r--r--libs/binder/tests/binderLibTest.cpp954
-rw-r--r--libs/diskusage/dirsize.c1
-rw-r--r--libs/gui/Android.mk41
-rw-r--r--libs/gui/BitTube.cpp8
-rw-r--r--libs/gui/BufferItem.cpp144
-rw-r--r--libs/gui/BufferItemConsumer.cpp24
-rw-r--r--libs/gui/BufferQueue.cpp2
-rw-r--r--libs/gui/BufferQueueConsumer.cpp39
-rw-r--r--libs/gui/BufferQueueCore.cpp64
-rw-r--r--libs/gui/BufferQueueProducer.cpp202
-rw-r--r--libs/gui/BufferSlot.cpp2
-rw-r--r--libs/gui/ConsumerBase.cpp28
-rw-r--r--libs/gui/CpuConsumer.cpp52
-rw-r--r--libs/gui/GLConsumer.cpp221
-rw-r--r--libs/gui/GraphicBufferAlloc.cpp9
-rw-r--r--libs/gui/IConsumerListener.cpp6
-rw-r--r--libs/gui/IDisplayEventConnection.cpp16
-rw-r--r--libs/gui/IGraphicBufferAlloc.cpp44
-rw-r--r--libs/gui/IGraphicBufferConsumer.cpp252
-rw-r--r--libs/gui/IGraphicBufferProducer.cpp116
-rw-r--r--libs/gui/IProducerListener.cpp6
-rw-r--r--libs/gui/ISensorEventConnection.cpp16
-rw-r--r--libs/gui/ISensorServer.cpp18
-rw-r--r--libs/gui/ISurfaceComposer.cpp82
-rw-r--r--libs/gui/ISurfaceComposerClient.cpp40
-rw-r--r--libs/gui/LayerState.cpp52
-rw-r--r--libs/gui/Sensor.cpp19
-rw-r--r--libs/gui/SensorEventQueue.cpp13
-rw-r--r--libs/gui/SensorManager.cpp9
-rw-r--r--libs/gui/StreamSplitter.cpp8
-rw-r--r--libs/gui/Surface.cpp263
-rw-r--r--libs/gui/SurfaceComposerClient.cpp20
-rw-r--r--libs/gui/SurfaceControl.cpp6
-rw-r--r--libs/gui/SyncFeatures.cpp4
-rw-r--r--libs/gui/tests/Android.mk10
-rw-r--r--libs/gui/tests/BufferQueue_test.cpp84
-rw-r--r--libs/gui/tests/CpuConsumer_test.cpp37
-rw-r--r--libs/gui/tests/IGraphicBufferProducer_test.cpp56
-rw-r--r--libs/gui/tests/SRGB_test.cpp30
-rw-r--r--libs/gui/tests/StreamSplitter_test.cpp18
-rw-r--r--libs/gui/tests/SurfaceTextureClient_test.cpp38
-rw-r--r--libs/gui/tests/SurfaceTextureFBO_test.cpp6
-rw-r--r--libs/gui/tests/SurfaceTextureGL_test.cpp36
-rw-r--r--libs/gui/tests/Surface_test.cpp22
-rw-r--r--libs/input/tests/Android.mk8
-rw-r--r--libs/ui/Android.mk24
-rw-r--r--libs/ui/Fence.cpp19
-rw-r--r--libs/ui/FramebufferNativeWindow.cpp130
-rw-r--r--libs/ui/GraphicBuffer.cpp172
-rw-r--r--libs/ui/GraphicBufferAllocator.cpp61
-rw-r--r--libs/ui/GraphicBufferMapper.cpp33
-rw-r--r--libs/ui/PixelFormat.cpp12
-rw-r--r--libs/ui/Rect.cpp2
-rw-r--r--libs/ui/Region.cpp274
-rw-r--r--libs/ui/UiConfig.cpp3
-rw-r--r--libs/ui/tests/Android.mk59
-rw-r--r--libs/ui/tests/vec_test.cpp7
69 files changed, 3169 insertions, 1276 deletions
diff --git a/libs/binder/AppOpsManager.cpp b/libs/binder/AppOpsManager.cpp
index 61b4f7d..c562c30 100644
--- a/libs/binder/AppOpsManager.cpp
+++ b/libs/binder/AppOpsManager.cpp
@@ -44,7 +44,7 @@ sp<IAppOpsService> AppOpsManager::getService()
int64_t startTime = 0;
mLock.lock();
sp<IAppOpsService> service = mService;
- while (service == NULL || !service->asBinder()->isBinderAlive()) {
+ while (service == NULL || !IInterface::asBinder(service)->isBinderAlive()) {
sp<IBinder> binder = defaultServiceManager()->checkService(_appops);
if (binder == NULL) {
// Wait for the app ops service to come back...
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index 2554351..9d200fb 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -72,7 +72,7 @@ public:
BBinder::BBinder()
{
- atomic_init(&mExtras, 0);
+ atomic_init(&mExtras, static_cast<uintptr_t>(0));
}
bool BBinder::isBinderAlive() const
@@ -160,10 +160,18 @@ void BBinder::attachObject(
e->mObjects.attach(objectID, object, cleanupCookie, func);
}
+// The C11 standard doesn't allow atomic loads from const fields,
+// though C++11 does. Fudge it until standards get straightened out.
+static inline uintptr_t load_const_atomic(const atomic_uintptr_t* p,
+ memory_order mo) {
+ atomic_uintptr_t* non_const_p = const_cast<atomic_uintptr_t*>(p);
+ return atomic_load_explicit(non_const_p, mo);
+}
+
void* BBinder::findObject(const void* objectID) const
{
Extras* e = reinterpret_cast<Extras*>(
- atomic_load_explicit(&mExtras, memory_order_acquire));
+ load_const_atomic(&mExtras, memory_order_acquire));
if (!e) return NULL;
AutoMutex _l(e->mLock);
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 101de7e..345ba20 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -220,7 +220,6 @@ status_t BpBinder::unlinkToDeath(
if ((obit.recipient == recipient
|| (recipient == NULL && obit.cookie == cookie))
&& obit.flags == flags) {
- const uint32_t allFlags = obit.flags|flags;
if (outRecipient != NULL) {
*outRecipient = mObituaries->itemAt(i).recipient;
}
diff --git a/libs/binder/Debug.cpp b/libs/binder/Debug.cpp
index 0ffafbb..bdb7182 100644
--- a/libs/binder/Debug.cpp
+++ b/libs/binder/Debug.cpp
@@ -220,13 +220,8 @@ void printHexData(int32_t indent, const void *buf, size_t length,
for (word = 0; word < bytesPerLine; ) {
-#ifdef HAVE_LITTLE_ENDIAN
const size_t startIndex = word+(alignment-(alignment?1:0));
const ssize_t dir = -1;
-#else
- const size_t startIndex = word;
- const ssize_t dir = 1;
-#endif
for (index = 0; index < alignment || (alignment == 0 && index < bytesPerLine); index++) {
diff --git a/libs/binder/IAppOpsService.cpp b/libs/binder/IAppOpsService.cpp
index f58a352..86abdc0 100644
--- a/libs/binder/IAppOpsService.cpp
+++ b/libs/binder/IAppOpsService.cpp
@@ -91,14 +91,14 @@ public:
data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
data.writeInt32(op);
data.writeString16(packageName);
- data.writeStrongBinder(callback->asBinder());
+ data.writeStrongBinder(IInterface::asBinder(callback));
remote()->transact(START_WATCHING_MODE_TRANSACTION, data, &reply);
}
virtual void stopWatchingMode(const sp<IAppOpsCallback>& callback) {
Parcel data, reply;
data.writeInterfaceToken(IAppOpsService::getInterfaceDescriptor());
- data.writeStrongBinder(callback->asBinder());
+ data.writeStrongBinder(IInterface::asBinder(callback));
remote()->transact(STOP_WATCHING_MODE_TRANSACTION, data, &reply);
}
diff --git a/libs/binder/IInterface.cpp b/libs/binder/IInterface.cpp
index 29acf5d..8c60dc4 100644
--- a/libs/binder/IInterface.cpp
+++ b/libs/binder/IInterface.cpp
@@ -27,14 +27,18 @@ IInterface::IInterface()
IInterface::~IInterface() {
}
-sp<IBinder> IInterface::asBinder()
+// static
+sp<IBinder> IInterface::asBinder(const IInterface* iface)
{
- return this ? onAsBinder() : NULL;
+ if (iface == NULL) return NULL;
+ return const_cast<IInterface*>(iface)->onAsBinder();
}
-sp<const IBinder> IInterface::asBinder() const
+// static
+sp<IBinder> IInterface::asBinder(const sp<IInterface>& iface)
{
- return this ? const_cast<IInterface*>(this)->onAsBinder() : NULL;
+ if (iface == NULL) return NULL;
+ return iface->onAsBinder();
}
// ---------------------------------------------------------------------------
diff --git a/libs/binder/IMemory.cpp b/libs/binder/IMemory.cpp
index d8ed995..e9891a8 100644
--- a/libs/binder/IMemory.cpp
+++ b/libs/binder/IMemory.cpp
@@ -216,7 +216,7 @@ status_t BnMemory::onTransact(
CHECK_INTERFACE(IMemory, data, reply);
ssize_t offset;
size_t size;
- reply->writeStrongBinder( getMemory(&offset, &size)->asBinder() );
+ reply->writeStrongBinder( IInterface::asBinder(getMemory(&offset, &size)) );
reply->writeInt32(offset);
reply->writeInt32(size);
return NO_ERROR;
@@ -241,7 +241,7 @@ BpMemoryHeap::~BpMemoryHeap() {
if (mRealHeap) {
// by construction we're the last one
if (mBase != MAP_FAILED) {
- sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
+ sp<IBinder> binder = IInterface::asBinder(this);
if (VERBOSE) {
ALOGD("UNMAPPING binder=%p, heap=%p, size=%zu, fd=%d",
@@ -253,7 +253,7 @@ BpMemoryHeap::~BpMemoryHeap() {
}
} else {
// remove from list only if it was mapped before
- sp<IBinder> binder = const_cast<BpMemoryHeap*>(this)->asBinder();
+ sp<IBinder> binder = IInterface::asBinder(this);
free_heap(binder);
}
}
@@ -262,7 +262,7 @@ BpMemoryHeap::~BpMemoryHeap() {
void BpMemoryHeap::assertMapped() const
{
if (mHeapId == -1) {
- sp<IBinder> binder(const_cast<BpMemoryHeap*>(this)->asBinder());
+ sp<IBinder> binder(IInterface::asBinder(const_cast<BpMemoryHeap*>(this)));
sp<BpMemoryHeap> heap(static_cast<BpMemoryHeap*>(find_heap(binder).get()));
heap->assertReallyMapped();
if (heap->mBase != MAP_FAILED) {
@@ -297,7 +297,8 @@ void BpMemoryHeap::assertReallyMapped() const
uint32_t offset = reply.readInt32();
ALOGE_IF(err, "binder=%p transaction failed fd=%d, size=%zd, err=%d (%s)",
- asBinder().get(), parcel_fd, size, err, strerror(-err));
+ IInterface::asBinder(this).get(),
+ parcel_fd, size, err, strerror(-err));
int fd = dup( parcel_fd );
ALOGE_IF(fd==-1, "cannot dup fd=%d, size=%zd, err=%d (%s)",
@@ -314,7 +315,7 @@ void BpMemoryHeap::assertReallyMapped() const
mBase = mmap(0, size, access, MAP_SHARED, fd, offset);
if (mBase == MAP_FAILED) {
ALOGE("cannot map BpMemoryHeap (binder=%p), size=%zd, fd=%d (%s)",
- asBinder().get(), size, fd, strerror(errno));
+ IInterface::asBinder(this).get(), size, fd, strerror(errno));
close(fd);
} else {
mSize = size;
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index dd04dcf..9f68aa8 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -29,21 +29,14 @@
#include <private/binder/binder_module.h>
#include <private/binder/Static.h>
-#include <sys/ioctl.h>
-#include <signal.h>
#include <errno.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#ifdef HAVE_PTHREADS
#include <pthread.h>
#include <sched.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/ioctl.h>
#include <sys/resource.h>
-#endif
-#ifdef HAVE_WIN32_THREADS
-#include <windows.h>
-#endif
-
+#include <unistd.h>
#if LOG_NDEBUG
@@ -70,13 +63,11 @@
namespace android {
static const char* getReturnString(size_t idx);
-static const char* getCommandString(size_t idx);
static const void* printReturnCommand(TextOutput& out, const void* _cmd);
static const void* printCommand(TextOutput& out, const void* _cmd);
-// This will result in a missing symbol failure if the IF_LOG_COMMANDS()
-// conditionals don't get stripped... but that is probably what we want.
-#if !LOG_NDEBUG
+// Static const and functions will be optimized out if not used,
+// when LOG_NDEBUG and references in IF_LOG_COMMANDS() are optimized out.
static const char *kReturnStrings[] = {
"BR_ERROR",
"BR_OK",
@@ -126,14 +117,6 @@ static const char* getReturnString(size_t idx)
return "unknown";
}
-static const char* getCommandString(size_t idx)
-{
- if (idx < sizeof(kCommandStrings) / sizeof(kCommandStrings[0]))
- return kCommandStrings[idx];
- else
- return "unknown";
-}
-
static const void* printBinderTransactionData(TextOutput& out, const void* data)
{
const binder_transaction_data* btd =
@@ -145,7 +128,7 @@ static const void* printBinderTransactionData(TextOutput& out, const void* data)
out << "target.ptr=" << btd->target.ptr;
}
out << " (cookie " << btd->cookie << ")" << endl
- << "code=" << TypeCode(btd->code) << ", flags=" << (void*)btd->flags << endl
+ << "code=" << TypeCode(btd->code) << ", flags=" << (void*)(long)btd->flags << endl
<< "data=" << btd->data.ptr.buffer << " (" << (void*)btd->data_size
<< " bytes)" << endl
<< "offsets=" << btd->data.ptr.offsets << " (" << (void*)btd->offsets_size
@@ -157,10 +140,10 @@ static const void* printReturnCommand(TextOutput& out, const void* _cmd)
{
static const size_t N = sizeof(kReturnStrings)/sizeof(kReturnStrings[0]);
const int32_t* cmd = (const int32_t*)_cmd;
- int32_t code = *cmd++;
+ uint32_t code = (uint32_t)*cmd++;
size_t cmdIndex = code & 0xff;
- if (code == (int32_t) BR_ERROR) {
- out << "BR_ERROR: " << (void*)(*cmd++) << endl;
+ if (code == BR_ERROR) {
+ out << "BR_ERROR: " << (void*)(long)(*cmd++) << endl;
return cmd;
} else if (cmdIndex >= N) {
out << "Unknown reply: " << code << endl;
@@ -187,21 +170,21 @@ static const void* printReturnCommand(TextOutput& out, const void* _cmd)
case BR_DECREFS: {
const int32_t b = *cmd++;
const int32_t c = *cmd++;
- out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
+ out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
} break;
case BR_ATTEMPT_ACQUIRE: {
const int32_t p = *cmd++;
const int32_t b = *cmd++;
const int32_t c = *cmd++;
- out << ": target=" << (void*)b << " (cookie " << (void*)c
+ out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c
<< "), pri=" << p;
} break;
case BR_DEAD_BINDER:
case BR_CLEAR_DEATH_NOTIFICATION_DONE: {
const int32_t c = *cmd++;
- out << ": death cookie " << (void*)c;
+ out << ": death cookie " << (void*)(long)c;
} break;
default:
@@ -218,7 +201,7 @@ static const void* printCommand(TextOutput& out, const void* _cmd)
{
static const size_t N = sizeof(kCommandStrings)/sizeof(kCommandStrings[0]);
const int32_t* cmd = (const int32_t*)_cmd;
- int32_t code = *cmd++;
+ uint32_t code = (uint32_t)*cmd++;
size_t cmdIndex = code & 0xff;
if (cmdIndex >= N) {
@@ -242,7 +225,7 @@ static const void* printCommand(TextOutput& out, const void* _cmd)
case BC_FREE_BUFFER: {
const int32_t buf = *cmd++;
- out << ": buffer=" << (void*)buf;
+ out << ": buffer=" << (void*)(long)buf;
} break;
case BC_INCREFS:
@@ -257,7 +240,7 @@ static const void* printCommand(TextOutput& out, const void* _cmd)
case BC_ACQUIRE_DONE: {
const int32_t b = *cmd++;
const int32_t c = *cmd++;
- out << ": target=" << (void*)b << " (cookie " << (void*)c << ")";
+ out << ": target=" << (void*)(long)b << " (cookie " << (void*)(long)c << ")";
} break;
case BC_ATTEMPT_ACQUIRE: {
@@ -270,12 +253,12 @@ static const void* printCommand(TextOutput& out, const void* _cmd)
case BC_CLEAR_DEATH_NOTIFICATION: {
const int32_t h = *cmd++;
const int32_t c = *cmd++;
- out << ": handle=" << h << " (death cookie " << (void*)c << ")";
+ out << ": handle=" << h << " (death cookie " << (void*)(long)c << ")";
} break;
case BC_DEAD_BINDER_DONE: {
const int32_t c = *cmd++;
- out << ": death cookie " << (void*)c;
+ out << ": death cookie " << (void*)(long)c;
} break;
default:
@@ -287,7 +270,6 @@ static const void* printCommand(TextOutput& out, const void* _cmd)
out << endl;
return cmd;
}
-#endif
static pthread_mutex_t gTLSMutex = PTHREAD_MUTEX_INITIALIZER;
static bool gHaveTLS = false;
@@ -361,12 +343,12 @@ status_t IPCThreadState::clearLastError()
return err;
}
-int IPCThreadState::getCallingPid() const
+pid_t IPCThreadState::getCallingPid() const
{
return mCallingPid;
}
-int IPCThreadState::getCallingUid() const
+uid_t IPCThreadState::getCallingUid() const
{
return mCallingUid;
}
@@ -682,7 +664,7 @@ status_t IPCThreadState::clearDeathNotification(int32_t handle, BpBinder* proxy)
IPCThreadState::IPCThreadState()
: mProcess(ProcessState::self()),
- mMyThreadId(androidGetTid()),
+ mMyThreadId(gettid()),
mStrictModePolicy(0),
mLastTransactionBinderFlags(0)
{
@@ -708,7 +690,7 @@ status_t IPCThreadState::sendReply(const Parcel& reply, uint32_t flags)
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
- int32_t cmd;
+ uint32_t cmd;
int32_t err;
while (1) {
@@ -717,7 +699,7 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
if (err < NO_ERROR) break;
if (mIn.dataAvail() == 0) continue;
- cmd = mIn.readInt32();
+ cmd = (uint32_t)mIn.readInt32();
IF_LOG_COMMANDS() {
alog << "Processing waitForResponse Command: "
@@ -947,7 +929,7 @@ status_t IPCThreadState::executeCommand(int32_t cmd)
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
- switch (cmd) {
+ switch ((uint32_t)cmd) {
case BR_ERROR:
result = mIn.readInt32();
break;
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 7b1b0e7..3c716df 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -87,7 +87,7 @@ bool checkPermission(const String16& permission, pid_t pid, uid_t uid)
}
// Is this a permission failure, or did the controller go away?
- if (pc->asBinder()->isBinderAlive()) {
+ if (IInterface::asBinder(pc)->isBinderAlive()) {
ALOGW("Permission failure: %s from uid=%d pid=%d",
String8(permission).string(), uid, pid);
return false;
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 87ce5d0..d769caa 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -57,7 +57,7 @@
#define PAD_SIZE(s) (((s)+3)&~3)
// Note: must be kept in sync with android/os/StrictMode.java's PENALTY_GATHER
-#define STRICT_MODE_PENALTY_GATHER 0x100
+#define STRICT_MODE_PENALTY_GATHER (0x40 << 16)
// Note: must be kept in sync with android/os/Parcel.java's EX_HAS_REPLY_HEADER
#define EX_HAS_REPLY_HEADER -128
@@ -645,6 +645,12 @@ status_t Parcel::writeInt32(int32_t val)
{
return writeAligned(val);
}
+
+status_t Parcel::writeUint32(uint32_t val)
+{
+ return writeAligned(val);
+}
+
status_t Parcel::writeInt32Array(size_t len, const int32_t *val) {
if (!val) {
return writeAligned(-1);
@@ -1033,6 +1039,15 @@ int32_t Parcel::readInt32() const
return readAligned<int32_t>();
}
+status_t Parcel::readUint32(uint32_t *pArg) const
+{
+ return readAligned(pArg);
+}
+
+uint32_t Parcel::readUint32() const
+{
+ return readAligned<uint32_t>();
+}
status_t Parcel::readInt64(int64_t *pArg) const
{
@@ -1442,7 +1457,7 @@ void Parcel::ipcSetDataReference(const uint8_t* data, size_t dataSize,
for (size_t i = 0; i < mObjectsSize; i++) {
binder_size_t offset = mObjects[i];
if (offset < minOffset) {
- ALOGE("%s: bad object offset %"PRIu64" < %"PRIu64"\n",
+ ALOGE("%s: bad object offset %" PRIu64 " < %" PRIu64 "\n",
__func__, (uint64_t)offset, (uint64_t)minOffset);
mObjectsSize = 0;
break;
diff --git a/libs/binder/tests/Android.mk b/libs/binder/tests/Android.mk
new file mode 100644
index 0000000..3668729
--- /dev/null
+++ b/libs/binder/tests/Android.mk
@@ -0,0 +1,34 @@
+#
+# Copyright (C) 2014 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.
+#
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+ifneq ($(TARGET_USES_64_BIT_BINDER),true)
+ifneq ($(TARGET_IS_64_BIT),true)
+LOCAL_CFLAGS += -DBINDER_IPC_32BIT=1
+endif
+endif
+
+LOCAL_MODULE := binderDriverInterfaceTest
+LOCAL_SRC_FILES := binderDriverInterfaceTest.cpp
+include $(BUILD_NATIVE_TEST)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := binderLibTest
+LOCAL_SRC_FILES := binderLibTest.cpp
+LOCAL_SHARED_LIBRARIES := libbinder libutils
+include $(BUILD_NATIVE_TEST)
diff --git a/libs/binder/tests/binderDriverInterfaceTest.cpp b/libs/binder/tests/binderDriverInterfaceTest.cpp
new file mode 100644
index 0000000..315f349
--- /dev/null
+++ b/libs/binder/tests/binderDriverInterfaceTest.cpp
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2014 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 <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <gtest/gtest.h>
+#include <linux/binder.h>
+#include <binder/IBinder.h>
+#include <sys/mman.h>
+#include <poll.h>
+
+#define BINDER_DEV_NAME "/dev/binder"
+
+testing::Environment* binder_env;
+
+class BinderDriverInterfaceTestEnv : public ::testing::Environment {
+ virtual void SetUp() {
+ int ret;
+ uint32_t max_threads = 0;
+
+ m_binderFd = open(BINDER_DEV_NAME, O_RDWR | O_NONBLOCK);
+ ASSERT_GE(m_binderFd, 0);
+ m_buffer = mmap(NULL, 64*1024, PROT_READ, MAP_SHARED, m_binderFd, 0);
+ ASSERT_NE(m_buffer, (void *)NULL);
+ ret = ioctl(m_binderFd, BINDER_SET_MAX_THREADS, &max_threads);
+ EXPECT_EQ(0, ret);
+ EnterLooper();
+ }
+ virtual void TearDown() {
+ close(m_binderFd);
+ }
+ private:
+ int m_binderFd;
+ void *m_buffer;
+ public:
+ int getBinderFd(void) {
+ return m_binderFd;
+ }
+ void EnterLooper(void) {
+ int ret;
+ const uint32_t bc[] = {
+ BC_ENTER_LOOPER,
+ };
+ struct binder_write_read bwr = binder_write_read();
+ bwr.write_buffer = (uintptr_t)bc;
+ bwr.write_size = sizeof(bc);
+ ret = ioctl(m_binderFd, BINDER_WRITE_READ, &bwr);
+ EXPECT_EQ(0, ret);
+ if (ret < 0) {
+ EXPECT_EQ(0, errno);
+ }
+ EXPECT_EQ(sizeof(bc), bwr.write_consumed);
+ }
+};
+
+class BinderDriverInterfaceTest : public ::testing::Test {
+ public:
+ virtual void SetUp() {
+ m_binderFd = static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->getBinderFd();
+ }
+ virtual void TearDown() {
+ }
+ protected:
+ void binderTestIoctlRetErr2(int cmd, void *arg, int expect_ret, int expect_errno, int accept_errno) {
+ int ret;
+
+ ret = ioctl(m_binderFd, cmd, arg);
+ EXPECT_EQ(expect_ret, ret);
+ if (ret < 0) {
+ if (errno != accept_errno)
+ EXPECT_EQ(expect_errno, errno);
+ }
+ }
+ void binderTestIoctlErr2(int cmd, void *arg, int expect_errno, int accept_errno) {
+ binderTestIoctlRetErr2(cmd, arg, -1, expect_errno, accept_errno);
+ }
+ void binderTestIoctlErr1(int cmd, void *arg, int expect_errno) {
+ binderTestIoctlErr2(cmd, arg, expect_errno, expect_errno);
+ }
+ void binderTestIoctl(int cmd, void *arg) {
+ binderTestIoctlRetErr2(cmd, arg, 0, 0, 0);
+ }
+ void binderTestIoctlUnimplemented(int cmd, void *arg) {
+ int ret;
+
+ ret = ioctl(m_binderFd, cmd, arg);
+ if (ret < 0) {
+ /* Not currently implmented. Allow ret == -1, errno == EINVAL */
+ EXPECT_EQ(-1, ret);
+ EXPECT_EQ(EINVAL, errno);
+ }
+ }
+ void binderTestReadEmpty(void) {
+ size_t i;
+ uint32_t br[32];
+ struct binder_write_read bwr = binder_write_read();
+ SCOPED_TRACE("TestReadEmpty");
+ bwr.read_buffer = (uintptr_t)br;
+ bwr.read_size = sizeof(br);
+ binderTestIoctlErr1(BINDER_WRITE_READ, &bwr, EAGAIN);
+ EXPECT_EQ(0u, bwr.read_consumed);
+ for (i = 0; i * sizeof(uint32_t) < bwr.read_consumed; i++) {
+ SCOPED_TRACE(testing::Message() << "i = " << i);
+ EXPECT_EQ(BR_NOOP, br[i]);
+ }
+ }
+ void binderWaitForReadData(int timeout_ms) {
+ int ret;
+ pollfd pfd = pollfd();
+
+ pfd.fd = m_binderFd;
+ pfd.events = POLLIN;
+ ret = poll(&pfd, 1, timeout_ms);
+ EXPECT_EQ(1, ret);
+ }
+ private:
+ int m_binderFd;
+};
+
+TEST_F(BinderDriverInterfaceTest, Version) {
+ struct binder_version version;
+ binderTestIoctl(BINDER_VERSION, &version);
+ ASSERT_EQ(BINDER_CURRENT_PROTOCOL_VERSION, version.protocol_version);
+}
+
+TEST_F(BinderDriverInterfaceTest, WriteReadNull) {
+ binderTestIoctlErr1(BINDER_WRITE_READ, NULL, EFAULT);
+}
+
+TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNull) {
+ binderTestIoctlErr2(BINDER_SET_IDLE_TIMEOUT, NULL, EFAULT, EINVAL);
+}
+
+TEST_F(BinderDriverInterfaceTest, SetMaxThreadsNull) {
+ binderTestIoctlErr2(BINDER_SET_MAX_THREADS, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
+}
+
+TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNull) {
+ binderTestIoctlErr2(BINDER_SET_IDLE_PRIORITY, NULL, EFAULT, EINVAL);
+}
+
+TEST_F(BinderDriverInterfaceTest, VersionNull) {
+ binderTestIoctlErr2(BINDER_VERSION, NULL, EFAULT, EINVAL); /* TODO: don't accept EINVAL */
+}
+
+TEST_F(BinderDriverInterfaceTest, SetIdleTimeoutNoTest) {
+ int64_t idle_timeout = 100000;
+ binderTestIoctlUnimplemented(BINDER_SET_IDLE_TIMEOUT, &idle_timeout);
+}
+
+TEST_F(BinderDriverInterfaceTest, SetMaxThreads) {
+ uint32_t max_threads = 0;
+ binderTestIoctl(BINDER_SET_MAX_THREADS, &max_threads);
+}
+
+TEST_F(BinderDriverInterfaceTest, SetIdlePriorityNoTest) {
+ int idle_priority = 0;
+ binderTestIoctlUnimplemented(BINDER_SET_IDLE_PRIORITY, &idle_priority);
+}
+
+TEST_F(BinderDriverInterfaceTest, SetContextMgrBusy) {
+ int32_t dummy = 0;
+ binderTestIoctlErr1(BINDER_SET_CONTEXT_MGR, &dummy, EBUSY);
+}
+
+TEST_F(BinderDriverInterfaceTest, ThreadExit) {
+ int32_t dummy = 0;
+ binderTestIoctl(BINDER_THREAD_EXIT, &dummy);
+ static_cast<BinderDriverInterfaceTestEnv *>(binder_env)->EnterLooper();
+}
+
+TEST_F(BinderDriverInterfaceTest, WriteReadEmpty) {
+ struct binder_write_read bwr = binder_write_read();
+ binderTestIoctl(BINDER_WRITE_READ, &bwr);
+}
+
+TEST_F(BinderDriverInterfaceTest, Read) {
+ binderTestReadEmpty();
+}
+
+TEST_F(BinderDriverInterfaceTest, IncRefsAcquireReleaseDecRefs) {
+ const uint32_t bc[] = {
+ BC_INCREFS,
+ 0,
+ BC_ACQUIRE,
+ 0,
+ BC_RELEASE,
+ 0,
+ BC_DECREFS,
+ 0,
+ };
+ struct binder_write_read bwr = binder_write_read();
+ bwr.write_buffer = (uintptr_t)bc;
+ bwr.write_size = sizeof(bc);
+ binderTestIoctl(BINDER_WRITE_READ, &bwr);
+ EXPECT_EQ(sizeof(bc), bwr.write_consumed);
+ binderTestReadEmpty();
+}
+
+TEST_F(BinderDriverInterfaceTest, Transaction) {
+ binder_uintptr_t cookie = 1234;
+ struct {
+ uint32_t cmd1;
+ struct binder_transaction_data arg1;
+ } __attribute__((packed)) bc1 = {
+ .cmd1 = BC_TRANSACTION,
+ .arg1 = {
+ .target = { 0 },
+ .cookie = 0,
+ .code = android::IBinder::PING_TRANSACTION,
+ .flags = 0,
+ .sender_pid = 0,
+ .sender_euid = 0,
+ .data_size = 0,
+ .offsets_size = 0,
+ .data = {0, 0},
+ },
+ };
+ struct {
+ uint32_t cmd0;
+ uint32_t cmd1;
+ uint32_t cmd2;
+ binder_transaction_data arg2;
+ uint32_t pad[16];
+ } __attribute__((packed)) br;
+ struct binder_write_read bwr = binder_write_read();
+
+ bwr.write_buffer = (uintptr_t)&bc1;
+ bwr.write_size = sizeof(bc1);
+ bwr.read_buffer = (uintptr_t)&br;
+ bwr.read_size = sizeof(br);
+
+ {
+ SCOPED_TRACE("1st WriteRead");
+ binderTestIoctl(BINDER_WRITE_READ, &bwr);
+ }
+ EXPECT_EQ(sizeof(bc1), bwr.write_consumed);
+ if (bwr.read_consumed < offsetof(typeof(br), pad)) {
+ SCOPED_TRACE("2nd WriteRead");
+ binderWaitForReadData(10000);
+ binderTestIoctl(BINDER_WRITE_READ, &bwr);
+ }
+ EXPECT_EQ(offsetof(typeof(br), pad), bwr.read_consumed);
+ if (bwr.read_consumed > offsetof(typeof(br), cmd0))
+ EXPECT_EQ(BR_NOOP, br.cmd0);
+ if (bwr.read_consumed > offsetof(typeof(br), cmd1))
+ EXPECT_EQ(BR_TRANSACTION_COMPLETE, br.cmd1);
+ if (bwr.read_consumed > offsetof(typeof(br), cmd2))
+ EXPECT_EQ(BR_REPLY, br.cmd2);
+ if (bwr.read_consumed >= offsetof(typeof(br), pad)) {
+ EXPECT_EQ(0u, br.arg2.target.ptr);
+ EXPECT_EQ(0u, br.arg2.cookie);
+ EXPECT_EQ(0u, br.arg2.code);
+ EXPECT_EQ(0u, br.arg2.flags);
+ EXPECT_EQ(0u, br.arg2.data_size);
+ EXPECT_EQ(0u, br.arg2.offsets_size);
+
+ SCOPED_TRACE("3rd WriteRead");
+
+ binderTestReadEmpty();
+
+ struct {
+ uint32_t cmd1;
+ binder_uintptr_t arg1;
+ } __attribute__((packed)) bc2 = {
+ .cmd1 = BC_FREE_BUFFER,
+ .arg1 = br.arg2.data.ptr.buffer,
+ };
+
+ bwr.write_buffer = (uintptr_t)&bc2;
+ bwr.write_size = sizeof(bc2);
+ bwr.write_consumed = 0;
+ bwr.read_size = 0;
+
+ binderTestIoctl(BINDER_WRITE_READ, &bwr);
+ EXPECT_EQ(sizeof(bc2), bwr.write_consumed);
+ }
+ binderTestReadEmpty();
+}
+
+TEST_F(BinderDriverInterfaceTest, RequestDeathNotification) {
+ binder_uintptr_t cookie = 1234;
+ struct {
+ uint32_t cmd0;
+ uint32_t arg0;
+ uint32_t cmd1;
+ struct binder_handle_cookie arg1;
+ uint32_t cmd2;
+ struct binder_handle_cookie arg2;
+ uint32_t cmd3;
+ uint32_t arg3;
+ } __attribute__((packed)) bc = {
+ .cmd0 = BC_INCREFS,
+ .arg0 = 0,
+ .cmd1 = BC_REQUEST_DEATH_NOTIFICATION,
+ .arg1 = {
+ .handle = 0,
+ .cookie = cookie,
+ },
+ .cmd2 = BC_CLEAR_DEATH_NOTIFICATION,
+ .arg2 = {
+ .handle = 0,
+ .cookie = cookie,
+ },
+ .cmd3 = BC_DECREFS,
+ .arg3 = 0,
+ };
+ struct {
+ uint32_t cmd0;
+ uint32_t cmd1;
+ binder_uintptr_t arg1;
+ uint32_t pad[16];
+ } __attribute__((packed)) br;
+ struct binder_write_read bwr = binder_write_read();
+
+ bwr.write_buffer = (uintptr_t)&bc;
+ bwr.write_size = sizeof(bc);
+ bwr.read_buffer = (uintptr_t)&br;
+ bwr.read_size = sizeof(br);
+
+ binderTestIoctl(BINDER_WRITE_READ, &bwr);
+ EXPECT_EQ(sizeof(bc), bwr.write_consumed);
+ EXPECT_EQ(sizeof(br) - sizeof(br.pad), bwr.read_consumed);
+ EXPECT_EQ(BR_NOOP, br.cmd0);
+ EXPECT_EQ(BR_CLEAR_DEATH_NOTIFICATION_DONE, br.cmd1);
+ EXPECT_EQ(cookie, br.arg1);
+ binderTestReadEmpty();
+}
+
+int main(int argc, char **argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+ binder_env = AddGlobalTestEnvironment(new BinderDriverInterfaceTestEnv());
+
+ return RUN_ALL_TESTS();
+}
+
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
new file mode 100644
index 0000000..3df3acf
--- /dev/null
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -0,0 +1,954 @@
+/*
+ * Copyright (C) 2014 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 <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <gtest/gtest.h>
+
+#include <binder/Binder.h>
+#include <binder/IBinder.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+
+#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
+
+using namespace android;
+
+static testing::Environment* binder_env;
+static char *binderservername;
+static char binderserverarg[] = "--binderserver";
+
+static String16 binderLibTestServiceName = String16("test.binderLib");
+
+enum BinderLibTestTranscationCode {
+ BINDER_LIB_TEST_NOP_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+ BINDER_LIB_TEST_REGISTER_SERVER,
+ BINDER_LIB_TEST_ADD_SERVER,
+ BINDER_LIB_TEST_CALL_BACK,
+ BINDER_LIB_TEST_NOP_CALL_BACK,
+ BINDER_LIB_TEST_GET_ID_TRANSACTION,
+ BINDER_LIB_TEST_INDIRECT_TRANSACTION,
+ BINDER_LIB_TEST_SET_ERROR_TRANSACTION,
+ BINDER_LIB_TEST_GET_STATUS_TRANSACTION,
+ BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION,
+ BINDER_LIB_TEST_LINK_DEATH_TRANSACTION,
+ BINDER_LIB_TEST_WRITE_FILE_TRANSACTION,
+ BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION,
+ BINDER_LIB_TEST_EXIT_TRANSACTION,
+ BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION,
+ BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION,
+};
+
+pid_t start_server_process(int arg2)
+{
+ int ret;
+ pid_t pid;
+ status_t status;
+ int pipefd[2];
+ char stri[16];
+ char strpipefd1[16];
+ char *childargv[] = {
+ binderservername,
+ binderserverarg,
+ stri,
+ strpipefd1,
+ NULL
+ };
+
+ ret = pipe(pipefd);
+ if (ret < 0)
+ return ret;
+
+ snprintf(stri, sizeof(stri), "%d", arg2);
+ snprintf(strpipefd1, sizeof(strpipefd1), "%d", pipefd[1]);
+
+ pid = fork();
+ if (pid == -1)
+ return pid;
+ if (pid == 0) {
+ close(pipefd[0]);
+ execv(binderservername, childargv);
+ status = -errno;
+ write(pipefd[1], &status, sizeof(status));
+ fprintf(stderr, "execv failed, %s\n", strerror(errno));
+ _exit(EXIT_FAILURE);
+ }
+ close(pipefd[1]);
+ ret = read(pipefd[0], &status, sizeof(status));
+ //printf("pipe read returned %d, status %d\n", ret, status);
+ close(pipefd[0]);
+ if (ret == sizeof(status)) {
+ ret = status;
+ } else {
+ kill(pid, SIGKILL);
+ if (ret >= 0) {
+ ret = NO_INIT;
+ }
+ }
+ if (ret < 0) {
+ wait(NULL);
+ return ret;
+ }
+ return pid;
+}
+
+class BinderLibTestEnv : public ::testing::Environment {
+ public:
+ BinderLibTestEnv() {}
+ sp<IBinder> getServer(void) {
+ return m_server;
+ }
+
+ private:
+ virtual void SetUp() {
+ m_serverpid = start_server_process(0);
+ //printf("m_serverpid %d\n", m_serverpid);
+ ASSERT_GT(m_serverpid, 0);
+
+ sp<IServiceManager> sm = defaultServiceManager();
+ //printf("%s: pid %d, get service\n", __func__, m_pid);
+ m_server = sm->getService(binderLibTestServiceName);
+ ASSERT_TRUE(m_server != NULL);
+ //printf("%s: pid %d, get service done\n", __func__, m_pid);
+ }
+ virtual void TearDown() {
+ status_t ret;
+ Parcel data, reply;
+ int exitStatus;
+ pid_t pid;
+
+ //printf("%s: pid %d\n", __func__, m_pid);
+ if (m_server != NULL) {
+ ret = m_server->transact(BINDER_LIB_TEST_GET_STATUS_TRANSACTION, data, &reply);
+ EXPECT_EQ(0, ret);
+ ret = m_server->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
+ EXPECT_EQ(0, ret);
+ }
+ if (m_serverpid > 0) {
+ //printf("wait for %d\n", m_pids[i]);
+ pid = wait(&exitStatus);
+ EXPECT_EQ(m_serverpid, pid);
+ EXPECT_TRUE(WIFEXITED(exitStatus));
+ EXPECT_EQ(0, WEXITSTATUS(exitStatus));
+ }
+ }
+
+ pid_t m_serverpid;
+ sp<IBinder> m_server;
+};
+
+class BinderLibTest : public ::testing::Test {
+ public:
+ virtual void SetUp() {
+ m_server = static_cast<BinderLibTestEnv *>(binder_env)->getServer();
+ }
+ virtual void TearDown() {
+ }
+ protected:
+ sp<IBinder> addServer(int32_t *idPtr = NULL)
+ {
+ int ret;
+ int32_t id;
+ Parcel data, reply;
+ sp<IBinder> binder;
+
+ ret = m_server->transact(BINDER_LIB_TEST_ADD_SERVER, data, &reply);
+ EXPECT_EQ(NO_ERROR, ret);
+
+ EXPECT_FALSE(binder != NULL);
+ binder = reply.readStrongBinder();
+ EXPECT_TRUE(binder != NULL);
+ ret = reply.readInt32(&id);
+ EXPECT_EQ(NO_ERROR, ret);
+ if (idPtr)
+ *idPtr = id;
+ return binder;
+ }
+ void waitForReadData(int fd, int timeout_ms) {
+ int ret;
+ pollfd pfd = pollfd();
+
+ pfd.fd = fd;
+ pfd.events = POLLIN;
+ ret = poll(&pfd, 1, timeout_ms);
+ EXPECT_EQ(1, ret);
+ }
+
+ sp<IBinder> m_server;
+};
+
+class BinderLibTestBundle : public Parcel
+{
+ public:
+ BinderLibTestBundle(void) {}
+ BinderLibTestBundle(const Parcel *source) : m_isValid(false) {
+ int32_t mark;
+ int32_t bundleLen;
+ size_t pos;
+
+ if (source->readInt32(&mark))
+ return;
+ if (mark != MARK_START)
+ return;
+ if (source->readInt32(&bundleLen))
+ return;
+ pos = source->dataPosition();
+ if (Parcel::appendFrom(source, pos, bundleLen))
+ return;
+ source->setDataPosition(pos + bundleLen);
+ if (source->readInt32(&mark))
+ return;
+ if (mark != MARK_END)
+ return;
+ m_isValid = true;
+ setDataPosition(0);
+ }
+ void appendTo(Parcel *dest) {
+ dest->writeInt32(MARK_START);
+ dest->writeInt32(dataSize());
+ dest->appendFrom(this, 0, dataSize());
+ dest->writeInt32(MARK_END);
+ };
+ bool isValid(void) {
+ return m_isValid;
+ }
+ private:
+ enum {
+ MARK_START = B_PACK_CHARS('B','T','B','S'),
+ MARK_END = B_PACK_CHARS('B','T','B','E'),
+ };
+ bool m_isValid;
+};
+
+class BinderLibTestEvent
+{
+ public:
+ BinderLibTestEvent(void)
+ : m_eventTriggered(false)
+ {
+ pthread_mutex_init(&m_waitMutex, NULL);
+ pthread_cond_init(&m_waitCond, NULL);
+ }
+ int waitEvent(int timeout_s)
+ {
+ int ret;
+ pthread_mutex_lock(&m_waitMutex);
+ if (!m_eventTriggered) {
+#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
+ pthread_cond_timeout_np(&m_waitCond, &m_waitMutex, timeout_s * 1000);
+#else
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += timeout_s;
+ pthread_cond_timedwait(&m_waitCond, &m_waitMutex, &ts);
+#endif
+ }
+ ret = m_eventTriggered ? NO_ERROR : TIMED_OUT;
+ pthread_mutex_unlock(&m_waitMutex);
+ return ret;
+ }
+ protected:
+ void triggerEvent(void) {
+ pthread_mutex_lock(&m_waitMutex);
+ pthread_cond_signal(&m_waitCond);
+ m_eventTriggered = true;
+ pthread_mutex_unlock(&m_waitMutex);
+ };
+ private:
+ pthread_mutex_t m_waitMutex;
+ pthread_cond_t m_waitCond;
+ bool m_eventTriggered;
+};
+
+class BinderLibTestCallBack : public BBinder, public BinderLibTestEvent
+{
+ public:
+ BinderLibTestCallBack()
+ : m_result(NOT_ENOUGH_DATA)
+ {
+ }
+ status_t getResult(void)
+ {
+ return m_result;
+ }
+
+ private:
+ virtual status_t onTransact(uint32_t code,
+ const Parcel& data, Parcel* reply,
+ uint32_t flags = 0)
+ {
+ (void)reply;
+ (void)flags;
+ switch(code) {
+ case BINDER_LIB_TEST_CALL_BACK:
+ m_result = data.readInt32();
+ triggerEvent();
+ return NO_ERROR;
+ default:
+ return UNKNOWN_TRANSACTION;
+ }
+ }
+
+ status_t m_result;
+};
+
+class TestDeathRecipient : public IBinder::DeathRecipient, public BinderLibTestEvent
+{
+ private:
+ virtual void binderDied(const wp<IBinder>& who) {
+ (void)who;
+ triggerEvent();
+ };
+};
+
+TEST_F(BinderLibTest, NopTransaction) {
+ status_t ret;
+ Parcel data, reply;
+ ret = m_server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data, &reply);
+ EXPECT_EQ(NO_ERROR, ret);
+}
+
+TEST_F(BinderLibTest, SetError) {
+ int32_t testValue[] = { 0, -123, 123 };
+ for (size_t i = 0; i < ARRAY_SIZE(testValue); i++) {
+ status_t ret;
+ Parcel data, reply;
+ data.writeInt32(testValue[i]);
+ ret = m_server->transact(BINDER_LIB_TEST_SET_ERROR_TRANSACTION, data, &reply);
+ EXPECT_EQ(testValue[i], ret);
+ }
+}
+
+TEST_F(BinderLibTest, GetId) {
+ status_t ret;
+ int32_t id;
+ Parcel data, reply;
+ ret = m_server->transact(BINDER_LIB_TEST_GET_ID_TRANSACTION, data, &reply);
+ EXPECT_EQ(NO_ERROR, ret);
+ ret = reply.readInt32(&id);
+ EXPECT_EQ(NO_ERROR, ret);
+ EXPECT_EQ(0, id);
+}
+
+TEST_F(BinderLibTest, PtrSize) {
+ status_t ret;
+ int32_t ptrsize;
+ Parcel data, reply;
+ sp<IBinder> server = addServer();
+ ASSERT_TRUE(server != NULL);
+ ret = server->transact(BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION, data, &reply);
+ EXPECT_EQ(NO_ERROR, ret);
+ ret = reply.readInt32(&ptrsize);
+ EXPECT_EQ(NO_ERROR, ret);
+ RecordProperty("TestPtrSize", sizeof(void *));
+ RecordProperty("ServerPtrSize", sizeof(void *));
+}
+
+TEST_F(BinderLibTest, IndirectGetId2)
+{
+ status_t ret;
+ int32_t id;
+ int32_t count;
+ Parcel data, reply;
+ int32_t serverId[3];
+
+ data.writeInt32(ARRAY_SIZE(serverId));
+ for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
+ sp<IBinder> server;
+ BinderLibTestBundle datai;
+
+ server = addServer(&serverId[i]);
+ ASSERT_TRUE(server != NULL);
+ data.writeStrongBinder(server);
+ data.writeInt32(BINDER_LIB_TEST_GET_ID_TRANSACTION);
+ datai.appendTo(&data);
+ }
+
+ ret = m_server->transact(BINDER_LIB_TEST_INDIRECT_TRANSACTION, data, &reply);
+ ASSERT_EQ(NO_ERROR, ret);
+
+ ret = reply.readInt32(&id);
+ ASSERT_EQ(NO_ERROR, ret);
+ EXPECT_EQ(0, id);
+
+ ret = reply.readInt32(&count);
+ ASSERT_EQ(NO_ERROR, ret);
+ EXPECT_EQ(ARRAY_SIZE(serverId), count);
+
+ for (size_t i = 0; i < (size_t)count; i++) {
+ BinderLibTestBundle replyi(&reply);
+ EXPECT_TRUE(replyi.isValid());
+ ret = replyi.readInt32(&id);
+ EXPECT_EQ(NO_ERROR, ret);
+ EXPECT_EQ(serverId[i], id);
+ EXPECT_EQ(replyi.dataSize(), replyi.dataPosition());
+ }
+
+ EXPECT_EQ(reply.dataSize(), reply.dataPosition());
+}
+
+TEST_F(BinderLibTest, IndirectGetId3)
+{
+ status_t ret;
+ int32_t id;
+ int32_t count;
+ Parcel data, reply;
+ int32_t serverId[3];
+
+ data.writeInt32(ARRAY_SIZE(serverId));
+ for (size_t i = 0; i < ARRAY_SIZE(serverId); i++) {
+ sp<IBinder> server;
+ BinderLibTestBundle datai;
+ BinderLibTestBundle datai2;
+
+ server = addServer(&serverId[i]);
+ ASSERT_TRUE(server != NULL);
+ data.writeStrongBinder(server);
+ data.writeInt32(BINDER_LIB_TEST_INDIRECT_TRANSACTION);
+
+ datai.writeInt32(1);
+ datai.writeStrongBinder(m_server);
+ datai.writeInt32(BINDER_LIB_TEST_GET_ID_TRANSACTION);
+ datai2.appendTo(&datai);
+
+ datai.appendTo(&data);
+ }
+
+ ret = m_server->transact(BINDER_LIB_TEST_INDIRECT_TRANSACTION, data, &reply);
+ ASSERT_EQ(NO_ERROR, ret);
+
+ ret = reply.readInt32(&id);
+ ASSERT_EQ(NO_ERROR, ret);
+ EXPECT_EQ(0, id);
+
+ ret = reply.readInt32(&count);
+ ASSERT_EQ(NO_ERROR, ret);
+ EXPECT_EQ(ARRAY_SIZE(serverId), count);
+
+ for (size_t i = 0; i < (size_t)count; i++) {
+ int32_t counti;
+
+ BinderLibTestBundle replyi(&reply);
+ EXPECT_TRUE(replyi.isValid());
+ ret = replyi.readInt32(&id);
+ EXPECT_EQ(NO_ERROR, ret);
+ EXPECT_EQ(serverId[i], id);
+
+ ret = replyi.readInt32(&counti);
+ ASSERT_EQ(NO_ERROR, ret);
+ EXPECT_EQ(1, counti);
+
+ BinderLibTestBundle replyi2(&replyi);
+ EXPECT_TRUE(replyi2.isValid());
+ ret = replyi2.readInt32(&id);
+ EXPECT_EQ(NO_ERROR, ret);
+ EXPECT_EQ(0, id);
+ EXPECT_EQ(replyi2.dataSize(), replyi2.dataPosition());
+
+ EXPECT_EQ(replyi.dataSize(), replyi.dataPosition());
+ }
+
+ EXPECT_EQ(reply.dataSize(), reply.dataPosition());
+}
+
+TEST_F(BinderLibTest, CallBack)
+{
+ status_t ret;
+ Parcel data, reply;
+ sp<BinderLibTestCallBack> callBack = new BinderLibTestCallBack();
+ data.writeStrongBinder(callBack);
+ ret = m_server->transact(BINDER_LIB_TEST_NOP_CALL_BACK, data, &reply, TF_ONE_WAY);
+ EXPECT_EQ(NO_ERROR, ret);
+ ret = callBack->waitEvent(5);
+ EXPECT_EQ(NO_ERROR, ret);
+ ret = callBack->getResult();
+ EXPECT_EQ(NO_ERROR, ret);
+}
+
+TEST_F(BinderLibTest, AddServer)
+{
+ sp<IBinder> server = addServer();
+ ASSERT_TRUE(server != NULL);
+}
+
+TEST_F(BinderLibTest, DeathNotificationNoRefs)
+{
+ status_t ret;
+
+ sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
+
+ {
+ sp<IBinder> binder = addServer();
+ ASSERT_TRUE(binder != NULL);
+ ret = binder->linkToDeath(testDeathRecipient);
+ EXPECT_EQ(NO_ERROR, ret);
+ }
+ IPCThreadState::self()->flushCommands();
+ ret = testDeathRecipient->waitEvent(5);
+ EXPECT_EQ(NO_ERROR, ret);
+#if 0 /* Is there an unlink api that does not require a strong reference? */
+ ret = binder->unlinkToDeath(testDeathRecipient);
+ EXPECT_EQ(NO_ERROR, ret);
+#endif
+}
+
+TEST_F(BinderLibTest, DeathNotificationWeakRef)
+{
+ status_t ret;
+ wp<IBinder> wbinder;
+
+ sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
+
+ {
+ sp<IBinder> binder = addServer();
+ ASSERT_TRUE(binder != NULL);
+ ret = binder->linkToDeath(testDeathRecipient);
+ EXPECT_EQ(NO_ERROR, ret);
+ wbinder = binder;
+ }
+ IPCThreadState::self()->flushCommands();
+ ret = testDeathRecipient->waitEvent(5);
+ EXPECT_EQ(NO_ERROR, ret);
+#if 0 /* Is there an unlink api that does not require a strong reference? */
+ ret = binder->unlinkToDeath(testDeathRecipient);
+ EXPECT_EQ(NO_ERROR, ret);
+#endif
+}
+
+TEST_F(BinderLibTest, DeathNotificationStrongRef)
+{
+ status_t ret;
+ sp<IBinder> sbinder;
+
+ sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
+
+ {
+ sp<IBinder> binder = addServer();
+ ASSERT_TRUE(binder != NULL);
+ ret = binder->linkToDeath(testDeathRecipient);
+ EXPECT_EQ(NO_ERROR, ret);
+ sbinder = binder;
+ }
+ {
+ Parcel data, reply;
+ ret = sbinder->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
+ EXPECT_EQ(0, ret);
+ }
+ IPCThreadState::self()->flushCommands();
+ ret = testDeathRecipient->waitEvent(5);
+ EXPECT_EQ(NO_ERROR, ret);
+ ret = sbinder->unlinkToDeath(testDeathRecipient);
+ EXPECT_EQ(DEAD_OBJECT, ret);
+}
+
+TEST_F(BinderLibTest, DeathNotificationMultiple)
+{
+ status_t ret;
+ const int clientcount = 2;
+ sp<IBinder> target;
+ sp<IBinder> linkedclient[clientcount];
+ sp<BinderLibTestCallBack> callBack[clientcount];
+ sp<IBinder> passiveclient[clientcount];
+
+ target = addServer();
+ ASSERT_TRUE(target != NULL);
+ for (int i = 0; i < clientcount; i++) {
+ {
+ Parcel data, reply;
+
+ linkedclient[i] = addServer();
+ ASSERT_TRUE(linkedclient[i] != NULL);
+ callBack[i] = new BinderLibTestCallBack();
+ data.writeStrongBinder(target);
+ data.writeStrongBinder(callBack[i]);
+ ret = linkedclient[i]->transact(BINDER_LIB_TEST_LINK_DEATH_TRANSACTION, data, &reply, TF_ONE_WAY);
+ EXPECT_EQ(NO_ERROR, ret);
+ }
+ {
+ Parcel data, reply;
+
+ passiveclient[i] = addServer();
+ ASSERT_TRUE(passiveclient[i] != NULL);
+ data.writeStrongBinder(target);
+ ret = passiveclient[i]->transact(BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION, data, &reply, TF_ONE_WAY);
+ EXPECT_EQ(NO_ERROR, ret);
+ }
+ }
+ {
+ Parcel data, reply;
+ ret = target->transact(BINDER_LIB_TEST_EXIT_TRANSACTION, data, &reply, TF_ONE_WAY);
+ EXPECT_EQ(0, ret);
+ }
+
+ for (int i = 0; i < clientcount; i++) {
+ ret = callBack[i]->waitEvent(5);
+ EXPECT_EQ(NO_ERROR, ret);
+ ret = callBack[i]->getResult();
+ EXPECT_EQ(NO_ERROR, ret);
+ }
+}
+
+TEST_F(BinderLibTest, PassFile) {
+ int ret;
+ int pipefd[2];
+ uint8_t buf[1] = { 0 };
+ uint8_t write_value = 123;
+
+ ret = pipe2(pipefd, O_NONBLOCK);
+ ASSERT_EQ(0, ret);
+
+ {
+ Parcel data, reply;
+ uint8_t writebuf[1] = { write_value };
+
+ ret = data.writeFileDescriptor(pipefd[1], true);
+ EXPECT_EQ(NO_ERROR, ret);
+
+ ret = data.writeInt32(sizeof(writebuf));
+ EXPECT_EQ(NO_ERROR, ret);
+
+ ret = data.write(writebuf, sizeof(writebuf));
+ EXPECT_EQ(NO_ERROR, ret);
+
+ ret = m_server->transact(BINDER_LIB_TEST_WRITE_FILE_TRANSACTION, data, &reply);
+ EXPECT_EQ(NO_ERROR, ret);
+ }
+
+ ret = read(pipefd[0], buf, sizeof(buf));
+ EXPECT_EQ(sizeof(buf), ret);
+ EXPECT_EQ(write_value, buf[0]);
+
+ waitForReadData(pipefd[0], 5000); /* wait for other proccess to close pipe */
+
+ ret = read(pipefd[0], buf, sizeof(buf));
+ EXPECT_EQ(0, ret);
+
+ close(pipefd[0]);
+}
+
+TEST_F(BinderLibTest, PromoteLocal) {
+ sp<IBinder> strong = new BBinder();
+ wp<IBinder> weak = strong;
+ sp<IBinder> strong_from_weak = weak.promote();
+ EXPECT_TRUE(strong != NULL);
+ EXPECT_EQ(strong, strong_from_weak);
+ strong = NULL;
+ strong_from_weak = NULL;
+ strong_from_weak = weak.promote();
+ EXPECT_TRUE(strong_from_weak == NULL);
+}
+
+TEST_F(BinderLibTest, PromoteRemote) {
+ int ret;
+ Parcel data, reply;
+ sp<IBinder> strong = new BBinder();
+ sp<IBinder> server = addServer();
+
+ ASSERT_TRUE(server != NULL);
+ ASSERT_TRUE(strong != NULL);
+
+ ret = data.writeWeakBinder(strong);
+ EXPECT_EQ(NO_ERROR, ret);
+
+ ret = server->transact(BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION, data, &reply);
+ EXPECT_GE(ret, 0);
+}
+
+class BinderLibTestService : public BBinder
+{
+ public:
+ BinderLibTestService(int32_t id)
+ : m_id(id)
+ , m_nextServerId(id + 1)
+ , m_serverStartRequested(false)
+ {
+ pthread_mutex_init(&m_serverWaitMutex, NULL);
+ pthread_cond_init(&m_serverWaitCond, NULL);
+ }
+ ~BinderLibTestService()
+ {
+ exit(EXIT_SUCCESS);
+ }
+ virtual status_t onTransact(uint32_t code,
+ const Parcel& data, Parcel* reply,
+ uint32_t flags = 0) {
+ //printf("%s: code %d\n", __func__, code);
+ (void)flags;
+
+ if (getuid() != (uid_t)IPCThreadState::self()->getCallingUid()) {
+ return PERMISSION_DENIED;
+ }
+ switch (code) {
+ case BINDER_LIB_TEST_REGISTER_SERVER: {
+ int32_t id;
+ sp<IBinder> binder;
+ id = data.readInt32();
+ binder = data.readStrongBinder();
+ if (binder == NULL) {
+ return BAD_VALUE;
+ }
+
+ if (m_id != 0)
+ return INVALID_OPERATION;
+
+ pthread_mutex_lock(&m_serverWaitMutex);
+ if (m_serverStartRequested) {
+ m_serverStartRequested = false;
+ m_serverStarted = binder;
+ pthread_cond_signal(&m_serverWaitCond);
+ }
+ pthread_mutex_unlock(&m_serverWaitMutex);
+ return NO_ERROR;
+ }
+ case BINDER_LIB_TEST_ADD_SERVER: {
+ int ret;
+ uint8_t buf[1] = { 0 };
+ int serverid;
+
+ if (m_id != 0) {
+ return INVALID_OPERATION;
+ }
+ pthread_mutex_lock(&m_serverWaitMutex);
+ if (m_serverStartRequested) {
+ ret = -EBUSY;
+ } else {
+ serverid = m_nextServerId++;
+ m_serverStartRequested = true;
+
+ pthread_mutex_unlock(&m_serverWaitMutex);
+ ret = start_server_process(serverid);
+ pthread_mutex_lock(&m_serverWaitMutex);
+ }
+ if (ret > 0) {
+ if (m_serverStartRequested) {
+#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE)
+ ret = pthread_cond_timeout_np(&m_serverWaitCond, &m_serverWaitMutex, 5000);
+#else
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += 5;
+ ret = pthread_cond_timedwait(&m_serverWaitCond, &m_serverWaitMutex, &ts);
+#endif
+ }
+ if (m_serverStartRequested) {
+ m_serverStartRequested = false;
+ ret = -ETIMEDOUT;
+ } else {
+ reply->writeStrongBinder(m_serverStarted);
+ reply->writeInt32(serverid);
+ m_serverStarted = NULL;
+ ret = NO_ERROR;
+ }
+ } else if (ret >= 0) {
+ m_serverStartRequested = false;
+ ret = UNKNOWN_ERROR;
+ }
+ pthread_mutex_unlock(&m_serverWaitMutex);
+ return ret;
+ }
+ case BINDER_LIB_TEST_NOP_TRANSACTION:
+ return NO_ERROR;
+ case BINDER_LIB_TEST_NOP_CALL_BACK: {
+ Parcel data2, reply2;
+ sp<IBinder> binder;
+ binder = data.readStrongBinder();
+ if (binder == NULL) {
+ return BAD_VALUE;
+ }
+ reply2.writeInt32(NO_ERROR);
+ binder->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
+ return NO_ERROR;
+ }
+ case BINDER_LIB_TEST_GET_ID_TRANSACTION:
+ reply->writeInt32(m_id);
+ return NO_ERROR;
+ case BINDER_LIB_TEST_INDIRECT_TRANSACTION: {
+ int32_t count;
+ uint32_t indirect_code;
+ sp<IBinder> binder;
+
+ count = data.readInt32();
+ reply->writeInt32(m_id);
+ reply->writeInt32(count);
+ for (int i = 0; i < count; i++) {
+ binder = data.readStrongBinder();
+ if (binder == NULL) {
+ return BAD_VALUE;
+ }
+ indirect_code = data.readInt32();
+ BinderLibTestBundle data2(&data);
+ if (!data2.isValid()) {
+ return BAD_VALUE;
+ }
+ BinderLibTestBundle reply2;
+ binder->transact(indirect_code, data2, &reply2);
+ reply2.appendTo(reply);
+ }
+ return NO_ERROR;
+ }
+ case BINDER_LIB_TEST_SET_ERROR_TRANSACTION:
+ reply->setError(data.readInt32());
+ return NO_ERROR;
+ case BINDER_LIB_TEST_GET_PTR_SIZE_TRANSACTION:
+ reply->writeInt32(sizeof(void *));
+ return NO_ERROR;
+ case BINDER_LIB_TEST_GET_STATUS_TRANSACTION:
+ return NO_ERROR;
+ case BINDER_LIB_TEST_ADD_STRONG_REF_TRANSACTION:
+ m_strongRef = data.readStrongBinder();
+ return NO_ERROR;
+ case BINDER_LIB_TEST_LINK_DEATH_TRANSACTION: {
+ int ret;
+ Parcel data2, reply2;
+ sp<TestDeathRecipient> testDeathRecipient = new TestDeathRecipient();
+ sp<IBinder> target;
+ sp<IBinder> callback;
+
+ target = data.readStrongBinder();
+ if (target == NULL) {
+ return BAD_VALUE;
+ }
+ callback = data.readStrongBinder();
+ if (callback == NULL) {
+ return BAD_VALUE;
+ }
+ ret = target->linkToDeath(testDeathRecipient);
+ if (ret == NO_ERROR)
+ ret = testDeathRecipient->waitEvent(5);
+ data2.writeInt32(ret);
+ callback->transact(BINDER_LIB_TEST_CALL_BACK, data2, &reply2);
+ return NO_ERROR;
+ }
+ case BINDER_LIB_TEST_WRITE_FILE_TRANSACTION: {
+ int ret;
+ int32_t size;
+ const void *buf;
+ int fd;
+
+ fd = data.readFileDescriptor();
+ if (fd < 0) {
+ return BAD_VALUE;
+ }
+ ret = data.readInt32(&size);
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+ buf = data.readInplace(size);
+ if (buf == NULL) {
+ return BAD_VALUE;
+ }
+ ret = write(fd, buf, size);
+ if (ret != size)
+ return UNKNOWN_ERROR;
+ return NO_ERROR;
+ }
+ case BINDER_LIB_TEST_PROMOTE_WEAK_REF_TRANSACTION: {
+ int ret;
+ wp<IBinder> weak;
+ sp<IBinder> strong;
+ Parcel data2, reply2;
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> server = sm->getService(binderLibTestServiceName);
+
+ weak = data.readWeakBinder();
+ if (weak == NULL) {
+ return BAD_VALUE;
+ }
+ strong = weak.promote();
+
+ ret = server->transact(BINDER_LIB_TEST_NOP_TRANSACTION, data2, &reply2);
+ if (ret != NO_ERROR)
+ exit(EXIT_FAILURE);
+
+ if (strong == NULL) {
+ reply->setError(1);
+ }
+ return NO_ERROR;
+ }
+ case BINDER_LIB_TEST_DELAYED_EXIT_TRANSACTION:
+ alarm(10);
+ return NO_ERROR;
+ case BINDER_LIB_TEST_EXIT_TRANSACTION:
+ while (wait(NULL) != -1 || errno != ECHILD)
+ ;
+ exit(EXIT_SUCCESS);
+ default:
+ return UNKNOWN_TRANSACTION;
+ };
+ }
+ private:
+ int32_t m_id;
+ int32_t m_nextServerId;
+ pthread_mutex_t m_serverWaitMutex;
+ pthread_cond_t m_serverWaitCond;
+ bool m_serverStartRequested;
+ sp<IBinder> m_serverStarted;
+ sp<IBinder> m_strongRef;
+};
+
+int run_server(int index, int readypipefd)
+{
+ status_t ret;
+ sp<IServiceManager> sm = defaultServiceManager();
+ {
+ sp<BinderLibTestService> testService = new BinderLibTestService(index);
+ if (index == 0) {
+ ret = sm->addService(binderLibTestServiceName, testService);
+ } else {
+ sp<IBinder> server = sm->getService(binderLibTestServiceName);
+ Parcel data, reply;
+ data.writeInt32(index);
+ data.writeStrongBinder(testService);
+
+ ret = server->transact(BINDER_LIB_TEST_REGISTER_SERVER, data, &reply);
+ }
+ }
+ write(readypipefd, &ret, sizeof(ret));
+ close(readypipefd);
+ //printf("%s: ret %d\n", __func__, ret);
+ if (ret)
+ return 1;
+ //printf("%s: joinThreadPool\n", __func__);
+ ProcessState::self()->startThreadPool();
+ IPCThreadState::self()->joinThreadPool();
+ //printf("%s: joinThreadPool returned\n", __func__);
+ return 1; /* joinThreadPool should not return */
+}
+
+int main(int argc, char **argv) {
+ int ret;
+
+ if (argc == 3 && !strcmp(argv[1], "--servername")) {
+ binderservername = argv[2];
+ } else {
+ binderservername = argv[0];
+ }
+
+ if (argc == 4 && !strcmp(argv[1], binderserverarg)) {
+ return run_server(atoi(argv[2]), atoi(argv[3]));
+ }
+
+ ::testing::InitGoogleTest(&argc, argv);
+ binder_env = AddGlobalTestEnvironment(new BinderLibTestEnv());
+ ProcessState::self()->startThreadPool();
+ return RUN_ALL_TESTS();
+}
+
diff --git a/libs/diskusage/dirsize.c b/libs/diskusage/dirsize.c
index 24e5af0..7576994 100644
--- a/libs/diskusage/dirsize.c
+++ b/libs/diskusage/dirsize.c
@@ -18,6 +18,7 @@
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
+#include <unistd.h>
#include <diskusage/dirsize.h>
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index ca94aa3..8a965dd 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -1,7 +1,42 @@
-LOCAL_PATH:= $(call my-dir)
+# Copyright 2010 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.
+
+LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= \
+LOCAL_CLANG := true
+LOCAL_CPPFLAGS := -std=c++1y -Weverything -Werror
+
+# The static constructors and destructors in this library have not been noted to
+# introduce significant overheads
+LOCAL_CPPFLAGS += -Wno-exit-time-destructors
+LOCAL_CPPFLAGS += -Wno-global-constructors
+
+# We only care about compiling as C++14
+LOCAL_CPPFLAGS += -Wno-c++98-compat-pedantic
+
+# We don't need to enumerate every case in a switch as long as a default case
+# is present
+LOCAL_CPPFLAGS += -Wno-switch-enum
+
+# Allow calling variadic macros without a __VA_ARGS__ list
+LOCAL_CPPFLAGS += -Wno-gnu-zero-variadic-macro-arguments
+
+# Don't warn about struct padding
+LOCAL_CPPFLAGS += -Wno-padded
+
+LOCAL_SRC_FILES := \
IGraphicBufferConsumer.cpp \
IConsumerListener.cpp \
BitTube.cpp \
@@ -47,7 +82,7 @@ LOCAL_SHARED_LIBRARIES := \
liblog
-LOCAL_MODULE:= libgui
+LOCAL_MODULE := libgui
ifeq ($(TARGET_BOARD_PLATFORM), tegra)
LOCAL_CFLAGS += -DDONT_USE_FENCE_SYNC
diff --git a/libs/gui/BitTube.cpp b/libs/gui/BitTube.cpp
index 3ed1f37..b653c5b 100644
--- a/libs/gui/BitTube.cpp
+++ b/libs/gui/BitTube.cpp
@@ -149,12 +149,12 @@ ssize_t BitTube::sendObjects(const sp<BitTube>& tube,
ssize_t size = tube->write(vaddr, count*objSize);
// should never happen because of SOCK_SEQPACKET
- LOG_ALWAYS_FATAL_IF((size >= 0) && (size % objSize),
+ LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
"BitTube::sendObjects(count=%zu, size=%zu), res=%zd (partial events were sent!)",
count, objSize, size);
//ALOGE_IF(size<0, "error %d sending %d events", size, count);
- return size < 0 ? size : size / objSize;
+ return size < 0 ? size : size / static_cast<ssize_t>(objSize);
}
ssize_t BitTube::recvObjects(const sp<BitTube>& tube,
@@ -164,12 +164,12 @@ ssize_t BitTube::recvObjects(const sp<BitTube>& tube,
ssize_t size = tube->read(vaddr, count*objSize);
// should never happen because of SOCK_SEQPACKET
- LOG_ALWAYS_FATAL_IF((size >= 0) && (size % objSize),
+ LOG_ALWAYS_FATAL_IF((size >= 0) && (size % static_cast<ssize_t>(objSize)),
"BitTube::recvObjects(count=%zu, size=%zu), res=%zd (partial events were received!)",
count, objSize, size);
//ALOGE_IF(size<0, "error %d receiving %d events", size, count);
- return size < 0 ? size : size / objSize;
+ return size < 0 ? size : size / static_cast<ssize_t>(objSize);
}
// ----------------------------------------------------------------------------
diff --git a/libs/gui/BufferItem.cpp b/libs/gui/BufferItem.cpp
index e6fc791..5793d40 100644
--- a/libs/gui/BufferItem.cpp
+++ b/libs/gui/BufferItem.cpp
@@ -28,6 +28,7 @@ BufferItem::BufferItem() :
mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
mTimestamp(0),
mIsAutoTimestamp(false),
+ mDataSpace(HAL_DATASPACE_UNKNOWN),
mFrameNumber(0),
mSlot(INVALID_BUFFER_SLOT),
mIsDroppable(false),
@@ -38,66 +39,66 @@ BufferItem::BufferItem() :
BufferItem::~BufferItem() {}
-BufferItem::operator IGraphicBufferConsumer::BufferItem() const {
- IGraphicBufferConsumer::BufferItem bufferItem;
- bufferItem.mGraphicBuffer = mGraphicBuffer;
- bufferItem.mFence = mFence;
- bufferItem.mCrop = mCrop;
- bufferItem.mTransform = mTransform;
- bufferItem.mScalingMode = mScalingMode;
- bufferItem.mTimestamp = mTimestamp;
- bufferItem.mIsAutoTimestamp = mIsAutoTimestamp;
- bufferItem.mFrameNumber = mFrameNumber;
- bufferItem.mBuf = mSlot;
- bufferItem.mIsDroppable = mIsDroppable;
- bufferItem.mAcquireCalled = mAcquireCalled;
- bufferItem.mTransformToDisplayInverse = mTransformToDisplayInverse;
- return bufferItem;
+template <typename T>
+static void addAligned(size_t& size, T /* value */) {
+ size = FlattenableUtils::align<sizeof(T)>(size);
+ size += sizeof(T);
}
size_t BufferItem::getPodSize() const {
- size_t c = sizeof(mCrop) +
- sizeof(mTransform) +
- sizeof(mScalingMode) +
- sizeof(mTimestamp) +
- sizeof(mIsAutoTimestamp) +
- sizeof(mFrameNumber) +
- sizeof(mSlot) +
- sizeof(mIsDroppable) +
- sizeof(mAcquireCalled) +
- sizeof(mTransformToDisplayInverse);
- return c;
+ // Must align<8> before writing these fields for this to be correct
+ size_t size = 0;
+ addAligned(size, mCrop);
+ addAligned(size, mTransform);
+ addAligned(size, mScalingMode);
+ addAligned(size, mTimestamp);
+ addAligned(size, mIsAutoTimestamp);
+ addAligned(size, mDataSpace);
+ addAligned(size, mFrameNumber);
+ addAligned(size, mSlot);
+ addAligned(size, mIsDroppable);
+ addAligned(size, mAcquireCalled);
+ addAligned(size, mTransformToDisplayInverse);
+ return size;
}
size_t BufferItem::getFlattenedSize() const {
- size_t c = 0;
+ size_t size = sizeof(uint32_t); // Flags
if (mGraphicBuffer != 0) {
- c += mGraphicBuffer->getFlattenedSize();
- FlattenableUtils::align<4>(c);
+ size += mGraphicBuffer->getFlattenedSize();
+ FlattenableUtils::align<4>(size);
}
if (mFence != 0) {
- c += mFence->getFlattenedSize();
- FlattenableUtils::align<4>(c);
+ size += mFence->getFlattenedSize();
+ FlattenableUtils::align<4>(size);
}
- return sizeof(int32_t) + c + getPodSize();
+ size += mSurfaceDamage.getFlattenedSize();
+ size = FlattenableUtils::align<8>(size);
+ return size + getPodSize();
}
size_t BufferItem::getFdCount() const {
- size_t c = 0;
+ size_t count = 0;
if (mGraphicBuffer != 0) {
- c += mGraphicBuffer->getFdCount();
+ count += mGraphicBuffer->getFdCount();
}
if (mFence != 0) {
- c += mFence->getFdCount();
+ count += mFence->getFdCount();
}
- return c;
+ return count;
+}
+
+template <typename T>
+static void writeAligned(void*& buffer, size_t& size, T value) {
+ size -= FlattenableUtils::align<alignof(T)>(buffer);
+ FlattenableUtils::write(buffer, size, value);
}
status_t BufferItem::flatten(
void*& buffer, size_t& size, int*& fds, size_t& count) const {
// make sure we have enough space
- if (count < BufferItem::getFlattenedSize()) {
+ if (size < BufferItem::getFlattenedSize()) {
return NO_MEMORY;
}
@@ -121,30 +122,45 @@ status_t BufferItem::flatten(
flags |= 2;
}
- // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
+ status_t err = mSurfaceDamage.flatten(buffer, size);
+ if (err) return err;
+ FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
+
+ // Must align<8> so that getPodSize returns the correct value
+ size -= FlattenableUtils::align<8>(buffer);
+
+ // Check we still have enough space
if (size < getPodSize()) {
return NO_MEMORY;
}
- FlattenableUtils::write(buffer, size, mCrop);
- FlattenableUtils::write(buffer, size, mTransform);
- FlattenableUtils::write(buffer, size, mScalingMode);
- FlattenableUtils::write(buffer, size, mTimestamp);
- FlattenableUtils::write(buffer, size, mIsAutoTimestamp);
- FlattenableUtils::write(buffer, size, mFrameNumber);
- FlattenableUtils::write(buffer, size, mSlot);
- FlattenableUtils::write(buffer, size, mIsDroppable);
- FlattenableUtils::write(buffer, size, mAcquireCalled);
- FlattenableUtils::write(buffer, size, mTransformToDisplayInverse);
+ writeAligned(buffer, size, mCrop);
+ writeAligned(buffer, size, mTransform);
+ writeAligned(buffer, size, mScalingMode);
+ writeAligned(buffer, size, mTimestamp);
+ writeAligned(buffer, size, mIsAutoTimestamp);
+ writeAligned(buffer, size, mDataSpace);
+ writeAligned(buffer, size, mFrameNumber);
+ writeAligned(buffer, size, mSlot);
+ writeAligned(buffer, size, mIsDroppable);
+ writeAligned(buffer, size, mAcquireCalled);
+ writeAligned(buffer, size, mTransformToDisplayInverse);
return NO_ERROR;
}
+template <typename T>
+static void readAligned(const void*& buffer, size_t& size, T& value) {
+ size -= FlattenableUtils::align<alignof(T)>(buffer);
+ FlattenableUtils::read(buffer, size, value);
+}
+
status_t BufferItem::unflatten(
void const*& buffer, size_t& size, int const*& fds, size_t& count) {
- if (size < sizeof(uint32_t))
+ if (size < sizeof(uint32_t)) {
return NO_MEMORY;
+ }
uint32_t flags = 0;
FlattenableUtils::read(buffer, size, flags);
@@ -163,21 +179,29 @@ status_t BufferItem::unflatten(
size -= FlattenableUtils::align<4>(buffer);
}
- // check we have enough space
+ status_t err = mSurfaceDamage.unflatten(buffer, size);
+ if (err) return err;
+ FlattenableUtils::advance(buffer, size, mSurfaceDamage.getFlattenedSize());
+
+ // Must align<8> so that getPodSize returns the correct value
+ size -= FlattenableUtils::align<8>(buffer);
+
+ // Check we still have enough space
if (size < getPodSize()) {
return NO_MEMORY;
}
- FlattenableUtils::read(buffer, size, mCrop);
- FlattenableUtils::read(buffer, size, mTransform);
- FlattenableUtils::read(buffer, size, mScalingMode);
- FlattenableUtils::read(buffer, size, mTimestamp);
- FlattenableUtils::read(buffer, size, mIsAutoTimestamp);
- FlattenableUtils::read(buffer, size, mFrameNumber);
- FlattenableUtils::read(buffer, size, mSlot);
- FlattenableUtils::read(buffer, size, mIsDroppable);
- FlattenableUtils::read(buffer, size, mAcquireCalled);
- FlattenableUtils::read(buffer, size, mTransformToDisplayInverse);
+ readAligned(buffer, size, mCrop);
+ readAligned(buffer, size, mTransform);
+ readAligned(buffer, size, mScalingMode);
+ readAligned(buffer, size, mTimestamp);
+ readAligned(buffer, size, mIsAutoTimestamp);
+ readAligned(buffer, size, mDataSpace);
+ readAligned(buffer, size, mFrameNumber);
+ readAligned(buffer, size, mSlot);
+ readAligned(buffer, size, mIsDroppable);
+ readAligned(buffer, size, mAcquireCalled);
+ readAligned(buffer, size, mTransformToDisplayInverse);
return NO_ERROR;
}
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index fe50c55..194121f 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -16,16 +16,17 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "BufferItemConsumer"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+//#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <utils/Log.h>
+#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
-#define BI_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
+//#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
+//#define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
+//#define BI_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
+//#define BI_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define BI_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
namespace android {
@@ -44,8 +45,7 @@ BufferItemConsumer::BufferItemConsumer(
}
}
-BufferItemConsumer::~BufferItemConsumer() {
-}
+BufferItemConsumer::~BufferItemConsumer() {}
void BufferItemConsumer::setName(const String8& name) {
Mutex::Autolock _l(mMutex);
@@ -105,9 +105,15 @@ status_t BufferItemConsumer::setDefaultBufferSize(uint32_t w, uint32_t h) {
return mConsumer->setDefaultBufferSize(w, h);
}
-status_t BufferItemConsumer::setDefaultBufferFormat(uint32_t defaultFormat) {
+status_t BufferItemConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
Mutex::Autolock _l(mMutex);
return mConsumer->setDefaultBufferFormat(defaultFormat);
}
+status_t BufferItemConsumer::setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace) {
+ Mutex::Autolock _l(mMutex);
+ return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
+}
+
} // namespace android
diff --git a/libs/gui/BufferQueue.cpp b/libs/gui/BufferQueue.cpp
index 61fd8c4..2fcbaf2 100644
--- a/libs/gui/BufferQueue.cpp
+++ b/libs/gui/BufferQueue.cpp
@@ -32,7 +32,7 @@ BufferQueue::ProxyConsumerListener::ProxyConsumerListener(
BufferQueue::ProxyConsumerListener::~ProxyConsumerListener() {}
void BufferQueue::ProxyConsumerListener::onFrameAvailable(
- const android::BufferItem& item) {
+ const BufferItem& item) {
sp<ConsumerListener> listener(mConsumerListener.promote());
if (listener != NULL) {
listener->onFrameAvailable(item);
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index 36e3c06..c7d5e00 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -120,6 +120,7 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
if (mCore->stillTracking(front)) {
// Front buffer is still in mSlots, so mark the slot as free
mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
+ mCore->mFreeBuffers.push_back(front->mSlot);
}
mCore->mQueue.erase(front);
front = mCore->mQueue.begin();
@@ -173,6 +174,8 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer,
ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
+ mCore->validateConsistencyLocked();
+
return NO_ERROR;
}
@@ -199,6 +202,7 @@ status_t BufferQueueConsumer::detachBuffer(int slot) {
mCore->freeBufferLocked(slot);
mCore->mDequeueCondition.broadcast();
+ mCore->validateConsistencyLocked();
return NO_ERROR;
}
@@ -217,18 +221,11 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot,
Mutex::Autolock lock(mCore->mMutex);
- // Make sure we don't have too many acquired buffers and find a free slot
- // to put the buffer into (the oldest if there are multiple).
+ // Make sure we don't have too many acquired buffers
int numAcquiredBuffers = 0;
- int found = BufferQueueCore::INVALID_BUFFER_SLOT;
for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
if (mSlots[s].mBufferState == BufferSlot::ACQUIRED) {
++numAcquiredBuffers;
- } else if (mSlots[s].mBufferState == BufferSlot::FREE) {
- if (found == BufferQueueCore::INVALID_BUFFER_SLOT ||
- mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) {
- found = s;
- }
}
}
@@ -238,6 +235,17 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot,
mCore->mMaxAcquiredBufferCount);
return INVALID_OPERATION;
}
+
+ // Find a free slot to put the buffer into
+ int found = BufferQueueCore::INVALID_BUFFER_SLOT;
+ if (!mCore->mFreeSlots.empty()) {
+ auto slot = mCore->mFreeSlots.begin();
+ found = *slot;
+ mCore->mFreeSlots.erase(slot);
+ } else if (!mCore->mFreeBuffers.empty()) {
+ found = mCore->mFreeBuffers.front();
+ mCore->mFreeBuffers.remove(found);
+ }
if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
BQ_LOGE("attachBuffer(P): could not find free buffer slot");
return NO_MEMORY;
@@ -271,6 +279,8 @@ status_t BufferQueueConsumer::attachBuffer(int* outSlot,
// for attached buffers.
mSlots[*outSlot].mAcquireCalled = false;
+ mCore->validateConsistencyLocked();
+
return NO_ERROR;
}
@@ -311,6 +321,7 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
mSlots[slot].mEglFence = eglFence;
mSlots[slot].mFence = releaseFence;
mSlots[slot].mBufferState = BufferSlot::FREE;
+ mCore->mFreeBuffers.push_back(slot);
listener = mCore->mConnectedProducerListener;
BQ_LOGV("releaseBuffer: releasing slot %d", slot);
} else if (mSlots[slot].mNeedsCleanupOnRelease) {
@@ -325,6 +336,7 @@ status_t BufferQueueConsumer::releaseBuffer(int slot, uint64_t frameNumber,
}
mCore->mDequeueCondition.broadcast();
+ mCore->validateConsistencyLocked();
} // Autolock scope
// Call back without lock held
@@ -488,7 +500,7 @@ void BufferQueueConsumer::setConsumerName(const String8& name) {
mConsumerName = name;
}
-status_t BufferQueueConsumer::setDefaultBufferFormat(uint32_t defaultFormat) {
+status_t BufferQueueConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
ATRACE_CALL();
BQ_LOGV("setDefaultBufferFormat: %u", defaultFormat);
Mutex::Autolock lock(mCore->mMutex);
@@ -496,6 +508,15 @@ status_t BufferQueueConsumer::setDefaultBufferFormat(uint32_t defaultFormat) {
return NO_ERROR;
}
+status_t BufferQueueConsumer::setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace) {
+ ATRACE_CALL();
+ BQ_LOGV("setDefaultBufferDataSpace: %u", defaultDataSpace);
+ Mutex::Autolock lock(mCore->mMutex);
+ mCore->mDefaultBufferDataSpace = defaultDataSpace;
+ return NO_ERROR;
+}
+
status_t BufferQueueConsumer::setConsumerUsageBits(uint32_t usage) {
ATRACE_CALL();
BQ_LOGV("setConsumerUsageBits: %#x", usage);
diff --git a/libs/gui/BufferQueueCore.cpp b/libs/gui/BufferQueueCore.cpp
index ec1e631..bc75ca7 100644
--- a/libs/gui/BufferQueueCore.cpp
+++ b/libs/gui/BufferQueueCore.cpp
@@ -53,6 +53,8 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
mConnectedProducerListener(),
mSlots(),
mQueue(),
+ mFreeSlots(),
+ mFreeBuffers(),
mOverrideMaxBufferCount(0),
mDequeueCondition(),
mUseAsyncBuffer(true),
@@ -60,13 +62,15 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
mDefaultBufferFormat(PIXEL_FORMAT_RGBA_8888),
mDefaultWidth(1),
mDefaultHeight(1),
+ mDefaultBufferDataSpace(HAL_DATASPACE_UNKNOWN),
mDefaultMaxBufferCount(2),
mMaxAcquiredBufferCount(1),
mBufferHasBeenQueued(false),
mFrameCounter(0),
mTransformHint(0),
mIsAllocating(false),
- mIsAllocatingCondition()
+ mIsAllocatingCondition(),
+ mAllowAllocation(true)
{
if (allocator == NULL) {
sp<ISurfaceComposer> composer(ComposerService::getComposerService());
@@ -75,6 +79,9 @@ BufferQueueCore::BufferQueueCore(const sp<IGraphicBufferAlloc>& allocator) :
BQ_LOGE("createGraphicBufferAlloc failed");
}
}
+ for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
+ mFreeSlots.insert(slot);
+ }
}
BufferQueueCore::~BufferQueueCore() {}
@@ -189,12 +196,20 @@ status_t BufferQueueCore::setDefaultMaxBufferCountLocked(int count) {
void BufferQueueCore::freeBufferLocked(int slot) {
BQ_LOGV("freeBufferLocked: slot %d", slot);
+ bool hadBuffer = mSlots[slot].mGraphicBuffer != NULL;
mSlots[slot].mGraphicBuffer.clear();
if (mSlots[slot].mBufferState == BufferSlot::ACQUIRED) {
mSlots[slot].mNeedsCleanupOnRelease = true;
}
+ if (mSlots[slot].mBufferState != BufferSlot::FREE) {
+ mFreeSlots.insert(slot);
+ } else if (hadBuffer) {
+ // If the slot was FREE, but we had a buffer, we need to move this slot
+ // from the free buffers list to the the free slots list
+ mFreeBuffers.remove(slot);
+ mFreeSlots.insert(slot);
+ }
mSlots[slot].mBufferState = BufferSlot::FREE;
- mSlots[slot].mFrameNumber = UINT32_MAX;
mSlots[slot].mAcquireCalled = false;
// Destroy fence as BufferQueue now takes ownership
@@ -203,6 +218,7 @@ void BufferQueueCore::freeBufferLocked(int slot) {
mSlots[slot].mEglFence = EGL_NO_SYNC_KHR;
}
mSlots[slot].mFence = Fence::NO_FENCE;
+ validateConsistencyLocked();
}
void BufferQueueCore::freeAllBuffersLocked() {
@@ -235,4 +251,48 @@ void BufferQueueCore::waitWhileAllocatingLocked() const {
}
}
+void BufferQueueCore::validateConsistencyLocked() const {
+ static const useconds_t PAUSE_TIME = 0;
+ for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
+ bool isInFreeSlots = mFreeSlots.count(slot) != 0;
+ bool isInFreeBuffers =
+ std::find(mFreeBuffers.cbegin(), mFreeBuffers.cend(), slot) !=
+ mFreeBuffers.cend();
+ if (mSlots[slot].mBufferState == BufferSlot::FREE) {
+ if (mSlots[slot].mGraphicBuffer == NULL) {
+ if (!isInFreeSlots) {
+ BQ_LOGE("Slot %d is FREE but is not in mFreeSlots", slot);
+ usleep(PAUSE_TIME);
+ }
+ if (isInFreeBuffers) {
+ BQ_LOGE("Slot %d is in mFreeSlots "
+ "but is also in mFreeBuffers", slot);
+ usleep(PAUSE_TIME);
+ }
+ } else {
+ if (!isInFreeBuffers) {
+ BQ_LOGE("Slot %d is FREE but is not in mFreeBuffers", slot);
+ usleep(PAUSE_TIME);
+ }
+ if (isInFreeSlots) {
+ BQ_LOGE("Slot %d is in mFreeBuffers "
+ "but is also in mFreeSlots", slot);
+ usleep(PAUSE_TIME);
+ }
+ }
+ } else {
+ if (isInFreeSlots) {
+ BQ_LOGE("Slot %d is in mFreeSlots but is not FREE (%d)",
+ slot, mSlots[slot].mBufferState);
+ usleep(PAUSE_TIME);
+ }
+ if (isInFreeBuffers) {
+ BQ_LOGE("Slot %d is in mFreeBuffers but is not FREE (%d)",
+ slot, mSlots[slot].mBufferState);
+ usleep(PAUSE_TIME);
+ }
+ }
+ }
+}
+
} // namespace android
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 16b9747..86e45c8 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -161,8 +161,6 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller,
}
}
- // Look for a free buffer to give to the client
- *found = BufferQueueCore::INVALID_BUFFER_SLOT;
int dequeuedCount = 0;
int acquiredCount = 0;
for (int s = 0; s < maxBufferCount; ++s) {
@@ -173,15 +171,6 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller,
case BufferSlot::ACQUIRED:
++acquiredCount;
break;
- case BufferSlot::FREE:
- // We return the oldest of the free buffers to avoid
- // stalling the producer if possible, since the consumer
- // may still have pending reads of in-flight buffers
- if (*found == BufferQueueCore::INVALID_BUFFER_SLOT ||
- mSlots[s].mFrameNumber < mSlots[*found].mFrameNumber) {
- *found = s;
- }
- break;
default:
break;
}
@@ -214,6 +203,8 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller,
}
}
+ *found = BufferQueueCore::INVALID_BUFFER_SLOT;
+
// If we disconnect and reconnect quickly, we can be in a state where
// our slots are empty but we have many buffers in the queue. This can
// cause us to run out of memory if we outrun the consumer. Wait here if
@@ -223,6 +214,19 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller,
if (tooManyBuffers) {
BQ_LOGV("%s: queue size is %zu, waiting", caller,
mCore->mQueue.size());
+ } else {
+ if (!mCore->mFreeBuffers.empty()) {
+ auto slot = mCore->mFreeBuffers.begin();
+ *found = *slot;
+ mCore->mFreeBuffers.erase(slot);
+ } else if (mCore->mAllowAllocation && !mCore->mFreeSlots.empty()) {
+ auto slot = mCore->mFreeSlots.begin();
+ // Only return free slots up to the max buffer count
+ if (*slot < maxBufferCount) {
+ *found = *slot;
+ mCore->mFreeSlots.erase(slot);
+ }
+ }
}
// If no buffer is found, or if the queue has too many buffers
@@ -250,7 +254,7 @@ status_t BufferQueueProducer::waitForFreeSlotThenRelock(const char* caller,
status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
sp<android::Fence> *outFence, bool async,
- uint32_t width, uint32_t height, uint32_t format, uint32_t usage) {
+ uint32_t width, uint32_t height, PixelFormat format, uint32_t usage) {
ATRACE_CALL();
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
@@ -281,17 +285,39 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
// Enable the usage bits the consumer requested
usage |= mCore->mConsumerUsageBits;
- int found;
- status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async,
- &found, &returnFlags);
- if (status != NO_ERROR) {
- return status;
+ const bool useDefaultSize = !width && !height;
+ if (useDefaultSize) {
+ width = mCore->mDefaultWidth;
+ height = mCore->mDefaultHeight;
}
- // This should not happen
- if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
- BQ_LOGE("dequeueBuffer: no available buffer slots");
- return -EBUSY;
+ int found = BufferItem::INVALID_BUFFER_SLOT;
+ while (found == BufferItem::INVALID_BUFFER_SLOT) {
+ status_t status = waitForFreeSlotThenRelock("dequeueBuffer", async,
+ &found, &returnFlags);
+ if (status != NO_ERROR) {
+ return status;
+ }
+
+ // This should not happen
+ if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
+ BQ_LOGE("dequeueBuffer: no available buffer slots");
+ return -EBUSY;
+ }
+
+ const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
+
+ // If we are not allowed to allocate new buffers,
+ // waitForFreeSlotThenRelock must have returned a slot containing a
+ // buffer. If this buffer would require reallocation to meet the
+ // requested attributes, we free it and attempt to get another one.
+ if (!mCore->mAllowAllocation) {
+ if (buffer->needsReallocation(width, height, format, usage)) {
+ mCore->freeBufferLocked(found);
+ found = BufferItem::INVALID_BUFFER_SLOT;
+ continue;
+ }
+ }
}
*outSlot = found;
@@ -299,20 +325,11 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
attachedByConsumer = mSlots[found].mAttachedByConsumer;
- const bool useDefaultSize = !width && !height;
- if (useDefaultSize) {
- width = mCore->mDefaultWidth;
- height = mCore->mDefaultHeight;
- }
-
mSlots[found].mBufferState = BufferSlot::DEQUEUED;
const sp<GraphicBuffer>& buffer(mSlots[found].mGraphicBuffer);
if ((buffer == NULL) ||
- (static_cast<uint32_t>(buffer->width) != width) ||
- (static_cast<uint32_t>(buffer->height) != height) ||
- (static_cast<uint32_t>(buffer->format) != format) ||
- ((static_cast<uint32_t>(buffer->usage) & usage) != usage))
+ buffer->needsReallocation(width, height, format, usage))
{
mSlots[found].mAcquireCalled = false;
mSlots[found].mGraphicBuffer = NULL;
@@ -335,13 +352,15 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
*outFence = mSlots[found].mFence;
mSlots[found].mEglFence = EGL_NO_SYNC_KHR;
mSlots[found].mFence = Fence::NO_FENCE;
+
+ mCore->validateConsistencyLocked();
} // Autolock scope
if (returnFlags & BUFFER_NEEDS_REALLOCATION) {
status_t error;
BQ_LOGV("dequeueBuffer: allocating a new buffer for slot %d", *outSlot);
sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
- width, height, format, usage, &error));
+ width, height, format, usage, &error));
if (graphicBuffer == NULL) {
BQ_LOGE("dequeueBuffer: createGraphicBuffer failed");
return error;
@@ -355,7 +374,6 @@ status_t BufferQueueProducer::dequeueBuffer(int *outSlot,
return NO_INIT;
}
- mSlots[*outSlot].mFrameNumber = UINT32_MAX;
mSlots[*outSlot].mGraphicBuffer = graphicBuffer;
} // Autolock scope
}
@@ -414,6 +432,7 @@ status_t BufferQueueProducer::detachBuffer(int slot) {
mCore->freeBufferLocked(slot);
mCore->mDequeueCondition.broadcast();
+ mCore->validateConsistencyLocked();
return NO_ERROR;
}
@@ -438,27 +457,19 @@ status_t BufferQueueProducer::detachNextBuffer(sp<GraphicBuffer>* outBuffer,
return NO_INIT;
}
- // Find the oldest valid slot
- int found = BufferQueueCore::INVALID_BUFFER_SLOT;
- for (int s = 0; s < BufferQueueDefs::NUM_BUFFER_SLOTS; ++s) {
- if (mSlots[s].mBufferState == BufferSlot::FREE &&
- mSlots[s].mGraphicBuffer != NULL) {
- if (found == BufferQueueCore::INVALID_BUFFER_SLOT ||
- mSlots[s].mFrameNumber < mSlots[found].mFrameNumber) {
- found = s;
- }
- }
- }
-
- if (found == BufferQueueCore::INVALID_BUFFER_SLOT) {
+ if (mCore->mFreeBuffers.empty()) {
return NO_MEMORY;
}
+ int found = mCore->mFreeBuffers.front();
+ mCore->mFreeBuffers.remove(found);
+
BQ_LOGV("detachNextBuffer detached slot %d", found);
*outBuffer = mSlots[found].mGraphicBuffer;
*outFence = mSlots[found].mFence;
mCore->freeBufferLocked(found);
+ mCore->validateConsistencyLocked();
return NO_ERROR;
}
@@ -506,6 +517,8 @@ status_t BufferQueueProducer::attachBuffer(int* outSlot,
mSlots[*outSlot].mFence = Fence::NO_FENCE;
mSlots[*outSlot].mRequestBufferCalled = true;
+ mCore->validateConsistencyLocked();
+
return returnFlags;
}
@@ -516,14 +529,16 @@ status_t BufferQueueProducer::queueBuffer(int slot,
int64_t timestamp;
bool isAutoTimestamp;
+ android_dataspace dataSpace;
Rect crop;
int scalingMode;
uint32_t transform;
uint32_t stickyTransform;
bool async;
sp<Fence> fence;
- input.deflate(&timestamp, &isAutoTimestamp, &crop, &scalingMode, &transform,
- &async, &fence, &stickyTransform);
+ input.deflate(&timestamp, &isAutoTimestamp, &dataSpace, &crop, &scalingMode,
+ &transform, &async, &fence, &stickyTransform);
+ Region surfaceDamage = input.getSurfaceDamage();
if (fence == NULL) {
BQ_LOGE("queueBuffer: fence is NULL");
@@ -579,11 +594,11 @@ status_t BufferQueueProducer::queueBuffer(int slot,
return BAD_VALUE;
}
- BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64
+ BQ_LOGV("queueBuffer: slot=%d/%" PRIu64 " time=%" PRIu64 " dataSpace=%d"
" crop=[%d,%d,%d,%d] transform=%#x scale=%s",
- slot, mCore->mFrameCounter + 1, timestamp,
- crop.left, crop.top, crop.right, crop.bottom,
- transform, BufferItem::scalingModeName(scalingMode));
+ slot, mCore->mFrameCounter + 1, timestamp, dataSpace,
+ crop.left, crop.top, crop.right, crop.bottom, transform,
+ BufferItem::scalingModeName(static_cast<uint32_t>(scalingMode)));
const sp<GraphicBuffer>& graphicBuffer(mSlots[slot].mGraphicBuffer);
Rect bufferRect(graphicBuffer->getWidth(), graphicBuffer->getHeight());
@@ -595,6 +610,11 @@ status_t BufferQueueProducer::queueBuffer(int slot,
return BAD_VALUE;
}
+ // Override UNKNOWN dataspace with consumer default
+ if (dataSpace == HAL_DATASPACE_UNKNOWN) {
+ dataSpace = mCore->mDefaultBufferDataSpace;
+ }
+
mSlots[slot].mFence = fence;
mSlots[slot].mBufferState = BufferSlot::QUEUED;
++mCore->mFrameCounter;
@@ -603,16 +623,19 @@ status_t BufferQueueProducer::queueBuffer(int slot,
item.mAcquireCalled = mSlots[slot].mAcquireCalled;
item.mGraphicBuffer = mSlots[slot].mGraphicBuffer;
item.mCrop = crop;
- item.mTransform = transform & ~NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY;
+ item.mTransform = transform &
+ ~static_cast<uint32_t>(NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
item.mTransformToDisplayInverse =
- bool(transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY);
- item.mScalingMode = scalingMode;
+ (transform & NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY) != 0;
+ item.mScalingMode = static_cast<uint32_t>(scalingMode);
item.mTimestamp = timestamp;
item.mIsAutoTimestamp = isAutoTimestamp;
+ item.mDataSpace = dataSpace;
item.mFrameNumber = mCore->mFrameCounter;
item.mSlot = slot;
item.mFence = fence;
item.mIsDroppable = mCore->mDequeueBufferCannotBlock || async;
+ item.mSurfaceDamage = surfaceDamage;
mStickyTransform = stickyTransform;
@@ -630,9 +653,7 @@ status_t BufferQueueProducer::queueBuffer(int slot,
// mark it as freed
if (mCore->stillTracking(front)) {
mSlots[front->mSlot].mBufferState = BufferSlot::FREE;
- // Reset the frame number of the freed buffer so that it is
- // the first in line to be dequeued again
- mSlots[front->mSlot].mFrameNumber = 0;
+ mCore->mFreeBuffers.push_front(front->mSlot);
}
// Overwrite the droppable buffer with the incoming one
*front = item;
@@ -647,12 +668,15 @@ status_t BufferQueueProducer::queueBuffer(int slot,
mCore->mDequeueCondition.broadcast();
output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
- mCore->mTransformHint, mCore->mQueue.size());
+ mCore->mTransformHint,
+ static_cast<uint32_t>(mCore->mQueue.size()));
ATRACE_INT(mCore->mConsumerName.string(), mCore->mQueue.size());
// Take a ticket for the callback functions
callbackTicket = mNextCallbackTicket++;
+
+ mCore->validateConsistencyLocked();
} // Autolock scope
// Wait without lock held
@@ -713,10 +737,11 @@ void BufferQueueProducer::cancelBuffer(int slot, const sp<Fence>& fence) {
return;
}
+ mCore->mFreeBuffers.push_front(slot);
mSlots[slot].mBufferState = BufferSlot::FREE;
- mSlots[slot].mFrameNumber = 0;
mSlots[slot].mFence = fence;
mCore->mDequeueCondition.broadcast();
+ mCore->validateConsistencyLocked();
}
int BufferQueueProducer::query(int what, int *outValue) {
@@ -736,25 +761,28 @@ int BufferQueueProducer::query(int what, int *outValue) {
int value;
switch (what) {
case NATIVE_WINDOW_WIDTH:
- value = mCore->mDefaultWidth;
+ value = static_cast<int32_t>(mCore->mDefaultWidth);
break;
case NATIVE_WINDOW_HEIGHT:
- value = mCore->mDefaultHeight;
+ value = static_cast<int32_t>(mCore->mDefaultHeight);
break;
case NATIVE_WINDOW_FORMAT:
- value = mCore->mDefaultBufferFormat;
+ value = static_cast<int32_t>(mCore->mDefaultBufferFormat);
break;
case NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS:
value = mCore->getMinUndequeuedBufferCountLocked(false);
break;
case NATIVE_WINDOW_STICKY_TRANSFORM:
- value = static_cast<int>(mStickyTransform);
+ value = static_cast<int32_t>(mStickyTransform);
break;
case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND:
value = (mCore->mQueue.size() > 1);
break;
case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
- value = mCore->mConsumerUsageBits;
+ value = static_cast<int32_t>(mCore->mConsumerUsageBits);
+ break;
+ case NATIVE_WINDOW_DEFAULT_DATASPACE:
+ value = static_cast<int32_t>(mCore->mDefaultBufferDataSpace);
break;
default:
return BAD_VALUE;
@@ -802,13 +830,14 @@ status_t BufferQueueProducer::connect(const sp<IProducerListener>& listener,
case NATIVE_WINDOW_API_CAMERA:
mCore->mConnectedApi = api;
output->inflate(mCore->mDefaultWidth, mCore->mDefaultHeight,
- mCore->mTransformHint, mCore->mQueue.size());
+ mCore->mTransformHint,
+ static_cast<uint32_t>(mCore->mQueue.size()));
// Set up a death notification so that we can disconnect
// automatically if the remote producer dies
if (listener != NULL &&
- listener->asBinder()->remoteBinder() != NULL) {
- status = listener->asBinder()->linkToDeath(
+ IInterface::asBinder(listener)->remoteBinder() != NULL) {
+ status = IInterface::asBinder(listener)->linkToDeath(
static_cast<IBinder::DeathRecipient*>(this));
if (status != NO_ERROR) {
BQ_LOGE("connect(P): linkToDeath failed: %s (%d)",
@@ -857,7 +886,7 @@ status_t BufferQueueProducer::disconnect(int api) {
// Remove our death notification callback if we have one
if (mCore->mConnectedProducerListener != NULL) {
sp<IBinder> token =
- mCore->mConnectedProducerListener->asBinder();
+ IInterface::asBinder(mCore->mConnectedProducerListener);
// This can fail if we're here because of the death
// notification, but we just ignore it
token->unlinkToDeath(
@@ -904,19 +933,25 @@ status_t BufferQueueProducer::setSidebandStream(const sp<NativeHandle>& stream)
}
void BufferQueueProducer::allocateBuffers(bool async, uint32_t width,
- uint32_t height, uint32_t format, uint32_t usage) {
+ uint32_t height, PixelFormat format, uint32_t usage) {
ATRACE_CALL();
while (true) {
Vector<int> freeSlots;
size_t newBufferCount = 0;
uint32_t allocWidth = 0;
uint32_t allocHeight = 0;
- uint32_t allocFormat = 0;
+ PixelFormat allocFormat = PIXEL_FORMAT_UNKNOWN;
uint32_t allocUsage = 0;
{ // Autolock scope
Mutex::Autolock lock(mCore->mMutex);
mCore->waitWhileAllocatingLocked();
+ if (!mCore->mAllowAllocation) {
+ BQ_LOGE("allocateBuffers: allocation is not allowed for this "
+ "BufferQueue");
+ return;
+ }
+
int currentBufferCount = 0;
for (int slot = 0; slot < BufferQueueDefs::NUM_BUFFER_SLOTS; ++slot) {
if (mSlots[slot].mGraphicBuffer != NULL) {
@@ -937,7 +972,8 @@ void BufferQueueProducer::allocateBuffers(bool async, uint32_t width,
currentBufferCount, maxBufferCount);
if (maxBufferCount <= currentBufferCount)
return;
- newBufferCount = maxBufferCount - currentBufferCount;
+ newBufferCount =
+ static_cast<size_t>(maxBufferCount - currentBufferCount);
if (freeSlots.size() < newBufferCount) {
BQ_LOGE("allocateBuffers: ran out of free slots");
return;
@@ -950,7 +986,7 @@ void BufferQueueProducer::allocateBuffers(bool async, uint32_t width,
mCore->mIsAllocating = true;
} // Autolock scope
- Vector<sp<GraphicBuffer> > buffers;
+ Vector<sp<GraphicBuffer>> buffers;
for (size_t i = 0; i < newBufferCount; ++i) {
status_t result = NO_ERROR;
sp<GraphicBuffer> graphicBuffer(mCore->mAllocator->createGraphicBuffer(
@@ -970,7 +1006,8 @@ void BufferQueueProducer::allocateBuffers(bool async, uint32_t width,
Mutex::Autolock lock(mCore->mMutex);
uint32_t checkWidth = width > 0 ? width : mCore->mDefaultWidth;
uint32_t checkHeight = height > 0 ? height : mCore->mDefaultHeight;
- uint32_t checkFormat = format != 0 ? format : mCore->mDefaultBufferFormat;
+ PixelFormat checkFormat = format != 0 ?
+ format : mCore->mDefaultBufferFormat;
uint32_t checkUsage = usage | mCore->mConsumerUsageBits;
if (checkWidth != allocWidth || checkHeight != allocHeight ||
checkFormat != allocFormat || checkUsage != allocUsage) {
@@ -992,17 +1029,32 @@ void BufferQueueProducer::allocateBuffers(bool async, uint32_t width,
}
mCore->freeBufferLocked(slot); // Clean up the slot first
mSlots[slot].mGraphicBuffer = buffers[i];
- mSlots[slot].mFrameNumber = 0;
mSlots[slot].mFence = Fence::NO_FENCE;
+
+ // freeBufferLocked puts this slot on the free slots list. Since
+ // we then attached a buffer, move the slot to free buffer list.
+ mCore->mFreeSlots.erase(slot);
+ mCore->mFreeBuffers.push_front(slot);
+
BQ_LOGV("allocateBuffers: allocated a new buffer in slot %d", slot);
}
mCore->mIsAllocating = false;
mCore->mIsAllocatingCondition.broadcast();
+ mCore->validateConsistencyLocked();
} // Autolock scope
}
}
+status_t BufferQueueProducer::allowAllocation(bool allow) {
+ ATRACE_CALL();
+ BQ_LOGV("allowAllocation: %s", allow ? "true" : "false");
+
+ Mutex::Autolock lock(mCore->mMutex);
+ mCore->mAllowAllocation = allow;
+ return NO_ERROR;
+}
+
void BufferQueueProducer::binderDied(const wp<android::IBinder>& /* who */) {
// If we're here, it means that a producer we were connected to died.
// We're guaranteed that we are still connected to it because we remove
diff --git a/libs/gui/BufferSlot.cpp b/libs/gui/BufferSlot.cpp
index b8877fe..01595de 100644
--- a/libs/gui/BufferSlot.cpp
+++ b/libs/gui/BufferSlot.cpp
@@ -24,8 +24,8 @@ const char* BufferSlot::bufferStateName(BufferState state) {
case BufferSlot::QUEUED: return "QUEUED";
case BufferSlot::FREE: return "FREE";
case BufferSlot::ACQUIRED: return "ACQUIRED";
- default: return "Unknown";
}
+ return "Unknown";
}
} // namespace android
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index 210e98e..e576018 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -27,6 +27,7 @@
#include <hardware/hardware.h>
+#include <gui/BufferItem.h>
#include <gui/IGraphicBufferAlloc.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
@@ -39,11 +40,11 @@
#include <utils/Trace.h>
// Macros for including the ConsumerBase name in log messages
-#define CB_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define CB_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define CB_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define CB_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define CB_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define CB_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
+//#define CB_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
+//#define CB_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
+//#define CB_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define CB_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
namespace android {
@@ -162,6 +163,21 @@ void ConsumerBase::setFrameAvailableListener(
mFrameAvailableListener = listener;
}
+status_t ConsumerBase::detachBuffer(int slot) {
+ CB_LOGV("detachBuffer");
+ Mutex::Autolock lock(mMutex);
+
+ status_t result = mConsumer->detachBuffer(slot);
+ if (result != NO_ERROR) {
+ CB_LOGE("Failed to detach buffer: %d", result);
+ return result;
+ }
+
+ freeBufferLocked(slot);
+
+ return result;
+}
+
void ConsumerBase::dump(String8& result) const {
dump(result, "");
}
@@ -179,7 +195,7 @@ void ConsumerBase::dumpLocked(String8& result, const char* prefix) const {
}
}
-status_t ConsumerBase::acquireBufferLocked(BufferQueue::BufferItem *item,
+status_t ConsumerBase::acquireBufferLocked(BufferItem *item,
nsecs_t presentWhen) {
status_t err = mConsumer->acquireBuffer(item, presentWhen);
if (err != NO_ERROR) {
diff --git a/libs/gui/CpuConsumer.cpp b/libs/gui/CpuConsumer.cpp
index c541ff4..eb39469 100644
--- a/libs/gui/CpuConsumer.cpp
+++ b/libs/gui/CpuConsumer.cpp
@@ -16,22 +16,23 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "CpuConsumer"
-#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+//#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <cutils/compiler.h>
#include <utils/Log.h>
+#include <gui/BufferItem.h>
#include <gui/CpuConsumer.h>
-#define CC_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define CC_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define CC_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define CC_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define CC_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define CC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
+//#define CC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
+//#define CC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define CC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define CC_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
namespace android {
CpuConsumer::CpuConsumer(const sp<IGraphicBufferConsumer>& bq,
- uint32_t maxLockedBuffers, bool controlledByApp) :
+ size_t maxLockedBuffers, bool controlledByApp) :
ConsumerBase(bq, controlledByApp),
mMaxLockedBuffers(maxLockedBuffers),
mCurrentLockedBuffers(0)
@@ -40,7 +41,7 @@ CpuConsumer::CpuConsumer(const sp<IGraphicBufferConsumer>& bq,
mAcquiredBuffers.insertAt(0, maxLockedBuffers);
mConsumer->setConsumerUsageBits(GRALLOC_USAGE_SW_READ_OFTEN);
- mConsumer->setMaxAcquiredBufferCount(maxLockedBuffers);
+ mConsumer->setMaxAcquiredBufferCount(static_cast<int32_t>(maxLockedBuffers));
}
CpuConsumer::~CpuConsumer() {
@@ -61,24 +62,29 @@ status_t CpuConsumer::setDefaultBufferSize(uint32_t width, uint32_t height)
return mConsumer->setDefaultBufferSize(width, height);
}
-status_t CpuConsumer::setDefaultBufferFormat(uint32_t defaultFormat)
+status_t CpuConsumer::setDefaultBufferFormat(PixelFormat defaultFormat)
{
Mutex::Autolock _l(mMutex);
return mConsumer->setDefaultBufferFormat(defaultFormat);
}
+status_t CpuConsumer::setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace)
+{
+ Mutex::Autolock _l(mMutex);
+ return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
+}
+
static bool isPossiblyYUV(PixelFormat format) {
- switch ((int)format) {
+ switch (static_cast<int>(format)) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_BGRA_8888:
- case HAL_PIXEL_FORMAT_sRGB_A_8888:
- case HAL_PIXEL_FORMAT_sRGB_X_8888:
case HAL_PIXEL_FORMAT_Y8:
case HAL_PIXEL_FORMAT_Y16:
- case HAL_PIXEL_FORMAT_RAW16: // same as HAL_PIXEL_FORMAT_RAW_SENSOR
+ case HAL_PIXEL_FORMAT_RAW16:
case HAL_PIXEL_FORMAT_RAW10:
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
case HAL_PIXEL_FORMAT_BLOB:
@@ -100,12 +106,12 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
if (!nativeBuffer) return BAD_VALUE;
if (mCurrentLockedBuffers == mMaxLockedBuffers) {
- CC_LOGW("Max buffers have been locked (%d), cannot lock anymore.",
+ CC_LOGW("Max buffers have been locked (%zd), cannot lock anymore.",
mMaxLockedBuffers);
return NOT_ENOUGH_DATA;
}
- BufferQueue::BufferItem b;
+ BufferItem b;
Mutex::Autolock _l(mMutex);
@@ -173,7 +179,7 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
}
size_t lockedIdx = 0;
- for (; lockedIdx < mMaxLockedBuffers; lockedIdx++) {
+ for (; lockedIdx < static_cast<size_t>(mMaxLockedBuffers); lockedIdx++) {
if (mAcquiredBuffers[lockedIdx].mSlot ==
BufferQueue::INVALID_BUFFER_SLOT) {
break;
@@ -193,19 +199,20 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
nativeBuffer->format = format;
nativeBuffer->flexFormat = flexFormat;
nativeBuffer->stride = (ycbcr.y != NULL) ?
- ycbcr.ystride :
+ static_cast<uint32_t>(ycbcr.ystride) :
mSlots[buf].mGraphicBuffer->getStride();
nativeBuffer->crop = b.mCrop;
nativeBuffer->transform = b.mTransform;
nativeBuffer->scalingMode = b.mScalingMode;
nativeBuffer->timestamp = b.mTimestamp;
+ nativeBuffer->dataSpace = b.mDataSpace;
nativeBuffer->frameNumber = b.mFrameNumber;
nativeBuffer->dataCb = reinterpret_cast<uint8_t*>(ycbcr.cb);
nativeBuffer->dataCr = reinterpret_cast<uint8_t*>(ycbcr.cr);
- nativeBuffer->chromaStride = ycbcr.cstride;
- nativeBuffer->chromaStep = ycbcr.chroma_step;
+ nativeBuffer->chromaStride = static_cast<uint32_t>(ycbcr.cstride);
+ nativeBuffer->chromaStep = static_cast<uint32_t>(ycbcr.chroma_step);
mCurrentLockedBuffers++;
@@ -215,10 +222,9 @@ status_t CpuConsumer::lockNextBuffer(LockedBuffer *nativeBuffer) {
status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) {
Mutex::Autolock _l(mMutex);
size_t lockedIdx = 0;
- status_t err;
void *bufPtr = reinterpret_cast<void *>(nativeBuffer.data);
- for (; lockedIdx < mMaxLockedBuffers; lockedIdx++) {
+ for (; lockedIdx < static_cast<size_t>(mMaxLockedBuffers); lockedIdx++) {
if (bufPtr == mAcquiredBuffers[lockedIdx].mBufferPointer) break;
}
if (lockedIdx == mMaxLockedBuffers) {
@@ -229,13 +235,13 @@ status_t CpuConsumer::unlockBuffer(const LockedBuffer &nativeBuffer) {
return releaseAcquiredBufferLocked(lockedIdx);
}
-status_t CpuConsumer::releaseAcquiredBufferLocked(int lockedIdx) {
+status_t CpuConsumer::releaseAcquiredBufferLocked(size_t lockedIdx) {
status_t err;
int fd = -1;
err = mAcquiredBuffers[lockedIdx].mGraphicBuffer->unlockAsync(&fd);
if (err != OK) {
- CC_LOGE("%s: Unable to unlock graphic buffer %d", __FUNCTION__,
+ CC_LOGE("%s: Unable to unlock graphic buffer %zd", __FUNCTION__,
lockedIdx);
return err;
}
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 318c087..96c0841 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -29,6 +29,7 @@
#include <hardware/hardware.h>
+#include <gui/BufferItem.h>
#include <gui/GLConsumer.h>
#include <gui/IGraphicBufferAlloc.h>
#include <gui/ISurfaceComposer.h>
@@ -47,18 +48,28 @@ EGLAPI const char* eglQueryStringImplementationANDROID(EGLDisplay dpy, EGLint na
namespace android {
// Macros for including the GLConsumer name in log messages
-#define ST_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define ST_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define GLC_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define GLC_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
+//#define GLC_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define GLC_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define GLC_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
static const struct {
- size_t width, height;
+ uint32_t width, height;
char const* bits;
} kDebugData = { 15, 12,
- "___________________________________XX_XX_______X_X_____X_X____X_XXXXXXX_X____XXXXXXXXXXX__"
- "___XX_XXX_XX_______XXXXXXX_________X___X_________X_____X__________________________________"
+ "_______________"
+ "_______________"
+ "_____XX_XX_____"
+ "__X_X_____X_X__"
+ "__X_XXXXXXX_X__"
+ "__XXXXXXXXXXX__"
+ "___XX_XXX_XX___"
+ "____XXXXXXX____"
+ "_____X___X_____"
+ "____X_____X____"
+ "_______________"
+ "_______________"
};
// Transform matrices
@@ -135,7 +146,7 @@ GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t tex,
mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
mAttached(true)
{
- ST_LOGV("GLConsumer");
+ GLC_LOGV("GLConsumer");
memcpy(mCurrentTransformMatrix, mtxIdentity,
sizeof(mCurrentTransformMatrix));
@@ -154,7 +165,7 @@ GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget,
mDefaultWidth(1),
mDefaultHeight(1),
mFilteringEnabled(true),
- mTexName(-1),
+ mTexName(0),
mUseFenceSync(useFenceSync),
mTexTarget(texTarget),
mEglDisplay(EGL_NO_DISPLAY),
@@ -162,7 +173,7 @@ GLConsumer::GLConsumer(const sp<IGraphicBufferConsumer>& bq, uint32_t texTarget,
mCurrentTexture(BufferQueue::INVALID_BUFFER_SLOT),
mAttached(false)
{
- ST_LOGV("GLConsumer");
+ GLC_LOGV("GLConsumer");
memcpy(mCurrentTransformMatrix, mtxIdentity,
sizeof(mCurrentTransformMatrix));
@@ -186,11 +197,11 @@ status_t GLConsumer::setDefaultBufferSize(uint32_t w, uint32_t h)
status_t GLConsumer::updateTexImage() {
ATRACE_CALL();
- ST_LOGV("updateTexImage");
+ GLC_LOGV("updateTexImage");
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
- ST_LOGE("updateTexImage: GLConsumer is abandoned!");
+ GLC_LOGE("updateTexImage: GLConsumer is abandoned!");
return NO_INIT;
}
@@ -200,7 +211,7 @@ status_t GLConsumer::updateTexImage() {
return err;
}
- BufferQueue::BufferItem item;
+ BufferItem item;
// Acquire the next buffer.
// In asynchronous mode the list is guaranteed to be one buffer
@@ -209,11 +220,11 @@ status_t GLConsumer::updateTexImage() {
if (err != NO_ERROR) {
if (err == BufferQueue::NO_BUFFER_AVAILABLE) {
// We always bind the texture even if we don't update its contents.
- ST_LOGV("updateTexImage: no buffers were available");
+ GLC_LOGV("updateTexImage: no buffers were available");
glBindTexture(mTexTarget, mTexName);
err = NO_ERROR;
} else {
- ST_LOGE("updateTexImage: acquire failed: %s (%d)",
+ GLC_LOGE("updateTexImage: acquire failed: %s (%d)",
strerror(-err), err);
}
return err;
@@ -234,11 +245,11 @@ status_t GLConsumer::updateTexImage() {
status_t GLConsumer::releaseTexImage() {
ATRACE_CALL();
- ST_LOGV("releaseTexImage");
+ GLC_LOGV("releaseTexImage");
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
- ST_LOGE("releaseTexImage: GLConsumer is abandoned!");
+ GLC_LOGE("releaseTexImage: GLConsumer is abandoned!");
return NO_INIT;
}
@@ -258,13 +269,13 @@ status_t GLConsumer::releaseTexImage() {
int buf = mCurrentTexture;
if (buf != BufferQueue::INVALID_BUFFER_SLOT) {
- ST_LOGV("releaseTexImage: (slot=%d, mAttached=%d)", buf, mAttached);
+ GLC_LOGV("releaseTexImage: (slot=%d, mAttached=%d)", buf, mAttached);
if (mAttached) {
// Do whatever sync ops we need to do before releasing the slot.
err = syncForReleaseLocked(mEglDisplay);
if (err != NO_ERROR) {
- ST_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err);
+ GLC_LOGE("syncForReleaseLocked failed (slot=%d), err=%d", buf, err);
return err;
}
} else {
@@ -274,7 +285,7 @@ status_t GLConsumer::releaseTexImage() {
err = releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer, mEglDisplay, EGL_NO_SYNC_KHR);
if (err < NO_ERROR) {
- ST_LOGE("releaseTexImage: failed to release buffer: %s (%d)",
+ GLC_LOGE("releaseTexImage: failed to release buffer: %s (%d)",
strerror(-err), err);
return err;
}
@@ -293,9 +304,9 @@ status_t GLConsumer::releaseTexImage() {
if (mAttached) {
// This binds a dummy buffer (mReleasedTexImage).
- status_t err = bindTextureImageLocked();
- if (err != NO_ERROR) {
- return err;
+ status_t result = bindTextureImageLocked();
+ if (result != NO_ERROR) {
+ return result;
}
} else {
// detached, don't touch the texture (and we may not even have an
@@ -316,14 +327,15 @@ sp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() {
GraphicBuffer::USAGE_SW_WRITE_RARELY);
uint32_t* bits;
buffer->lock(GraphicBuffer::USAGE_SW_WRITE_RARELY, reinterpret_cast<void**>(&bits));
- size_t w = buffer->getStride();
- size_t h = buffer->getHeight();
- memset(bits, 0, w*h*4);
- for (size_t y=0 ; y<kDebugData.height ; y++) {
- for (size_t x=0 ; x<kDebugData.width ; x++) {
- bits[x] = (kDebugData.bits[y*kDebugData.width+x] == 'X') ? 0xFF000000 : 0xFFFFFFFF;
+ uint32_t stride = buffer->getStride();
+ uint32_t height = buffer->getHeight();
+ memset(bits, 0, stride * height * 4);
+ for (uint32_t y = 0; y < kDebugData.height; y++) {
+ for (uint32_t x = 0; x < kDebugData.width; x++) {
+ bits[x] = (kDebugData.bits[y + kDebugData.width + x] == 'X') ?
+ 0xFF000000 : 0xFFFFFFFF;
}
- bits += w;
+ bits += stride;
}
buffer->unlock();
sReleasedTexImageBuffer = buffer;
@@ -331,7 +343,7 @@ sp<GraphicBuffer> GLConsumer::getDebugTexImageBuffer() {
return sReleasedTexImageBuffer;
}
-status_t GLConsumer::acquireBufferLocked(BufferQueue::BufferItem *item,
+status_t GLConsumer::acquireBufferLocked(BufferItem *item,
nsecs_t presentWhen) {
status_t err = ConsumerBase::acquireBufferLocked(item, presentWhen);
if (err != NO_ERROR) {
@@ -362,14 +374,14 @@ status_t GLConsumer::releaseBufferLocked(int buf,
return err;
}
-status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item)
+status_t GLConsumer::updateAndReleaseLocked(const BufferItem& item)
{
status_t err = NO_ERROR;
int buf = item.mBuf;
if (!mAttached) {
- ST_LOGE("updateAndRelease: GLConsumer is not attached to an OpenGL "
+ GLC_LOGE("updateAndRelease: GLConsumer is not attached to an OpenGL "
"ES context");
releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
mEglDisplay, EGL_NO_SYNC_KHR);
@@ -391,7 +403,7 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item)
// means the buffer was previously acquired).
err = mEglSlots[buf].mEglImage->createIfNeeded(mEglDisplay, item.mCrop);
if (err != NO_ERROR) {
- ST_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d",
+ GLC_LOGW("updateAndRelease: unable to createImage on display=%p slot=%d",
mEglDisplay, buf);
releaseBufferLocked(buf, mSlots[buf].mGraphicBuffer,
mEglDisplay, EGL_NO_SYNC_KHR);
@@ -410,7 +422,7 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item)
return err;
}
- ST_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)",
+ GLC_LOGV("updateAndRelease: (slot=%d buf=%p) -> (slot=%d buf=%p)",
mCurrentTexture, mCurrentTextureImage != NULL ?
mCurrentTextureImage->graphicBufferHandle() : 0,
buf, mSlots[buf].mGraphicBuffer->handle);
@@ -421,7 +433,7 @@ status_t GLConsumer::updateAndReleaseLocked(const BufferQueue::BufferItem& item)
mCurrentTexture, mCurrentTextureImage->graphicBuffer(),
mEglDisplay, mEglSlots[mCurrentTexture].mEglFence);
if (status < NO_ERROR) {
- ST_LOGE("updateAndRelease: failed to release buffer: %s (%d)",
+ GLC_LOGE("updateAndRelease: failed to release buffer: %s (%d)",
strerror(-status), status);
err = status;
// keep going, with error raised [?]
@@ -449,22 +461,22 @@ status_t GLConsumer::bindTextureImageLocked() {
return INVALID_OPERATION;
}
- GLint error;
+ GLenum error;
while ((error = glGetError()) != GL_NO_ERROR) {
- ST_LOGW("bindTextureImage: clearing GL error: %#04x", error);
+ GLC_LOGW("bindTextureImage: clearing GL error: %#04x", error);
}
glBindTexture(mTexTarget, mTexName);
if (mCurrentTexture == BufferQueue::INVALID_BUFFER_SLOT &&
mCurrentTextureImage == NULL) {
- ST_LOGE("bindTextureImage: no currently-bound texture");
+ GLC_LOGE("bindTextureImage: no currently-bound texture");
return NO_INIT;
}
status_t err = mCurrentTextureImage->createIfNeeded(mEglDisplay,
mCurrentCrop);
if (err != NO_ERROR) {
- ST_LOGW("bindTextureImage: can't create image on display=%p slot=%d",
+ GLC_LOGW("bindTextureImage: can't create image on display=%p slot=%d",
mEglDisplay, mCurrentTexture);
return UNKNOWN_ERROR;
}
@@ -476,17 +488,17 @@ status_t GLConsumer::bindTextureImageLocked() {
// forcing the creation of a new image.
if ((error = glGetError()) != GL_NO_ERROR) {
glBindTexture(mTexTarget, mTexName);
- status_t err = mCurrentTextureImage->createIfNeeded(mEglDisplay,
- mCurrentCrop,
- true);
- if (err != NO_ERROR) {
- ST_LOGW("bindTextureImage: can't create image on display=%p slot=%d",
+ status_t result = mCurrentTextureImage->createIfNeeded(mEglDisplay,
+ mCurrentCrop,
+ true);
+ if (result != NO_ERROR) {
+ GLC_LOGW("bindTextureImage: can't create image on display=%p slot=%d",
mEglDisplay, mCurrentTexture);
return UNKNOWN_ERROR;
}
mCurrentTextureImage->bindToTextureTarget(mTexTarget);
if ((error = glGetError()) != GL_NO_ERROR) {
- ST_LOGE("bindTextureImage: error binding external image: %#04x", error);
+ GLC_LOGE("bindTextureImage: error binding external image: %#04x", error);
return UNKNOWN_ERROR;
}
}
@@ -511,12 +523,12 @@ status_t GLConsumer::checkAndUpdateEglStateLocked(bool contextCheck) {
}
if (mEglDisplay != dpy || dpy == EGL_NO_DISPLAY) {
- ST_LOGE("checkAndUpdateEglState: invalid current EGLDisplay");
+ GLC_LOGE("checkAndUpdateEglState: invalid current EGLDisplay");
return INVALID_OPERATION;
}
if (mEglContext != ctx || ctx == EGL_NO_CONTEXT) {
- ST_LOGE("checkAndUpdateEglState: invalid current EGLContext");
+ GLC_LOGE("checkAndUpdateEglState: invalid current EGLContext");
return INVALID_OPERATION;
}
@@ -531,7 +543,7 @@ void GLConsumer::setReleaseFence(const sp<Fence>& fence) {
status_t err = addReleaseFence(mCurrentTexture,
mCurrentTextureImage->graphicBuffer(), fence);
if (err != OK) {
- ST_LOGE("setReleaseFence: failed to add the fence: %s (%d)",
+ GLC_LOGE("setReleaseFence: failed to add the fence: %s (%d)",
strerror(-err), err);
}
}
@@ -539,16 +551,16 @@ void GLConsumer::setReleaseFence(const sp<Fence>& fence) {
status_t GLConsumer::detachFromContext() {
ATRACE_CALL();
- ST_LOGV("detachFromContext");
+ GLC_LOGV("detachFromContext");
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
- ST_LOGE("detachFromContext: abandoned GLConsumer");
+ GLC_LOGE("detachFromContext: abandoned GLConsumer");
return NO_INIT;
}
if (!mAttached) {
- ST_LOGE("detachFromContext: GLConsumer is not attached to a "
+ GLC_LOGE("detachFromContext: GLConsumer is not attached to a "
"context");
return INVALID_OPERATION;
}
@@ -557,12 +569,12 @@ status_t GLConsumer::detachFromContext() {
EGLContext ctx = eglGetCurrentContext();
if (mEglDisplay != dpy && mEglDisplay != EGL_NO_DISPLAY) {
- ST_LOGE("detachFromContext: invalid current EGLDisplay");
+ GLC_LOGE("detachFromContext: invalid current EGLDisplay");
return INVALID_OPERATION;
}
if (mEglContext != ctx && mEglContext != EGL_NO_CONTEXT) {
- ST_LOGE("detachFromContext: invalid current EGLContext");
+ GLC_LOGE("detachFromContext: invalid current EGLContext");
return INVALID_OPERATION;
}
@@ -584,16 +596,16 @@ status_t GLConsumer::detachFromContext() {
status_t GLConsumer::attachToContext(uint32_t tex) {
ATRACE_CALL();
- ST_LOGV("attachToContext");
+ GLC_LOGV("attachToContext");
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
- ST_LOGE("attachToContext: abandoned GLConsumer");
+ GLC_LOGE("attachToContext: abandoned GLConsumer");
return NO_INIT;
}
if (mAttached) {
- ST_LOGE("attachToContext: GLConsumer is already attached to a "
+ GLC_LOGE("attachToContext: GLConsumer is already attached to a "
"context");
return INVALID_OPERATION;
}
@@ -602,12 +614,12 @@ status_t GLConsumer::attachToContext(uint32_t tex) {
EGLContext ctx = eglGetCurrentContext();
if (dpy == EGL_NO_DISPLAY) {
- ST_LOGE("attachToContext: invalid current EGLDisplay");
+ GLC_LOGE("attachToContext: invalid current EGLDisplay");
return INVALID_OPERATION;
}
if (ctx == EGL_NO_CONTEXT) {
- ST_LOGE("attachToContext: invalid current EGLContext");
+ GLC_LOGE("attachToContext: invalid current EGLContext");
return INVALID_OPERATION;
}
@@ -636,14 +648,14 @@ status_t GLConsumer::attachToContext(uint32_t tex) {
status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) {
- ST_LOGV("syncForReleaseLocked");
+ GLC_LOGV("syncForReleaseLocked");
if (mCurrentTexture != BufferQueue::INVALID_BUFFER_SLOT) {
if (SyncFeatures::getInstance().useNativeFenceSync()) {
EGLSyncKHR sync = eglCreateSyncKHR(dpy,
EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
if (sync == EGL_NO_SYNC_KHR) {
- ST_LOGE("syncForReleaseLocked: error creating EGL fence: %#x",
+ GLC_LOGE("syncForReleaseLocked: error creating EGL fence: %#x",
eglGetError());
return UNKNOWN_ERROR;
}
@@ -651,7 +663,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) {
int fenceFd = eglDupNativeFenceFDANDROID(dpy, sync);
eglDestroySyncKHR(dpy, sync);
if (fenceFd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
- ST_LOGE("syncForReleaseLocked: error dup'ing native fence "
+ GLC_LOGE("syncForReleaseLocked: error dup'ing native fence "
"fd: %#x", eglGetError());
return UNKNOWN_ERROR;
}
@@ -659,7 +671,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) {
status_t err = addReleaseFenceLocked(mCurrentTexture,
mCurrentTextureImage->graphicBuffer(), fence);
if (err != OK) {
- ST_LOGE("syncForReleaseLocked: error adding release fence: "
+ GLC_LOGE("syncForReleaseLocked: error adding release fence: "
"%s (%d)", strerror(-err), err);
return err;
}
@@ -672,11 +684,11 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) {
// before the producer accesses it.
EGLint result = eglClientWaitSyncKHR(dpy, fence, 0, 1000000000);
if (result == EGL_FALSE) {
- ST_LOGE("syncForReleaseLocked: error waiting for previous "
+ GLC_LOGE("syncForReleaseLocked: error waiting for previous "
"fence: %#x", eglGetError());
return UNKNOWN_ERROR;
} else if (result == EGL_TIMEOUT_EXPIRED_KHR) {
- ST_LOGE("syncForReleaseLocked: timeout waiting for previous "
+ GLC_LOGE("syncForReleaseLocked: timeout waiting for previous "
"fence");
return TIMED_OUT;
}
@@ -687,7 +699,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) {
// OpenGL ES context.
fence = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, NULL);
if (fence == EGL_NO_SYNC_KHR) {
- ST_LOGE("syncForReleaseLocked: error creating fence: %#x",
+ GLC_LOGE("syncForReleaseLocked: error creating fence: %#x",
eglGetError());
return UNKNOWN_ERROR;
}
@@ -699,7 +711,7 @@ status_t GLConsumer::syncForReleaseLocked(EGLDisplay dpy) {
return OK;
}
-bool GLConsumer::isExternalFormat(uint32_t format)
+bool GLConsumer::isExternalFormat(PixelFormat format)
{
switch (format) {
// supported YUV formats
@@ -730,14 +742,14 @@ void GLConsumer::getTransformMatrix(float mtx[16]) {
void GLConsumer::setFilteringEnabled(bool enabled) {
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
- ST_LOGE("setFilteringEnabled: GLConsumer is abandoned!");
+ GLC_LOGE("setFilteringEnabled: GLConsumer is abandoned!");
return;
}
bool needsRecompute = mFilteringEnabled != enabled;
mFilteringEnabled = enabled;
if (needsRecompute && mCurrentTextureImage==NULL) {
- ST_LOGD("setFilteringEnabled called with mCurrentTextureImage == NULL");
+ GLC_LOGD("setFilteringEnabled called with mCurrentTextureImage == NULL");
}
if (needsRecompute && mCurrentTextureImage != NULL) {
@@ -746,7 +758,7 @@ void GLConsumer::setFilteringEnabled(bool enabled) {
}
void GLConsumer::computeCurrentTransformMatrixLocked() {
- ST_LOGV("computeCurrentTransformMatrixLocked");
+ GLC_LOGV("computeCurrentTransformMatrixLocked");
float xform[16];
for (int i = 0; i < 16; i++) {
@@ -778,7 +790,7 @@ void GLConsumer::computeCurrentTransformMatrixLocked() {
NULL : mCurrentTextureImage->graphicBuffer();
if (buf == NULL) {
- ST_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureImage is NULL");
+ GLC_LOGD("computeCurrentTransformMatrixLocked: mCurrentTextureImage is NULL");
}
float mtxBeforeFlipV[16];
@@ -850,13 +862,13 @@ void GLConsumer::computeCurrentTransformMatrixLocked() {
}
nsecs_t GLConsumer::getTimestamp() {
- ST_LOGV("getTimestamp");
+ GLC_LOGV("getTimestamp");
Mutex::Autolock lock(mMutex);
return mCurrentTimestamp;
}
-nsecs_t GLConsumer::getFrameNumber() {
- ST_LOGV("getFrameNumber");
+uint64_t GLConsumer::getFrameNumber() {
+ GLC_LOGV("getFrameNumber");
Mutex::Autolock lock(mMutex);
return mCurrentFrameNumber;
}
@@ -872,30 +884,33 @@ Rect GLConsumer::getCurrentCrop() const {
Rect outCrop = mCurrentCrop;
if (mCurrentScalingMode == NATIVE_WINDOW_SCALING_MODE_SCALE_CROP) {
- int32_t newWidth = mCurrentCrop.width();
- int32_t newHeight = mCurrentCrop.height();
+ uint32_t newWidth = static_cast<uint32_t>(mCurrentCrop.width());
+ uint32_t newHeight = static_cast<uint32_t>(mCurrentCrop.height());
if (newWidth * mDefaultHeight > newHeight * mDefaultWidth) {
newWidth = newHeight * mDefaultWidth / mDefaultHeight;
- ST_LOGV("too wide: newWidth = %d", newWidth);
+ GLC_LOGV("too wide: newWidth = %d", newWidth);
} else if (newWidth * mDefaultHeight < newHeight * mDefaultWidth) {
newHeight = newWidth * mDefaultHeight / mDefaultWidth;
- ST_LOGV("too tall: newHeight = %d", newHeight);
+ GLC_LOGV("too tall: newHeight = %d", newHeight);
}
+ uint32_t currentWidth = static_cast<uint32_t>(mCurrentCrop.width());
+ uint32_t currentHeight = static_cast<uint32_t>(mCurrentCrop.height());
+
// The crop is too wide
- if (newWidth < mCurrentCrop.width()) {
- int32_t dw = (newWidth - mCurrentCrop.width())/2;
- outCrop.left -=dw;
- outCrop.right += dw;
+ if (newWidth < currentWidth) {
+ uint32_t dw = (currentWidth - newWidth) / 2;
+ outCrop.left += dw;
+ outCrop.right -= dw;
// The crop is too tall
- } else if (newHeight < mCurrentCrop.height()) {
- int32_t dh = (newHeight - mCurrentCrop.height())/2;
- outCrop.top -= dh;
- outCrop.bottom += dh;
+ } else if (newHeight < currentHeight) {
+ uint32_t dh = (currentHeight - newHeight) / 2;
+ outCrop.top += dh;
+ outCrop.bottom -= dh;
}
- ST_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]",
+ GLC_LOGV("getCurrentCrop final crop [%d,%d,%d,%d]",
outCrop.left, outCrop.top,
outCrop.right,outCrop.bottom);
}
@@ -929,12 +944,12 @@ status_t GLConsumer::doGLFenceWaitLocked() const {
EGLContext ctx = eglGetCurrentContext();
if (mEglDisplay != dpy || mEglDisplay == EGL_NO_DISPLAY) {
- ST_LOGE("doGLFenceWait: invalid current EGLDisplay");
+ GLC_LOGE("doGLFenceWait: invalid current EGLDisplay");
return INVALID_OPERATION;
}
if (mEglContext != ctx || mEglContext == EGL_NO_CONTEXT) {
- ST_LOGE("doGLFenceWait: invalid current EGLContext");
+ GLC_LOGE("doGLFenceWait: invalid current EGLContext");
return INVALID_OPERATION;
}
@@ -943,7 +958,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const {
// Create an EGLSyncKHR from the current fence.
int fenceFd = mCurrentFence->dup();
if (fenceFd == -1) {
- ST_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno);
+ GLC_LOGE("doGLFenceWait: error dup'ing fence fd: %d", errno);
return -errno;
}
EGLint attribs[] = {
@@ -954,7 +969,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const {
EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
if (sync == EGL_NO_SYNC_KHR) {
close(fenceFd);
- ST_LOGE("doGLFenceWait: error creating EGL fence: %#x",
+ GLC_LOGE("doGLFenceWait: error creating EGL fence: %#x",
eglGetError());
return UNKNOWN_ERROR;
}
@@ -966,7 +981,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const {
EGLint eglErr = eglGetError();
eglDestroySyncKHR(dpy, sync);
if (eglErr != EGL_SUCCESS) {
- ST_LOGE("doGLFenceWait: error waiting for EGL fence: %#x",
+ GLC_LOGE("doGLFenceWait: error waiting for EGL fence: %#x",
eglErr);
return UNKNOWN_ERROR;
}
@@ -974,7 +989,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const {
status_t err = mCurrentFence->waitForever(
"GLConsumer::doGLFenceWaitLocked");
if (err != NO_ERROR) {
- ST_LOGE("doGLFenceWait: error waiting for fence: %d", err);
+ GLC_LOGE("doGLFenceWait: error waiting for fence: %d", err);
return err;
}
}
@@ -984,7 +999,7 @@ status_t GLConsumer::doGLFenceWaitLocked() const {
}
void GLConsumer::freeBufferLocked(int slotIndex) {
- ST_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
+ GLC_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
if (slotIndex == mCurrentTexture) {
mCurrentTexture = BufferQueue::INVALID_BUFFER_SLOT;
}
@@ -993,7 +1008,7 @@ void GLConsumer::freeBufferLocked(int slotIndex) {
}
void GLConsumer::abandonLocked() {
- ST_LOGV("abandonLocked");
+ GLC_LOGV("abandonLocked");
mCurrentTextureImage.clear();
ConsumerBase::abandonLocked();
}
@@ -1004,11 +1019,17 @@ void GLConsumer::setName(const String8& name) {
mConsumer->setConsumerName(name);
}
-status_t GLConsumer::setDefaultBufferFormat(uint32_t defaultFormat) {
+status_t GLConsumer::setDefaultBufferFormat(PixelFormat defaultFormat) {
Mutex::Autolock lock(mMutex);
return mConsumer->setDefaultBufferFormat(defaultFormat);
}
+status_t GLConsumer::setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace) {
+ Mutex::Autolock lock(mMutex);
+ return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
+}
+
status_t GLConsumer::setConsumerUsageBits(uint32_t usage) {
Mutex::Autolock lock(mMutex);
usage |= DEFAULT_USAGE_FLAGS;
@@ -1107,12 +1128,14 @@ status_t GLConsumer::EglImage::createIfNeeded(EGLDisplay eglDisplay,
}
void GLConsumer::EglImage::bindToTextureTarget(uint32_t texTarget) {
- glEGLImageTargetTexture2DOES(texTarget, (GLeglImageOES)mEglImage);
+ glEGLImageTargetTexture2DOES(texTarget,
+ static_cast<GLeglImageOES>(mEglImage));
}
EGLImageKHR GLConsumer::EglImage::createImage(EGLDisplay dpy,
const sp<GraphicBuffer>& graphicBuffer, const Rect& crop) {
- EGLClientBuffer cbuf = (EGLClientBuffer)graphicBuffer->getNativeBuffer();
+ EGLClientBuffer cbuf =
+ static_cast<EGLClientBuffer>(graphicBuffer->getNativeBuffer());
EGLint attrs[] = {
EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
EGL_IMAGE_CROP_LEFT_ANDROID, crop.left,
diff --git a/libs/gui/GraphicBufferAlloc.cpp b/libs/gui/GraphicBufferAlloc.cpp
index b360e81..9643402 100644
--- a/libs/gui/GraphicBufferAlloc.cpp
+++ b/libs/gui/GraphicBufferAlloc.cpp
@@ -31,9 +31,10 @@ GraphicBufferAlloc::GraphicBufferAlloc() {
GraphicBufferAlloc::~GraphicBufferAlloc() {
}
-sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage, status_t* error) {
- sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(w, h, format, usage));
+sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t width,
+ uint32_t height, PixelFormat format, uint32_t usage, status_t* error) {
+ sp<GraphicBuffer> graphicBuffer(
+ new GraphicBuffer(width, height, format, usage));
status_t err = graphicBuffer->initCheck();
*error = err;
if (err != 0 || graphicBuffer->handle == 0) {
@@ -42,7 +43,7 @@ sp<GraphicBuffer> GraphicBufferAlloc::createGraphicBuffer(uint32_t w, uint32_t h
}
ALOGE("GraphicBufferAlloc::createGraphicBuffer(w=%d, h=%d) "
"failed (%s), handle=%p",
- w, h, strerror(-err), graphicBuffer->handle);
+ width, height, strerror(-err), graphicBuffer->handle);
return 0;
}
return graphicBuffer;
diff --git a/libs/gui/IConsumerListener.cpp b/libs/gui/IConsumerListener.cpp
index 409dfe4..cab7dc3 100644
--- a/libs/gui/IConsumerListener.cpp
+++ b/libs/gui/IConsumerListener.cpp
@@ -40,6 +40,8 @@ public:
: BpInterface<IConsumerListener>(impl) {
}
+ virtual ~BpConsumerListener();
+
virtual void onFrameAvailable(const BufferItem& item) {
Parcel data, reply;
data.writeInterfaceToken(IConsumerListener::getInterfaceDescriptor());
@@ -60,6 +62,10 @@ public:
}
};
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpConsumerListener::~BpConsumerListener() {}
+
IMPLEMENT_META_INTERFACE(ConsumerListener, "android.gui.IConsumerListener");
// ----------------------------------------------------------------------
diff --git a/libs/gui/IDisplayEventConnection.cpp b/libs/gui/IDisplayEventConnection.cpp
index 887d176..9890f44 100644
--- a/libs/gui/IDisplayEventConnection.cpp
+++ b/libs/gui/IDisplayEventConnection.cpp
@@ -44,6 +44,8 @@ public:
{
}
+ virtual ~BpDisplayEventConnection();
+
virtual sp<BitTube> getDataChannel() const
{
Parcel data, reply;
@@ -55,7 +57,7 @@ public:
virtual void setVsyncRate(uint32_t count) {
Parcel data, reply;
data.writeInterfaceToken(IDisplayEventConnection::getInterfaceDescriptor());
- data.writeInt32(count);
+ data.writeUint32(count);
remote()->transact(SET_VSYNC_RATE, data, &reply);
}
@@ -66,6 +68,10 @@ public:
}
};
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpDisplayEventConnection::~BpDisplayEventConnection() {}
+
IMPLEMENT_META_INTERFACE(DisplayEventConnection, "android.gui.DisplayEventConnection");
// ----------------------------------------------------------------------------
@@ -79,17 +85,17 @@ status_t BnDisplayEventConnection::onTransact(
sp<BitTube> channel(getDataChannel());
channel->writeToParcel(reply);
return NO_ERROR;
- } break;
+ }
case SET_VSYNC_RATE: {
CHECK_INTERFACE(IDisplayEventConnection, data, reply);
- setVsyncRate(data.readInt32());
+ setVsyncRate(data.readUint32());
return NO_ERROR;
- } break;
+ }
case REQUEST_NEXT_VSYNC: {
CHECK_INTERFACE(IDisplayEventConnection, data, reply);
requestNextVsync();
return NO_ERROR;
- } break;
+ }
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/IGraphicBufferAlloc.cpp b/libs/gui/IGraphicBufferAlloc.cpp
index 139f219..09b63a1 100644
--- a/libs/gui/IGraphicBufferAlloc.cpp
+++ b/libs/gui/IGraphicBufferAlloc.cpp
@@ -42,14 +42,17 @@ public:
{
}
- virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat format, uint32_t usage, status_t* error) {
+ virtual ~BpGraphicBufferAlloc();
+
+ virtual sp<GraphicBuffer> createGraphicBuffer(uint32_t width,
+ uint32_t height, PixelFormat format, uint32_t usage,
+ status_t* error) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferAlloc::getInterfaceDescriptor());
- data.writeInt32(w);
- data.writeInt32(h);
- data.writeInt32(format);
- data.writeInt32(usage);
+ data.writeUint32(width);
+ data.writeUint32(height);
+ data.writeInt32(static_cast<int32_t>(format));
+ data.writeUint32(usage);
remote()->transact(CREATE_GRAPHIC_BUFFER, data, &reply);
sp<GraphicBuffer> graphicBuffer;
status_t result = reply.readInt32();
@@ -65,6 +68,10 @@ public:
}
};
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpGraphicBufferAlloc::~BpGraphicBufferAlloc() {}
+
IMPLEMENT_META_INTERFACE(GraphicBufferAlloc, "android.ui.IGraphicBufferAlloc");
// ----------------------------------------------------------------------
@@ -74,27 +81,26 @@ status_t BnGraphicBufferAlloc::onTransact(
{
// codes that don't require permission check
- /* BufferReference just keeps a strong reference to a
- * GraphicBuffer until it is destroyed (that is, until
- * no local or remote process have a reference to it).
- */
+ // BufferReference just keeps a strong reference to a GraphicBuffer until it
+ // is destroyed (that is, until no local or remote process have a reference
+ // to it).
class BufferReference : public BBinder {
- sp<GraphicBuffer> buffer;
+ sp<GraphicBuffer> mBuffer;
public:
- BufferReference(const sp<GraphicBuffer>& buffer) : buffer(buffer) { }
+ BufferReference(const sp<GraphicBuffer>& buffer) : mBuffer(buffer) {}
};
- switch(code) {
+ switch (code) {
case CREATE_GRAPHIC_BUFFER: {
CHECK_INTERFACE(IGraphicBufferAlloc, data, reply);
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- PixelFormat format = data.readInt32();
- uint32_t usage = data.readInt32();
+ uint32_t width = data.readUint32();
+ uint32_t height = data.readUint32();
+ PixelFormat format = static_cast<PixelFormat>(data.readInt32());
+ uint32_t usage = data.readUint32();
status_t error;
sp<GraphicBuffer> result =
- createGraphicBuffer(w, h, format, usage, &error);
+ createGraphicBuffer(width, height, format, usage, &error);
reply->writeInt32(error);
if (result != 0) {
reply->write(*result);
@@ -107,7 +113,7 @@ status_t BnGraphicBufferAlloc::onTransact(
reply->writeStrongBinder( new BufferReference(result) );
}
return NO_ERROR;
- } break;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/IGraphicBufferConsumer.cpp b/libs/gui/IGraphicBufferConsumer.cpp
index dc917a8..3c0907a 100644
--- a/libs/gui/IGraphicBufferConsumer.cpp
+++ b/libs/gui/IGraphicBufferConsumer.cpp
@@ -23,6 +23,7 @@
#include <binder/Parcel.h>
#include <binder/IInterface.h>
+#include <gui/BufferItem.h>
#include <gui/IConsumerListener.h>
#include <gui/IGraphicBufferConsumer.h>
@@ -32,159 +33,6 @@
#include <system/window.h>
namespace android {
-// ---------------------------------------------------------------------------
-
-IGraphicBufferConsumer::BufferItem::BufferItem() :
- mTransform(0),
- mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
- mTimestamp(0),
- mIsAutoTimestamp(false),
- mFrameNumber(0),
- mBuf(INVALID_BUFFER_SLOT),
- mIsDroppable(false),
- mAcquireCalled(false),
- mTransformToDisplayInverse(false) {
- mCrop.makeInvalid();
-}
-
-size_t IGraphicBufferConsumer::BufferItem::getPodSize() const {
- size_t c = sizeof(mCrop) +
- sizeof(mTransform) +
- sizeof(mScalingMode) +
- sizeof(mTimestamp) +
- sizeof(mIsAutoTimestamp) +
- sizeof(mFrameNumber) +
- sizeof(mBuf) +
- sizeof(mIsDroppable) +
- sizeof(mAcquireCalled) +
- sizeof(mTransformToDisplayInverse);
- return c;
-}
-
-size_t IGraphicBufferConsumer::BufferItem::getFlattenedSize() const {
- size_t c = 0;
- if (mGraphicBuffer != 0) {
- c += mGraphicBuffer->getFlattenedSize();
- c = FlattenableUtils::align<4>(c);
- }
- if (mFence != 0) {
- c += mFence->getFlattenedSize();
- c = FlattenableUtils::align<4>(c);
- }
- return sizeof(int32_t) + c + getPodSize();
-}
-
-size_t IGraphicBufferConsumer::BufferItem::getFdCount() const {
- size_t c = 0;
- if (mGraphicBuffer != 0) {
- c += mGraphicBuffer->getFdCount();
- }
- if (mFence != 0) {
- c += mFence->getFdCount();
- }
- return c;
-}
-
-static void writeBoolAsInt(void*& buffer, size_t& size, bool b) {
- FlattenableUtils::write(buffer, size, static_cast<int32_t>(b));
-}
-
-static bool readBoolFromInt(void const*& buffer, size_t& size) {
- int32_t i;
- FlattenableUtils::read(buffer, size, i);
- return static_cast<bool>(i);
-}
-
-status_t IGraphicBufferConsumer::BufferItem::flatten(
- void*& buffer, size_t& size, int*& fds, size_t& count) const {
-
- // make sure we have enough space
- if (size < BufferItem::getFlattenedSize()) {
- return NO_MEMORY;
- }
-
- // content flags are stored first
- uint32_t& flags = *static_cast<uint32_t*>(buffer);
-
- // advance the pointer
- FlattenableUtils::advance(buffer, size, sizeof(uint32_t));
-
- flags = 0;
- if (mGraphicBuffer != 0) {
- status_t err = mGraphicBuffer->flatten(buffer, size, fds, count);
- if (err) return err;
- size -= FlattenableUtils::align<4>(buffer);
- flags |= 1;
- }
- if (mFence != 0) {
- status_t err = mFence->flatten(buffer, size, fds, count);
- if (err) return err;
- size -= FlattenableUtils::align<4>(buffer);
- flags |= 2;
- }
-
- // check we have enough space (in case flattening the fence/graphicbuffer lied to us)
- if (size < getPodSize()) {
- return NO_MEMORY;
- }
-
- FlattenableUtils::write(buffer, size, mCrop);
- FlattenableUtils::write(buffer, size, mTransform);
- FlattenableUtils::write(buffer, size, mScalingMode);
- FlattenableUtils::write(buffer, size, mTimestamp);
- writeBoolAsInt(buffer, size, mIsAutoTimestamp);
- FlattenableUtils::write(buffer, size, mFrameNumber);
- FlattenableUtils::write(buffer, size, mBuf);
- writeBoolAsInt(buffer, size, mIsDroppable);
- writeBoolAsInt(buffer, size, mAcquireCalled);
- writeBoolAsInt(buffer, size, mTransformToDisplayInverse);
-
- return NO_ERROR;
-}
-
-status_t IGraphicBufferConsumer::BufferItem::unflatten(
- void const*& buffer, size_t& size, int const*& fds, size_t& count) {
-
- if (size < sizeof(uint32_t))
- return NO_MEMORY;
-
- uint32_t flags = 0;
- FlattenableUtils::read(buffer, size, flags);
-
- if (flags & 1) {
- mGraphicBuffer = new GraphicBuffer();
- status_t err = mGraphicBuffer->unflatten(buffer, size, fds, count);
- if (err) return err;
- size -= FlattenableUtils::align<4>(buffer);
- }
-
- if (flags & 2) {
- mFence = new Fence();
- status_t err = mFence->unflatten(buffer, size, fds, count);
- if (err) return err;
- size -= FlattenableUtils::align<4>(buffer);
- }
-
- // check we have enough space
- if (size < getPodSize()) {
- return NO_MEMORY;
- }
-
- FlattenableUtils::read(buffer, size, mCrop);
- FlattenableUtils::read(buffer, size, mTransform);
- FlattenableUtils::read(buffer, size, mScalingMode);
- FlattenableUtils::read(buffer, size, mTimestamp);
- mIsAutoTimestamp = readBoolFromInt(buffer, size);
- FlattenableUtils::read(buffer, size, mFrameNumber);
- FlattenableUtils::read(buffer, size, mBuf);
- mIsDroppable = readBoolFromInt(buffer, size);
- mAcquireCalled = readBoolFromInt(buffer, size);
- mTransformToDisplayInverse = readBoolFromInt(buffer, size);
-
- return NO_ERROR;
-}
-
-// ---------------------------------------------------------------------------
enum {
ACQUIRE_BUFFER = IBinder::FIRST_CALL_TRANSACTION,
@@ -200,6 +48,7 @@ enum {
SET_MAX_ACQUIRED_BUFFER_COUNT,
SET_CONSUMER_NAME,
SET_DEFAULT_BUFFER_FORMAT,
+ SET_DEFAULT_BUFFER_DATA_SPACE,
SET_CONSUMER_USAGE_BITS,
SET_TRANSFORM_HINT,
GET_SIDEBAND_STREAM,
@@ -215,6 +64,8 @@ public:
{
}
+ virtual ~BpGraphicBufferConsumer();
+
virtual status_t acquireBuffer(BufferItem *buffer, nsecs_t presentWhen) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
@@ -261,7 +112,7 @@ public:
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
data.writeInt32(buf);
- data.writeInt64(frameNumber);
+ data.writeInt64(static_cast<int64_t>(frameNumber));
data.write(*releaseFence);
status_t result = remote()->transact(RELEASE_BUFFER, data, &reply);
if (result != NO_ERROR) {
@@ -273,7 +124,7 @@ public:
virtual status_t consumerConnect(const sp<IConsumerListener>& consumer, bool controlledByApp) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
- data.writeStrongBinder(consumer->asBinder());
+ data.writeStrongBinder(IInterface::asBinder(consumer));
data.writeInt32(controlledByApp);
status_t result = remote()->transact(CONSUMER_CONNECT, data, &reply);
if (result != NO_ERROR) {
@@ -303,15 +154,15 @@ public:
if (result != NO_ERROR) {
return result;
}
- *slotMask = reply.readInt64();
+ *slotMask = static_cast<uint64_t>(reply.readInt64());
return reply.readInt32();
}
- virtual status_t setDefaultBufferSize(uint32_t w, uint32_t h) {
+ virtual status_t setDefaultBufferSize(uint32_t width, uint32_t height) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
- data.writeInt32(w);
- data.writeInt32(h);
+ data.writeUint32(width);
+ data.writeUint32(height);
status_t result = remote()->transact(SET_DEFAULT_BUFFER_SIZE, data, &reply);
if (result != NO_ERROR) {
return result;
@@ -358,10 +209,10 @@ public:
remote()->transact(SET_CONSUMER_NAME, data, &reply);
}
- virtual status_t setDefaultBufferFormat(uint32_t defaultFormat) {
+ virtual status_t setDefaultBufferFormat(PixelFormat defaultFormat) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
- data.writeInt32(defaultFormat);
+ data.writeInt32(static_cast<int32_t>(defaultFormat));
status_t result = remote()->transact(SET_DEFAULT_BUFFER_FORMAT, data, &reply);
if (result != NO_ERROR) {
return result;
@@ -369,10 +220,23 @@ public:
return reply.readInt32();
}
+ virtual status_t setDefaultBufferDataSpace(
+ android_dataspace defaultDataSpace) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(defaultDataSpace));
+ status_t result = remote()->transact(SET_DEFAULT_BUFFER_DATA_SPACE,
+ data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ return reply.readInt32();
+ }
+
virtual status_t setConsumerUsageBits(uint32_t usage) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
- data.writeInt32(usage);
+ data.writeUint32(usage);
status_t result = remote()->transact(SET_CONSUMER_USAGE_BITS, data, &reply);
if (result != NO_ERROR) {
return result;
@@ -383,7 +247,7 @@ public:
virtual status_t setTransformHint(uint32_t hint) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferConsumer::getInterfaceDescriptor());
- data.writeInt32(hint);
+ data.writeUint32(hint);
status_t result = remote()->transact(SET_TRANSFORM_HINT, data, &reply);
if (result != NO_ERROR) {
return result;
@@ -415,6 +279,10 @@ public:
}
};
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpGraphicBufferConsumer::~BpGraphicBufferConsumer() {}
+
IMPLEMENT_META_INTERFACE(GraphicBufferConsumer, "android.gui.IGraphicBufferConsumer");
// ----------------------------------------------------------------------
@@ -432,14 +300,14 @@ status_t BnGraphicBufferConsumer::onTransact(
if (err) return err;
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case DETACH_BUFFER: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
int slot = data.readInt32();
int result = detachBuffer(slot);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case ATTACH_BUFFER: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
sp<GraphicBuffer> buffer = new GraphicBuffer();
@@ -449,11 +317,11 @@ status_t BnGraphicBufferConsumer::onTransact(
reply->writeInt32(slot);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case RELEASE_BUFFER: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
int buf = data.readInt32();
- uint64_t frameNumber = data.readInt64();
+ uint64_t frameNumber = static_cast<uint64_t>(data.readInt64());
sp<Fence> releaseFence = new Fence();
status_t err = data.read(*releaseFence);
if (err) return err;
@@ -461,7 +329,7 @@ status_t BnGraphicBufferConsumer::onTransact(
EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case CONSUMER_CONNECT: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
sp<IConsumerListener> consumer = IConsumerListener::asInterface( data.readStrongBinder() );
@@ -469,75 +337,83 @@ status_t BnGraphicBufferConsumer::onTransact(
status_t result = consumerConnect(consumer, controlledByApp);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case CONSUMER_DISCONNECT: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
status_t result = consumerDisconnect();
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case GET_RELEASED_BUFFERS: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
uint64_t slotMask;
status_t result = getReleasedBuffers(&slotMask);
- reply->writeInt64(slotMask);
+ reply->writeInt64(static_cast<int64_t>(slotMask));
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case SET_DEFAULT_BUFFER_SIZE: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- status_t result = setDefaultBufferSize(w, h);
+ uint32_t width = data.readUint32();
+ uint32_t height = data.readUint32();
+ status_t result = setDefaultBufferSize(width, height);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case SET_DEFAULT_MAX_BUFFER_COUNT: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
- uint32_t bufferCount = data.readInt32();
+ int bufferCount = data.readInt32();
status_t result = setDefaultMaxBufferCount(bufferCount);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case DISABLE_ASYNC_BUFFER: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
status_t result = disableAsyncBuffer();
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case SET_MAX_ACQUIRED_BUFFER_COUNT: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
- uint32_t maxAcquiredBuffers = data.readInt32();
+ int maxAcquiredBuffers = data.readInt32();
status_t result = setMaxAcquiredBufferCount(maxAcquiredBuffers);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case SET_CONSUMER_NAME: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
setConsumerName( data.readString8() );
return NO_ERROR;
- } break;
+ }
case SET_DEFAULT_BUFFER_FORMAT: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
- uint32_t defaultFormat = data.readInt32();
+ PixelFormat defaultFormat = static_cast<PixelFormat>(data.readInt32());
status_t result = setDefaultBufferFormat(defaultFormat);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
+ case SET_DEFAULT_BUFFER_DATA_SPACE: {
+ CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
+ android_dataspace defaultDataSpace =
+ static_cast<android_dataspace>(data.readInt32());
+ status_t result = setDefaultBufferDataSpace(defaultDataSpace);
+ reply->writeInt32(result);
+ return NO_ERROR;
+ }
case SET_CONSUMER_USAGE_BITS: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
- uint32_t usage = data.readInt32();
+ uint32_t usage = data.readUint32();
status_t result = setConsumerUsageBits(usage);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case SET_TRANSFORM_HINT: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
- uint32_t hint = data.readInt32();
+ uint32_t hint = data.readUint32();
status_t result = setTransformHint(hint);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case DUMP: {
CHECK_INTERFACE(IGraphicBufferConsumer, data, reply);
String8 result = data.readString8();
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 67690b7..ec05f60 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -46,6 +46,7 @@ enum {
DISCONNECT,
SET_SIDEBAND_STREAM,
ALLOCATE_BUFFERS,
+ ALLOW_ALLOCATION,
};
class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
@@ -56,6 +57,8 @@ public:
{
}
+ virtual ~BpGraphicBufferProducer();
+
virtual status_t requestBuffer(int bufferIdx, sp<GraphicBuffer>* buf) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
@@ -91,14 +94,15 @@ public:
}
virtual status_t dequeueBuffer(int *buf, sp<Fence>* fence, bool async,
- uint32_t w, uint32_t h, uint32_t format, uint32_t usage) {
+ uint32_t width, uint32_t height, PixelFormat format,
+ uint32_t usage) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
- data.writeInt32(async);
- data.writeInt32(w);
- data.writeInt32(h);
- data.writeInt32(format);
- data.writeInt32(usage);
+ data.writeInt32(static_cast<int32_t>(async));
+ data.writeUint32(width);
+ data.writeUint32(height);
+ data.writeInt32(static_cast<int32_t>(format));
+ data.writeUint32(usage);
status_t result = remote()->transact(DEQUEUE_BUFFER, data, &reply);
if (result != NO_ERROR) {
return result;
@@ -211,7 +215,7 @@ public:
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
if (listener != NULL) {
data.writeInt32(1);
- data.writeStrongBinder(listener->asBinder());
+ data.writeStrongBinder(IInterface::asBinder(listener));
} else {
data.writeInt32(0);
}
@@ -255,21 +259,37 @@ public:
}
virtual void allocateBuffers(bool async, uint32_t width, uint32_t height,
- uint32_t format, uint32_t usage) {
+ PixelFormat format, uint32_t usage) {
Parcel data, reply;
data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
data.writeInt32(static_cast<int32_t>(async));
- data.writeInt32(static_cast<int32_t>(width));
- data.writeInt32(static_cast<int32_t>(height));
+ data.writeUint32(width);
+ data.writeUint32(height);
data.writeInt32(static_cast<int32_t>(format));
- data.writeInt32(static_cast<int32_t>(usage));
+ data.writeUint32(usage);
status_t result = remote()->transact(ALLOCATE_BUFFERS, data, &reply);
if (result != NO_ERROR) {
ALOGE("allocateBuffers failed to transact: %d", result);
}
}
+
+ virtual status_t allowAllocation(bool allow) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(allow));
+ status_t result = remote()->transact(ALLOW_ALLOCATION, data, &reply);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readInt32();
+ return result;
+ }
};
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpGraphicBufferProducer::~BpGraphicBufferProducer() {}
+
IMPLEMENT_META_INTERFACE(GraphicBufferProducer, "android.gui.IGraphicBufferProducer");
// ----------------------------------------------------------------------
@@ -289,24 +309,25 @@ status_t BnGraphicBufferProducer::onTransact(
}
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case SET_BUFFER_COUNT: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
int bufferCount = data.readInt32();
int result = setBufferCount(bufferCount);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case DEQUEUE_BUFFER: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
- bool async = data.readInt32();
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- uint32_t format = data.readInt32();
- uint32_t usage = data.readInt32();
+ bool async = static_cast<bool>(data.readInt32());
+ uint32_t width = data.readUint32();
+ uint32_t height = data.readUint32();
+ PixelFormat format = static_cast<PixelFormat>(data.readInt32());
+ uint32_t usage = data.readUint32();
int buf = 0;
sp<Fence> fence;
- int result = dequeueBuffer(&buf, &fence, async, w, h, format, usage);
+ int result = dequeueBuffer(&buf, &fence, async, width, height,
+ format, usage);
reply->writeInt32(buf);
reply->writeInt32(fence != NULL);
if (fence != NULL) {
@@ -314,14 +335,14 @@ status_t BnGraphicBufferProducer::onTransact(
}
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case DETACH_BUFFER: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
int slot = data.readInt32();
int result = detachBuffer(slot);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case DETACH_NEXT_BUFFER: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
sp<GraphicBuffer> buffer;
@@ -339,7 +360,7 @@ status_t BnGraphicBufferProducer::onTransact(
}
}
return NO_ERROR;
- } break;
+ }
case ATTACH_BUFFER: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
sp<GraphicBuffer> buffer = new GraphicBuffer();
@@ -349,7 +370,7 @@ status_t BnGraphicBufferProducer::onTransact(
reply->writeInt32(slot);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case QUEUE_BUFFER: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
int buf = data.readInt32();
@@ -361,7 +382,7 @@ status_t BnGraphicBufferProducer::onTransact(
status_t result = queueBuffer(buf, input, output);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case CANCEL_BUFFER: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
int buf = data.readInt32();
@@ -369,7 +390,7 @@ status_t BnGraphicBufferProducer::onTransact(
data.read(*fence.get());
cancelBuffer(buf, fence);
return NO_ERROR;
- } break;
+ }
case QUERY: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
int value = 0;
@@ -378,7 +399,7 @@ status_t BnGraphicBufferProducer::onTransact(
reply->writeInt32(value);
reply->writeInt32(res);
return NO_ERROR;
- } break;
+ }
case CONNECT: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
sp<IProducerListener> listener;
@@ -393,14 +414,14 @@ status_t BnGraphicBufferProducer::onTransact(
status_t res = connect(listener, api, producerControlledByApp, output);
reply->writeInt32(res);
return NO_ERROR;
- } break;
+ }
case DISCONNECT: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
int api = data.readInt32();
status_t res = disconnect(api);
reply->writeInt32(res);
return NO_ERROR;
- } break;
+ }
case SET_SIDEBAND_STREAM: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
sp<NativeHandle> stream;
@@ -410,16 +431,24 @@ status_t BnGraphicBufferProducer::onTransact(
status_t result = setSidebandStream(stream);
reply->writeInt32(result);
return NO_ERROR;
- } break;
- case ALLOCATE_BUFFERS:
+ }
+ case ALLOCATE_BUFFERS: {
CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
bool async = static_cast<bool>(data.readInt32());
- uint32_t width = static_cast<uint32_t>(data.readInt32());
- uint32_t height = static_cast<uint32_t>(data.readInt32());
- uint32_t format = static_cast<uint32_t>(data.readInt32());
- uint32_t usage = static_cast<uint32_t>(data.readInt32());
+ uint32_t width = data.readUint32();
+ uint32_t height = data.readUint32();
+ PixelFormat format = static_cast<PixelFormat>(data.readInt32());
+ uint32_t usage = data.readUint32();
allocateBuffers(async, width, height, format, usage);
return NO_ERROR;
+ }
+ case ALLOW_ALLOCATION: {
+ CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+ bool allow = static_cast<bool>(data.readInt32());
+ status_t result = allowAllocation(allow);
+ reply->writeInt32(result);
+ return NO_ERROR;
+ }
}
return BBinder::onTransact(code, data, reply, flags);
}
@@ -433,12 +462,14 @@ IGraphicBufferProducer::QueueBufferInput::QueueBufferInput(const Parcel& parcel)
size_t IGraphicBufferProducer::QueueBufferInput::getFlattenedSize() const {
return sizeof(timestamp)
+ sizeof(isAutoTimestamp)
+ + sizeof(dataSpace)
+ sizeof(crop)
+ sizeof(scalingMode)
+ sizeof(transform)
+ sizeof(stickyTransform)
+ sizeof(async)
- + fence->getFlattenedSize();
+ + fence->getFlattenedSize()
+ + surfaceDamage.getFlattenedSize();
}
size_t IGraphicBufferProducer::QueueBufferInput::getFdCount() const {
@@ -453,12 +484,17 @@ status_t IGraphicBufferProducer::QueueBufferInput::flatten(
}
FlattenableUtils::write(buffer, size, timestamp);
FlattenableUtils::write(buffer, size, isAutoTimestamp);
+ FlattenableUtils::write(buffer, size, dataSpace);
FlattenableUtils::write(buffer, size, crop);
FlattenableUtils::write(buffer, size, scalingMode);
FlattenableUtils::write(buffer, size, transform);
FlattenableUtils::write(buffer, size, stickyTransform);
FlattenableUtils::write(buffer, size, async);
- return fence->flatten(buffer, size, fds, count);
+ status_t result = fence->flatten(buffer, size, fds, count);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ return surfaceDamage.flatten(buffer, size);
}
status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
@@ -467,6 +503,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
size_t minNeeded =
sizeof(timestamp)
+ sizeof(isAutoTimestamp)
+ + sizeof(dataSpace)
+ sizeof(crop)
+ sizeof(scalingMode)
+ sizeof(transform)
@@ -479,6 +516,7 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
FlattenableUtils::read(buffer, size, timestamp);
FlattenableUtils::read(buffer, size, isAutoTimestamp);
+ FlattenableUtils::read(buffer, size, dataSpace);
FlattenableUtils::read(buffer, size, crop);
FlattenableUtils::read(buffer, size, scalingMode);
FlattenableUtils::read(buffer, size, transform);
@@ -486,7 +524,11 @@ status_t IGraphicBufferProducer::QueueBufferInput::unflatten(
FlattenableUtils::read(buffer, size, async);
fence = new Fence();
- return fence->unflatten(buffer, size, fds, count);
+ status_t result = fence->unflatten(buffer, size, fds, count);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ return surfaceDamage.unflatten(buffer, size);
}
}; // namespace android
diff --git a/libs/gui/IProducerListener.cpp b/libs/gui/IProducerListener.cpp
index efe4069..81adc95 100644
--- a/libs/gui/IProducerListener.cpp
+++ b/libs/gui/IProducerListener.cpp
@@ -30,6 +30,8 @@ public:
BpProducerListener(const sp<IBinder>& impl)
: BpInterface<IProducerListener>(impl) {}
+ virtual ~BpProducerListener();
+
virtual void onBufferReleased() {
Parcel data, reply;
data.writeInterfaceToken(IProducerListener::getInterfaceDescriptor());
@@ -37,6 +39,10 @@ public:
}
};
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpProducerListener::~BpProducerListener() {}
+
IMPLEMENT_META_INTERFACE(ProducerListener, "android.gui.IProducerListener")
status_t BnProducerListener::onTransact(uint32_t code, const Parcel& data,
diff --git a/libs/gui/ISensorEventConnection.cpp b/libs/gui/ISensorEventConnection.cpp
index 28fcb53..dc7a35c 100644
--- a/libs/gui/ISensorEventConnection.cpp
+++ b/libs/gui/ISensorEventConnection.cpp
@@ -45,6 +45,8 @@ public:
{
}
+ virtual ~BpSensorEventConnection();
+
virtual sp<BitTube> getSensorChannel() const
{
Parcel data, reply;
@@ -85,6 +87,10 @@ public:
}
};
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpSensorEventConnection::~BpSensorEventConnection() {}
+
IMPLEMENT_META_INTERFACE(SensorEventConnection, "android.gui.SensorEventConnection");
// ----------------------------------------------------------------------------
@@ -98,7 +104,7 @@ status_t BnSensorEventConnection::onTransact(
sp<BitTube> channel(getSensorChannel());
channel->writeToParcel(reply);
return NO_ERROR;
- } break;
+ }
case ENABLE_DISABLE: {
CHECK_INTERFACE(ISensorEventConnection, data, reply);
int handle = data.readInt32();
@@ -110,21 +116,21 @@ status_t BnSensorEventConnection::onTransact(
maxBatchReportLatencyNs, reservedFlags);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case SET_EVENT_RATE: {
CHECK_INTERFACE(ISensorEventConnection, data, reply);
int handle = data.readInt32();
- int ns = data.readInt64();
+ nsecs_t ns = data.readInt64();
status_t result = setEventRate(handle, ns);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case FLUSH_SENSOR: {
CHECK_INTERFACE(ISensorEventConnection, data, reply);
status_t result = flush();
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/ISensorServer.cpp b/libs/gui/ISensorServer.cpp
index 0b76f37..8e09e7c 100644
--- a/libs/gui/ISensorServer.cpp
+++ b/libs/gui/ISensorServer.cpp
@@ -45,6 +45,8 @@ public:
{
}
+ virtual ~BpSensorServer();
+
virtual Vector<Sensor> getSensorList()
{
Parcel data, reply;
@@ -52,7 +54,7 @@ public:
remote()->transact(GET_SENSOR_LIST, data, &reply);
Sensor s;
Vector<Sensor> v;
- int32_t n = reply.readInt32();
+ uint32_t n = reply.readUint32();
v.setCapacity(n);
while (n--) {
reply.read(s);
@@ -70,6 +72,10 @@ public:
}
};
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpSensorServer::~BpSensorServer() {}
+
IMPLEMENT_META_INTERFACE(SensorServer, "android.gui.SensorServer");
// ----------------------------------------------------------------------
@@ -82,18 +88,18 @@ status_t BnSensorServer::onTransact(
CHECK_INTERFACE(ISensorServer, data, reply);
Vector<Sensor> v(getSensorList());
size_t n = v.size();
- reply->writeInt32(n);
- for (size_t i=0 ; i<n ; i++) {
+ reply->writeUint32(static_cast<uint32_t>(n));
+ for (size_t i = 0; i < n; i++) {
reply->write(v[i]);
}
return NO_ERROR;
- } break;
+ }
case CREATE_SENSOR_EVENT_CONNECTION: {
CHECK_INTERFACE(ISensorServer, data, reply);
sp<ISensorEventConnection> connection(createSensorEventConnection());
- reply->writeStrongBinder(connection->asBinder());
+ reply->writeStrongBinder(IInterface::asBinder(connection));
return NO_ERROR;
- } break;
+ }
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index ebb687a..78886d5 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -51,9 +51,10 @@ public:
{
}
+ virtual ~BpSurfaceComposer();
+
virtual sp<ISurfaceComposerClient> createConnection()
{
- uint32_t n;
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
@@ -62,7 +63,6 @@ public:
virtual sp<IGraphicBufferAlloc> createGraphicBufferAlloc()
{
- uint32_t n;
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
remote()->transact(BnSurfaceComposer::CREATE_GRAPHIC_BUFFER_ALLOC, data, &reply);
@@ -76,23 +76,18 @@ public:
{
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- {
- Vector<ComposerState>::const_iterator b(state.begin());
- Vector<ComposerState>::const_iterator e(state.end());
- data.writeInt32(state.size());
- for ( ; b != e ; ++b ) {
- b->write(data);
- }
+
+ data.writeUint32(static_cast<uint32_t>(state.size()));
+ for (const auto& s : state) {
+ s.write(data);
}
- {
- Vector<DisplayState>::const_iterator b(displays.begin());
- Vector<DisplayState>::const_iterator e(displays.end());
- data.writeInt32(displays.size());
- for ( ; b != e ; ++b ) {
- b->write(data);
- }
+
+ data.writeUint32(static_cast<uint32_t>(displays.size()));
+ for (const auto& d : displays) {
+ d.write(data);
}
- data.writeInt32(flags);
+
+ data.writeUint32(flags);
remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
}
@@ -113,12 +108,12 @@ public:
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
data.writeStrongBinder(display);
- data.writeStrongBinder(producer->asBinder());
+ data.writeStrongBinder(IInterface::asBinder(producer));
data.write(sourceCrop);
- data.writeInt32(reqWidth);
- data.writeInt32(reqHeight);
- data.writeInt32(minLayerZ);
- data.writeInt32(maxLayerZ);
+ data.writeUint32(reqWidth);
+ data.writeUint32(reqHeight);
+ data.writeUint32(minLayerZ);
+ data.writeUint32(maxLayerZ);
data.writeInt32(static_cast<int32_t>(useIdentityTransform));
data.writeInt32(static_cast<int32_t>(rotation));
remote()->transact(BnSurfaceComposer::CAPTURE_SCREEN, data, &reply);
@@ -137,7 +132,7 @@ public:
"interface descriptor: %s (%d)", strerror(-err), -err);
return false;
}
- err = data.writeStrongBinder(bufferProducer->asBinder());
+ err = data.writeStrongBinder(IInterface::asBinder(bufferProducer));
if (err != NO_ERROR) {
ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
"strong binder to parcel: %s (%d)", strerror(-err), -err);
@@ -226,7 +221,7 @@ public:
remote()->transact(BnSurfaceComposer::GET_DISPLAY_CONFIGS, data, &reply);
status_t result = reply.readInt32();
if (result == NO_ERROR) {
- size_t numConfigs = static_cast<size_t>(reply.readInt32());
+ size_t numConfigs = reply.readUint32();
configs->clear();
configs->resize(numConfigs);
for (size_t c = 0; c < numConfigs; ++c) {
@@ -289,6 +284,10 @@ public:
}
};
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpSurfaceComposer::~BpSurfaceComposer() {}
+
IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
// ----------------------------------------------------------------------
@@ -299,46 +298,49 @@ status_t BnSurfaceComposer::onTransact(
switch(code) {
case CREATE_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> b = createConnection()->asBinder();
+ sp<IBinder> b = IInterface::asBinder(createConnection());
reply->writeStrongBinder(b);
return NO_ERROR;
}
case CREATE_GRAPHIC_BUFFER_ALLOC: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> b = createGraphicBufferAlloc()->asBinder();
+ sp<IBinder> b = IInterface::asBinder(createGraphicBufferAlloc());
reply->writeStrongBinder(b);
return NO_ERROR;
}
case SET_TRANSACTION_STATE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
- size_t count = data.readInt32();
+
+ size_t count = data.readUint32();
if (count > data.dataSize()) {
return BAD_VALUE;
}
ComposerState s;
Vector<ComposerState> state;
state.setCapacity(count);
- for (size_t i=0 ; i<count ; i++) {
+ for (size_t i = 0; i < count; i++) {
if (s.read(data) == BAD_VALUE) {
return BAD_VALUE;
}
state.add(s);
}
- count = data.readInt32();
+
+ count = data.readUint32();
if (count > data.dataSize()) {
return BAD_VALUE;
}
DisplayState d;
Vector<DisplayState> displays;
displays.setCapacity(count);
- for (size_t i=0 ; i<count ; i++) {
+ for (size_t i = 0; i < count; i++) {
if (d.read(data) == BAD_VALUE) {
return BAD_VALUE;
}
displays.add(d);
}
- uint32_t flags = data.readInt32();
- setTransactionState(state, displays, flags);
+
+ uint32_t stateFlags = data.readUint32();
+ setTransactionState(state, displays, stateFlags);
return NO_ERROR;
}
case BOOT_FINISHED: {
@@ -353,12 +355,12 @@ status_t BnSurfaceComposer::onTransact(
interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
Rect sourceCrop;
data.read(sourceCrop);
- uint32_t reqWidth = data.readInt32();
- uint32_t reqHeight = data.readInt32();
- uint32_t minLayerZ = data.readInt32();
- uint32_t maxLayerZ = data.readInt32();
+ uint32_t reqWidth = data.readUint32();
+ uint32_t reqHeight = data.readUint32();
+ uint32_t minLayerZ = data.readUint32();
+ uint32_t maxLayerZ = data.readUint32();
bool useIdentityTransform = static_cast<bool>(data.readInt32());
- uint32_t rotation = data.readInt32();
+ int32_t rotation = data.readInt32();
status_t res = captureScreen(display, producer,
sourceCrop, reqWidth, reqHeight, minLayerZ, maxLayerZ,
@@ -378,7 +380,7 @@ status_t BnSurfaceComposer::onTransact(
case CREATE_DISPLAY_EVENT_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
sp<IDisplayEventConnection> connection(createDisplayEventConnection());
- reply->writeStrongBinder(connection->asBinder());
+ reply->writeStrongBinder(IInterface::asBinder(connection));
return NO_ERROR;
}
case CREATE_DISPLAY: {
@@ -409,7 +411,7 @@ status_t BnSurfaceComposer::onTransact(
status_t result = getDisplayConfigs(display, &configs);
reply->writeInt32(result);
if (result == NO_ERROR) {
- reply->writeInt32(static_cast<int32_t>(configs.size()));
+ reply->writeUint32(static_cast<uint32_t>(configs.size()));
for (size_t c = 0; c < configs.size(); ++c) {
memcpy(reply->writeInplace(sizeof(DisplayInfo)),
&configs[c], sizeof(DisplayInfo));
@@ -469,8 +471,6 @@ status_t BnSurfaceComposer::onTransact(
return BBinder::onTransact(code, data, reply, flags);
}
}
- // should be unreachable
- return NO_ERROR;
}
// ----------------------------------------------------------------------------
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
index 3da6423..2ecb908 100644
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ b/libs/gui/ISurfaceComposerClient.cpp
@@ -51,17 +51,19 @@ public:
: BpInterface<ISurfaceComposerClient>(impl) {
}
- virtual status_t createSurface(const String8& name, uint32_t w,
- uint32_t h, PixelFormat format, uint32_t flags,
+ virtual ~BpSurfaceComposerClient();
+
+ virtual status_t createSurface(const String8& name, uint32_t width,
+ uint32_t height, PixelFormat format, uint32_t flags,
sp<IBinder>* handle,
sp<IGraphicBufferProducer>* gbp) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposerClient::getInterfaceDescriptor());
data.writeString8(name);
- data.writeInt32(w);
- data.writeInt32(h);
- data.writeInt32(format);
- data.writeInt32(flags);
+ data.writeUint32(width);
+ data.writeUint32(height);
+ data.writeInt32(static_cast<int32_t>(format));
+ data.writeUint32(flags);
remote()->transact(CREATE_SURFACE, data, &reply);
*handle = reply.readStrongBinder();
*gbp = interface_cast<IGraphicBufferProducer>(reply.readStrongBinder());
@@ -94,6 +96,10 @@ public:
}
};
+// Out-of-line virtual method definition to trigger vtable emission in this
+// translation unit (see clang warning -Wweak-vtables)
+BpSurfaceComposerClient::~BpSurfaceComposerClient() {}
+
IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");
// ----------------------------------------------------------------------
@@ -105,31 +111,31 @@ status_t BnSurfaceComposerClient::onTransact(
case CREATE_SURFACE: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
String8 name = data.readString8();
- uint32_t w = data.readInt32();
- uint32_t h = data.readInt32();
- PixelFormat format = data.readInt32();
- uint32_t flags = data.readInt32();
+ uint32_t width = data.readUint32();
+ uint32_t height = data.readUint32();
+ PixelFormat format = static_cast<PixelFormat>(data.readInt32());
+ uint32_t createFlags = data.readUint32();
sp<IBinder> handle;
sp<IGraphicBufferProducer> gbp;
- status_t result = createSurface(name, w, h, format, flags,
- &handle, &gbp);
+ status_t result = createSurface(name, width, height, format,
+ createFlags, &handle, &gbp);
reply->writeStrongBinder(handle);
- reply->writeStrongBinder(gbp->asBinder());
+ reply->writeStrongBinder(IInterface::asBinder(gbp));
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case DESTROY_SURFACE: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
reply->writeInt32(destroySurface( data.readStrongBinder() ) );
return NO_ERROR;
- } break;
+ }
case CLEAR_LAYER_FRAME_STATS: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
sp<IBinder> handle = data.readStrongBinder();
status_t result = clearLayerFrameStats(handle);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
case GET_LAYER_FRAME_STATS: {
CHECK_INTERFACE(ISurfaceComposerClient, data, reply);
sp<IBinder> handle = data.readStrongBinder();
@@ -138,7 +144,7 @@ status_t BnSurfaceComposerClient::onTransact(
reply->write(stats);
reply->writeInt32(result);
return NO_ERROR;
- } break;
+ }
default:
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 1183d59..00323dc 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -25,16 +25,16 @@ namespace android {
status_t layer_state_t::write(Parcel& output) const
{
output.writeStrongBinder(surface);
- output.writeInt32(what);
+ output.writeUint32(what);
output.writeFloat(x);
output.writeFloat(y);
- output.writeInt32(z);
- output.writeInt32(w);
- output.writeInt32(h);
- output.writeInt32(layerStack);
+ output.writeUint32(z);
+ output.writeUint32(w);
+ output.writeUint32(h);
+ output.writeUint32(layerStack);
output.writeFloat(alpha);
- output.writeInt32(flags);
- output.writeInt32(mask);
+ output.writeUint32(flags);
+ output.writeUint32(mask);
*reinterpret_cast<layer_state_t::matrix22_t *>(
output.writeInplace(sizeof(layer_state_t::matrix22_t))) = matrix;
output.write(crop);
@@ -45,16 +45,16 @@ status_t layer_state_t::write(Parcel& output) const
status_t layer_state_t::read(const Parcel& input)
{
surface = input.readStrongBinder();
- what = input.readInt32();
+ what = input.readUint32();
x = input.readFloat();
y = input.readFloat();
- z = input.readInt32();
- w = input.readInt32();
- h = input.readInt32();
- layerStack = input.readInt32();
+ z = input.readUint32();
+ w = input.readUint32();
+ h = input.readUint32();
+ layerStack = input.readUint32();
alpha = input.readFloat();
- flags = input.readInt32();
- mask = input.readInt32();
+ flags = static_cast<uint8_t>(input.readUint32());
+ mask = static_cast<uint8_t>(input.readUint32());
const void* matrix_data = input.readInplace(sizeof(layer_state_t::matrix22_t));
if (matrix_data) {
matrix = *reinterpret_cast<layer_state_t::matrix22_t const *>(matrix_data);
@@ -67,7 +67,7 @@ status_t layer_state_t::read(const Parcel& input)
}
status_t ComposerState::write(Parcel& output) const {
- output.writeStrongBinder(client->asBinder());
+ output.writeStrongBinder(IInterface::asBinder(client));
return state.write(output);
}
@@ -79,27 +79,27 @@ status_t ComposerState::read(const Parcel& input) {
status_t DisplayState::write(Parcel& output) const {
output.writeStrongBinder(token);
- output.writeStrongBinder(surface->asBinder());
- output.writeInt32(what);
- output.writeInt32(layerStack);
- output.writeInt32(orientation);
+ output.writeStrongBinder(IInterface::asBinder(surface));
+ output.writeUint32(what);
+ output.writeUint32(layerStack);
+ output.writeUint32(orientation);
output.write(viewport);
output.write(frame);
- output.writeInt32(width);
- output.writeInt32(height);
+ output.writeUint32(width);
+ output.writeUint32(height);
return NO_ERROR;
}
status_t DisplayState::read(const Parcel& input) {
token = input.readStrongBinder();
surface = interface_cast<IGraphicBufferProducer>(input.readStrongBinder());
- what = input.readInt32();
- layerStack = input.readInt32();
- orientation = input.readInt32();
+ what = input.readUint32();
+ layerStack = input.readUint32();
+ orientation = input.readUint32();
input.read(viewport);
input.read(frame);
- width = input.readInt32();
- height = input.readInt32();
+ width = input.readUint32();
+ height = input.readUint32();
return NO_ERROR;
}
diff --git a/libs/gui/Sensor.cpp b/libs/gui/Sensor.cpp
index b4291bb..35661f2 100644
--- a/libs/gui/Sensor.cpp
+++ b/libs/gui/Sensor.cpp
@@ -72,7 +72,7 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
static_cast<int64_t>(hwSensor->maxDelay));
mMaxDelay = INT_MAX;
} else {
- mMaxDelay = (int32_t) hwSensor->maxDelay;
+ mMaxDelay = static_cast<int32_t>(hwSensor->maxDelay);
}
} else {
// For older hals set maxDelay to 0.
@@ -204,6 +204,13 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
mFlags |= SENSOR_FLAG_WAKE_UP;
}
break;
+ case SENSOR_TYPE_WRIST_TILT_GESTURE:
+ mStringType = SENSOR_STRING_TYPE_WRIST_TILT_GESTURE;
+ mFlags |= SENSOR_FLAG_SPECIAL_REPORTING_MODE;
+ if (halVersion < SENSORS_DEVICE_API_VERSION_1_3) {
+ mFlags |= SENSOR_FLAG_WAKE_UP;
+ }
+ break;
default:
// Only pipe the stringType, requiredPermission and flags for custom sensors.
if (halVersion > SENSORS_DEVICE_API_VERSION_1_0 && hwSensor->stringType) {
@@ -214,7 +221,7 @@ Sensor::Sensor(struct sensor_t const* hwSensor, int halVersion)
}
if (halVersion >= SENSORS_DEVICE_API_VERSION_1_3) {
- mFlags = (int32_t) hwSensor->flags;
+ mFlags = static_cast<uint32_t>(hwSensor->flags);
} else {
// This is an OEM defined sensor on an older HAL. Use minDelay to determine the
// reporting mode of the sensor.
@@ -295,11 +302,11 @@ int32_t Sensor::getVersion() const {
return mVersion;
}
-int32_t Sensor::getFifoReservedEventCount() const {
+uint32_t Sensor::getFifoReservedEventCount() const {
return mFifoReservedEventCount;
}
-int32_t Sensor::getFifoMaxEventCount() const {
+uint32_t Sensor::getFifoMaxEventCount() const {
return mFifoMaxEventCount;
}
@@ -315,7 +322,7 @@ int32_t Sensor::getMaxDelay() const {
return mMaxDelay;
}
-int32_t Sensor::getFlags() const {
+uint32_t Sensor::getFlags() const {
return mFlags;
}
@@ -407,7 +414,7 @@ status_t Sensor::unflatten(void const* buffer, size_t size) {
void Sensor::flattenString8(void*& buffer, size_t& size,
const String8& string8) {
- uint32_t len = string8.length();
+ uint32_t len = static_cast<uint32_t>(string8.length());
FlattenableUtils::write(buffer, size, len);
memcpy(static_cast<char*>(buffer), string8.string(), len);
FlattenableUtils::advance(buffer, size, FlattenableUtils::align<4>(len));
diff --git a/libs/gui/SensorEventQueue.cpp b/libs/gui/SensorEventQueue.cpp
index 1305e9f..76ae470 100644
--- a/libs/gui/SensorEventQueue.cpp
+++ b/libs/gui/SensorEventQueue.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "Sensors"
+#include <algorithm>
#include <stdint.h>
#include <sys/types.h>
#include <sys/socket.h>
@@ -31,6 +32,8 @@
#include <android/sensor.h>
+using std::min;
+
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
@@ -68,14 +71,14 @@ ssize_t SensorEventQueue::read(ASensorEvent* events, size_t numEvents) {
if (err < 0) {
return err;
}
- mAvailable = err;
+ mAvailable = static_cast<size_t>(err);
mConsumed = 0;
}
- size_t count = numEvents < mAvailable ? numEvents : mAvailable;
- memcpy(events, mRecBuffer + mConsumed, count*sizeof(ASensorEvent));
+ size_t count = min(numEvents, mAvailable);
+ memcpy(events, mRecBuffer + mConsumed, count * sizeof(ASensorEvent));
mAvailable -= count;
mConsumed += count;
- return count;
+ return static_cast<ssize_t>(count);
}
sp<Looper> SensorEventQueue::getLooper() const
@@ -157,7 +160,7 @@ void SensorEventQueue::sendAck(const ASensorEvent* events, int count) {
ssize_t size = ::send(mSensorChannel->getFd(), &mNumAcksToSend, sizeof(mNumAcksToSend),
MSG_DONTWAIT | MSG_NOSIGNAL);
if (size < 0) {
- ALOGE("sendAck failure %d %d", size, mNumAcksToSend);
+ ALOGE("sendAck failure %zd %d", size, mNumAcksToSend);
} else {
mNumAcksToSend = 0;
}
diff --git a/libs/gui/SensorManager.cpp b/libs/gui/SensorManager.cpp
index 7b4fa2f..d6df404 100644
--- a/libs/gui/SensorManager.cpp
+++ b/libs/gui/SensorManager.cpp
@@ -86,11 +86,12 @@ status_t SensorManager::assertStateLocked() const {
};
mDeathObserver = new DeathObserver(*const_cast<SensorManager *>(this));
- mSensorServer->asBinder()->linkToDeath(mDeathObserver);
+ IInterface::asBinder(mSensorServer)->linkToDeath(mDeathObserver);
mSensors = mSensorServer->getSensorList();
size_t count = mSensors.size();
- mSensorList = (Sensor const**)malloc(count * sizeof(Sensor*));
+ mSensorList =
+ static_cast<Sensor const**>(malloc(count * sizeof(Sensor*)));
for (size_t i=0 ; i<count ; i++) {
mSensorList[i] = mSensors.array() + i;
}
@@ -106,10 +107,10 @@ ssize_t SensorManager::getSensorList(Sensor const* const** list) const
Mutex::Autolock _l(mLock);
status_t err = assertStateLocked();
if (err < 0) {
- return ssize_t(err);
+ return static_cast<ssize_t>(err);
}
*list = mSensorList;
- return mSensors.size();
+ return static_cast<ssize_t>(mSensors.size());
}
Sensor const* SensorManager::getDefaultSensor(int type)
diff --git a/libs/gui/StreamSplitter.cpp b/libs/gui/StreamSplitter.cpp
index 5f39905..43f9214 100644
--- a/libs/gui/StreamSplitter.cpp
+++ b/libs/gui/StreamSplitter.cpp
@@ -20,6 +20,7 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
+#include <gui/BufferItem.h>
#include <gui/IGraphicBufferConsumer.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/StreamSplitter.h>
@@ -80,7 +81,7 @@ status_t StreamSplitter::addOutput(
IGraphicBufferProducer::QueueBufferOutput queueBufferOutput;
sp<OutputListener> listener(new OutputListener(this, outputQueue));
- outputQueue->asBinder()->linkToDeath(listener);
+ IInterface::asBinder(outputQueue)->linkToDeath(listener);
status_t status = outputQueue->connect(listener, NATIVE_WINDOW_API_CPU,
/* producerControlledByApp */ false, &queueBufferOutput);
if (status != NO_ERROR) {
@@ -123,7 +124,7 @@ void StreamSplitter::onFrameAvailable(const BufferItem& /* item */) {
++mOutstandingBuffers;
// Acquire and detach the buffer from the input
- IGraphicBufferConsumer::BufferItem bufferItem;
+ BufferItem bufferItem;
status_t status = mInput->acquireBuffer(&bufferItem, /* presentWhen */ 0);
LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
"acquiring buffer from input failed (%d)", status);
@@ -141,7 +142,8 @@ void StreamSplitter::onFrameAvailable(const BufferItem& /* item */) {
IGraphicBufferProducer::QueueBufferInput queueInput(
bufferItem.mTimestamp, bufferItem.mIsAutoTimestamp,
- bufferItem.mCrop, bufferItem.mScalingMode,
+ bufferItem.mDataSpace, bufferItem.mCrop,
+ static_cast<int32_t>(bufferItem.mScalingMode),
bufferItem.mTransform, bufferItem.mIsDroppable,
bufferItem.mFence);
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 0e2baa2..b8acad2 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -27,6 +27,7 @@
#include <utils/NativeHandle.h>
#include <ui/Fence.h>
+#include <ui/Region.h>
#include <gui/IProducerListener.h>
#include <gui/ISurfaceComposer.h>
@@ -64,6 +65,7 @@ Surface::Surface(
mReqFormat = 0;
mReqUsage = 0;
mTimestamp = NATIVE_WINDOW_TIMESTAMP_AUTO;
+ mDataSpace = HAL_DATASPACE_UNKNOWN;
mCrop.clear();
mScalingMode = NATIVE_WINDOW_SCALING_MODE_FREEZE;
mTransform = 0;
@@ -96,8 +98,8 @@ void Surface::setSidebandStream(const sp<NativeHandle>& stream) {
void Surface::allocateBuffers() {
uint32_t reqWidth = mReqWidth ? mReqWidth : mUserWidth;
uint32_t reqHeight = mReqHeight ? mReqHeight : mUserHeight;
- mGraphicBufferProducer->allocateBuffers(mSwapIntervalZero, mReqWidth,
- mReqHeight, mReqFormat, mReqUsage);
+ mGraphicBufferProducer->allocateBuffers(mSwapIntervalZero, reqWidth,
+ reqHeight, mReqFormat, mReqUsage);
}
int Surface::hook_setSwapInterval(ANativeWindow* window, int interval) {
@@ -193,17 +195,17 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
ATRACE_CALL();
ALOGV("Surface::dequeueBuffer");
- int reqW;
- int reqH;
+ uint32_t reqWidth;
+ uint32_t reqHeight;
bool swapIntervalZero;
- uint32_t reqFormat;
+ PixelFormat reqFormat;
uint32_t reqUsage;
{
Mutex::Autolock lock(mMutex);
- reqW = mReqWidth ? mReqWidth : mUserWidth;
- reqH = mReqHeight ? mReqHeight : mUserHeight;
+ reqWidth = mReqWidth ? mReqWidth : mUserWidth;
+ reqHeight = mReqHeight ? mReqHeight : mUserHeight;
swapIntervalZero = mSwapIntervalZero;
reqFormat = mReqFormat;
@@ -213,12 +215,12 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
int buf = -1;
sp<Fence> fence;
status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence, swapIntervalZero,
- reqW, reqH, reqFormat, reqUsage);
+ reqWidth, reqHeight, reqFormat, reqUsage);
if (result < 0) {
ALOGV("dequeueBuffer: IGraphicBufferProducer::dequeueBuffer(%d, %d, %d, %d, %d)"
- "failed: %d", swapIntervalZero, reqW, reqH, reqFormat, reqUsage,
- result);
+ "failed: %d", swapIntervalZero, reqWidth, reqHeight, reqFormat,
+ reqUsage, result);
return result;
}
@@ -274,7 +276,6 @@ int Surface::cancelBuffer(android_native_buffer_t* buffer,
int Surface::getSlotFromBufferLocked(
android_native_buffer_t* buffer) const {
- bool dumpedState = false;
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
if (mSlots[i].buffer != NULL &&
mSlots[i].buffer->handle == buffer->handle) {
@@ -318,8 +319,27 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
sp<Fence> fence(fenceFd >= 0 ? new Fence(fenceFd) : Fence::NO_FENCE);
IGraphicBufferProducer::QueueBufferOutput output;
IGraphicBufferProducer::QueueBufferInput input(timestamp, isAutoTimestamp,
- crop, mScalingMode, mTransform ^ mStickyTransform, mSwapIntervalZero,
- fence, mStickyTransform);
+ mDataSpace, crop, mScalingMode, mTransform ^ mStickyTransform,
+ mSwapIntervalZero, fence, mStickyTransform);
+
+ if (mConnectedToCpu || mDirtyRegion.bounds() == Rect::INVALID_RECT) {
+ input.setSurfaceDamage(Region::INVALID_REGION);
+ } else {
+ // The surface damage was specified using the OpenGL ES convention of
+ // the origin being in the bottom-left corner. Here we flip to the
+ // convention that the rest of the system uses (top-left corner) by
+ // subtracting all top/bottom coordinates from the buffer height.
+ Region flippedRegion;
+ for (auto rect : mDirtyRegion) {
+ auto top = buffer->height - rect.bottom;
+ auto bottom = buffer->height - rect.top;
+ Rect flippedRect{rect.left, top, rect.right, bottom};
+ flippedRegion.orSelf(flippedRect);
+ }
+
+ input.setSurfaceDamage(flippedRegion);
+ }
+
status_t err = mGraphicBufferProducer->queueBuffer(i, input, &output);
if (err != OK) {
ALOGE("queueBuffer: error queuing buffer to SurfaceTexture, %d", err);
@@ -336,6 +356,11 @@ int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
mConsumerRunningBehind = (numPendingBuffers >= 2);
+ if (!mConnectedToCpu) {
+ // Clear surface damage back to full-buffer
+ mDirtyRegion = Region::INVALID_REGION;
+ }
+
return err;
}
@@ -347,7 +372,7 @@ int Surface::query(int what, int* value) const {
switch (what) {
case NATIVE_WINDOW_FORMAT:
if (mReqFormat) {
- *value = mReqFormat;
+ *value = static_cast<int>(mReqFormat);
return NO_ERROR;
}
break;
@@ -365,13 +390,15 @@ int Surface::query(int what, int* value) const {
*value = NATIVE_WINDOW_SURFACE;
return NO_ERROR;
case NATIVE_WINDOW_DEFAULT_WIDTH:
- *value = mUserWidth ? mUserWidth : mDefaultWidth;
+ *value = static_cast<int>(
+ mUserWidth ? mUserWidth : mDefaultWidth);
return NO_ERROR;
case NATIVE_WINDOW_DEFAULT_HEIGHT:
- *value = mUserHeight ? mUserHeight : mDefaultHeight;
+ *value = static_cast<int>(
+ mUserHeight ? mUserHeight : mDefaultHeight);
return NO_ERROR;
case NATIVE_WINDOW_TRANSFORM_HINT:
- *value = mTransformHint;
+ *value = static_cast<int>(mTransformHint);
return NO_ERROR;
case NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND: {
status_t err = NO_ERROR;
@@ -448,6 +475,12 @@ int Surface::perform(int operation, va_list args)
case NATIVE_WINDOW_SET_SIDEBAND_STREAM:
res = dispatchSetSidebandStream(args);
break;
+ case NATIVE_WINDOW_SET_BUFFERS_DATASPACE:
+ res = dispatchSetBuffersDataSpace(args);
+ break;
+ case NATIVE_WINDOW_SET_SURFACE_DAMAGE:
+ res = dispatchSetSurfaceDamage(args);
+ break;
default:
res = NAME_NOT_FOUND;
break;
@@ -467,7 +500,7 @@ int Surface::dispatchDisconnect(va_list args) {
int Surface::dispatchSetUsage(va_list args) {
int usage = va_arg(args, int);
- return setUsage(usage);
+ return setUsage(static_cast<uint32_t>(usage));
}
int Surface::dispatchSetCrop(va_list args) {
@@ -477,49 +510,49 @@ int Surface::dispatchSetCrop(va_list args) {
int Surface::dispatchSetBufferCount(va_list args) {
size_t bufferCount = va_arg(args, size_t);
- return setBufferCount(bufferCount);
+ return setBufferCount(static_cast<int32_t>(bufferCount));
}
int Surface::dispatchSetBuffersGeometry(va_list args) {
- int w = va_arg(args, int);
- int h = va_arg(args, int);
- int f = va_arg(args, int);
- int err = setBuffersDimensions(w, h);
+ uint32_t width = va_arg(args, uint32_t);
+ uint32_t height = va_arg(args, uint32_t);
+ PixelFormat format = va_arg(args, PixelFormat);
+ int err = setBuffersDimensions(width, height);
if (err != 0) {
return err;
}
- return setBuffersFormat(f);
+ return setBuffersFormat(format);
}
int Surface::dispatchSetBuffersDimensions(va_list args) {
- int w = va_arg(args, int);
- int h = va_arg(args, int);
- return setBuffersDimensions(w, h);
+ uint32_t width = va_arg(args, uint32_t);
+ uint32_t height = va_arg(args, uint32_t);
+ return setBuffersDimensions(width, height);
}
int Surface::dispatchSetBuffersUserDimensions(va_list args) {
- int w = va_arg(args, int);
- int h = va_arg(args, int);
- return setBuffersUserDimensions(w, h);
+ uint32_t width = va_arg(args, uint32_t);
+ uint32_t height = va_arg(args, uint32_t);
+ return setBuffersUserDimensions(width, height);
}
int Surface::dispatchSetBuffersFormat(va_list args) {
- int f = va_arg(args, int);
- return setBuffersFormat(f);
+ PixelFormat format = va_arg(args, PixelFormat);
+ return setBuffersFormat(format);
}
int Surface::dispatchSetScalingMode(va_list args) {
- int m = va_arg(args, int);
- return setScalingMode(m);
+ int mode = va_arg(args, int);
+ return setScalingMode(mode);
}
int Surface::dispatchSetBuffersTransform(va_list args) {
- int transform = va_arg(args, int);
+ uint32_t transform = va_arg(args, uint32_t);
return setBuffersTransform(transform);
}
int Surface::dispatchSetBuffersStickyTransform(va_list args) {
- int transform = va_arg(args, int);
+ uint32_t transform = va_arg(args, uint32_t);
return setBuffersStickyTransform(transform);
}
@@ -545,10 +578,27 @@ int Surface::dispatchSetSidebandStream(va_list args) {
return OK;
}
+int Surface::dispatchSetBuffersDataSpace(va_list args) {
+ android_dataspace dataspace =
+ static_cast<android_dataspace>(va_arg(args, int));
+ return setBuffersDataSpace(dataspace);
+}
+
+int Surface::dispatchSetSurfaceDamage(va_list args) {
+ android_native_rect_t* rects = va_arg(args, android_native_rect_t*);
+ size_t numRects = va_arg(args, size_t);
+ setSurfaceDamage(rects, numRects);
+ return NO_ERROR;
+}
+
int Surface::connect(int api) {
+ static sp<IProducerListener> listener = new DummyProducerListener();
+ return connect(api, listener);
+}
+
+int Surface::connect(int api, const sp<IProducerListener>& listener) {
ATRACE_CALL();
ALOGV("Surface::connect");
- static sp<IProducerListener> listener = new DummyProducerListener();
Mutex::Autolock lock(mMutex);
IGraphicBufferProducer::QueueBufferOutput output;
int err = mGraphicBufferProducer->connect(listener, api, mProducerControlledByApp, &output);
@@ -567,7 +617,13 @@ int Surface::connect(int api) {
}
if (!err && api == NATIVE_WINDOW_API_CPU) {
mConnectedToCpu = true;
+ // Clear the dirty region in case we're switching from a non-CPU API
+ mDirtyRegion.clear();
+ } else if (!err) {
+ // Initialize the dirty region for tracking surface damage
+ mDirtyRegion = Region::INVALID_REGION;
}
+
return err;
}
@@ -595,6 +651,55 @@ int Surface::disconnect(int api) {
return err;
}
+int Surface::detachNextBuffer(ANativeWindowBuffer** outBuffer,
+ sp<Fence>* outFence) {
+ ATRACE_CALL();
+ ALOGV("Surface::detachNextBuffer");
+
+ if (outBuffer == NULL || outFence == NULL) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mMutex);
+
+ sp<GraphicBuffer> buffer(NULL);
+ sp<Fence> fence(NULL);
+ status_t result = mGraphicBufferProducer->detachNextBuffer(
+ &buffer, &fence);
+ if (result != NO_ERROR) {
+ return result;
+ }
+
+ *outBuffer = buffer.get();
+ if (fence != NULL && fence->isValid()) {
+ *outFence = fence;
+ } else {
+ *outFence = Fence::NO_FENCE;
+ }
+
+ return NO_ERROR;
+}
+
+int Surface::attachBuffer(ANativeWindowBuffer* buffer)
+{
+ ATRACE_CALL();
+ ALOGV("Surface::attachBuffer");
+
+ Mutex::Autolock lock(mMutex);
+
+ sp<GraphicBuffer> graphicBuffer(static_cast<GraphicBuffer*>(buffer));
+ int32_t attachedSlot = -1;
+ status_t result = mGraphicBufferProducer->attachBuffer(
+ &attachedSlot, graphicBuffer);
+ if (result != NO_ERROR) {
+ ALOGE("attachBuffer: IGraphicBufferProducer call failed (%d)", result);
+ return result;
+ }
+ mSlots[attachedSlot].buffer = graphicBuffer;
+
+ return NO_ERROR;
+}
+
int Surface::setUsage(uint32_t reqUsage)
{
ALOGV("Surface::setUsage");
@@ -639,47 +744,38 @@ int Surface::setBufferCount(int bufferCount)
return err;
}
-int Surface::setBuffersDimensions(int w, int h)
+int Surface::setBuffersDimensions(uint32_t width, uint32_t height)
{
ATRACE_CALL();
ALOGV("Surface::setBuffersDimensions");
- if (w<0 || h<0)
- return BAD_VALUE;
-
- if ((w && !h) || (!w && h))
+ if ((width && !height) || (!width && height))
return BAD_VALUE;
Mutex::Autolock lock(mMutex);
- mReqWidth = w;
- mReqHeight = h;
+ mReqWidth = width;
+ mReqHeight = height;
return NO_ERROR;
}
-int Surface::setBuffersUserDimensions(int w, int h)
+int Surface::setBuffersUserDimensions(uint32_t width, uint32_t height)
{
ATRACE_CALL();
ALOGV("Surface::setBuffersUserDimensions");
- if (w<0 || h<0)
- return BAD_VALUE;
-
- if ((w && !h) || (!w && h))
+ if ((width && !height) || (!width && height))
return BAD_VALUE;
Mutex::Autolock lock(mMutex);
- mUserWidth = w;
- mUserHeight = h;
+ mUserWidth = width;
+ mUserHeight = height;
return NO_ERROR;
}
-int Surface::setBuffersFormat(int format)
+int Surface::setBuffersFormat(PixelFormat format)
{
ALOGV("Surface::setBuffersFormat");
- if (format<0)
- return BAD_VALUE;
-
Mutex::Autolock lock(mMutex);
mReqFormat = format;
return NO_ERROR;
@@ -705,7 +801,7 @@ int Surface::setScalingMode(int mode)
return NO_ERROR;
}
-int Surface::setBuffersTransform(int transform)
+int Surface::setBuffersTransform(uint32_t transform)
{
ATRACE_CALL();
ALOGV("Surface::setBuffersTransform");
@@ -714,7 +810,7 @@ int Surface::setBuffersTransform(int transform)
return NO_ERROR;
}
-int Surface::setBuffersStickyTransform(int transform)
+int Surface::setBuffersStickyTransform(uint32_t transform)
{
ATRACE_CALL();
ALOGV("Surface::setBuffersStickyTransform");
@@ -731,12 +827,41 @@ int Surface::setBuffersTimestamp(int64_t timestamp)
return NO_ERROR;
}
+int Surface::setBuffersDataSpace(android_dataspace dataSpace)
+{
+ ALOGV("Surface::setBuffersDataSpace");
+ Mutex::Autolock lock(mMutex);
+ mDataSpace = dataSpace;
+ return NO_ERROR;
+}
+
void Surface::freeAllBuffers() {
for (int i = 0; i < NUM_BUFFER_SLOTS; i++) {
mSlots[i].buffer = 0;
}
}
+void Surface::setSurfaceDamage(android_native_rect_t* rects, size_t numRects) {
+ ATRACE_CALL();
+ ALOGV("Surface::setSurfaceDamage");
+ Mutex::Autolock lock(mMutex);
+
+ if (mConnectedToCpu || numRects == 0) {
+ mDirtyRegion = Region::INVALID_REGION;
+ return;
+ }
+
+ mDirtyRegion.clear();
+ for (size_t r = 0; r < numRects; ++r) {
+ // We intentionally flip top and bottom here, since because they're
+ // specified with a bottom-left origin, top > bottom, which fails
+ // validation in the Region class. We will fix this up when we flip to a
+ // top-left origin in queueBuffer.
+ Rect rect(rects[r].left, rects[r].bottom, rects[r].right, rects[r].top);
+ mDirtyRegion.orSelf(rect);
+ }
+}
+
// ----------------------------------------------------------------------
// the lock/unlock APIs must be used from the same thread
@@ -748,30 +873,34 @@ static status_t copyBlt(
// src and dst with, height and format must be identical. no verification
// is done here.
status_t err;
- uint8_t const * src_bits = NULL;
- err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(), (void**)&src_bits);
+ uint8_t* src_bits = NULL;
+ err = src->lock(GRALLOC_USAGE_SW_READ_OFTEN, reg.bounds(),
+ reinterpret_cast<void**>(&src_bits));
ALOGE_IF(err, "error locking src buffer %s", strerror(-err));
uint8_t* dst_bits = NULL;
- err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(), (void**)&dst_bits);
+ err = dst->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, reg.bounds(),
+ reinterpret_cast<void**>(&dst_bits));
ALOGE_IF(err, "error locking dst buffer %s", strerror(-err));
Region::const_iterator head(reg.begin());
Region::const_iterator tail(reg.end());
if (head != tail && src_bits && dst_bits) {
const size_t bpp = bytesPerPixel(src->format);
- const size_t dbpr = dst->stride * bpp;
- const size_t sbpr = src->stride * bpp;
+ const size_t dbpr = static_cast<uint32_t>(dst->stride) * bpp;
+ const size_t sbpr = static_cast<uint32_t>(src->stride) * bpp;
while (head != tail) {
const Rect& r(*head++);
- ssize_t h = r.height();
+ int32_t h = r.height();
if (h <= 0) continue;
- size_t size = r.width() * bpp;
- uint8_t const * s = src_bits + (r.left + src->stride * r.top) * bpp;
- uint8_t * d = dst_bits + (r.left + dst->stride * r.top) * bpp;
+ size_t size = static_cast<uint32_t>(r.width()) * bpp;
+ uint8_t const * s = src_bits +
+ static_cast<uint32_t>(r.left + src->stride * r.top) * bpp;
+ uint8_t * d = dst_bits +
+ static_cast<uint32_t>(r.left + dst->stride * r.top) * bpp;
if (dbpr==sbpr && size==sbpr) {
- size *= h;
+ size *= static_cast<size_t>(h);
h = 1;
}
do {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 6446926..707a321 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -71,7 +71,7 @@ void ComposerService::connectLocked() {
};
mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
- mComposerService->asBinder()->linkToDeath(mDeathObserver);
+ IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
}
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
@@ -143,7 +143,7 @@ public:
status_t setSize(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
uint32_t w, uint32_t h);
status_t setLayer(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
- int32_t z);
+ uint32_t z);
status_t setFlags(const sp<SurfaceComposerClient>& client, const sp<IBinder>& id,
uint32_t flags, uint32_t mask);
status_t setTransparentRegionHint(
@@ -293,7 +293,7 @@ status_t Composer::setSize(const sp<SurfaceComposerClient>& client,
}
status_t Composer::setLayer(const sp<SurfaceComposerClient>& client,
- const sp<IBinder>& id, int32_t z) {
+ const sp<IBinder>& id, uint32_t z) {
Mutex::Autolock _l(mLock);
layer_state_t* s = getLayerStateLocked(client, id);
if (!s)
@@ -395,7 +395,7 @@ DisplayState& Composer::getDisplayStateLocked(const sp<IBinder>& token) {
s.what = 0;
index = mDisplayStates.add(s);
}
- return mDisplayStates.editItemAt(index);
+ return mDisplayStates.editItemAt(static_cast<size_t>(index));
}
void Composer::setDisplaySurface(const sp<IBinder>& token,
@@ -462,14 +462,14 @@ status_t SurfaceComposerClient::initCheck() const {
}
sp<IBinder> SurfaceComposerClient::connection() const {
- return (mClient != 0) ? mClient->asBinder() : 0;
+ return IInterface::asBinder(mClient);
}
status_t SurfaceComposerClient::linkToComposerDeath(
const sp<IBinder::DeathRecipient>& recipient,
void* cookie, uint32_t flags) {
sp<ISurfaceComposer> sm(ComposerService::getComposerService());
- return sm->asBinder()->linkToDeath(recipient, cookie, flags);
+ return IInterface::asBinder(sm)->linkToDeath(recipient, cookie, flags);
}
void SurfaceComposerClient::dispose() {
@@ -571,7 +571,7 @@ status_t SurfaceComposerClient::setSize(const sp<IBinder>& id, uint32_t w, uint3
return getComposer().setSize(this, id, w, h);
}
-status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, int32_t z) {
+status_t SurfaceComposerClient::setLayer(const sp<IBinder>& id, uint32_t z) {
return getComposer().setLayer(this, id, z);
}
@@ -657,7 +657,7 @@ status_t SurfaceComposerClient::getDisplayInfo(const sp<IBinder>& display,
return NAME_NOT_FOUND;
}
- *info = configs[activeId];
+ *info = configs[static_cast<size_t>(activeId)];
return NO_ERROR;
}
@@ -752,14 +752,14 @@ status_t ScreenshotClient::update(const sp<IBinder>& display,
status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop,
bool useIdentityTransform) {
- return ScreenshotClient::update(display, sourceCrop, 0, 0, 0, -1UL,
+ return ScreenshotClient::update(display, sourceCrop, 0, 0, 0, -1U,
useIdentityTransform, ISurfaceComposer::eRotateNone);
}
status_t ScreenshotClient::update(const sp<IBinder>& display, Rect sourceCrop,
uint32_t reqWidth, uint32_t reqHeight, bool useIdentityTransform) {
return ScreenshotClient::update(display, sourceCrop, reqWidth, reqHeight,
- 0, -1UL, useIdentityTransform, ISurfaceComposer::eRotateNone);
+ 0, -1U, useIdentityTransform, ISurfaceComposer::eRotateNone);
}
void ScreenshotClient::release() {
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 7597c99..1983027 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -89,12 +89,12 @@ bool SurfaceControl::isSameSurface(
return lhs->mHandle == rhs->mHandle;
}
-status_t SurfaceControl::setLayerStack(int32_t layerStack) {
+status_t SurfaceControl::setLayerStack(uint32_t layerStack) {
status_t err = validate();
if (err < 0) return err;
return mClient->setLayerStack(mHandle, layerStack);
}
-status_t SurfaceControl::setLayer(int32_t layer) {
+status_t SurfaceControl::setLayer(uint32_t layer) {
status_t err = validate();
if (err < 0) return err;
return mClient->setLayer(mHandle, layer);
@@ -176,7 +176,7 @@ status_t SurfaceControl::writeSurfaceToParcel(
if (control != NULL) {
bp = control->mGraphicBufferProducer;
}
- return parcel->writeStrongBinder(bp->asBinder());
+ return parcel->writeStrongBinder(IInterface::asBinder(bp));
}
sp<Surface> SurfaceControl::getSurface() const
diff --git a/libs/gui/SyncFeatures.cpp b/libs/gui/SyncFeatures.cpp
index e5804a7..187b211 100644
--- a/libs/gui/SyncFeatures.cpp
+++ b/libs/gui/SyncFeatures.cpp
@@ -16,7 +16,6 @@
#define LOG_TAG "GLConsumer"
-#define GL_GLEXT_PROTOTYPES
#define EGL_EGLEXT_PROTOTYPES
#include <EGL/egl.h>
@@ -78,10 +77,11 @@ bool SyncFeatures::useFenceSync() const {
// on some devices it's better to not use EGL_KHR_fence_sync
// even if they have it
return false;
-#endif
+#else
// currently we shall only attempt to use EGL_KHR_fence_sync if
// USE_FENCE_SYNC is set in our makefile
return !mHasNativeFenceSync && mHasFenceSync;
+#endif
}
bool SyncFeatures::useWaitSync() const {
return (useNativeFenceSync() || useFenceSync()) && mHasWaitSync;
diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk
index e460290..6ad9986 100644
--- a/libs/gui/tests/Android.mk
+++ b/libs/gui/tests/Android.mk
@@ -1,6 +1,9 @@
# Build the unit tests,
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
+LOCAL_CLANG := true
LOCAL_MODULE := libgui_test
@@ -31,17 +34,10 @@ LOCAL_SHARED_LIBRARIES := \
libbinder \
libcutils \
libgui \
- libstlport \
libsync \
libui \
libutils \
-LOCAL_C_INCLUDES := \
- bionic \
- bionic/libstdc++/include \
- external/gtest/include \
- external/stlport/stlport \
-
# Build the binary to $(TARGET_OUT_DATA_NATIVE_TESTS)/$(LOCAL_MODULE)
# to integrate with auto-test framework.
include $(BUILD_NATIVE_TEST)
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 96de11f..1584fef 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "BufferQueue_test"
//#define LOG_NDEBUG 0
+#include <gui/BufferItem.h>
#include <gui/BufferQueue.h>
#include <gui/IProducerListener.h>
@@ -72,6 +73,8 @@ struct DummyConsumer : public BnConsumerListener {
virtual void onSidebandStreamChanged() {}
};
+static const uint32_t TEST_DATA = 0x12345678u;
+
// XXX: Tests that fork a process to hold the BufferQueue must run before tests
// that use a local BufferQueue, or else Binder will get unhappy
TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) {
@@ -87,8 +90,8 @@ TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) {
sp<IGraphicBufferConsumer> consumer;
BufferQueue::createBufferQueue(&producer, &consumer);
sp<IServiceManager> serviceManager = defaultServiceManager();
- serviceManager->addService(PRODUCER_NAME, producer->asBinder());
- serviceManager->addService(CONSUMER_NAME, consumer->asBinder());
+ serviceManager->addService(PRODUCER_NAME, IInterface::asBinder(producer));
+ serviceManager->addService(CONSUMER_NAME, IInterface::asBinder(consumer));
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
LOG_ALWAYS_FATAL("Shouldn't be here");
@@ -121,20 +124,21 @@ TEST_F(BufferQueueTest, BufferQueueInAnotherProcess) {
uint32_t* dataIn;
ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
reinterpret_cast<void**>(&dataIn)));
- *dataIn = 0x12345678;
+ *dataIn = TEST_DATA;
ASSERT_EQ(OK, buffer->unlock());
- IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+ IGraphicBufferProducer::QueueBufferInput input(0, false,
+ HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
uint32_t* dataOut;
ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
reinterpret_cast<void**>(&dataOut)));
- ASSERT_EQ(*dataOut, 0x12345678);
+ ASSERT_EQ(*dataOut, TEST_DATA);
ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
}
@@ -150,9 +154,10 @@ TEST_F(BufferQueueTest, AcquireBuffer_ExceedsMaxAcquireCount_Fails) {
int slot;
sp<Fence> fence;
sp<GraphicBuffer> buf;
- IGraphicBufferProducer::QueueBufferInput qbi(0, false, Rect(0, 0, 1, 1),
+ IGraphicBufferProducer::QueueBufferInput qbi(0, false,
+ HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
- BufferQueue::BufferItem item;
+ BufferItem item;
for (int i = 0; i < 2; i++) {
ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
@@ -236,7 +241,7 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
uint32_t* dataIn;
ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
reinterpret_cast<void**>(&dataIn)));
- *dataIn = 0x12345678;
+ *dataIn = TEST_DATA;
ASSERT_EQ(OK, buffer->unlock());
int newSlot;
@@ -244,17 +249,18 @@ TEST_F(BufferQueueTest, DetachAndReattachOnProducerSide) {
ASSERT_EQ(BAD_VALUE, mProducer->attachBuffer(&newSlot, NULL));
ASSERT_EQ(OK, mProducer->attachBuffer(&newSlot, buffer));
- IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+ IGraphicBufferProducer::QueueBufferInput input(0, false,
+ HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
ASSERT_EQ(OK, mProducer->queueBuffer(newSlot, input, &output));
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
uint32_t* dataOut;
ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
reinterpret_cast<void**>(&dataOut)));
- ASSERT_EQ(*dataOut, 0x12345678);
+ ASSERT_EQ(*dataOut, TEST_DATA);
ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
}
@@ -273,7 +279,8 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
GRALLOC_USAGE_SW_WRITE_OFTEN));
ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
- IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+ IGraphicBufferProducer::QueueBufferInput input(0, false,
+ HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
@@ -282,7 +289,7 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
BufferQueueDefs::NUM_BUFFER_SLOTS)); // Index too high
ASSERT_EQ(BAD_VALUE, mConsumer->detachBuffer(0)); // Not acquired
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
@@ -292,7 +299,7 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
ASSERT_EQ(OK, item.mGraphicBuffer->lock(
GraphicBuffer::USAGE_SW_WRITE_OFTEN,
reinterpret_cast<void**>(&dataIn)));
- *dataIn = 0x12345678;
+ *dataIn = TEST_DATA;
ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
int newSlot;
@@ -312,7 +319,7 @@ TEST_F(BufferQueueTest, DetachAndReattachOnConsumerSide) {
uint32_t* dataOut;
ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
reinterpret_cast<void**>(&dataOut)));
- ASSERT_EQ(*dataOut, 0x12345678);
+ ASSERT_EQ(*dataOut, TEST_DATA);
ASSERT_EQ(OK, buffer->unlock());
}
@@ -335,14 +342,15 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
uint32_t* dataIn;
ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
reinterpret_cast<void**>(&dataIn)));
- *dataIn = 0x12345678;
+ *dataIn = TEST_DATA;
ASSERT_EQ(OK, buffer->unlock());
- IGraphicBufferProducer::QueueBufferInput input(0, false, Rect(0, 0, 1, 1),
+ IGraphicBufferProducer::QueueBufferInput input(0, false,
+ HAL_DATASPACE_UNKNOWN, Rect(0, 0, 1, 1),
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false, Fence::NO_FENCE);
ASSERT_EQ(OK, mProducer->queueBuffer(slot, input, &output));
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, static_cast<nsecs_t>(0)));
ASSERT_EQ(OK, mConsumer->detachBuffer(item.mBuf));
@@ -354,8 +362,44 @@ TEST_F(BufferQueueTest, MoveFromConsumerToProducer) {
uint32_t* dataOut;
ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
reinterpret_cast<void**>(&dataOut)));
- ASSERT_EQ(*dataOut, 0x12345678);
+ ASSERT_EQ(*dataOut, TEST_DATA);
ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
}
+TEST_F(BufferQueueTest, TestDisallowingAllocation) {
+ createBufferQueue();
+ sp<DummyConsumer> dc(new DummyConsumer);
+ ASSERT_EQ(OK, mConsumer->consumerConnect(dc, true));
+ IGraphicBufferProducer::QueueBufferOutput output;
+ ASSERT_EQ(OK, mProducer->connect(new DummyProducerListener,
+ NATIVE_WINDOW_API_CPU, true, &output));
+
+ static const uint32_t WIDTH = 320;
+ static const uint32_t HEIGHT = 240;
+
+ ASSERT_EQ(OK, mConsumer->setDefaultBufferSize(WIDTH, HEIGHT));
+
+ int slot;
+ sp<Fence> fence;
+ sp<GraphicBuffer> buffer;
+ // This should return an error since it would require an allocation
+ ASSERT_EQ(OK, mProducer->allowAllocation(false));
+ ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false, 0, 0,
+ 0, GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ // This should succeed, now that we've lifted the prohibition
+ ASSERT_EQ(OK, mProducer->allowAllocation(true));
+ ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION,
+ mProducer->dequeueBuffer(&slot, &fence, false, 0, 0, 0,
+ GRALLOC_USAGE_SW_WRITE_OFTEN));
+
+ // Release the previous buffer back to the BufferQueue
+ mProducer->cancelBuffer(slot, fence);
+
+ // This should fail since we're requesting a different size
+ ASSERT_EQ(OK, mProducer->allowAllocation(false));
+ ASSERT_EQ(WOULD_BLOCK, mProducer->dequeueBuffer(&slot, &fence, false,
+ WIDTH * 2, HEIGHT * 2, 0, GRALLOC_USAGE_SW_WRITE_OFTEN));
+}
+
} // namespace android
diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp
index abd3724..2dc9ccc 100644
--- a/libs/gui/tests/CpuConsumer_test.cpp
+++ b/libs/gui/tests/CpuConsumer_test.cpp
@@ -94,7 +94,7 @@ protected:
mPendingFrames--;
}
- virtual void onFrameAvailable() {
+ virtual void onFrameAvailable(const BufferItem&) {
Mutex::Autolock lock(mMutex);
mPendingFrames++;
mCondition.signal();
@@ -125,7 +125,7 @@ protected:
mPendingFrames--;
}
- virtual void onFrameAvailable() {
+ virtual void onFrameAvailable(const BufferItem&) {
Mutex::Autolock lock(mMutex);
mPendingFrames++;
mFrameCondition.signal();
@@ -166,7 +166,7 @@ void checkPixel(const CpuConsumer::LockedBuffer &buf,
uint32_t x, uint32_t y, uint32_t r, uint32_t g=0, uint32_t b=0) {
// Ignores components that don't exist for given pixel
switch(buf.format) {
- case HAL_PIXEL_FORMAT_RAW_SENSOR: {
+ case HAL_PIXEL_FORMAT_RAW16: {
String8 msg;
uint16_t *bPtr = (uint16_t*)buf.data;
bPtr += y * buf.stride + x;
@@ -429,7 +429,7 @@ void checkBayerRawBuffer(const CpuConsumer::LockedBuffer &buf) {
void checkAnyBuffer(const CpuConsumer::LockedBuffer &buf, int format) {
switch (format) {
- case HAL_PIXEL_FORMAT_RAW_SENSOR:
+ case HAL_PIXEL_FORMAT_RAW16:
checkBayerRawBuffer(buf);
break;
case HAL_PIXEL_FORMAT_Y8:
@@ -457,9 +457,12 @@ void configureANW(const sp<ANativeWindow>& anw,
const CpuConsumerTestParams& params,
int maxBufferSlack) {
status_t err;
- err = native_window_set_buffers_geometry(anw.get(),
- params.width, params.height, params.format);
- ASSERT_NO_ERROR(err, "set_buffers_geometry error: ");
+ err = native_window_set_buffers_dimensions(anw.get(),
+ params.width, params.height);
+ ASSERT_NO_ERROR(err, "set_buffers_dimensions error: ");
+
+ err = native_window_set_buffers_format(anw.get(), params.format);
+ ASSERT_NO_ERROR(err, "set_buffers_format error: ");
err = native_window_set_usage(anw.get(),
GRALLOC_USAGE_SW_WRITE_OFTEN);
@@ -505,7 +508,7 @@ void produceOneFrame(const sp<ANativeWindow>& anw,
case HAL_PIXEL_FORMAT_YV12:
fillYV12Buffer(img, params.width, params.height, *stride);
break;
- case HAL_PIXEL_FORMAT_RAW_SENSOR:
+ case HAL_PIXEL_FORMAT_RAW16:
fillBayerRawBuffer(img, params.width, params.height, buf->getStride());
break;
case HAL_PIXEL_FORMAT_Y8:
@@ -537,7 +540,7 @@ void produceOneFrame(const sp<ANativeWindow>& anw,
ASSERT_NO_ERROR(err, "queueBuffer error:");
};
-// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
+// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
// supported on all devices.
TEST_P(CpuConsumerTest, FromCpuSingle) {
status_t err;
@@ -571,7 +574,7 @@ TEST_P(CpuConsumerTest, FromCpuSingle) {
mCC->unlockBuffer(b);
}
-// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
+// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
// supported on all devices.
TEST_P(CpuConsumerTest, FromCpuManyInQueue) {
status_t err;
@@ -614,7 +617,7 @@ TEST_P(CpuConsumerTest, FromCpuManyInQueue) {
}
}
-// This test is disabled because the HAL_PIXEL_FORMAT_RAW_SENSOR format is not
+// This test is disabled because the HAL_PIXEL_FORMAT_RAW16 format is not
// supported on all devices.
TEST_P(CpuConsumerTest, FromCpuLockMax) {
status_t err;
@@ -710,12 +713,12 @@ CpuConsumerTestParams y16TestSets[] = {
};
CpuConsumerTestParams rawTestSets[] = {
- { 512, 512, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
- { 512, 512, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
- { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
- { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
- { 100, 100, 1, HAL_PIXEL_FORMAT_RAW_SENSOR},
- { 100, 100, 3, HAL_PIXEL_FORMAT_RAW_SENSOR},
+ { 512, 512, 1, HAL_PIXEL_FORMAT_RAW16},
+ { 512, 512, 3, HAL_PIXEL_FORMAT_RAW16},
+ { 2608, 1960, 1, HAL_PIXEL_FORMAT_RAW16},
+ { 2608, 1960, 3, HAL_PIXEL_FORMAT_RAW16},
+ { 100, 100, 1, HAL_PIXEL_FORMAT_RAW16},
+ { 100, 100, 3, HAL_PIXEL_FORMAT_RAW16},
};
CpuConsumerTestParams rgba8888TestSets[] = {
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index 8d5fd8f..ff58420 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -38,30 +38,31 @@
#define TEST_CONTROLLED_BY_APP false
#define TEST_PRODUCER_USAGE_BITS (0)
-// TODO: Make these public constants in a header
-enum {
+namespace android {
+
+namespace {
// Default dimensions before setDefaultBufferSize is called
- DEFAULT_WIDTH = 1,
- DEFAULT_HEIGHT = 1,
+ const uint32_t DEFAULT_WIDTH = 1;
+ const uint32_t DEFAULT_HEIGHT = 1;
// Default format before setDefaultBufferFormat is called
- DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888,
+ const PixelFormat DEFAULT_FORMAT = HAL_PIXEL_FORMAT_RGBA_8888;
// Default transform hint before setTransformHint is called
- DEFAULT_TRANSFORM_HINT = 0,
-};
+ const uint32_t DEFAULT_TRANSFORM_HINT = 0;
-namespace android {
+ // TODO: Make these constants in header
+ const int DEFAULT_CONSUMER_USAGE_BITS = 0;
-namespace {
-// Parameters for a generic "valid" input for queueBuffer.
-const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611;
-const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false;
-const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT);
-const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0;
-const int QUEUE_BUFFER_INPUT_TRANSFORM = 0;
-const bool QUEUE_BUFFER_INPUT_ASYNC = false;
-const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE;
+ // Parameters for a generic "valid" input for queueBuffer.
+ const int64_t QUEUE_BUFFER_INPUT_TIMESTAMP = 1384888611;
+ const bool QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP = false;
+ const android_dataspace QUEUE_BUFFER_INPUT_DATASPACE = HAL_DATASPACE_UNKNOWN;
+ const Rect QUEUE_BUFFER_INPUT_RECT = Rect(DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ const int QUEUE_BUFFER_INPUT_SCALING_MODE = 0;
+ const int QUEUE_BUFFER_INPUT_TRANSFORM = 0;
+ const bool QUEUE_BUFFER_INPUT_ASYNC = false;
+ const sp<Fence> QUEUE_BUFFER_INPUT_FENCE = Fence::NO_FENCE;
}; // namespace anonymous
struct DummyConsumer : public BnConsumerListener {
@@ -126,6 +127,7 @@ protected:
QueueBufferInputBuilder() {
timestamp = QUEUE_BUFFER_INPUT_TIMESTAMP;
isAutoTimestamp = QUEUE_BUFFER_INPUT_IS_AUTO_TIMESTAMP;
+ dataSpace = QUEUE_BUFFER_INPUT_DATASPACE;
crop = QUEUE_BUFFER_INPUT_RECT;
scalingMode = QUEUE_BUFFER_INPUT_SCALING_MODE;
transform = QUEUE_BUFFER_INPUT_TRANSFORM;
@@ -137,6 +139,7 @@ protected:
return IGraphicBufferProducer::QueueBufferInput(
timestamp,
isAutoTimestamp,
+ dataSpace,
crop,
scalingMode,
transform,
@@ -154,6 +157,11 @@ protected:
return *this;
}
+ QueueBufferInputBuilder& setDataSpace(android_dataspace dataSpace) {
+ this->dataSpace = dataSpace;
+ return *this;
+ }
+
QueueBufferInputBuilder& setCrop(Rect crop) {
this->crop = crop;
return *this;
@@ -182,6 +190,7 @@ protected:
private:
int64_t timestamp;
bool isAutoTimestamp;
+ android_dataspace dataSpace;
Rect crop;
int scalingMode;
uint32_t transform;
@@ -264,15 +273,12 @@ TEST_F(IGraphicBufferProducerTest, Disconnect_ReturnsError) {
TEST_F(IGraphicBufferProducerTest, Query_Succeeds) {
ASSERT_NO_FATAL_FAILURE(ConnectProducer());
- // TODO: Make these constants in header
- const int DEFAULT_CONSUMER_USAGE_BITS = 0;
-
- int value = -1;
+ int32_t value = -1;
EXPECT_OK(mProducer->query(NATIVE_WINDOW_WIDTH, &value));
- EXPECT_EQ(DEFAULT_WIDTH, value);
+ EXPECT_EQ(DEFAULT_WIDTH, static_cast<uint32_t>(value));
EXPECT_OK(mProducer->query(NATIVE_WINDOW_HEIGHT, &value));
- EXPECT_EQ(DEFAULT_HEIGHT, value);
+ EXPECT_EQ(DEFAULT_HEIGHT, static_cast<uint32_t>(value));
EXPECT_OK(mProducer->query(NATIVE_WINDOW_FORMAT, &value));
EXPECT_EQ(DEFAULT_FORMAT, value);
@@ -293,7 +299,7 @@ TEST_F(IGraphicBufferProducerTest, Query_ReturnsError) {
ASSERT_NO_FATAL_FAILURE(ConnectProducer());
// One past the end of the last 'query' enum value. Update this if we add more enums.
- const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_CONSUMER_USAGE_BITS + 1;
+ const int NATIVE_WINDOW_QUERY_LAST_OFF_BY_ONE = NATIVE_WINDOW_DEFAULT_DATASPACE + 1;
int value;
// What was out of range
@@ -360,7 +366,7 @@ TEST_F(IGraphicBufferProducerTest, Queue_Succeeds) {
EXPECT_EQ(DEFAULT_WIDTH, width);
EXPECT_EQ(DEFAULT_HEIGHT, height);
EXPECT_EQ(DEFAULT_TRANSFORM_HINT, transformHint);
- EXPECT_EQ(1, numPendingBuffers); // since queueBuffer was called exactly once
+ EXPECT_EQ(1u, numPendingBuffers); // since queueBuffer was called exactly once
}
// Buffer was not in the dequeued state
diff --git a/libs/gui/tests/SRGB_test.cpp b/libs/gui/tests/SRGB_test.cpp
index 2d5b8aa..3b11b97 100644
--- a/libs/gui/tests/SRGB_test.cpp
+++ b/libs/gui/tests/SRGB_test.cpp
@@ -17,8 +17,14 @@
#define LOG_TAG "SRGB_test"
//#define LOG_NDEBUG 0
+// Ignore for this file because it flags every instance of
+// ASSERT_EQ(GL_NO_ERROR, glGetError());
+#pragma clang diagnostic ignored "-Wsign-compare"
+
#include "GLTest.h"
+#include <math.h>
+
#include <gui/CpuConsumer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
@@ -212,10 +218,11 @@ protected:
ASSERT_EQ(GL_NO_ERROR, glGetError());
}
- void checkLockedBuffer(PixelFormat format) {
+ void checkLockedBuffer(PixelFormat format, android_dataspace dataSpace) {
ASSERT_EQ(mLockedBuffer.format, format);
ASSERT_EQ(mLockedBuffer.width, DISPLAY_WIDTH);
ASSERT_EQ(mLockedBuffer.height, DISPLAY_HEIGHT);
+ ASSERT_EQ(mLockedBuffer.dataSpace, dataSpace);
}
static bool withinTolerance(int a, int b) {
@@ -326,14 +333,15 @@ private:
ANativeWindow_Buffer outBuffer;
ARect outBufferBounds;
mOutputSurface->lock(&outBuffer, &outBufferBounds);
- ASSERT_EQ(mLockedBuffer.width, outBuffer.width);
- ASSERT_EQ(mLockedBuffer.height, outBuffer.height);
- ASSERT_EQ(mLockedBuffer.stride, outBuffer.stride);
+ ASSERT_EQ(mLockedBuffer.width, static_cast<uint32_t>(outBuffer.width));
+ ASSERT_EQ(mLockedBuffer.height, static_cast<uint32_t>(outBuffer.height));
+ ASSERT_EQ(mLockedBuffer.stride, static_cast<uint32_t>(outBuffer.stride));
if (mLockedBuffer.format == outBuffer.format) {
memcpy(outBuffer.bits, mLockedBuffer.data, bufferSize);
} else {
- ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_sRGB_A_8888);
+ ASSERT_EQ(mLockedBuffer.format, PIXEL_FORMAT_RGBA_8888);
+ ASSERT_EQ(mLockedBuffer.dataSpace, HAL_DATASPACE_SRGB);
ASSERT_EQ(outBuffer.format, PIXEL_FORMAT_RGBA_8888);
uint8_t* outPointer = reinterpret_cast<uint8_t*>(outBuffer.bits);
for (int y = 0; y < outBuffer.height; ++y) {
@@ -378,7 +386,8 @@ TEST_F(SRGBTest, GLRenderFromSRGBTexture) {
// Lock
ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
- ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888));
+ ASSERT_NO_FATAL_FAILURE(
+ checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN));
// Compare a pixel in the middle of each texture
int midSRGBOffset = (DISPLAY_HEIGHT / 4) * mLockedBuffer.stride *
@@ -396,7 +405,8 @@ TEST_F(SRGBTest, GLRenderFromSRGBTexture) {
// the debug surface if necessary
}
-TEST_F(SRGBTest, RenderToSRGBSurface) {
+// XXX: Disabled since we don't currently expect this to work
+TEST_F(SRGBTest, DISABLED_RenderToSRGBSurface) {
ASSERT_NO_FATAL_FAILURE(initShaders());
// By default, the first buffer we write into will be RGB
@@ -409,7 +419,8 @@ TEST_F(SRGBTest, RenderToSRGBSurface) {
// Lock
ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
- ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_RGBA_8888));
+ ASSERT_NO_FATAL_FAILURE(
+ checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_UNKNOWN));
// Save the values of the middle pixel for later comparison against SRGB
uint8_t values[PIXEL_SIZE] = {};
@@ -458,7 +469,8 @@ TEST_F(SRGBTest, RenderToSRGBSurface) {
ASSERT_EQ(NO_ERROR, mCpuConsumer->lockNextBuffer(&mLockedBuffer));
// Make sure we actually got the SRGB buffer on the consumer side
- ASSERT_NO_FATAL_FAILURE(checkLockedBuffer(PIXEL_FORMAT_sRGB_A_8888));
+ ASSERT_NO_FATAL_FAILURE(
+ checkLockedBuffer(PIXEL_FORMAT_RGBA_8888, HAL_DATASPACE_SRGB));
// Verify that the stored value is the same, accounting for RGB/SRGB
for (int c = 0; c < PIXEL_SIZE; ++c) {
diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp
index 4e63a6f..00cc39d 100644
--- a/libs/gui/tests/StreamSplitter_test.cpp
+++ b/libs/gui/tests/StreamSplitter_test.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "StreamSplitter_test"
//#define LOG_NDEBUG 0
+#include <gui/BufferItem.h>
#include <gui/BufferQueue.h>
#include <gui/IConsumerListener.h>
#include <gui/ISurfaceComposer.h>
@@ -75,6 +76,8 @@ private:
int mAllocCount;
};
+static const uint32_t TEST_DATA = 0x12345678u;
+
TEST_F(StreamSplitterTest, OneInputOneOutput) {
sp<CountedAllocator> allocator(new CountedAllocator);
@@ -107,21 +110,22 @@ TEST_F(StreamSplitterTest, OneInputOneOutput) {
uint32_t* dataIn;
ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
reinterpret_cast<void**>(&dataIn)));
- *dataIn = 0x12345678;
+ *dataIn = TEST_DATA;
ASSERT_EQ(OK, buffer->unlock());
IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
+ HAL_DATASPACE_UNKNOWN,
Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
Fence::NO_FENCE);
ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, outputConsumer->acquireBuffer(&item, 0));
uint32_t* dataOut;
ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
reinterpret_cast<void**>(&dataOut)));
- ASSERT_EQ(*dataOut, 0x12345678);
+ ASSERT_EQ(*dataOut, TEST_DATA);
ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
ASSERT_EQ(OK, outputConsumer->releaseBuffer(item.mBuf, item.mFrameNumber,
@@ -173,22 +177,23 @@ TEST_F(StreamSplitterTest, OneInputMultipleOutputs) {
uint32_t* dataIn;
ASSERT_EQ(OK, buffer->lock(GraphicBuffer::USAGE_SW_WRITE_OFTEN,
reinterpret_cast<void**>(&dataIn)));
- *dataIn = 0x12345678;
+ *dataIn = TEST_DATA;
ASSERT_EQ(OK, buffer->unlock());
IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
+ HAL_DATASPACE_UNKNOWN,
Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
Fence::NO_FENCE);
ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
for (int output = 0; output < NUM_OUTPUTS; ++output) {
- IGraphicBufferConsumer::BufferItem item;
+ BufferItem item;
ASSERT_EQ(OK, outputConsumers[output]->acquireBuffer(&item, 0));
uint32_t* dataOut;
ASSERT_EQ(OK, item.mGraphicBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN,
reinterpret_cast<void**>(&dataOut)));
- ASSERT_EQ(*dataOut, 0x12345678);
+ ASSERT_EQ(*dataOut, TEST_DATA);
ASSERT_EQ(OK, item.mGraphicBuffer->unlock());
ASSERT_EQ(OK, outputConsumers[output]->releaseBuffer(item.mBuf,
@@ -234,6 +239,7 @@ TEST_F(StreamSplitterTest, OutputAbandonment) {
outputConsumer->consumerDisconnect();
IGraphicBufferProducer::QueueBufferInput qbInput(0, false,
+ HAL_DATASPACE_UNKNOWN,
Rect(0, 0, 1, 1), NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, false,
Fence::NO_FENCE);
ASSERT_EQ(OK, inputProducer->queueBuffer(slot, qbInput, &qbOutput));
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index 8cdf3bc..d750cd0 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -207,12 +207,8 @@ TEST_F(SurfaceTextureClientTest, EglSwapBuffersAbandonErrorIsEglBadSurface) {
}
TEST_F(SurfaceTextureClientTest, BufferGeometryInvalidSizesFail) {
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, 0, 0));
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, -1, 0));
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, -1));
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, -1, 0));
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, 8, 0));
- EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 8, 0, 0));
+ EXPECT_GT(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 8));
+ EXPECT_GT(OK, native_window_set_buffers_dimensions(mANW.get(), 8, 0));
}
TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) {
@@ -226,7 +222,8 @@ TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) {
TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) {
ANativeWindowBuffer* buf;
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, PIXEL_FORMAT_RGB_565));
+ EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8));
+ EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
EXPECT_EQ(16, buf->width);
EXPECT_EQ(8, buf->height);
@@ -236,7 +233,8 @@ TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) {
TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) {
ANativeWindowBuffer* buf;
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
+ EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 0));
+ EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
EXPECT_EQ(1, buf->width);
EXPECT_EQ(1, buf->height);
@@ -246,7 +244,8 @@ TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) {
TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) {
ANativeWindowBuffer* buf;
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
+ EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8));
+ EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
EXPECT_EQ(16, buf->width);
EXPECT_EQ(8, buf->height);
@@ -256,13 +255,15 @@ TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) {
TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) {
ANativeWindowBuffer* buf;
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0));
+ EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 16, 8));
+ EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
EXPECT_EQ(16, buf->width);
EXPECT_EQ(8, buf->height);
EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format);
ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf, -1));
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, 0));
+ EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 0));
+ EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
EXPECT_EQ(1, buf->width);
EXPECT_EQ(1, buf->height);
@@ -272,7 +273,8 @@ TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) {
TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeChangedWithoutFormat) {
ANativeWindowBuffer* buf;
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565));
+ EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 0, 0));
+ EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), PIXEL_FORMAT_RGB_565));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf));
EXPECT_EQ(1, buf->width);
EXPECT_EQ(1, buf->height);
@@ -330,7 +332,8 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) {
EXPECT_EQ(8, buf[1]->height);
ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1));
ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1], -1));
- EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 12, 24, 0));
+ EXPECT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 12, 24));
+ EXPECT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
EXPECT_NE(buf[0], buf[1]);
@@ -468,7 +471,8 @@ TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) {
// Once we've queued a buffer, however we should not be able to dequeue more
// than (buffer-count - MIN_UNDEQUEUED_BUFFERS), which is 2 in this case.
- EXPECT_EQ(-EBUSY, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
+ EXPECT_EQ(INVALID_OPERATION,
+ native_window_dequeue_buffer_and_wait(mANW.get(), &buf[1]));
ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0], -1));
ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2], -1));
@@ -620,7 +624,8 @@ TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWi
crop.bottom = 5;
ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4));
- ASSERT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 8, 8, 0));
+ ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 8, 8));
+ ASSERT_EQ(OK, native_window_set_buffers_format(mANW.get(), 0));
ASSERT_EQ(OK, native_window_dequeue_buffer_and_wait(mANW.get(), &buf[0]));
ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &crop));
ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0], -1));
@@ -668,7 +673,8 @@ TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) {
const int numFmts = (sizeof(fmts) / sizeof(fmts[0]));
for (int i = 0; i < numFmts; i++) {
int fmt = -1;
- ASSERT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, fmts[i]));
+ ASSERT_EQ(OK, native_window_set_buffers_dimensions(anw.get(), 0, 0));
+ ASSERT_EQ(OK, native_window_set_buffers_format(anw.get(), fmts[i]));
ASSERT_EQ(OK, anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt));
EXPECT_EQ(fmts[i], fmt);
}
diff --git a/libs/gui/tests/SurfaceTextureFBO_test.cpp b/libs/gui/tests/SurfaceTextureFBO_test.cpp
index b165ae6..c243fc0 100644
--- a/libs/gui/tests/SurfaceTextureFBO_test.cpp
+++ b/libs/gui/tests/SurfaceTextureFBO_test.cpp
@@ -27,8 +27,10 @@ TEST_F(SurfaceTextureFBOTest, BlitFromCpuFilledBufferToFbo) {
const int texWidth = 64;
const int texHeight = 64;
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+ texWidth, texHeight));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_RGBA_8888));
ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
diff --git a/libs/gui/tests/SurfaceTextureGL_test.cpp b/libs/gui/tests/SurfaceTextureGL_test.cpp
index fa1e1b7..fad133f 100644
--- a/libs/gui/tests/SurfaceTextureGL_test.cpp
+++ b/libs/gui/tests/SurfaceTextureGL_test.cpp
@@ -28,8 +28,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) {
const int texWidth = 64;
const int texHeight = 66;
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+ texWidth, texHeight));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_YV12));
ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
@@ -74,8 +76,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) {
const int texWidth = 64;
const int texHeight = 64;
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+ texWidth, texHeight));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_YV12));
ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
@@ -120,8 +124,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
const int texWidth = 64;
const int texHeight = 66;
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+ texWidth, texHeight));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_YV12));
ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
@@ -185,8 +191,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BuffersRepeatedly) {
enum { numFrames = 1024 };
ASSERT_EQ(NO_ERROR, mST->setDefaultMaxBufferCount(2));
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_YV12));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+ texWidth, texHeight));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_YV12));
ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
GRALLOC_USAGE_SW_WRITE_OFTEN));
@@ -326,8 +334,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferNpot) {
const int texWidth = 64;
const int texHeight = 66;
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+ texWidth, texHeight));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_RGBA_8888));
ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
@@ -368,8 +378,10 @@ TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledRGBABufferPow2) {
const int texWidth = 64;
const int texHeight = 64;
- ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
- texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_dimensions(mANW.get(),
+ texWidth, texHeight));
+ ASSERT_EQ(NO_ERROR, native_window_set_buffers_format(mANW.get(),
+ HAL_PIXEL_FORMAT_RGBA_8888));
ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 5e6aeef..4f87824 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -155,4 +155,26 @@ TEST_F(SurfaceTest, QueryConsumerUsage) {
ASSERT_EQ(TEST_USAGE_FLAGS, flags);
}
+TEST_F(SurfaceTest, QueryDefaultBuffersDataSpace) {
+ const android_dataspace TEST_DATASPACE = HAL_DATASPACE_SRGB;
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1);
+
+ cpuConsumer->setDefaultBufferDataSpace(TEST_DATASPACE);
+
+ sp<Surface> s = new Surface(producer);
+
+ sp<ANativeWindow> anw(s);
+
+ android_dataspace dataSpace;
+
+ int err = anw->query(anw.get(), NATIVE_WINDOW_DEFAULT_DATASPACE,
+ reinterpret_cast<int*>(&dataSpace));
+
+ ASSERT_EQ(NO_ERROR, err);
+ ASSERT_EQ(TEST_DATASPACE, dataSpace);
+}
+
}
diff --git a/libs/input/tests/Android.mk b/libs/input/tests/Android.mk
index 9612a65..5bfa3d4 100644
--- a/libs/input/tests/Android.mk
+++ b/libs/input/tests/Android.mk
@@ -1,6 +1,5 @@
# Build the unit tests.
LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
# Build the unit tests.
test_src_files := \
@@ -14,14 +13,10 @@ shared_libraries := \
libutils \
libbinder \
libui \
- libstlport
-
-static_libraries := \
- libgtest \
- libgtest_main
$(foreach file,$(test_src_files), \
$(eval include $(CLEAR_VARS)) \
+ $(eval LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk) \
$(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
$(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
$(eval LOCAL_SRC_FILES := $(file)) \
@@ -33,6 +28,7 @@ $(foreach file,$(test_src_files), \
# run. All assertions are static_asserts and will fail during
# buildtime if something's wrong.
include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
LOCAL_SRC_FILES := StructLayout_test.cpp
LOCAL_MODULE := StructLayout_test
LOCAL_CFLAGS := -std=c++11 -O0
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index eec97be..1ce8626 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -12,10 +12,28 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES:= \
+LOCAL_CLANG := true
+LOCAL_CPPFLAGS := -std=c++1y -Weverything -Werror
+
+# The static constructors and destructors in this library have not been noted to
+# introduce significant overheads
+LOCAL_CPPFLAGS += -Wno-exit-time-destructors
+LOCAL_CPPFLAGS += -Wno-global-constructors
+
+# We only care about compiling as C++14
+LOCAL_CPPFLAGS += -Wno-c++98-compat-pedantic
+
+# We use four-character constants for the GraphicBuffer header, and don't care
+# that they're non-portable as long as they're consistent within one execution
+LOCAL_CPPFLAGS += -Wno-four-char-constants
+
+# Don't warn about struct padding
+LOCAL_CPPFLAGS += -Wno-padded
+
+LOCAL_SRC_FILES := \
Fence.cpp \
FramebufferNativeWindow.cpp \
FrameStats.cpp \
@@ -38,7 +56,7 @@ ifneq ($(BOARD_FRAMEBUFFER_FORCE_FORMAT),)
LOCAL_CFLAGS += -DFRAMEBUFFER_FORCE_FORMAT=$(BOARD_FRAMEBUFFER_FORCE_FORMAT)
endif
-LOCAL_MODULE:= libui
+LOCAL_MODULE := libui
include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/ui/Fence.cpp b/libs/ui/Fence.cpp
index 3c0306c..bf24ffb 100644
--- a/libs/ui/Fence.cpp
+++ b/libs/ui/Fence.cpp
@@ -18,10 +18,13 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
- // This is needed for stdint.h to define INT64_MAX in C++
- #define __STDC_LIMIT_MACROS
-
+// We would eliminate the non-conforming zero-length array, but we can't since
+// this is effectively included from the Linux kernel
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wzero-length-array"
#include <sync/sync.h>
+#pragma clang diagnostic pop
+
#include <ui/Fence.h>
#include <unistd.h>
#include <utils/Log.h>
@@ -45,7 +48,7 @@ Fence::~Fence() {
}
}
-status_t Fence::wait(unsigned int timeout) {
+status_t Fence::wait(int timeout) {
ATRACE_CALL();
if (mFenceFd == -1) {
return NO_ERROR;
@@ -59,7 +62,7 @@ status_t Fence::waitForever(const char* logname) {
if (mFenceFd == -1) {
return NO_ERROR;
}
- unsigned int warningTimeout = 3000;
+ int warningTimeout = 3000;
int err = sync_wait(mFenceFd, warningTimeout);
if (err < 0 && errno == ETIME) {
ALOGE("%s: fence %d didn't signal in %u ms", logname, mFenceFd,
@@ -127,7 +130,7 @@ nsecs_t Fence::getSignalTime() const {
}
size_t Fence::getFlattenedSize() const {
- return 1;
+ return 4;
}
size_t Fence::getFdCount() const {
@@ -138,7 +141,9 @@ status_t Fence::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) c
if (size < getFlattenedSize() || count < getFdCount()) {
return NO_MEMORY;
}
- FlattenableUtils::write(buffer, size, (uint32_t)getFdCount());
+ // Cast to uint32_t since the size of a size_t can vary between 32- and
+ // 64-bit processes
+ FlattenableUtils::write(buffer, size, static_cast<uint32_t>(getFdCount()));
if (isValid()) {
*fds++ = mFenceFd;
count--;
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 918f2e7..3ead25c 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -1,17 +1,17 @@
-/*
+/*
**
** Copyright 2007 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
+** 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
+** 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
+** 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.
*/
@@ -29,7 +29,9 @@
#include <ui/ANativeObjectBase.h>
#include <ui/Fence.h>
+#define INCLUDED_FROM_FRAMEBUFFER_NATIVE_WINDOW_CPP
#include <ui/FramebufferNativeWindow.h>
+#undef INCLUDED_FROM_FRAMEBUFFER_NATIVE_WINDOW_CPP
#include <ui/Rect.h>
#include <EGL/egl.h>
@@ -41,11 +43,11 @@
namespace android {
// ----------------------------------------------------------------------------
-class NativeBuffer
+class NativeBuffer final
: public ANativeObjectBase<
- ANativeWindowBuffer,
- NativeBuffer,
- LightRefBase<NativeBuffer> >
+ ANativeWindowBuffer,
+ NativeBuffer,
+ LightRefBase<NativeBuffer>>
{
public:
NativeBuffer(int w, int h, int f, int u) : BASE() {
@@ -55,43 +57,41 @@ public:
ANativeWindowBuffer::usage = u;
}
private:
- friend class LightRefBase<NativeBuffer>;
- ~NativeBuffer() { }; // this class cannot be overloaded
+ friend class LightRefBase<NativeBuffer>;
};
/*
* This implements the (main) framebuffer management. This class is used
* mostly by SurfaceFlinger, but also by command line GL application.
- *
+ *
* In fact this is an implementation of ANativeWindow on top of
* the framebuffer.
- *
- * Currently it is pretty simple, it manages only two buffers (the front and
+ *
+ * Currently it is pretty simple, it manages only two buffers (the front and
* back buffer).
- *
+ *
*/
-FramebufferNativeWindow::FramebufferNativeWindow()
+FramebufferNativeWindow::FramebufferNativeWindow()
: BASE(), fbDev(0), grDev(0), mUpdateOnDemand(false)
{
hw_module_t const* module;
if (hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module) == 0) {
- int stride;
int err;
int i;
err = framebuffer_open(module, &fbDev);
ALOGE_IF(err, "couldn't open framebuffer HAL (%s)", strerror(-err));
-
+
err = gralloc_open(module, &grDev);
ALOGE_IF(err, "couldn't open gralloc HAL (%s)", strerror(-err));
// bail out if we can't initialize the modules
if (!fbDev || !grDev)
return;
-
+
mUpdateOnDemand = (fbDev->setUpdateRect != 0);
-
+
// initialize the buffer FIFO
if(fbDev->numFramebuffers >= MIN_NUM_FRAME_BUFFERS &&
fbDev->numFramebuffers <= MAX_NUM_FRAME_BUFFERS){
@@ -114,36 +114,37 @@ FramebufferNativeWindow::FramebufferNativeWindow()
*((uint32_t *)&fbDev->format) = FRAMEBUFFER_FORCE_FORMAT;
#endif
- for (i = 0; i < mNumBuffers; i++)
- {
- buffers[i] = new NativeBuffer(
- fbDev->width, fbDev->height, fbDev->format, GRALLOC_USAGE_HW_FB);
+ for (i = 0; i < mNumBuffers; i++) {
+ buffers[i] = new NativeBuffer(
+ static_cast<int>(fbDev->width),
+ static_cast<int>(fbDev->height),
+ fbDev->format, GRALLOC_USAGE_HW_FB);
}
- for (i = 0; i < mNumBuffers; i++)
- {
- err = grDev->alloc(grDev,
- fbDev->width, fbDev->height, fbDev->format,
- GRALLOC_USAGE_HW_FB, &buffers[i]->handle, &buffers[i]->stride);
-
- ALOGE_IF(err, "fb buffer %d allocation failed w=%d, h=%d, err=%s",
- i, fbDev->width, fbDev->height, strerror(-err));
-
- if (err)
- {
- mNumBuffers = i;
- mNumFreeBuffers = i;
- mBufferHead = mNumBuffers-1;
- break;
- }
+ for (i = 0; i < mNumBuffers; i++) {
+ err = grDev->alloc(grDev,
+ static_cast<int>(fbDev->width),
+ static_cast<int>(fbDev->height),
+ fbDev->format, GRALLOC_USAGE_HW_FB,
+ &buffers[i]->handle, &buffers[i]->stride);
+
+ ALOGE_IF(err, "fb buffer %d allocation failed w=%d, h=%d, err=%s",
+ i, fbDev->width, fbDev->height, strerror(-err));
+
+ if (err) {
+ mNumBuffers = i;
+ mNumFreeBuffers = i;
+ mBufferHead = mNumBuffers-1;
+ break;
+ }
}
- const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags;
+ const_cast<uint32_t&>(ANativeWindow::flags) = fbDev->flags;
const_cast<float&>(ANativeWindow::xdpi) = fbDev->xdpi;
const_cast<float&>(ANativeWindow::ydpi) = fbDev->ydpi;
- const_cast<int&>(ANativeWindow::minSwapInterval) =
+ const_cast<int&>(ANativeWindow::minSwapInterval) =
fbDev->minSwapInterval;
- const_cast<int&>(ANativeWindow::maxSwapInterval) =
+ const_cast<int&>(ANativeWindow::maxSwapInterval) =
fbDev->maxSwapInterval;
} else {
ALOGE("Couldn't get gralloc module");
@@ -160,7 +161,7 @@ FramebufferNativeWindow::FramebufferNativeWindow()
ANativeWindow::queueBuffer_DEPRECATED = queueBuffer_DEPRECATED;
}
-FramebufferNativeWindow::~FramebufferNativeWindow()
+FramebufferNativeWindow::~FramebufferNativeWindow()
{
if (grDev) {
for(int i = 0; i < mNumBuffers; i++) {
@@ -176,7 +177,7 @@ FramebufferNativeWindow::~FramebufferNativeWindow()
}
}
-status_t FramebufferNativeWindow::setUpdateRectangle(const Rect& r)
+status_t FramebufferNativeWindow::setUpdateRectangle(const Rect& r)
{
if (!mUpdateOnDemand) {
return INVALID_OPERATION;
@@ -193,7 +194,7 @@ status_t FramebufferNativeWindow::compositionComplete()
}
int FramebufferNativeWindow::setSwapInterval(
- ANativeWindow* window, int interval)
+ ANativeWindow* window, int interval)
{
framebuffer_device_t* fb = getSelf(window)->fbDev;
return fb->setSwapInterval(fb, interval);
@@ -217,7 +218,7 @@ int FramebufferNativeWindow::getCurrentBufferIndex() const
return index;
}
-int FramebufferNativeWindow::dequeueBuffer_DEPRECATED(ANativeWindow* window,
+int FramebufferNativeWindow::dequeueBuffer_DEPRECATED(ANativeWindow* window,
ANativeWindowBuffer** buffer)
{
int fenceFd = -1;
@@ -232,12 +233,11 @@ int FramebufferNativeWindow::dequeueBuffer_DEPRECATED(ANativeWindow* window,
return result;
}
-int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,
+int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,
ANativeWindowBuffer** buffer, int* fenceFd)
{
FramebufferNativeWindow* self = getSelf(window);
Mutex::Autolock _l(self->mutex);
- framebuffer_device_t* fb = self->fbDev;
int index = self->mBufferHead++;
if (self->mBufferHead >= self->mNumBuffers)
@@ -247,7 +247,7 @@ int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,
while (self->mNumFreeBuffers < 2) {
self->mCondition.wait(self->mutex);
}
- ALOG_ASSERT(self->buffers[index] != self->front);
+ ALOG_ASSERT(self->buffers[index] != self->front, "");
// get this buffer
self->mNumFreeBuffers--;
@@ -259,19 +259,19 @@ int FramebufferNativeWindow::dequeueBuffer(ANativeWindow* window,
return 0;
}
-int FramebufferNativeWindow::lockBuffer_DEPRECATED(ANativeWindow* /*window*/,
+int FramebufferNativeWindow::lockBuffer_DEPRECATED(ANativeWindow* /*window*/,
ANativeWindowBuffer* /*buffer*/)
{
return NO_ERROR;
}
-int FramebufferNativeWindow::queueBuffer_DEPRECATED(ANativeWindow* window,
+int FramebufferNativeWindow::queueBuffer_DEPRECATED(ANativeWindow* window,
ANativeWindowBuffer* buffer)
{
return queueBuffer(window, buffer, -1);
}
-int FramebufferNativeWindow::queueBuffer(ANativeWindow* window,
+int FramebufferNativeWindow::queueBuffer(ANativeWindow* window,
ANativeWindowBuffer* buffer, int fenceFd)
{
FramebufferNativeWindow* self = getSelf(window);
@@ -282,7 +282,6 @@ int FramebufferNativeWindow::queueBuffer(ANativeWindow* window,
sp<Fence> fence(new Fence(fenceFd));
fence->wait(Fence::TIMEOUT_NEVER);
- const int index = self->mCurrentBufferIndex;
int res = fb->post(fb, handle);
self->front = static_cast<NativeBuffer*>(buffer);
self->mNumFreeBuffers++;
@@ -291,17 +290,17 @@ int FramebufferNativeWindow::queueBuffer(ANativeWindow* window,
}
int FramebufferNativeWindow::query(const ANativeWindow* window,
- int what, int* value)
+ int what, int* value)
{
const FramebufferNativeWindow* self = getSelf(window);
Mutex::Autolock _l(self->mutex);
framebuffer_device_t* fb = self->fbDev;
switch (what) {
case NATIVE_WINDOW_WIDTH:
- *value = fb->width;
+ *value = static_cast<int>(fb->width);
return NO_ERROR;
case NATIVE_WINDOW_HEIGHT:
- *value = fb->height;
+ *value = static_cast<int>(fb->height);
return NO_ERROR;
case NATIVE_WINDOW_FORMAT:
*value = fb->format;
@@ -313,10 +312,10 @@ int FramebufferNativeWindow::query(const ANativeWindow* window,
*value = 0;
return NO_ERROR;
case NATIVE_WINDOW_DEFAULT_WIDTH:
- *value = fb->width;
+ *value = static_cast<int>(fb->width);
return NO_ERROR;
case NATIVE_WINDOW_DEFAULT_HEIGHT:
- *value = fb->height;
+ *value = static_cast<int>(fb->height);
return NO_ERROR;
case NATIVE_WINDOW_TRANSFORM_HINT:
*value = 0;
@@ -357,7 +356,8 @@ int FramebufferNativeWindow::perform(ANativeWindow* /*window*/,
}; // namespace android
// ----------------------------------------------------------------------------
-using namespace android;
+using android::sp;
+using android::FramebufferNativeWindow;
EGLNativeWindowType android_createDisplaySurface(void)
{
@@ -368,5 +368,5 @@ EGLNativeWindowType android_createDisplaySurface(void)
sp<FramebufferNativeWindow> ref(w);
return NULL;
}
- return (EGLNativeWindowType)w;
+ return static_cast<EGLNativeWindowType>(w);
}
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 3ae8840..6a42a22 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -45,40 +45,40 @@ GraphicBuffer::GraphicBuffer()
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR), mId(getUniqueId())
{
- width =
- height =
- stride =
- format =
+ width =
+ height =
+ stride =
+ format =
usage = 0;
handle = NULL;
}
-GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat reqFormat, uint32_t reqUsage)
+GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
+ PixelFormat inFormat, uint32_t inUsage)
: BASE(), mOwner(ownData), mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR), mId(getUniqueId())
{
- width =
- height =
- stride =
- format =
+ width =
+ height =
+ stride =
+ format =
usage = 0;
handle = NULL;
- mInitCheck = initSize(w, h, reqFormat, reqUsage);
+ mInitCheck = initSize(inWidth, inHeight, inFormat, inUsage);
}
-GraphicBuffer::GraphicBuffer(uint32_t w, uint32_t h,
- PixelFormat inFormat, uint32_t inUsage,
- uint32_t inStride, native_handle_t* inHandle, bool keepOwnership)
+GraphicBuffer::GraphicBuffer(uint32_t inWidth, uint32_t inHeight,
+ PixelFormat inFormat, uint32_t inUsage, uint32_t inStride,
+ native_handle_t* inHandle, bool keepOwnership)
: BASE(), mOwner(keepOwnership ? ownHandle : ownNone),
mBufferMapper(GraphicBufferMapper::get()),
mInitCheck(NO_ERROR), mId(getUniqueId())
{
- width = w;
- height = h;
- stride = inStride;
+ width = static_cast<int>(inWidth);
+ height = static_cast<int>(inHeight);
+ stride = static_cast<int>(inStride);
format = inFormat;
- usage = inUsage;
+ usage = static_cast<int>(inUsage);
handle = inHandle;
}
@@ -116,7 +116,7 @@ void GraphicBuffer::free_handle()
}
status_t GraphicBuffer::initCheck() const {
- return mInitCheck;
+ return static_cast<status_t>(mInitCheck);
}
void GraphicBuffer::dumpAllocationsToSystemLog()
@@ -131,13 +131,17 @@ ANativeWindowBuffer* GraphicBuffer::getNativeBuffer() const
const_cast<GraphicBuffer*>(this));
}
-status_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f,
- uint32_t reqUsage)
+status_t GraphicBuffer::reallocate(uint32_t inWidth, uint32_t inHeight,
+ PixelFormat inFormat, uint32_t inUsage)
{
if (mOwner != ownData)
return INVALID_OPERATION;
- if (handle && w==width && h==height && f==format && reqUsage==usage)
+ if (handle &&
+ static_cast<int>(inWidth) == width &&
+ static_cast<int>(inHeight) == height &&
+ inFormat == format &&
+ static_cast<int>(inUsage) == usage)
return NO_ERROR;
if (handle) {
@@ -145,61 +149,74 @@ status_t GraphicBuffer::reallocate(uint32_t w, uint32_t h, PixelFormat f,
allocator.free(handle);
handle = 0;
}
- return initSize(w, h, f, reqUsage);
+ return initSize(inWidth, inHeight, inFormat, inUsage);
}
-status_t GraphicBuffer::initSize(uint32_t w, uint32_t h, PixelFormat format,
- uint32_t reqUsage)
+bool GraphicBuffer::needsReallocation(uint32_t inWidth, uint32_t inHeight,
+ PixelFormat inFormat, uint32_t inUsage)
+{
+ if (static_cast<int>(inWidth) != width) return true;
+ if (static_cast<int>(inHeight) != height) return true;
+ if (inFormat != format) return true;
+ if ((static_cast<uint32_t>(usage) & inUsage) != inUsage) return true;
+ return false;
+}
+
+status_t GraphicBuffer::initSize(uint32_t inWidth, uint32_t inHeight,
+ PixelFormat inFormat, uint32_t inUsage)
{
GraphicBufferAllocator& allocator = GraphicBufferAllocator::get();
- status_t err = allocator.alloc(w, h, format, reqUsage, &handle, &stride);
+ uint32_t outStride = 0;
+ status_t err = allocator.alloc(inWidth, inHeight, inFormat, inUsage,
+ &handle, &outStride);
if (err == NO_ERROR) {
- this->width = w;
- this->height = h;
- this->format = format;
- this->usage = reqUsage;
+ width = static_cast<int>(inWidth);
+ height = static_cast<int>(inHeight);
+ format = inFormat;
+ usage = static_cast<int>(inUsage);
+ stride = static_cast<int>(outStride);
}
return err;
}
-status_t GraphicBuffer::lock(uint32_t usage, void** vaddr)
+status_t GraphicBuffer::lock(uint32_t inUsage, void** vaddr)
{
const Rect lockBounds(width, height);
- status_t res = lock(usage, lockBounds, vaddr);
+ status_t res = lock(inUsage, lockBounds, vaddr);
return res;
}
-status_t GraphicBuffer::lock(uint32_t usage, const Rect& rect, void** vaddr)
+status_t GraphicBuffer::lock(uint32_t inUsage, const Rect& rect, void** vaddr)
{
- if (rect.left < 0 || rect.right > this->width ||
- rect.top < 0 || rect.bottom > this->height) {
+ if (rect.left < 0 || rect.right > width ||
+ rect.top < 0 || rect.bottom > height) {
ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
- rect.left, rect.top, rect.right, rect.bottom,
- this->width, this->height);
+ rect.left, rect.top, rect.right, rect.bottom,
+ width, height);
return BAD_VALUE;
}
- status_t res = getBufferMapper().lock(handle, usage, rect, vaddr);
+ status_t res = getBufferMapper().lock(handle, inUsage, rect, vaddr);
return res;
}
-status_t GraphicBuffer::lockYCbCr(uint32_t usage, android_ycbcr *ycbcr)
+status_t GraphicBuffer::lockYCbCr(uint32_t inUsage, android_ycbcr* ycbcr)
{
const Rect lockBounds(width, height);
- status_t res = lockYCbCr(usage, lockBounds, ycbcr);
+ status_t res = lockYCbCr(inUsage, lockBounds, ycbcr);
return res;
}
-status_t GraphicBuffer::lockYCbCr(uint32_t usage, const Rect& rect,
- android_ycbcr *ycbcr)
+status_t GraphicBuffer::lockYCbCr(uint32_t inUsage, const Rect& rect,
+ android_ycbcr* ycbcr)
{
- if (rect.left < 0 || rect.right > this->width ||
- rect.top < 0 || rect.bottom > this->height) {
+ if (rect.left < 0 || rect.right > width ||
+ rect.top < 0 || rect.bottom > height) {
ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
rect.left, rect.top, rect.right, rect.bottom,
- this->width, this->height);
+ width, height);
return BAD_VALUE;
}
- status_t res = getBufferMapper().lockYCbCr(handle, usage, rect, ycbcr);
+ status_t res = getBufferMapper().lockYCbCr(handle, inUsage, rect, ycbcr);
return res;
}
@@ -209,43 +226,48 @@ status_t GraphicBuffer::unlock()
return res;
}
-status_t GraphicBuffer::lockAsync(uint32_t usage, void** vaddr, int fenceFd)
+status_t GraphicBuffer::lockAsync(uint32_t inUsage, void** vaddr, int fenceFd)
{
const Rect lockBounds(width, height);
- status_t res = lockAsync(usage, lockBounds, vaddr, fenceFd);
+ status_t res = lockAsync(inUsage, lockBounds, vaddr, fenceFd);
return res;
}
-status_t GraphicBuffer::lockAsync(uint32_t usage, const Rect& rect, void** vaddr, int fenceFd)
+status_t GraphicBuffer::lockAsync(uint32_t inUsage, const Rect& rect,
+ void** vaddr, int fenceFd)
{
- if (rect.left < 0 || rect.right > this->width ||
- rect.top < 0 || rect.bottom > this->height) {
+ if (rect.left < 0 || rect.right > width ||
+ rect.top < 0 || rect.bottom > height) {
ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
rect.left, rect.top, rect.right, rect.bottom,
- this->width, this->height);
+ width, height);
return BAD_VALUE;
}
- status_t res = getBufferMapper().lockAsync(handle, usage, rect, vaddr, fenceFd);
+ status_t res = getBufferMapper().lockAsync(handle, inUsage, rect, vaddr,
+ fenceFd);
return res;
}
-status_t GraphicBuffer::lockAsyncYCbCr(uint32_t usage, android_ycbcr *ycbcr, int fenceFd)
+status_t GraphicBuffer::lockAsyncYCbCr(uint32_t inUsage, android_ycbcr* ycbcr,
+ int fenceFd)
{
const Rect lockBounds(width, height);
- status_t res = lockAsyncYCbCr(usage, lockBounds, ycbcr, fenceFd);
+ status_t res = lockAsyncYCbCr(inUsage, lockBounds, ycbcr, fenceFd);
return res;
}
-status_t GraphicBuffer::lockAsyncYCbCr(uint32_t usage, const Rect& rect, android_ycbcr *ycbcr, int fenceFd)
+status_t GraphicBuffer::lockAsyncYCbCr(uint32_t inUsage, const Rect& rect,
+ android_ycbcr* ycbcr, int fenceFd)
{
- if (rect.left < 0 || rect.right > this->width ||
- rect.top < 0 || rect.bottom > this->height) {
+ if (rect.left < 0 || rect.right > width ||
+ rect.top < 0 || rect.bottom > height) {
ALOGE("locking pixels (%d,%d,%d,%d) outside of buffer (w=%d, h=%d)",
rect.left, rect.top, rect.right, rect.bottom,
- this->width, this->height);
+ width, height);
return BAD_VALUE;
}
- status_t res = getBufferMapper().lockAsyncYCbCr(handle, usage, rect, ycbcr, fenceFd);
+ status_t res = getBufferMapper().lockAsyncYCbCr(handle, inUsage, rect,
+ ycbcr, fenceFd);
return res;
}
@@ -256,11 +278,11 @@ status_t GraphicBuffer::unlockAsync(int *fenceFd)
}
size_t GraphicBuffer::getFlattenedSize() const {
- return (10 + (handle ? handle->numInts : 0))*sizeof(int);
+ return static_cast<size_t>(10 + (handle ? handle->numInts : 0)) * sizeof(int);
}
size_t GraphicBuffer::getFdCount() const {
- return handle ? handle->numFds : 0;
+ return static_cast<size_t>(handle ? handle->numFds : 0);
}
status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const {
@@ -285,16 +307,17 @@ status_t GraphicBuffer::flatten(void*& buffer, size_t& size, int*& fds, size_t&
if (handle) {
buf[8] = handle->numFds;
buf[9] = handle->numInts;
- native_handle_t const* const h = handle;
- memcpy(fds, h->data, h->numFds*sizeof(int));
- memcpy(&buf[10], h->data + h->numFds, h->numInts*sizeof(int));
+ memcpy(fds, handle->data,
+ static_cast<size_t>(handle->numFds) * sizeof(int));
+ memcpy(&buf[10], handle->data + handle->numFds,
+ static_cast<size_t>(handle->numInts) * sizeof(int));
}
- buffer = reinterpret_cast<void*>(static_cast<int*>(buffer) + sizeNeeded);
+ buffer = static_cast<void*>(static_cast<uint8_t*>(buffer) + sizeNeeded);
size -= sizeNeeded;
if (handle) {
fds += handle->numFds;
- count -= handle->numFds;
+ count -= static_cast<size_t>(handle->numFds);
}
return NO_ERROR;
@@ -307,8 +330,8 @@ status_t GraphicBuffer::unflatten(
int const* buf = static_cast<int const*>(buffer);
if (buf[0] != 'GBFR') return BAD_TYPE;
- const size_t numFds = buf[8];
- const size_t numInts = buf[9];
+ const size_t numFds = static_cast<size_t>(buf[8]);
+ const size_t numInts = static_cast<size_t>(buf[9]);
// Limit the maxNumber to be relatively small. The number of fds or ints
// should not come close to this number, and the number itself was simply
@@ -318,7 +341,7 @@ status_t GraphicBuffer::unflatten(
if (numFds >= maxNumber || numInts >= (maxNumber - 10)) {
width = height = stride = format = usage = 0;
handle = NULL;
- ALOGE("unflatten: numFds or numInts is too large: %d, %d",
+ ALOGE("unflatten: numFds or numInts is too large: %zd, %zd",
numFds, numInts);
return BAD_VALUE;
}
@@ -340,15 +363,16 @@ status_t GraphicBuffer::unflatten(
stride = buf[3];
format = buf[4];
usage = buf[5];
- native_handle* h = native_handle_create(numFds, numInts);
+ native_handle* h = native_handle_create(
+ static_cast<int>(numFds), static_cast<int>(numInts));
if (!h) {
width = height = stride = format = usage = 0;
handle = NULL;
ALOGE("unflatten: native_handle_create failed");
return NO_MEMORY;
}
- memcpy(h->data, fds, numFds*sizeof(int));
- memcpy(h->data + numFds, &buf[10], numInts*sizeof(int));
+ memcpy(h->data, fds, numFds * sizeof(int));
+ memcpy(h->data + numFds, &buf[10], numInts * sizeof(int));
handle = h;
} else {
width = height = stride = format = usage = 0;
@@ -371,7 +395,7 @@ status_t GraphicBuffer::unflatten(
}
}
- buffer = reinterpret_cast<void const*>(static_cast<int const*>(buffer) + sizeNeeded);
+ buffer = static_cast<void const*>(static_cast<uint8_t const*>(buffer) + sizeNeeded);
size -= sizeNeeded;
fds += numFds;
count -= numFds;
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index ff550d9..85e9675 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -1,17 +1,17 @@
-/*
+/*
**
** Copyright 2009, 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
+** 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
+** 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
+** 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.
*/
@@ -66,11 +66,11 @@ void GraphicBufferAllocator::dump(String8& result) const
if (rec.size) {
snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
list.keyAt(i), rec.size/1024.0f,
- rec.w, rec.s, rec.h, rec.format, rec.usage);
+ rec.width, rec.stride, rec.height, rec.format, rec.usage);
} else {
snprintf(buffer, SIZE, "%10p: unknown | %4u (%4u) x %4u | %8X | 0x%08x\n",
list.keyAt(i),
- rec.w, rec.s, rec.h, rec.format, rec.usage);
+ rec.width, rec.stride, rec.height, rec.format, rec.usage);
}
result.append(buffer);
total += rec.size;
@@ -90,39 +90,40 @@ void GraphicBufferAllocator::dumpToSystemLog()
ALOGD("%s", s.string());
}
-status_t GraphicBufferAllocator::alloc(uint32_t w, uint32_t h, PixelFormat format,
- int usage, buffer_handle_t* handle, int32_t* stride)
+status_t GraphicBufferAllocator::alloc(uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t usage, buffer_handle_t* handle,
+ uint32_t* stride)
{
ATRACE_CALL();
+
// make sure to not allocate a N x 0 or 0 x N buffer, since this is
// allowed from an API stand-point allocate a 1x1 buffer instead.
- if (!w || !h)
- w = h = 1;
+ if (!width || !height)
+ width = height = 1;
// we have a h/w allocator and h/w buffer is requested
- status_t err;
-
- err = mAllocDev->alloc(mAllocDev, w, h, format, usage, handle, stride);
+ status_t err;
+
+ int outStride = 0;
+ err = mAllocDev->alloc(mAllocDev, static_cast<int>(width),
+ static_cast<int>(height), format, static_cast<int>(usage), handle,
+ &outStride);
+ *stride = static_cast<uint32_t>(outStride);
ALOGW_IF(err, "alloc(%u, %u, %d, %08x, ...) failed %d (%s)",
- w, h, format, usage, err, strerror(-err));
-
+ width, height, format, usage, err, strerror(-err));
+
if (err == NO_ERROR) {
Mutex::Autolock _l(sLock);
KeyedVector<buffer_handle_t, alloc_rec_t>& list(sAllocList);
- int bpp = bytesPerPixel(format);
- if (bpp < 0) {
- // probably a HAL custom format. in any case, we don't know
- // what its pixel size is.
- bpp = 0;
- }
+ uint32_t bpp = bytesPerPixel(format);
alloc_rec_t rec;
- rec.w = w;
- rec.h = h;
- rec.s = *stride;
+ rec.width = width;
+ rec.height = height;
+ rec.stride = *stride;
rec.format = format;
rec.usage = usage;
- rec.size = h * stride[0] * bpp;
+ rec.size = static_cast<size_t>(height * (*stride) * bpp);
list.add(*handle, rec);
}
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index e949b0c..31bfb2d 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -20,7 +20,12 @@
#include <stdint.h>
#include <errno.h>
+// We would eliminate the non-conforming zero-length array, but we can't since
+// this is effectively included from the Linux kernel
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wzero-length-array"
#include <sync/sync.h>
+#pragma clang diagnostic pop
#include <utils/Errors.h>
#include <utils/Log.h>
@@ -44,7 +49,7 @@ GraphicBufferMapper::GraphicBufferMapper()
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
ALOGE_IF(err, "FATAL: can't find the %s module", GRALLOC_HARDWARE_MODULE_ID);
if (err == 0) {
- mAllocMod = (gralloc_module_t const *)module;
+ mAllocMod = reinterpret_cast<gralloc_module_t const *>(module);
}
}
@@ -72,13 +77,13 @@ status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle)
return err;
}
-status_t GraphicBufferMapper::lock(buffer_handle_t handle,
- int usage, const Rect& bounds, void** vaddr)
+status_t GraphicBufferMapper::lock(buffer_handle_t handle,
+ uint32_t usage, const Rect& bounds, void** vaddr)
{
ATRACE_CALL();
status_t err;
- err = mAllocMod->lock(mAllocMod, handle, usage,
+ err = mAllocMod->lock(mAllocMod, handle, static_cast<int>(usage),
bounds.left, bounds.top, bounds.width(), bounds.height(),
vaddr);
@@ -87,7 +92,7 @@ status_t GraphicBufferMapper::lock(buffer_handle_t handle,
}
status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle,
- int usage, const Rect& bounds, android_ycbcr *ycbcr)
+ uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr)
{
ATRACE_CALL();
status_t err;
@@ -96,7 +101,7 @@ status_t GraphicBufferMapper::lockYCbCr(buffer_handle_t handle,
return -EINVAL; // do not log failure
}
- err = mAllocMod->lock_ycbcr(mAllocMod, handle, usage,
+ err = mAllocMod->lock_ycbcr(mAllocMod, handle, static_cast<int>(usage),
bounds.left, bounds.top, bounds.width(), bounds.height(),
ycbcr);
@@ -116,19 +121,19 @@ status_t GraphicBufferMapper::unlock(buffer_handle_t handle)
}
status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
- int usage, const Rect& bounds, void** vaddr, int fenceFd)
+ uint32_t usage, const Rect& bounds, void** vaddr, int fenceFd)
{
ATRACE_CALL();
status_t err;
if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3) {
- err = mAllocMod->lockAsync(mAllocMod, handle, usage,
+ err = mAllocMod->lockAsync(mAllocMod, handle, static_cast<int>(usage),
bounds.left, bounds.top, bounds.width(), bounds.height(),
vaddr, fenceFd);
} else {
sync_wait(fenceFd, -1);
close(fenceFd);
- err = mAllocMod->lock(mAllocMod, handle, usage,
+ err = mAllocMod->lock(mAllocMod, handle, static_cast<int>(usage),
bounds.left, bounds.top, bounds.width(), bounds.height(),
vaddr);
}
@@ -138,20 +143,20 @@ status_t GraphicBufferMapper::lockAsync(buffer_handle_t handle,
}
status_t GraphicBufferMapper::lockAsyncYCbCr(buffer_handle_t handle,
- int usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd)
+ uint32_t usage, const Rect& bounds, android_ycbcr *ycbcr, int fenceFd)
{
ATRACE_CALL();
status_t err;
if (mAllocMod->common.module_api_version >= GRALLOC_MODULE_API_VERSION_0_3
&& mAllocMod->lockAsync_ycbcr != NULL) {
- err = mAllocMod->lockAsync_ycbcr(mAllocMod, handle, usage,
- bounds.left, bounds.top, bounds.width(), bounds.height(),
- ycbcr, fenceFd);
+ err = mAllocMod->lockAsync_ycbcr(mAllocMod, handle,
+ static_cast<int>(usage), bounds.left, bounds.top,
+ bounds.width(), bounds.height(), ycbcr, fenceFd);
} else if (mAllocMod->lock_ycbcr != NULL) {
sync_wait(fenceFd, -1);
close(fenceFd);
- err = mAllocMod->lock_ycbcr(mAllocMod, handle, usage,
+ err = mAllocMod->lock_ycbcr(mAllocMod, handle, static_cast<int>(usage),
bounds.left, bounds.top, bounds.width(), bounds.height(),
ycbcr);
} else {
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index 5ce7fba..cab1dde 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -15,19 +15,16 @@
*/
#include <ui/PixelFormat.h>
-#include <hardware/hardware.h>
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
-ssize_t bytesPerPixel(PixelFormat format) {
+uint32_t bytesPerPixel(PixelFormat format) {
switch (format) {
case PIXEL_FORMAT_RGBA_8888:
case PIXEL_FORMAT_RGBX_8888:
case PIXEL_FORMAT_BGRA_8888:
- case PIXEL_FORMAT_sRGB_A_8888:
- case PIXEL_FORMAT_sRGB_X_8888:
return 4;
case PIXEL_FORMAT_RGB_888:
return 3;
@@ -36,10 +33,10 @@ ssize_t bytesPerPixel(PixelFormat format) {
case PIXEL_FORMAT_RGBA_4444:
return 2;
}
- return BAD_VALUE;
+ return 0;
}
-ssize_t bitsPerPixel(PixelFormat format) {
+uint32_t bitsPerPixel(PixelFormat format) {
switch (format) {
case PIXEL_FORMAT_RGBA_8888:
case PIXEL_FORMAT_RGBX_8888:
@@ -52,10 +49,9 @@ ssize_t bitsPerPixel(PixelFormat format) {
case PIXEL_FORMAT_RGBA_4444:
return 16;
}
- return BAD_VALUE;
+ return 0;
}
// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------
-
diff --git a/libs/ui/Rect.cpp b/libs/ui/Rect.cpp
index b480f3a..dcce21f 100644
--- a/libs/ui/Rect.cpp
+++ b/libs/ui/Rect.cpp
@@ -19,6 +19,8 @@
namespace android {
+const Rect Rect::INVALID_RECT{0, 0, -1, -1};
+
static inline int32_t min(int32_t a, int32_t b) {
return (a < b) ? a : b;
}
diff --git a/libs/ui/Region.cpp b/libs/ui/Region.cpp
index fa812f4..3810da4 100644
--- a/libs/ui/Region.cpp
+++ b/libs/ui/Region.cpp
@@ -53,6 +53,8 @@ enum {
direction_RTL
};
+const Region Region::INVALID_REGION(Rect::INVALID_RECT);
+
// ----------------------------------------------------------------------------
Region::Region() {
@@ -102,8 +104,8 @@ static void reverseRectsResolvingJunctions(const Rect* begin, const Rect* end,
current--;
} while (current->top == lastTop && current >= begin);
- unsigned int beginLastSpan = -1;
- unsigned int endLastSpan = -1;
+ int beginLastSpan = -1;
+ int endLastSpan = -1;
int top = -1;
int bottom = -1;
@@ -118,7 +120,7 @@ static void reverseRectsResolvingJunctions(const Rect* begin, const Rect* end,
} else {
beginLastSpan = endLastSpan + 1;
}
- endLastSpan = dst.size() - 1;
+ endLastSpan = static_cast<int>(dst.size()) - 1;
top = current->top;
bottom = current->bottom;
@@ -126,43 +128,46 @@ static void reverseRectsResolvingJunctions(const Rect* begin, const Rect* end,
int left = current->left;
int right = current->right;
- for (unsigned int prevIndex = beginLastSpan; prevIndex <= endLastSpan; prevIndex++) {
- const Rect* prev = &dst[prevIndex];
+ for (int prevIndex = beginLastSpan; prevIndex <= endLastSpan; prevIndex++) {
+ // prevIndex can't be -1 here because if endLastSpan is set to a
+ // value greater than -1 (allowing the loop to execute),
+ // beginLastSpan (and therefore prevIndex) will also be increased
+ const Rect prev = dst[static_cast<size_t>(prevIndex)];
if (spanDirection == direction_RTL) {
// iterating over previous span RTL, quit if it's too far left
- if (prev->right <= left) break;
+ if (prev.right <= left) break;
- if (prev->right > left && prev->right < right) {
- dst.add(Rect(prev->right, top, right, bottom));
- right = prev->right;
+ if (prev.right > left && prev.right < right) {
+ dst.add(Rect(prev.right, top, right, bottom));
+ right = prev.right;
}
- if (prev->left > left && prev->left < right) {
- dst.add(Rect(prev->left, top, right, bottom));
- right = prev->left;
+ if (prev.left > left && prev.left < right) {
+ dst.add(Rect(prev.left, top, right, bottom));
+ right = prev.left;
}
// if an entry in the previous span is too far right, nothing further left in the
// current span will need it
- if (prev->left >= right) {
+ if (prev.left >= right) {
beginLastSpan = prevIndex;
}
} else {
// iterating over previous span LTR, quit if it's too far right
- if (prev->left >= right) break;
+ if (prev.left >= right) break;
- if (prev->left > left && prev->left < right) {
- dst.add(Rect(left, top, prev->left, bottom));
- left = prev->left;
+ if (prev.left > left && prev.left < right) {
+ dst.add(Rect(left, top, prev.left, bottom));
+ left = prev.left;
}
- if (prev->right > left && prev->right < right) {
- dst.add(Rect(left, top, prev->right, bottom));
- left = prev->right;
+ if (prev.right > left && prev.right < right) {
+ dst.add(Rect(left, top, prev.right, bottom));
+ left = prev.right;
}
// if an entry in the previous span is too far left, nothing further right in the
// current span will need it
- if (prev->right <= left) {
+ if (prev.right <= left) {
beginLastSpan = prevIndex;
}
}
@@ -250,10 +255,16 @@ void Region::set(const Rect& r)
mStorage.add(r);
}
+void Region::set(int32_t w, int32_t h)
+{
+ mStorage.clear();
+ mStorage.add(Rect(w, h));
+}
+
void Region::set(uint32_t w, uint32_t h)
{
mStorage.clear();
- mStorage.add(Rect(w,h));
+ mStorage.add(Rect(w, h));
}
bool Region::isTriviallyEqual(const Region& region) const {
@@ -404,7 +415,7 @@ const Region Region::operation(const Region& rhs, int dx, int dy, int op) const
// This is our region rasterizer, which merges rects and spans together
// to obtain an optimal region.
-class Region::rasterizer : public region_operator<Rect>::region_rasterizer
+class Region::rasterizer : public region_operator<Rect>::region_rasterizer
{
Rect bounds;
Vector<Rect>& storage;
@@ -413,80 +424,91 @@ class Region::rasterizer : public region_operator<Rect>::region_rasterizer
Vector<Rect> span;
Rect* cur;
public:
- rasterizer(Region& reg)
+ rasterizer(Region& reg)
: bounds(INT_MAX, 0, INT_MIN, 0), storage(reg.mStorage), head(), tail(), cur() {
storage.clear();
}
- ~rasterizer() {
- if (span.size()) {
- flushSpan();
- }
- if (storage.size()) {
- bounds.top = storage.itemAt(0).top;
- bounds.bottom = storage.top().bottom;
- if (storage.size() == 1) {
- storage.clear();
- }
- } else {
- bounds.left = 0;
- bounds.right = 0;
+ virtual ~rasterizer();
+
+ virtual void operator()(const Rect& rect);
+
+private:
+ template<typename T>
+ static inline T min(T rhs, T lhs) { return rhs < lhs ? rhs : lhs; }
+ template<typename T>
+ static inline T max(T rhs, T lhs) { return rhs > lhs ? rhs : lhs; }
+
+ void flushSpan();
+};
+
+Region::rasterizer::~rasterizer()
+{
+ if (span.size()) {
+ flushSpan();
+ }
+ if (storage.size()) {
+ bounds.top = storage.itemAt(0).top;
+ bounds.bottom = storage.top().bottom;
+ if (storage.size() == 1) {
+ storage.clear();
}
- storage.add(bounds);
+ } else {
+ bounds.left = 0;
+ bounds.right = 0;
}
-
- virtual void operator()(const Rect& rect) {
- //ALOGD(">>> %3d, %3d, %3d, %3d",
- // rect.left, rect.top, rect.right, rect.bottom);
- if (span.size()) {
- if (cur->top != rect.top) {
- flushSpan();
- } else if (cur->right == rect.left) {
- cur->right = rect.right;
- return;
- }
+ storage.add(bounds);
+}
+
+void Region::rasterizer::operator()(const Rect& rect)
+{
+ //ALOGD(">>> %3d, %3d, %3d, %3d",
+ // rect.left, rect.top, rect.right, rect.bottom);
+ if (span.size()) {
+ if (cur->top != rect.top) {
+ flushSpan();
+ } else if (cur->right == rect.left) {
+ cur->right = rect.right;
+ return;
}
- span.add(rect);
- cur = span.editArray() + (span.size() - 1);
}
-private:
- template<typename T>
- static inline T min(T rhs, T lhs) { return rhs < lhs ? rhs : lhs; }
- template<typename T>
- static inline T max(T rhs, T lhs) { return rhs > lhs ? rhs : lhs; }
- void flushSpan() {
- bool merge = false;
- if (tail-head == ssize_t(span.size())) {
- Rect const* p = span.editArray();
- Rect const* q = head;
- if (p->top == q->bottom) {
- merge = true;
- while (q != tail) {
- if ((p->left != q->left) || (p->right != q->right)) {
- merge = false;
- break;
- }
- p++, q++;
+ span.add(rect);
+ cur = span.editArray() + (span.size() - 1);
+}
+
+void Region::rasterizer::flushSpan()
+{
+ bool merge = false;
+ if (tail-head == ssize_t(span.size())) {
+ Rect const* p = span.editArray();
+ Rect const* q = head;
+ if (p->top == q->bottom) {
+ merge = true;
+ while (q != tail) {
+ if ((p->left != q->left) || (p->right != q->right)) {
+ merge = false;
+ break;
}
+ p++, q++;
}
}
- if (merge) {
- const int bottom = span[0].bottom;
- Rect* r = head;
- while (r != tail) {
- r->bottom = bottom;
- r++;
- }
- } else {
- bounds.left = min(span.itemAt(0).left, bounds.left);
- bounds.right = max(span.top().right, bounds.right);
- storage.appendVector(span);
- tail = storage.editArray() + storage.size();
- head = tail - span.size();
+ }
+ if (merge) {
+ const int bottom = span[0].bottom;
+ Rect* r = head;
+ while (r != tail) {
+ r->bottom = bottom;
+ r++;
}
- span.clear();
+ } else {
+ bounds.left = min(span.itemAt(0).left, bounds.left);
+ bounds.right = max(span.top().right, bounds.right);
+ storage.appendVector(span);
+ tail = storage.editArray() + storage.size();
+ head = tail - span.size();
}
-};
+ span.clear();
+}
bool Region::validate(const Region& reg, const char* name, bool silent)
{
@@ -497,8 +519,12 @@ bool Region::validate(const Region& reg, const char* name, bool silent)
Rect b(*prev);
while (cur != tail) {
if (cur->isValid() == false) {
- ALOGE_IF(!silent, "%s: region contains an invalid Rect", name);
- result = false;
+ // We allow this particular flavor of invalid Rect, since it is used
+ // as a signal value in various parts of the system
+ if (*cur != Rect::INVALID_RECT) {
+ ALOGE_IF(!silent, "%s: region contains an invalid Rect", name);
+ result = false;
+ }
}
if (cur->right > region_operator<Rect>::max_value) {
ALOGE_IF(!silent, "%s: rect->right > max_value", name);
@@ -670,7 +696,9 @@ void Region::boolean_operation(int op, Region& dst,
const Region& lhs,
const Rect& rhs, int dx, int dy)
{
- if (!rhs.isValid()) {
+ // We allow this particular flavor of invalid Rect, since it is used as a
+ // signal value in various parts of the system
+ if (!rhs.isValid() && rhs != Rect::INVALID_RECT) {
ALOGE("Region::boolean_operation(op=%d) invalid Rect={%d,%d,%d,%d}",
op, rhs.left, rhs.top, rhs.right, rhs.bottom);
return;
@@ -733,35 +761,52 @@ void Region::translate(Region& dst, const Region& reg, int dx, int dy)
// ----------------------------------------------------------------------------
size_t Region::getFlattenedSize() const {
- return mStorage.size() * sizeof(Rect);
+ return sizeof(uint32_t) + mStorage.size() * sizeof(Rect);
}
status_t Region::flatten(void* buffer, size_t size) const {
#if VALIDATE_REGIONS
validate(*this, "Region::flatten");
#endif
- if (size < mStorage.size() * sizeof(Rect)) {
+ if (size < getFlattenedSize()) {
return NO_MEMORY;
}
- Rect* rects = reinterpret_cast<Rect*>(buffer);
- memcpy(rects, mStorage.array(), mStorage.size() * sizeof(Rect));
+ // Cast to uint32_t since the size of a size_t can vary between 32- and
+ // 64-bit processes
+ FlattenableUtils::write(buffer, size, static_cast<uint32_t>(mStorage.size()));
+ for (auto rect : mStorage) {
+ status_t result = rect.flatten(buffer, size);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ FlattenableUtils::advance(buffer, size, sizeof(rect));
+ }
return NO_ERROR;
}
status_t Region::unflatten(void const* buffer, size_t size) {
+ if (size < sizeof(uint32_t)) {
+ return NO_MEMORY;
+ }
+
+ uint32_t numRects = 0;
+ FlattenableUtils::read(buffer, size, numRects);
+ if (size < numRects * sizeof(Rect)) {
+ return NO_MEMORY;
+ }
+
Region result;
- if (size >= sizeof(Rect)) {
- Rect const* rects = reinterpret_cast<Rect const*>(buffer);
- size_t count = size / sizeof(Rect);
- if (count > 0) {
- result.mStorage.clear();
- ssize_t err = result.mStorage.insertAt(0, count);
- if (err < 0) {
- return status_t(err);
- }
- memcpy(result.mStorage.editArray(), rects, count*sizeof(Rect));
+ result.mStorage.clear();
+ for (size_t r = 0; r < numRects; ++r) {
+ Rect rect;
+ status_t status = rect.unflatten(buffer, size);
+ if (status != NO_ERROR) {
+ return status;
}
+ FlattenableUtils::advance(buffer, size, sizeof(rect));
+ result.mStorage.push_back(rect);
}
+
#if VALIDATE_REGIONS
validate(result, "Region::unflatten");
#endif
@@ -786,10 +831,8 @@ Region::const_iterator Region::end() const {
}
Rect const* Region::getArray(size_t* count) const {
- const_iterator const b(begin());
- const_iterator const e(end());
- if (count) *count = e-b;
- return b;
+ if (count) *count = static_cast<size_t>(end() - begin());
+ return begin();
}
SharedBuffer const* Region::getSharedBuffer(size_t* count) const {
@@ -806,29 +849,22 @@ SharedBuffer const* Region::getSharedBuffer(size_t* count) const {
// ----------------------------------------------------------------------------
-void Region::dump(String8& out, const char* what, uint32_t flags) const
+void Region::dump(String8& out, const char* what, uint32_t /* flags */) const
{
- (void)flags;
const_iterator head = begin();
const_iterator const tail = end();
- size_t SIZE = 256;
- char buffer[SIZE];
-
- snprintf(buffer, SIZE, " Region %s (this=%p, count=%" PRIdPTR ")\n",
- what, this, tail-head);
- out.append(buffer);
+ out.appendFormat(" Region %s (this=%p, count=%" PRIdPTR ")\n",
+ what, this, tail - head);
while (head != tail) {
- snprintf(buffer, SIZE, " [%3d, %3d, %3d, %3d]\n",
- head->left, head->top, head->right, head->bottom);
- out.append(buffer);
- head++;
+ out.appendFormat(" [%3d, %3d, %3d, %3d]\n", head->left, head->top,
+ head->right, head->bottom);
+ ++head;
}
}
-void Region::dump(const char* what, uint32_t flags) const
+void Region::dump(const char* what, uint32_t /* flags */) const
{
- (void)flags;
const_iterator head = begin();
const_iterator const tail = end();
ALOGD(" Region %s (this=%p, count=%" PRIdPTR ")\n", what, this, tail-head);
diff --git a/libs/ui/UiConfig.cpp b/libs/ui/UiConfig.cpp
index 8b2130e..9e7ba8e 100644
--- a/libs/ui/UiConfig.cpp
+++ b/libs/ui/UiConfig.cpp
@@ -18,8 +18,11 @@
namespace android {
+#ifdef FRAMEBUFFER_FORCE_FORMAT
+// We need the two-level macro to stringify the contents of a macro argument
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
+#endif
void appendUiConfigString(String8& configStr)
{
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
index b0c57db..6438b1f 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -1,31 +1,36 @@
-# Build the unit tests.
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-# Build the unit tests.
-test_src_files := \
- Region_test.cpp \
- vec_test.cpp \
- mat_test.cpp
-
-shared_libraries := \
- libutils \
- libui
+#
+# Copyright (C) 2014 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.
+#
-static_libraries := \
- libgtest \
- libgtest_main
+LOCAL_PATH := $(call my-dir)
-$(foreach file,$(test_src_files), \
- $(eval include $(CLEAR_VARS)) \
- $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
- $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
- $(eval LOCAL_SRC_FILES := $(file)) \
- $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
- $(eval include $(BUILD_NATIVE_TEST)) \
-)
+include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_SHARED_LIBRARIES := libui
+LOCAL_SRC_FILES := Region_test.cpp
+LOCAL_MODULE := Region_test
+include $(BUILD_NATIVE_TEST)
-# Build the unit tests.
+include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_SRC_FILES := vec_test.cpp
+LOCAL_MODULE := vec_test
+include $(BUILD_NATIVE_TEST)
-# Build the manual test programs.
-include $(call all-makefiles-under, $(LOCAL_PATH))
+include $(CLEAR_VARS)
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+LOCAL_SRC_FILES := mat_test.cpp
+LOCAL_MODULE := mat_test
+include $(BUILD_NATIVE_TEST)
diff --git a/libs/ui/tests/vec_test.cpp b/libs/ui/tests/vec_test.cpp
index 00f737e..454c999 100644
--- a/libs/ui/tests/vec_test.cpp
+++ b/libs/ui/tests/vec_test.cpp
@@ -16,17 +16,18 @@
#define LOG_TAG "RegionTest"
+#include <math.h>
#include <stdlib.h>
+
#include <ui/Region.h>
#include <ui/Rect.h>
-#include <gtest/gtest.h>
-
#include <ui/vec4.h>
+#include <gtest/gtest.h>
+
namespace android {
class VecTest : public testing::Test {
-protected:
};
TEST_F(VecTest, Basics) {