Merge changes from topic "read heatmap"
* changes:
Consume video frames
Add video device to epoll in EventHub
diff --git a/libs/binder/Value.cpp b/libs/binder/Value.cpp
index a28a618..19c57ba 100644
--- a/libs/binder/Value.cpp
+++ b/libs/binder/Value.cpp
@@ -97,7 +97,7 @@
template<typename T> class Value::Content : public Value::ContentBase {
public:
Content() = default;
- Content(const T & value) : mValue(value) { }
+ explicit Content(const T & value) : mValue(value) { }
virtual ~Content() = default;
diff --git a/libs/binder/include/binder/BufferedTextOutput.h b/libs/binder/include/binder/BufferedTextOutput.h
index 9a7c43b..feae93d 100644
--- a/libs/binder/include/binder/BufferedTextOutput.h
+++ b/libs/binder/include/binder/BufferedTextOutput.h
@@ -32,7 +32,7 @@
MULTITHREADED = 0x0001
};
- BufferedTextOutput(uint32_t flags = 0);
+ explicit BufferedTextOutput(uint32_t flags = 0);
virtual ~BufferedTextOutput();
virtual status_t print(const char* txt, size_t len);
diff --git a/libs/binder/include/binder/IpPrefix.h b/libs/binder/include/binder/IpPrefix.h
index dd5bc3a..c7e7a50 100644
--- a/libs/binder/include/binder/IpPrefix.h
+++ b/libs/binder/include/binder/IpPrefix.h
@@ -74,8 +74,8 @@
private:
union InternalUnion {
InternalUnion() = default;
- InternalUnion(const struct in6_addr &addr):mIn6Addr(addr) { };
- InternalUnion(const struct in_addr &addr):mInAddr(addr) { };
+ explicit InternalUnion(const struct in6_addr &addr):mIn6Addr(addr) { };
+ explicit InternalUnion(const struct in_addr &addr):mInAddr(addr) { };
struct in6_addr mIn6Addr;
struct in_addr mInAddr;
} mUnion;
diff --git a/libs/binder/include/binder/MemoryDealer.h b/libs/binder/include/binder/MemoryDealer.h
index fe5a31d..b483be0 100644
--- a/libs/binder/include/binder/MemoryDealer.h
+++ b/libs/binder/include/binder/MemoryDealer.h
@@ -34,7 +34,7 @@
class MemoryDealer : public RefBase
{
public:
- MemoryDealer(size_t size, const char* name = nullptr,
+ explicit MemoryDealer(size_t size, const char* name = nullptr,
uint32_t flags = 0 /* or bits such as MemoryHeapBase::READ_ONLY */ );
virtual sp<IMemory> allocate(size_t size);
diff --git a/libs/binder/include/binder/MemoryHeapBase.h b/libs/binder/include/binder/MemoryHeapBase.h
index 2f5039d..100d784 100644
--- a/libs/binder/include/binder/MemoryHeapBase.h
+++ b/libs/binder/include/binder/MemoryHeapBase.h
@@ -47,12 +47,12 @@
/*
* maps memory from the given device
*/
- MemoryHeapBase(const char* device, size_t size = 0, uint32_t flags = 0);
+ explicit MemoryHeapBase(const char* device, size_t size = 0, uint32_t flags = 0);
/*
* maps memory from ashmem, with the given name for debugging
*/
- MemoryHeapBase(size_t size, uint32_t flags = 0, char const* name = nullptr);
+ explicit MemoryHeapBase(size_t size, uint32_t flags = 0, char const* name = nullptr);
virtual ~MemoryHeapBase();
diff --git a/libs/binder/include/binder/ParcelFileDescriptor.h b/libs/binder/include/binder/ParcelFileDescriptor.h
index ad950af..662e56e 100644
--- a/libs/binder/include/binder/ParcelFileDescriptor.h
+++ b/libs/binder/include/binder/ParcelFileDescriptor.h
@@ -31,7 +31,7 @@
public:
ParcelFileDescriptor();
explicit ParcelFileDescriptor(android::base::unique_fd fd);
- explicit ParcelFileDescriptor(ParcelFileDescriptor&& other) : mFd(std::move(other.mFd)) { }
+ ParcelFileDescriptor(ParcelFileDescriptor&& other) : mFd(std::move(other.mFd)) { }
~ParcelFileDescriptor() override;
int get() const { return mFd.get(); }
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index 13f67ba..3712c84 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -80,7 +80,7 @@
private:
friend class IPCThreadState;
- ProcessState(const char* driver);
+ explicit ProcessState(const char* driver);
~ProcessState();
ProcessState(const ProcessState& o);
diff --git a/libs/binder/include/binder/TextOutput.h b/libs/binder/include/binder/TextOutput.h
index 851e01f..5b5f766 100644
--- a/libs/binder/include/binder/TextOutput.h
+++ b/libs/binder/include/binder/TextOutput.h
@@ -38,7 +38,7 @@
class Bundle {
public:
- inline Bundle(TextOutput& to) : mTO(to) { to.pushBundle(); }
+ inline explicit Bundle(TextOutput& to) : mTO(to) { to.pushBundle(); }
inline ~Bundle() { mTO.popBundle(); }
private:
TextOutput& mTO;
@@ -80,7 +80,7 @@
class TypeCode
{
public:
- inline TypeCode(uint32_t code);
+ inline explicit TypeCode(uint32_t code);
inline ~TypeCode();
inline uint32_t typeCode() const;
diff --git a/libs/binder/include/binder/Value.h b/libs/binder/include/binder/Value.h
index 4dee3d8..735f40e 100644
--- a/libs/binder/include/binder/Value.h
+++ b/libs/binder/include/binder/Value.h
@@ -74,20 +74,20 @@
bool operator!=(const Value& rhs) const { return !this->operator==(rhs); }
Value(const Value& value);
- Value(const bool& value);
- Value(const int8_t& value);
- Value(const int32_t& value);
- Value(const int64_t& value);
- Value(const double& value);
- Value(const String16& value);
- Value(const std::vector<bool>& value);
- Value(const std::vector<uint8_t>& value);
- Value(const std::vector<int32_t>& value);
- Value(const std::vector<int64_t>& value);
- Value(const std::vector<double>& value);
- Value(const std::vector<String16>& value);
- Value(const os::PersistableBundle& value);
- Value(const binder::Map& value);
+ Value(const bool& value); // NOLINT(google-explicit-constructor)
+ Value(const int8_t& value); // NOLINT(google-explicit-constructor)
+ Value(const int32_t& value); // NOLINT(google-explicit-constructor)
+ Value(const int64_t& value); // NOLINT(google-explicit-constructor)
+ Value(const double& value); // NOLINT(google-explicit-constructor)
+ Value(const String16& value); // NOLINT(google-explicit-constructor)
+ Value(const std::vector<bool>& value); // NOLINT(google-explicit-constructor)
+ Value(const std::vector<uint8_t>& value); // NOLINT(google-explicit-constructor)
+ Value(const std::vector<int32_t>& value); // NOLINT(google-explicit-constructor)
+ Value(const std::vector<int64_t>& value); // NOLINT(google-explicit-constructor)
+ Value(const std::vector<double>& value); // NOLINT(google-explicit-constructor)
+ Value(const std::vector<String16>& value); // NOLINT(google-explicit-constructor)
+ Value(const os::PersistableBundle& value); // NOLINT(google-explicit-constructor)
+ Value(const binder::Map& value); // NOLINT(google-explicit-constructor)
Value& operator=(const Value& rhs);
Value& operator=(const int8_t& rhs);
@@ -153,8 +153,8 @@
// String Convenience Adapters
// ---------------------------
- Value(const String8& value): Value(String16(value)) { }
- Value(const ::std::string& value): Value(String8(value.c_str())) { }
+ explicit Value(const String8& value): Value(String16(value)) { }
+ explicit Value(const ::std::string& value): Value(String8(value.c_str())) { }
void putString(const String8& value) { return putString(String16(value)); }
void putString(const ::std::string& value) { return putString(String8(value.c_str())); }
Value& operator=(const String8& rhs) { return *this = String16(rhs); }
diff --git a/libs/binder/ndk/ibinder_internal.h b/libs/binder/ndk/ibinder_internal.h
index ac592ea..7852298 100644
--- a/libs/binder/ndk/ibinder_internal.h
+++ b/libs/binder/ndk/ibinder_internal.h
@@ -34,7 +34,7 @@
struct ABpBinder;
struct AIBinder : public virtual ::android::RefBase {
- AIBinder(const AIBinder_Class* clazz);
+ explicit AIBinder(const AIBinder_Class* clazz);
virtual ~AIBinder();
bool associateClass(const AIBinder_Class* clazz);
@@ -97,7 +97,7 @@
ABpBinder* asABpBinder() override { return this; }
private:
- ABpBinder(const ::android::sp<::android::IBinder>& binder);
+ explicit ABpBinder(const ::android::sp<::android::IBinder>& binder);
};
struct AIBinder_Class {
@@ -141,7 +141,7 @@
const AIBinder_DeathRecipient_onBinderDied& mOnDied;
};
- AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied);
+ explicit AIBinder_DeathRecipient(AIBinder_DeathRecipient_onBinderDied onDied);
binder_status_t linkToDeath(AIBinder* binder, void* cookie);
binder_status_t unlinkToDeath(AIBinder* binder, void* cookie);
diff --git a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
index ff1860e..80773f3 100644
--- a/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_auto_utils.h
@@ -51,7 +51,7 @@
* Convenience operator for implicitly constructing an SpAIBinder from nullptr. This is not
* explicit because it is not taking ownership of anything.
*/
- SpAIBinder(std::nullptr_t) : SpAIBinder() {}
+ SpAIBinder(std::nullptr_t) : SpAIBinder() {} // NOLINT(google-explicit-constructor)
/**
* This will delete the underlying object if it exists. See operator=.
diff --git a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
index 1532725..a42c60b 100644
--- a/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
+++ b/libs/binder/ndk/include_ndk/android/binder_interface_utils.h
@@ -137,7 +137,7 @@
template <typename INTERFACE>
class BpCInterface : public INTERFACE {
public:
- BpCInterface(const SpAIBinder& binder) : mBinder(binder) {}
+ explicit BpCInterface(const SpAIBinder& binder) : mBinder(binder) {}
virtual ~BpCInterface() {}
SpAIBinder asBinder() override;
diff --git a/libs/binder/ndk/parcel_internal.h b/libs/binder/ndk/parcel_internal.h
index f292309..6b7295e 100644
--- a/libs/binder/ndk/parcel_internal.h
+++ b/libs/binder/ndk/parcel_internal.h
@@ -27,7 +27,8 @@
const ::android::Parcel* get() const { return mParcel; }
::android::Parcel* get() { return mParcel; }
- AParcel(const AIBinder* binder) : AParcel(binder, new ::android::Parcel, true /*owns*/) {}
+ explicit AParcel(const AIBinder* binder)
+ : AParcel(binder, new ::android::Parcel, true /*owns*/) {}
AParcel(const AIBinder* binder, ::android::Parcel* parcel, bool owns)
: mBinder(binder), mParcel(parcel), mOwns(owns) {}
diff --git a/libs/binder/ndk/status_internal.h b/libs/binder/ndk/status_internal.h
index d39f0d8..f6227f7 100644
--- a/libs/binder/ndk/status_internal.h
+++ b/libs/binder/ndk/status_internal.h
@@ -23,7 +23,7 @@
struct AStatus {
AStatus() {} // ok
- AStatus(::android::binder::Status&& status) : mStatus(std::move(status)) {}
+ explicit AStatus(::android::binder::Status&& status) : mStatus(std::move(status)) {}
::android::binder::Status* get() { return &mStatus; }
const ::android::binder::Status* get() const { return &mStatus; }
diff --git a/libs/binder/ndk/test/iface.cpp b/libs/binder/ndk/test/iface.cpp
index 6ef964e..64832f3 100644
--- a/libs/binder/ndk/test/iface.cpp
+++ b/libs/binder/ndk/test/iface.cpp
@@ -74,7 +74,7 @@
class BpFoo : public IFoo {
public:
- BpFoo(AIBinder* binder) : mBinder(binder) {}
+ explicit BpFoo(AIBinder* binder) : mBinder(binder) {}
virtual ~BpFoo() { AIBinder_decStrong(mBinder); }
virtual binder_status_t doubleNumber(int32_t in, int32_t* out) {
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index ae04b0f..78f1159 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -233,7 +233,7 @@
{
public:
BinderLibTestBundle(void) {}
- BinderLibTestBundle(const Parcel *source) : m_isValid(false) {
+ explicit BinderLibTestBundle(const Parcel *source) : m_isValid(false) {
int32_t mark;
int32_t bundleLen;
size_t pos;
@@ -1079,7 +1079,7 @@
class BinderLibTestService : public BBinder
{
public:
- BinderLibTestService(int32_t id)
+ explicit BinderLibTestService(int32_t id)
: m_id(id)
, m_nextServerId(id + 1)
, m_serverStartRequested(false)
diff --git a/libs/binder/tests/schd-dbg.cpp b/libs/binder/tests/schd-dbg.cpp
index 6cf7f36..ec9534a 100644
--- a/libs/binder/tests/schd-dbg.cpp
+++ b/libs/binder/tests/schd-dbg.cpp
@@ -218,7 +218,7 @@
uint64_t m_total_time = 0;
uint64_t m_miss = 0;
bool tracing;
- Results(bool _tracing) : tracing(_tracing) {
+ explicit Results(bool _tracing) : tracing(_tracing) {
}
inline bool miss_deadline(uint64_t nano) {
return nano > deadline_us * 1000;
diff --git a/libs/gui/BufferHubProducer.cpp b/libs/gui/BufferHubProducer.cpp
index 16952a6..4be014f 100644
--- a/libs/gui/BufferHubProducer.cpp
+++ b/libs/gui/BufferHubProducer.cpp
@@ -64,13 +64,13 @@
} else if (buffers_[slot].mGraphicBuffer != nullptr) {
ALOGE("requestBuffer: slot %d is not empty.", slot);
return BAD_VALUE;
- } else if (buffers_[slot].mBufferProducer == nullptr) {
+ } else if (buffers_[slot].mProducerBuffer == nullptr) {
ALOGE("requestBuffer: slot %d is not dequeued.", slot);
return BAD_VALUE;
}
- const auto& buffer_producer = buffers_[slot].mBufferProducer;
- sp<GraphicBuffer> graphic_buffer = buffer_producer->buffer()->buffer();
+ const auto& producer_buffer = buffers_[slot].mProducerBuffer;
+ sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
buffers_[slot].mGraphicBuffer = graphic_buffer;
buffers_[slot].mRequestBufferCalled = true;
@@ -158,19 +158,19 @@
}
size_t slot = 0;
- std::shared_ptr<BufferProducer> buffer_producer;
+ std::shared_ptr<ProducerBuffer> producer_buffer;
for (size_t retry = 0; retry < BufferHubQueue::kMaxQueueCapacity; retry++) {
LocalHandle fence;
auto buffer_status = queue_->Dequeue(dequeue_timeout_ms_, &slot, &fence);
if (!buffer_status) return NO_MEMORY;
- buffer_producer = buffer_status.take();
- if (!buffer_producer) return NO_MEMORY;
+ producer_buffer = buffer_status.take();
+ if (!producer_buffer) return NO_MEMORY;
- if (width == buffer_producer->width() && height == buffer_producer->height() &&
- uint32_t(format) == buffer_producer->format()) {
- // The producer queue returns a buffer producer matches the request.
+ if (width == producer_buffer->width() && height == producer_buffer->height() &&
+ uint32_t(format) == producer_buffer->format()) {
+ // The producer queue returns a producer buffer matches the request.
break;
}
@@ -179,8 +179,8 @@
ALOGI("dequeueBuffer: requested buffer (w=%u, h=%u, format=%u) is different "
"from the buffer returned at slot: %zu (w=%u, h=%u, format=%u). Need "
"re-allocattion.",
- width, height, format, slot, buffer_producer->width(), buffer_producer->height(),
- buffer_producer->format());
+ width, height, format, slot, producer_buffer->width(), producer_buffer->height(),
+ producer_buffer->format());
// Mark the slot as reallocating, so that later we can set
// BUFFER_NEEDS_REALLOCATION when the buffer actually get dequeued.
buffers_[slot].mIsReallocating = true;
@@ -249,18 +249,18 @@
ALOGE("detachBuffer: buffer in slot %zu has not been requested", slot);
return BAD_VALUE;
}
- std::shared_ptr<BufferProducer> buffer_producer = queue_->GetBuffer(slot);
- if (buffer_producer == nullptr || buffer_producer->buffer() == nullptr) {
- ALOGE("detachBuffer: Invalid BufferProducer at slot %zu.", slot);
+ std::shared_ptr<ProducerBuffer> producer_buffer = queue_->GetBuffer(slot);
+ if (producer_buffer == nullptr || producer_buffer->buffer() == nullptr) {
+ ALOGE("detachBuffer: Invalid ProducerBuffer at slot %zu.", slot);
return BAD_VALUE;
}
- sp<GraphicBuffer> graphic_buffer = buffer_producer->buffer()->buffer();
+ sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
if (graphic_buffer == nullptr) {
ALOGE("detachBuffer: Invalid GraphicBuffer at slot %zu.", slot);
return BAD_VALUE;
}
- // Remove the BufferProducer from the ProducerQueue.
+ // Remove the ProducerBuffer from the ProducerQueue.
status_t error = RemoveBuffer(slot);
if (error != NO_ERROR) {
ALOGE("detachBuffer: Failed to remove buffer, slot=%zu, error=%d.", slot, error);
@@ -269,9 +269,9 @@
// Here we need to convert the existing ProducerBuffer into a DetachedBufferHandle and inject
// the handle into the GraphicBuffer object at the requested slot.
- auto status_or_handle = buffer_producer->Detach();
+ auto status_or_handle = producer_buffer->Detach();
if (!status_or_handle.ok()) {
- ALOGE("detachBuffer: Failed to detach from a BufferProducer at slot %zu, error=%d.", slot,
+ ALOGE("detachBuffer: Failed to detach from a ProducerBuffer at slot %zu, error=%d.", slot,
status_or_handle.error());
return BAD_VALUE;
}
@@ -301,14 +301,14 @@
// sequence, except for two things:
//
// 1) It is unnecessary to know the dimensions, format, or usage of the next buffer, i.e. the
- // function just returns whatever BufferProducer is available from the ProducerQueue and no
+ // function just returns whatever ProducerBuffer is available from the ProducerQueue and no
// buffer allocation or re-allocation will happen.
// 2) It will not block, since if it cannot find an appropriate buffer to return, it will return
// an error instead.
size_t slot = 0;
LocalHandle fence;
- // First, dequeue a BufferProducer from the ProducerQueue with no timeout. Report error
+ // First, dequeue a ProducerBuffer from the ProducerQueue with no timeout. Report error
// immediately if ProducerQueue::Dequeue() fails.
auto status_or_buffer = queue_->Dequeue(/*timeout=*/0, &slot, &fence);
if (!status_or_buffer.ok()) {
@@ -316,8 +316,8 @@
return NO_MEMORY;
}
- std::shared_ptr<BufferProducer> buffer_producer = status_or_buffer.take();
- if (buffer_producer == nullptr) {
+ std::shared_ptr<ProducerBuffer> producer_buffer = status_or_buffer.take();
+ if (producer_buffer == nullptr) {
ALOGE("detachNextBuffer: Dequeued buffer is null.");
return NO_MEMORY;
}
@@ -331,14 +331,14 @@
buffers_[slot].mBufferState.string());
return BAD_VALUE;
}
- if (buffers_[slot].mBufferProducer == nullptr) {
- ALOGE("detachNextBuffer: BufferProducer at slot %zu is null.", slot);
+ if (buffers_[slot].mProducerBuffer == nullptr) {
+ ALOGE("detachNextBuffer: ProducerBuffer at slot %zu is null.", slot);
return BAD_VALUE;
}
- if (buffers_[slot].mBufferProducer->id() != buffer_producer->id()) {
- ALOGE("detachNextBuffer: BufferProducer at slot %zu has mismatched id, actual: "
+ if (buffers_[slot].mProducerBuffer->id() != producer_buffer->id()) {
+ ALOGE("detachNextBuffer: ProducerBuffer at slot %zu has mismatched id, actual: "
"%d, expected: %d.",
- slot, buffers_[slot].mBufferProducer->id(), buffer_producer->id());
+ slot, buffers_[slot].mProducerBuffer->id(), producer_buffer->id());
return BAD_VALUE;
}
@@ -347,8 +347,8 @@
buffers_[slot].mBufferState.dequeue();
// Second, request the buffer.
- sp<GraphicBuffer> graphic_buffer = buffer_producer->buffer()->buffer();
- buffers_[slot].mGraphicBuffer = buffer_producer->buffer()->buffer();
+ sp<GraphicBuffer> graphic_buffer = producer_buffer->buffer()->buffer();
+ buffers_[slot].mGraphicBuffer = producer_buffer->buffer()->buffer();
// Finally, detach the buffer and then return.
status_t error = DetachBufferLocked(slot);
@@ -452,11 +452,11 @@
return BAD_VALUE;
}
- // Post the buffer producer with timestamp in the metadata.
- const auto& buffer_producer = buffers_[slot].mBufferProducer;
+ // Post the producer buffer with timestamp in the metadata.
+ const auto& producer_buffer = buffers_[slot].mProducerBuffer;
// Check input crop is not out of boundary of current buffer.
- Rect buffer_rect(buffer_producer->width(), buffer_producer->height());
+ Rect buffer_rect(producer_buffer->width(), producer_buffer->height());
Rect cropped_rect(Rect::EMPTY_RECT);
crop.intersect(buffer_rect, &cropped_rect);
if (cropped_rect != crop) {
@@ -477,11 +477,11 @@
meta_data.scaling_mode = int32_t(scaling_mode);
meta_data.transform = int32_t(transform);
- buffer_producer->PostAsync(&meta_data, fence_fd);
+ producer_buffer->PostAsync(&meta_data, fence_fd);
buffers_[slot].mBufferState.queue();
- output->width = buffer_producer->width();
- output->height = buffer_producer->height();
+ output->width = producer_buffer->width();
+ output->height = producer_buffer->height();
output->transformHint = 0; // default value, we don't use it yet.
// |numPendingBuffers| counts of the number of buffers that has been enqueued
@@ -519,8 +519,8 @@
return BAD_VALUE;
}
- auto buffer_producer = buffers_[slot].mBufferProducer;
- queue_->Enqueue(buffer_producer, size_t(slot), 0U);
+ auto producer_buffer = buffers_[slot].mProducerBuffer;
+ queue_->Enqueue(producer_buffer, size_t(slot), 0U);
buffers_[slot].mBufferState.cancel();
buffers_[slot].mFence = fence;
ALOGV("cancelBuffer: slot %d", slot);
@@ -791,12 +791,12 @@
}
size_t slot = status.get();
- auto buffer_producer = queue_->GetBuffer(slot);
+ auto producer_buffer = queue_->GetBuffer(slot);
- LOG_ALWAYS_FATAL_IF(buffer_producer == nullptr, "Failed to get buffer producer at slot: %zu",
- slot);
+ LOG_ALWAYS_FATAL_IF(producer_buffer == nullptr,
+ "Failed to get the producer buffer at slot: %zu", slot);
- buffers_[slot].mBufferProducer = buffer_producer;
+ buffers_[slot].mProducerBuffer = producer_buffer;
return NO_ERROR;
}
@@ -810,7 +810,7 @@
}
// Reset in memory objects related the the buffer.
- buffers_[slot].mBufferProducer = nullptr;
+ buffers_[slot].mProducerBuffer = nullptr;
buffers_[slot].mBufferState.detachProducer();
buffers_[slot].mFence = Fence::NO_FENCE;
buffers_[slot].mGraphicBuffer = nullptr;
@@ -821,7 +821,7 @@
status_t BufferHubProducer::FreeAllBuffers() {
for (size_t slot = 0; slot < BufferHubQueue::kMaxQueueCapacity; slot++) {
// Reset in memory objects related the the buffer.
- buffers_[slot].mBufferProducer = nullptr;
+ buffers_[slot].mProducerBuffer = nullptr;
buffers_[slot].mBufferState.reset();
buffers_[slot].mFence = Fence::NO_FENCE;
buffers_[slot].mGraphicBuffer = nullptr;
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 2d6be26..799151a 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -73,11 +73,9 @@
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
}
- virtual void setTransactionState(
- const Vector<ComposerState>& state,
- const Vector<DisplayState>& displays,
- uint32_t flags)
- {
+ virtual void setTransactionState(const Vector<ComposerState>& state,
+ const Vector<DisplayState>& displays, uint32_t flags,
+ const sp<IBinder>& applyToken) {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
@@ -92,6 +90,7 @@
}
data.writeUint32(flags);
+ data.writeStrongBinder(applyToken);
remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE, data, &reply);
}
@@ -750,7 +749,8 @@
}
uint32_t stateFlags = data.readUint32();
- setTransactionState(state, displays, stateFlags);
+ sp<IBinder> applyToken = data.readStrongBinder();
+ setTransactionState(state, displays, stateFlags, applyToken);
return NO_ERROR;
}
case BOOT_FINISHED: {
diff --git a/libs/gui/OWNERS b/libs/gui/OWNERS
new file mode 100644
index 0000000..a7c7e79
--- /dev/null
+++ b/libs/gui/OWNERS
@@ -0,0 +1,8 @@
+brianderson@google.com
+jessehall@google.com
+jwcai@google.com
+mathias@google.com
+olv@google.com
+pceballos@google.com
+racarr@google.com
+stoza@google.com
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 9586219..5b004e2 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -264,7 +264,9 @@
mAnimation = false;
mEarlyWakeup = false;
- sf->setTransactionState(composerStates, displayStates, flags);
+ sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
+
+ sf->setTransactionState(composerStates, displayStates, flags, applyToken);
mStatus = NO_ERROR;
return NO_ERROR;
}
diff --git a/libs/gui/include/gui/BufferHubProducer.h b/libs/gui/include/gui/BufferHubProducer.h
index f7af19b..0e925ce 100644
--- a/libs/gui/include/gui/BufferHubProducer.h
+++ b/libs/gui/include/gui/BufferHubProducer.h
@@ -203,10 +203,10 @@
// requested buffer usage or geometry differs from that of the buffer
// allocated to a slot.
struct BufferHubSlot : public BufferSlot {
- BufferHubSlot() : mBufferProducer(nullptr), mIsReallocating(false) {}
+ BufferHubSlot() : mProducerBuffer(nullptr), mIsReallocating(false) {}
// BufferSlot comes from android framework, using m prefix to comply with
// the name convention with the reset of data fields from BufferSlot.
- std::shared_ptr<dvr::BufferProducer> mBufferProducer;
+ std::shared_ptr<dvr::ProducerBuffer> mProducerBuffer;
bool mIsReallocating;
};
BufferHubSlot buffers_[dvr::BufferHubQueue::kMaxQueueCapacity];
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index 3052c0b..8cb40e7 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -124,7 +124,8 @@
/* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
virtual void setTransactionState(const Vector<ComposerState>& state,
- const Vector<DisplayState>& displays, uint32_t flags) = 0;
+ const Vector<DisplayState>& displays, uint32_t flags,
+ const sp<IBinder>& applyToken) = 0;
/* signal that we're done booting.
* Requires ACCESS_SURFACE_FLINGER permission
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 67afbd6..c56304f 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -558,8 +558,8 @@
void destroyDisplay(const sp<IBinder>& /*display */) override {}
sp<IBinder> getBuiltInDisplay(int32_t /*id*/) override { return nullptr; }
void setTransactionState(const Vector<ComposerState>& /*state*/,
- const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/)
- override {}
+ const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/,
+ const sp<IBinder>& /*applyToken*/) override {}
void bootFinished() override {}
bool authenticateSurfaceTexture(
const sp<IGraphicBufferProducer>& /*surface*/) const override {
diff --git a/libs/vr/OWNERS b/libs/vr/OWNERS
new file mode 100644
index 0000000..ec2d712
--- /dev/null
+++ b/libs/vr/OWNERS
@@ -0,0 +1,4 @@
+hendrikw@google.com
+jwcai@google.com
+steventhomas@google.com
+
diff --git a/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h b/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
index 7aa50b1..726f035 100644
--- a/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
+++ b/libs/vr/libbufferhub/include/private/dvr/consumer_buffer.h
@@ -6,16 +6,6 @@
namespace android {
namespace dvr {
-// BufferConsumer was originally poorly named and gets easily confused with
-// IGraphicBufferConsumer. Actually, BufferConsumer is a single buffer that can
-// consume (i.e. read) data from a buffer, but it doesn't consume buffer. On
-// the other hand, IGraphicBufferConsumer is the consumer end of a BufferQueue
-// and it is used to consume buffers.
-//
-// TODO(b/116855254): Remove this typedef once rename is complete in other
-// projects and/or branches.
-typedef class ConsumerBuffer BufferConsumer;
-
// This is a connection to a producer buffer, which can be located in another
// application. When that buffer is Post()ed, this fd will be signaled and
// Acquire allows read access. The user is responsible for making sure that
diff --git a/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h b/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
index 2761416..7ec345c 100644
--- a/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
+++ b/libs/vr/libbufferhub/include/private/dvr/producer_buffer.h
@@ -6,23 +6,13 @@
namespace android {
namespace dvr {
-// BufferProducer was originally poorly named and gets easily confused with
-// IGraphicBufferProducer. Actually, BufferProducer is a single buffer that can
-// produce (i.e. write) data into a buffer, but it doesn't produce buffer. On
-// the other hand, IGraphicBufferProducer is the producer end of a BufferQueue
-// and it is used to produce buffers.
-//
-// TODO(b/116855254): Remove this typedef once rename is complete in other
-// projects and/or branches.
-typedef class ProducerBuffer BufferProducer;
-
// This represents a writable buffer. Calling Post notifies all clients and
// makes the buffer read-only. Call Gain to acquire write access. A buffer
// may have many consumers.
//
// The user of ProducerBuffer is responsible with making sure that the Post() is
// done with the correct metadata type and size. The user is also responsible
-// for making sure that remote ends (BufferConsumers) are also using the correct
+// for making sure that remote ends (ConsumerBuffers) are also using the correct
// metadata when acquiring the buffer. The API guarantees that a Post() with a
// metadata of wrong size will fail. However, it currently does not do any
// type checking.
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
index 9c4f73f..d7833f3 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
@@ -480,7 +480,7 @@
// Note that import might (though very unlikely) fail. If so, buffer_handle
// will be closed and included in returned buffer_slots.
- if (AddBuffer(BufferProducer::Import(std::move(buffer_handle)),
+ if (AddBuffer(ProducerBuffer::Import(std::move(buffer_handle)),
buffer_slot)) {
ALOGD_IF(TRACE, "ProducerQueue::AllocateBuffers: new buffer at slot: %zu",
buffer_slot);
@@ -517,7 +517,7 @@
}
Status<void> ProducerQueue::AddBuffer(
- const std::shared_ptr<BufferProducer>& buffer, size_t slot) {
+ const std::shared_ptr<ProducerBuffer>& buffer, size_t slot) {
ALOGD_IF(TRACE, "ProducerQueue::AddBuffer: queue_id=%d buffer_id=%d slot=%zu",
id(), buffer->id(), slot);
// For producer buffer, we need to enqueue the newly added buffer
@@ -530,7 +530,7 @@
}
Status<size_t> ProducerQueue::InsertBuffer(
- const std::shared_ptr<BufferProducer>& buffer) {
+ const std::shared_ptr<ProducerBuffer>& buffer) {
if (buffer == nullptr ||
!BufferHubDefs::IsClientGained(buffer->buffer_state(),
buffer->client_state_mask())) {
@@ -554,7 +554,7 @@
size_t slot = status_or_slot.get();
// Note that we are calling AddBuffer() from the base class to explicitly
- // avoid Enqueue() the BufferProducer.
+ // avoid Enqueue() the ProducerBuffer.
auto status = BufferHubQueue::AddBuffer(buffer, slot);
if (!status) {
ALOGE("ProducerQueue::InsertBuffer: Failed to add buffer: %s.",
@@ -576,13 +576,13 @@
return BufferHubQueue::RemoveBuffer(slot);
}
-Status<std::shared_ptr<BufferProducer>> ProducerQueue::Dequeue(
+Status<std::shared_ptr<ProducerBuffer>> ProducerQueue::Dequeue(
int timeout, size_t* slot, LocalHandle* release_fence) {
DvrNativeBufferMetadata canonical_meta;
return Dequeue(timeout, slot, &canonical_meta, release_fence);
}
-pdx::Status<std::shared_ptr<BufferProducer>> ProducerQueue::Dequeue(
+pdx::Status<std::shared_ptr<ProducerBuffer>> ProducerQueue::Dequeue(
int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta,
pdx::LocalHandle* release_fence, bool gain_posted_buffer) {
ATRACE_NAME("ProducerQueue::Dequeue");
@@ -591,14 +591,14 @@
return ErrorStatus(EINVAL);
}
- std::shared_ptr<BufferProducer> buffer;
+ std::shared_ptr<ProducerBuffer> buffer;
Status<std::shared_ptr<BufferHubBase>> dequeue_status =
BufferHubQueue::Dequeue(timeout, slot);
if (dequeue_status.ok()) {
- buffer = std::static_pointer_cast<BufferProducer>(dequeue_status.take());
+ buffer = std::static_pointer_cast<ProducerBuffer>(dequeue_status.take());
} else {
if (gain_posted_buffer) {
- Status<std::shared_ptr<BufferProducer>> dequeue_unacquired_status =
+ Status<std::shared_ptr<ProducerBuffer>> dequeue_unacquired_status =
ProducerQueue::DequeueUnacquiredBuffer(slot);
if (!dequeue_unacquired_status.ok()) {
ALOGE("%s: DequeueUnacquiredBuffer returned error: %d", __FUNCTION__,
@@ -618,7 +618,7 @@
return {std::move(buffer)};
}
-Status<std::shared_ptr<BufferProducer>> ProducerQueue::DequeueUnacquiredBuffer(
+Status<std::shared_ptr<ProducerBuffer>> ProducerQueue::DequeueUnacquiredBuffer(
size_t* slot) {
if (unavailable_buffers_slot_.size() < 1) {
ALOGE(
@@ -632,7 +632,7 @@
// unavailable_buffers_slot_.
for (auto iter = unavailable_buffers_slot_.begin();
iter != unavailable_buffers_slot_.end(); iter++) {
- std::shared_ptr<BufferProducer> buffer = ProducerQueue::GetBuffer(*iter);
+ std::shared_ptr<ProducerBuffer> buffer = ProducerQueue::GetBuffer(*iter);
if (buffer == nullptr) {
ALOGE("%s failed. Buffer slot %d is null.", __FUNCTION__,
static_cast<int>(*slot));
@@ -718,9 +718,9 @@
ALOGD_IF(TRACE, ": buffer_handle=%d", __FUNCTION__,
buffer_handle_slot.first.value());
- std::unique_ptr<BufferConsumer> buffer_consumer =
- BufferConsumer::Import(std::move(buffer_handle_slot.first));
- if (!buffer_consumer) {
+ std::unique_ptr<ConsumerBuffer> consumer_buffer =
+ ConsumerBuffer::Import(std::move(buffer_handle_slot.first));
+ if (!consumer_buffer) {
ALOGE("%s: Failed to import buffer: slot=%zu", __FUNCTION__,
buffer_handle_slot.second);
last_error = ErrorStatus(EPIPE);
@@ -728,7 +728,7 @@
}
auto add_status =
- AddBuffer(std::move(buffer_consumer), buffer_handle_slot.second);
+ AddBuffer(std::move(consumer_buffer), buffer_handle_slot.second);
if (!add_status) {
ALOGE("%s: Failed to add buffer: %s", __FUNCTION__,
add_status.GetErrorMessage().c_str());
@@ -745,13 +745,13 @@
}
Status<void> ConsumerQueue::AddBuffer(
- const std::shared_ptr<BufferConsumer>& buffer, size_t slot) {
+ const std::shared_ptr<ConsumerBuffer>& buffer, size_t slot) {
ALOGD_IF(TRACE, "%s: queue_id=%d buffer_id=%d slot=%zu", __FUNCTION__, id(),
buffer->id(), slot);
return BufferHubQueue::AddBuffer(buffer, slot);
}
-Status<std::shared_ptr<BufferConsumer>> ConsumerQueue::Dequeue(
+Status<std::shared_ptr<ConsumerBuffer>> ConsumerQueue::Dequeue(
int timeout, size_t* slot, void* meta, size_t user_metadata_size,
LocalHandle* acquire_fence) {
if (user_metadata_size != user_metadata_size_) {
@@ -780,7 +780,7 @@
return status;
}
-Status<std::shared_ptr<BufferConsumer>> ConsumerQueue::Dequeue(
+Status<std::shared_ptr<ConsumerBuffer>> ConsumerQueue::Dequeue(
int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta,
pdx::LocalHandle* acquire_fence) {
ATRACE_NAME("ConsumerQueue::Dequeue");
@@ -793,7 +793,7 @@
if (!status)
return status.error_status();
- auto buffer = std::static_pointer_cast<BufferConsumer>(status.take());
+ auto buffer = std::static_pointer_cast<ConsumerBuffer>(status.take());
const int ret = buffer->AcquireAsync(out_meta, acquire_fence);
if (ret < 0)
return ErrorStatus(-ret);
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
index 53ab2b2..d1f0564 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_client.h
@@ -307,12 +307,12 @@
return BASE::Create(std::move(handle));
}
- // Get a buffer producer. Note that the method doesn't check whether the
+ // Get a producer buffer. Note that the method doesn't check whether the
// buffer slot has a valid buffer that has been allocated already. When no
// buffer has been imported before it returns nullptr; otherwise it returns
- // a shared pointer to a BufferProducer.
- std::shared_ptr<BufferProducer> GetBuffer(size_t slot) const {
- return std::static_pointer_cast<BufferProducer>(
+ // a shared pointer to a ProducerBuffer.
+ std::shared_ptr<ProducerBuffer> GetBuffer(size_t slot) const {
+ return std::static_pointer_cast<ProducerBuffer>(
BufferHubQueue::GetBuffer(slot));
}
@@ -333,7 +333,7 @@
// Add a producer buffer to populate the queue. Once added, a producer buffer
// is available to use (i.e. in GAINED state).
- pdx::Status<void> AddBuffer(const std::shared_ptr<BufferProducer>& buffer,
+ pdx::Status<void> AddBuffer(const std::shared_ptr<ProducerBuffer>& buffer,
size_t slot);
// Inserts a ProducerBuffer into the queue. On success, the method returns the
@@ -341,7 +341,7 @@
// being inserted should be in Gain'ed state prior to the call and it's
// considered as already Dequeued when the function returns.
pdx::Status<size_t> InsertBuffer(
- const std::shared_ptr<BufferProducer>& buffer);
+ const std::shared_ptr<ProducerBuffer>& buffer);
// Remove producer buffer from the queue.
pdx::Status<void> RemoveBuffer(size_t slot) override;
@@ -355,7 +355,7 @@
// and caller should call Post() once it's done writing to release the buffer
// to the consumer side.
// @return a buffer in gained state, which was originally in released state.
- pdx::Status<std::shared_ptr<BufferProducer>> Dequeue(
+ pdx::Status<std::shared_ptr<ProducerBuffer>> Dequeue(
int timeout, size_t* slot, pdx::LocalHandle* release_fence);
// Dequeue a producer buffer to write. The returned buffer in |Gain|'ed mode,
@@ -363,7 +363,7 @@
// to the consumer side.
//
// @param timeout to dequeue a buffer.
- // @param slot is the slot of the output BufferProducer.
+ // @param slot is the slot of the output ProducerBuffer.
// @param release_fence for gaining a buffer.
// @param out_meta metadata of the output buffer.
// @param gain_posted_buffer whether to gain posted buffer if no released
@@ -375,12 +375,12 @@
// libdvrtracking from starving when there are non-responding clients. This
// gain_posted_buffer param can be removed once libdvrtracking start to use
// the new AHardwareBuffer API.
- pdx::Status<std::shared_ptr<BufferProducer>> Dequeue(
+ pdx::Status<std::shared_ptr<ProducerBuffer>> Dequeue(
int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta,
pdx::LocalHandle* release_fence, bool gain_posted_buffer = false);
// Enqueues a producer buffer in the queue.
- pdx::Status<void> Enqueue(const std::shared_ptr<BufferProducer>& buffer,
+ pdx::Status<void> Enqueue(const std::shared_ptr<ProducerBuffer>& buffer,
size_t slot, uint64_t index) {
return BufferHubQueue::Enqueue({buffer, slot, index});
}
@@ -406,18 +406,18 @@
// @param slot the slot of the returned buffer.
// @return a buffer in gained state, which was originally in posted state or
// released state.
- pdx::Status<std::shared_ptr<BufferProducer>> DequeueUnacquiredBuffer(
+ pdx::Status<std::shared_ptr<ProducerBuffer>> DequeueUnacquiredBuffer(
size_t* slot);
};
class ConsumerQueue : public BufferHubQueue {
public:
- // Get a buffer consumer. Note that the method doesn't check whether the
+ // Get a consumer buffer. Note that the method doesn't check whether the
// buffer slot has a valid buffer that has been imported already. When no
// buffer has been imported before it returns nullptr; otherwise returns a
- // shared pointer to a BufferConsumer.
- std::shared_ptr<BufferConsumer> GetBuffer(size_t slot) const {
- return std::static_pointer_cast<BufferConsumer>(
+ // shared pointer to a ConsumerBuffer.
+ std::shared_ptr<ConsumerBuffer> GetBuffer(size_t slot) const {
+ return std::static_pointer_cast<ConsumerBuffer>(
BufferHubQueue::GetBuffer(slot));
}
@@ -435,23 +435,23 @@
// Dequeue a consumer buffer to read. The returned buffer in |Acquired|'ed
// mode, and caller should call Releasse() once it's done writing to release
// the buffer to the producer side. |meta| is passed along from BufferHub,
- // The user of BufferProducer is responsible with making sure that the
+ // The user of ProducerBuffer is responsible with making sure that the
// Dequeue() is done with the corect metadata type and size with those used
// when the buffer is orignally created.
template <typename Meta>
- pdx::Status<std::shared_ptr<BufferConsumer>> Dequeue(
+ pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue(
int timeout, size_t* slot, Meta* meta, pdx::LocalHandle* acquire_fence) {
return Dequeue(timeout, slot, meta, sizeof(*meta), acquire_fence);
}
- pdx::Status<std::shared_ptr<BufferConsumer>> Dequeue(
+ pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue(
int timeout, size_t* slot, pdx::LocalHandle* acquire_fence) {
return Dequeue(timeout, slot, nullptr, 0, acquire_fence);
}
- pdx::Status<std::shared_ptr<BufferConsumer>> Dequeue(
+ pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue(
int timeout, size_t* slot, void* meta, size_t user_metadata_size,
pdx::LocalHandle* acquire_fence);
- pdx::Status<std::shared_ptr<BufferConsumer>> Dequeue(
+ pdx::Status<std::shared_ptr<ConsumerBuffer>> Dequeue(
int timeout, size_t* slot, DvrNativeBufferMetadata* out_meta,
pdx::LocalHandle* acquire_fence);
@@ -464,7 +464,7 @@
// is NOT available to use until the producer side |Post| it. |WaitForBuffers|
// will catch the |Post| and |Acquire| the buffer to make it available for
// consumer.
- pdx::Status<void> AddBuffer(const std::shared_ptr<BufferConsumer>& buffer,
+ pdx::Status<void> AddBuffer(const std::shared_ptr<ConsumerBuffer>& buffer,
size_t slot);
pdx::Status<void> OnBufferAllocated() override;
diff --git a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
index 159d6dc..6ae603b 100644
--- a/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
+++ b/libs/vr/libbufferhubqueue/tests/buffer_hub_queue-test.cpp
@@ -125,7 +125,7 @@
}
TEST_F(BufferHubQueueTest,
- TestDequeuePostedBufferIfNoAvailableReleasedBuffer_withBufferConsumer) {
+ TestDequeuePostedBufferIfNoAvailableReleasedBuffer_withConsumerBuffer) {
ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
// Allocate 3 buffers to use.
@@ -205,7 +205,7 @@
}
TEST_F(BufferHubQueueTest,
- TestDequeuePostedBufferIfNoAvailableReleasedBuffer_noBufferConsumer) {
+ TestDequeuePostedBufferIfNoAvailableReleasedBuffer_noConsumerBuffer) {
ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
// Allocate 4 buffers to use.
@@ -332,7 +332,7 @@
EXPECT_EQ(producer_queue_->capacity(), 0);
EXPECT_EQ(consumer_queue_->capacity(), 0);
- std::shared_ptr<BufferProducer> p1 = BufferProducer::Create(
+ std::shared_ptr<ProducerBuffer> p1 = ProducerBuffer::Create(
kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage, 0);
ASSERT_TRUE(p1 != nullptr);
ASSERT_EQ(p1->GainAsync(), 0);
@@ -345,7 +345,7 @@
EXPECT_EQ(status_or_slot.error(), EINVAL);
// Inserting a gained buffer will succeed.
- std::shared_ptr<BufferProducer> p2 = BufferProducer::Create(
+ std::shared_ptr<ProducerBuffer> p2 = ProducerBuffer::Create(
kBufferWidth, kBufferHeight, kBufferFormat, kBufferUsage);
ASSERT_EQ(p2->GainAsync(), 0);
ASSERT_TRUE(p2 != nullptr);
@@ -382,7 +382,7 @@
// Dequeue all the buffers and keep track of them in an array. This prevents
// the producer queue ring buffer ref counts from interfering with the tests.
struct Entry {
- std::shared_ptr<BufferProducer> buffer;
+ std::shared_ptr<ProducerBuffer> buffer;
LocalHandle fence;
size_t slot;
};
@@ -848,10 +848,10 @@
size_t slot;
LocalHandle fence;
pdx::Status<void> status;
- pdx::Status<std::shared_ptr<BufferConsumer>> consumer_status;
- pdx::Status<std::shared_ptr<BufferProducer>> producer_status;
- std::shared_ptr<BufferConsumer> consumer_buffer;
- std::shared_ptr<BufferProducer> producer_buffer;
+ pdx::Status<std::shared_ptr<ConsumerBuffer>> consumer_status;
+ pdx::Status<std::shared_ptr<ProducerBuffer>> producer_status;
+ std::shared_ptr<ConsumerBuffer> consumer_buffer;
+ std::shared_ptr<ProducerBuffer> producer_buffer;
DvrNativeBufferMetadata mi, mo;
ASSERT_TRUE(CreateQueues(config_builder_.Build(), UsagePolicy{}));
@@ -994,7 +994,7 @@
auto s3 = producer_queue_->Dequeue(0, &slot, &producer_meta, &fence);
EXPECT_TRUE(s3.ok());
- std::shared_ptr<BufferProducer> p1 = s3.take();
+ std::shared_ptr<ProducerBuffer> p1 = s3.take();
ASSERT_NE(p1, nullptr);
producer_meta.timestamp = 42;
@@ -1061,7 +1061,7 @@
auto s2 = producer_queue_->Dequeue(0, &slot, &producer_meta, &fence);
EXPECT_TRUE(s2.ok());
- std::shared_ptr<BufferProducer> p1 = s2.take();
+ std::shared_ptr<ProducerBuffer> p1 = s2.take();
ASSERT_NE(p1, nullptr);
producer_meta.timestamp = 42;
diff --git a/libs/vr/libdvr/dvr_buffer_queue.cpp b/libs/vr/libdvr/dvr_buffer_queue.cpp
index f4c6600..1ca653c 100644
--- a/libs/vr/libdvr/dvr_buffer_queue.cpp
+++ b/libs/vr/libdvr/dvr_buffer_queue.cpp
@@ -8,10 +8,10 @@
#include "dvr_buffer_queue_internal.h"
using namespace android;
-using android::dvr::BufferConsumer;
using android::dvr::BufferHubBase;
-using android::dvr::BufferProducer;
+using android::dvr::ConsumerBuffer;
using android::dvr::ConsumerQueue;
+using android::dvr::ProducerBuffer;
using android::dvr::ProducerQueue;
using android::dvr::ProducerQueueConfigBuilder;
using android::dvr::UsagePolicy;
@@ -103,13 +103,13 @@
"DvrWriteBufferQueue::GainBuffer: Buffer slot is not empty: %zu", slot);
write_buffers_[slot]->write_buffer = std::move(buffer_status.take());
- const auto& buffer_producer = write_buffers_[slot]->write_buffer;
- if (!buffer_producer)
+ const auto& producer_buffer = write_buffers_[slot]->write_buffer;
+ if (!producer_buffer)
return -ENOMEM;
- if (width_ == buffer_producer->width() &&
- height_ == buffer_producer->height() &&
- format_ == buffer_producer->format()) {
+ if (width_ == producer_buffer->width() &&
+ height_ == producer_buffer->height() &&
+ format_ == producer_buffer->format()) {
// Producer queue returns a buffer matches the current request.
break;
}
@@ -122,14 +122,14 @@
"DvrWriteBufferQueue::Dequeue: requested buffer at slot: %zu "
"(w=%u, h=%u, fmt=%u) is different from the buffer returned "
"(w=%u, h=%u, fmt=%u). Need re-allocation.",
- slot, width_, height_, format_, buffer_producer->width(),
- buffer_producer->height(), buffer_producer->format());
+ slot, width_, height_, format_, producer_buffer->width(),
+ producer_buffer->height(), producer_buffer->format());
// Currently, we are not storing |layer_count| and |usage| in queue
// configuration. Copy those setup from the last buffer dequeued before we
// remove it.
- uint32_t old_layer_count = buffer_producer->layer_count();
- uint64_t old_usage = buffer_producer->usage();
+ uint32_t old_layer_count = producer_buffer->layer_count();
+ uint64_t old_usage = producer_buffer->usage();
// Allocate a new producer buffer with new buffer configs. Note that if
// there are already multiple available buffers in the queue, the next one
@@ -443,7 +443,7 @@
// When buffer is removed from the queue, the slot is already invalid.
auto read_buffer = std::make_unique<DvrReadBuffer>();
read_buffer->read_buffer =
- std::static_pointer_cast<BufferConsumer>(buffer);
+ std::static_pointer_cast<ConsumerBuffer>(buffer);
callback(read_buffer.release(), context);
});
}
diff --git a/libs/vr/libdvr/dvr_display_manager.cpp b/libs/vr/libdvr/dvr_display_manager.cpp
index fe91b14..7f631e3 100644
--- a/libs/vr/libdvr/dvr_display_manager.cpp
+++ b/libs/vr/libdvr/dvr_display_manager.cpp
@@ -10,10 +10,10 @@
#include "dvr_internal.h"
#include "dvr_buffer_queue_internal.h"
-using android::dvr::BufferConsumer;
+using android::dvr::ConsumerBuffer;
using android::dvr::display::DisplayManagerClient;
-using android::dvr::display::SurfaceAttributes;
using android::dvr::display::SurfaceAttribute;
+using android::dvr::display::SurfaceAttributes;
using android::dvr::display::SurfaceState;
using android::pdx::rpc::EmptyVariant;
diff --git a/libs/vr/libdvr/dvr_internal.h b/libs/vr/libdvr/dvr_internal.h
index df8125a..f845cd8 100644
--- a/libs/vr/libdvr/dvr_internal.h
+++ b/libs/vr/libdvr/dvr_internal.h
@@ -16,21 +16,11 @@
namespace android {
namespace dvr {
-// TODO(b/116855254): Remove this typedef once rename is complete in libdvr.
-// Note that the dvr::BufferProducer and dvr::BufferConsumer were poorly named,
-// they should really be named as ProducerBuffer and ConsumerBuffer.
-typedef class ProducerBuffer BufferProducer;
-typedef class ConsumerBuffer BufferConsumer;
class IonBuffer;
DvrBuffer* CreateDvrBufferFromIonBuffer(
const std::shared_ptr<IonBuffer>& ion_buffer);
-DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
- const std::shared_ptr<BufferConsumer>& buffer_consumer);
-DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
- const std::shared_ptr<BufferProducer>& buffer_producer);
-
} // namespace dvr
} // namespace android
@@ -42,7 +32,7 @@
// DvrWriteBuffer acquired from a DvrWriteBufferQueue.
int32_t slot = -1;
- std::shared_ptr<android::dvr::BufferProducer> write_buffer;
+ std::shared_ptr<android::dvr::ProducerBuffer> write_buffer;
};
struct DvrReadBuffer {
@@ -51,7 +41,7 @@
// DvrReadBuffer acquired from a DvrReadBufferQueue.
int32_t slot = -1;
- std::shared_ptr<android::dvr::BufferConsumer> read_buffer;
+ std::shared_ptr<android::dvr::ConsumerBuffer> read_buffer;
};
struct DvrBuffer {
diff --git a/libs/vr/libdvr/dvr_surface.cpp b/libs/vr/libdvr/dvr_surface.cpp
index a3a47f1..0c7ec01 100644
--- a/libs/vr/libdvr/dvr_surface.cpp
+++ b/libs/vr/libdvr/dvr_surface.cpp
@@ -14,7 +14,6 @@
using android::dvr::display::Surface;
using android::dvr::display::SurfaceAttributes;
using android::dvr::display::SurfaceAttributeValue;
-using android::dvr::CreateDvrReadBufferFromBufferConsumer;
using android::pdx::rpc::EmptyVariant;
namespace {
diff --git a/libs/vr/libvrflinger/acquired_buffer.cpp b/libs/vr/libvrflinger/acquired_buffer.cpp
index 5d873d1..c360dee 100644
--- a/libs/vr/libvrflinger/acquired_buffer.cpp
+++ b/libs/vr/libvrflinger/acquired_buffer.cpp
@@ -8,11 +8,11 @@
namespace android {
namespace dvr {
-AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
+AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<ConsumerBuffer>& buffer,
LocalHandle acquire_fence, std::size_t slot)
: buffer_(buffer), acquire_fence_(std::move(acquire_fence)), slot_(slot) {}
-AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
+AcquiredBuffer::AcquiredBuffer(const std::shared_ptr<ConsumerBuffer>& buffer,
int* error) {
LocalHandle fence;
const int ret = buffer->Acquire(&fence);
@@ -75,7 +75,7 @@
return std::move(acquire_fence_);
}
-std::shared_ptr<BufferConsumer> AcquiredBuffer::ClaimBuffer() {
+std::shared_ptr<ConsumerBuffer> AcquiredBuffer::ClaimBuffer() {
return std::move(buffer_);
}
diff --git a/libs/vr/libvrflinger/acquired_buffer.h b/libs/vr/libvrflinger/acquired_buffer.h
index 9e35a39..7643e75 100644
--- a/libs/vr/libvrflinger/acquired_buffer.h
+++ b/libs/vr/libvrflinger/acquired_buffer.h
@@ -9,42 +9,42 @@
namespace android {
namespace dvr {
-// Manages the ACQUIRE/RELEASE ownership cycle of a BufferConsumer.
+// Manages the ACQUIRE/RELEASE ownership cycle of a ConsumerBuffer.
class AcquiredBuffer {
public:
static constexpr int kEmptyFence = pdx::LocalHandle::kEmptyFileHandle;
AcquiredBuffer() : buffer_(nullptr), acquire_fence_(kEmptyFence) {}
- // Constructs an AcquiredBuffer from a BufferConsumer pointer and an acquire
- // fence. The BufferConsumer MUST be in the ACQUIRED state prior to calling
+ // Constructs an AcquiredBuffer from a ConsumerBuffer pointer and an acquire
+ // fence. The ConsumerBuffer MUST be in the ACQUIRED state prior to calling
// this constructor; the constructor does not attempt to ACQUIRE the buffer
// itself.
- AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer,
+ AcquiredBuffer(const std::shared_ptr<ConsumerBuffer>& buffer,
pdx::LocalHandle acquire_fence, std::size_t slot = 0);
- // Constructs an AcquiredBuffer from a BufferConsumer. The BufferConsumer MUST
+ // Constructs an AcquiredBuffer from a ConsumerBuffer. The ConsumerBuffer MUST
// be in the POSTED state prior to calling this constructor, as this
// constructor attempts to ACQUIRE the buffer. If ACQUIRING the buffer fails
// this instance is left in the empty state. An optional error code is
// returned in |error|, which may be nullptr if not needed.
- AcquiredBuffer(const std::shared_ptr<BufferConsumer>& buffer, int* error);
+ AcquiredBuffer(const std::shared_ptr<ConsumerBuffer>& buffer, int* error);
// Move constructor. Behaves similarly to the move assignment operator below.
AcquiredBuffer(AcquiredBuffer&& other) noexcept;
~AcquiredBuffer();
- // Move assignment operator. Moves the BufferConsumer and acquire fence from
- // |other| into this instance after RELEASING the current BufferConsumer and
+ // Move assignment operator. Moves the ConsumerBuffer and acquire fence from
+ // |other| into this instance after RELEASING the current ConsumerBuffer and
// closing the acquire fence. After the move |other| is left in the empty
// state.
AcquiredBuffer& operator=(AcquiredBuffer&& other) noexcept;
- // Accessors for the underlying BufferConsumer, the acquire fence, and the
+ // Accessors for the underlying ConsumerBuffer, the acquire fence, and the
// use-case specific sequence value from the acquisition (see
// private/dvr/consumer_buffer.h).
- std::shared_ptr<BufferConsumer> buffer() const { return buffer_; }
+ std::shared_ptr<ConsumerBuffer> buffer() const { return buffer_; }
int acquire_fence() const { return acquire_fence_.Get(); }
// When non-empty, returns true if the acquired fence was signaled (or if the
@@ -58,11 +58,11 @@
// Returns the buffer, passing ownership to the caller. Caller is responsible
// for calling Release on the returned buffer.
- std::shared_ptr<BufferConsumer> ClaimBuffer();
+ std::shared_ptr<ConsumerBuffer> ClaimBuffer();
- // Releases the BufferConsumer, passing the release fence in |release_fence|
- // to the producer. On success, the BufferConsumer and acquire fence are set
- // to empty state; if release fails, the BufferConsumer and acquire fence are
+ // Releases the ConsumerBuffer, passing the release fence in |release_fence|
+ // to the producer. On success, the ConsumerBuffer and acquire fence are set
+ // to empty state; if release fails, the ConsumerBuffer and acquire fence are
// left in place and a negative error code is returned.
int Release(pdx::LocalHandle release_fence = {});
@@ -71,7 +71,7 @@
std::size_t slot() const { return slot_; }
private:
- std::shared_ptr<BufferConsumer> buffer_;
+ std::shared_ptr<ConsumerBuffer> buffer_;
// Mutable so that the fence can be closed when it is determined to be
// signaled during IsAvailable().
mutable pdx::LocalHandle acquire_fence_;
diff --git a/libs/vr/libvrsensor/pose_client.cpp b/libs/vr/libvrsensor/pose_client.cpp
index c72f75e..4ff6a09 100644
--- a/libs/vr/libvrsensor/pose_client.cpp
+++ b/libs/vr/libvrsensor/pose_client.cpp
@@ -221,7 +221,7 @@
return -status.error();
}
- auto buffer = BufferConsumer::Import(status.take());
+ auto buffer = ConsumerBuffer::Import(status.take());
if (!buffer) {
ALOGE("Pose failed to import ring buffer");
return -EIO;
@@ -290,7 +290,7 @@
const DvrVsyncPoseBuffer* mapped_vsync_pose_buffer_ = nullptr;
struct ControllerClientState {
- std::unique_ptr<BufferConsumer> pose_buffer;
+ std::unique_ptr<ConsumerBuffer> pose_buffer;
const DvrPoseAsync* mapped_pose_buffer = nullptr;
};
ControllerClientState controllers_[MAX_CONTROLLERS];
diff --git a/opengl/tests/hwc/hwcCommit.cpp b/opengl/tests/hwc/hwcCommit.cpp
index 3686dab..0a6ff55 100644
--- a/opengl/tests/hwc/hwcCommit.cpp
+++ b/opengl/tests/hwc/hwcCommit.cpp
@@ -183,7 +183,7 @@
uint32_t lower(void) { return _l; }
uint32_t upper(void) { return _u; }
- operator string();
+ operator string(); // NOLINT(google-explicit-constructor)
private:
uint32_t _l; // lower
@@ -216,7 +216,9 @@
static void double2Rational(double f, Range nRange, Range dRange,
Rational& lower, Rational& upper);
+ // NOLINTNEXTLINE(google-explicit-constructor)
operator string() const;
+ // NOLINTNEXTLINE(google-explicit-constructor)
operator double() const { return (double) _n / (double) _d; }
diff --git a/opengl/tests/hwc/hwcTestLib.h b/opengl/tests/hwc/hwcTestLib.h
index 922fc19..5a49393 100644
--- a/opengl/tests/hwc/hwcTestLib.h
+++ b/opengl/tests/hwc/hwcTestLib.h
@@ -58,7 +58,7 @@
float c2(void) const { return _c2; }
float c3(void) const { return _c3; }
- operator std::string();
+ operator std::string(); // NOLINT(google-explicit-constructor)
private:
float _c1;
@@ -71,7 +71,7 @@
class ColorRGB {
public:
ColorRGB(): _r(0.0), _g(0.0), _b(0.0) {};
- ColorRGB(float f): _r(f), _g(f), _b(f) {}; // Gray, NOLINT(implicit)
+ ColorRGB(float f): _r(f), _g(f), _b(f) {}; // Gray, NOLINT(google-explicit-constructor)
ColorRGB(float r, float g, float b): _r(r), _g(g), _b(b) {};
float r(void) const { return _r; }
float g(void) const { return _g; }
@@ -93,8 +93,8 @@
void setWidth(uint32_t w) { _w = w; }
void setHeight(uint32_t h) { _h = h; }
- operator std::string();
- operator hwc_rect() const;
+ operator std::string(); // NOLINT(google-explicit-constructor)
+ operator hwc_rect() const; // NOLINT(google-explicit-constructor)
private:
uint32_t _w;
diff --git a/services/surfaceflinger/OWNERS b/services/surfaceflinger/OWNERS
new file mode 100644
index 0000000..dc2b300
--- /dev/null
+++ b/services/surfaceflinger/OWNERS
@@ -0,0 +1,5 @@
+chaviw@google.com
+lpy@google.com
+marissaw@google.com
+racarr@google.com
+stoza@google.com
\ No newline at end of file
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 4a93be6..02cd9d9 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1568,11 +1568,23 @@
bool SurfaceFlinger::handleMessageTransaction() {
uint32_t transactionFlags = peekTransactionFlags();
+
+ // Apply any ready transactions in the queues if there are still transactions that have not been
+ // applied, wake up during the next vsync period and check again
+ bool transactionNeeded = false;
+ if (!flushTransactionQueues()) {
+ transactionNeeded = true;
+ }
+
if (transactionFlags) {
handleTransaction(transactionFlags);
- return true;
}
- return false;
+
+ if (transactionNeeded) {
+ setTransactionFlags(eTransactionNeeded);
+ }
+
+ return transactionFlags;
}
void SurfaceFlinger::handleMessageRefresh() {
@@ -3314,6 +3326,26 @@
return old;
}
+bool SurfaceFlinger::flushTransactionQueues() {
+ Mutex::Autolock _l(mStateLock);
+ auto it = mTransactionQueues.begin();
+ while (it != mTransactionQueues.end()) {
+ auto& [applyToken, transactionQueue] = *it;
+
+ while (!transactionQueue.empty()) {
+ const auto& [states, displays, flags] = transactionQueue.front();
+ if (composerStateContainsUnsignaledFences(states)) {
+ break;
+ }
+ applyTransactionState(states, displays, flags);
+ transactionQueue.pop();
+ }
+
+ it = (transactionQueue.empty()) ? mTransactionQueues.erase(it) : std::next(it, 1);
+ }
+ return mTransactionQueues.empty();
+}
+
bool SurfaceFlinger::containsAnyInvalidClientState(const Vector<ComposerState>& states) {
for (const ComposerState& state : states) {
// Here we need to check that the interface we're given is indeed
@@ -3336,19 +3368,44 @@
return false;
}
-void SurfaceFlinger::setTransactionState(
- const Vector<ComposerState>& states,
- const Vector<DisplayState>& displays,
- uint32_t flags)
-{
+bool SurfaceFlinger::composerStateContainsUnsignaledFences(const Vector<ComposerState>& states) {
+ for (const ComposerState& state : states) {
+ const layer_state_t& s = state.state;
+ if (!(s.what & layer_state_t::eAcquireFenceChanged)) {
+ continue;
+ }
+ if (s.acquireFence && s.acquireFence->getStatus() == Fence::Status::Unsignaled) {
+ return true;
+ }
+ }
+ return false;
+}
+
+void SurfaceFlinger::setTransactionState(const Vector<ComposerState>& states,
+ const Vector<DisplayState>& displays, uint32_t flags,
+ const sp<IBinder>& applyToken) {
ATRACE_CALL();
Mutex::Autolock _l(mStateLock);
- uint32_t transactionFlags = 0;
if (containsAnyInvalidClientState(states)) {
return;
}
+ // If its TransactionQueue already has a pending TransactionState or if it is pending
+ if (mTransactionQueues.find(applyToken) != mTransactionQueues.end() ||
+ composerStateContainsUnsignaledFences(states)) {
+ mTransactionQueues[applyToken].emplace(states, displays, flags);
+ setTransactionFlags(eTransactionNeeded);
+ return;
+ }
+
+ applyTransactionState(states, displays, flags);
+}
+
+void SurfaceFlinger::applyTransactionState(const Vector<ComposerState>& states,
+ const Vector<DisplayState>& displays, uint32_t flags) {
+ uint32_t transactionFlags = 0;
+
if (flags & eAnimation) {
// For window updates that are part of an animation we must wait for
// previous animation "frames" to be handled.
@@ -3938,7 +3995,7 @@
d.width = 0;
d.height = 0;
displays.add(d);
- setTransactionState(state, displays, 0);
+ setTransactionState(state, displays, 0, nullptr);
const auto display = getDisplayDevice(displayToken);
if (!display) return;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b1bfb3a..822bb18 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -442,7 +442,8 @@
virtual void destroyDisplay(const sp<IBinder>& displayToken);
virtual sp<IBinder> getBuiltInDisplay(int32_t id);
virtual void setTransactionState(const Vector<ComposerState>& state,
- const Vector<DisplayState>& displays, uint32_t flags);
+ const Vector<DisplayState>& displays, uint32_t flags,
+ const sp<IBinder>& applyToken);
virtual void bootFinished();
virtual bool authenticateSurfaceTexture(
const sp<IGraphicBufferProducer>& bufferProducer) const;
@@ -553,6 +554,10 @@
/* ------------------------------------------------------------------------
* Transactions
*/
+ void applyTransactionState(const Vector<ComposerState>& state,
+ const Vector<DisplayState>& displays, uint32_t flags)
+ REQUIRES(mStateLock);
+ bool flushTransactionQueues();
uint32_t getTransactionFlags(uint32_t flags);
uint32_t peekTransactionFlags();
// Can only be called from the main thread or with mStateLock held
@@ -561,6 +566,7 @@
void latchAndReleaseBuffer(const sp<Layer>& layer);
void commitTransaction();
bool containsAnyInvalidClientState(const Vector<ComposerState>& states);
+ bool composerStateContainsUnsignaledFences(const Vector<ComposerState>& states);
uint32_t setClientStateLocked(const ComposerState& composerState);
uint32_t setDisplayStateLocked(const DisplayState& s);
void setDestroyStateLocked(const ComposerState& composerState);
@@ -965,6 +971,22 @@
uint32_t mTexturePoolSize = 0;
std::vector<uint32_t> mTexturePool;
+ struct IBinderHash {
+ std::size_t operator()(const sp<IBinder>& strongPointer) const {
+ return std::hash<IBinder*>{}(strongPointer.get());
+ }
+ };
+ struct TransactionState {
+ TransactionState(const Vector<ComposerState>& composerStates,
+ const Vector<DisplayState>& displayStates, uint32_t transactionFlags)
+ : states(composerStates), displays(displayStates), flags(transactionFlags) {}
+
+ Vector<ComposerState> states;
+ Vector<DisplayState> displays;
+ uint32_t flags;
+ };
+ std::unordered_map<sp<IBinder>, std::queue<TransactionState>, IBinderHash> mTransactionQueues;
+
/* ------------------------------------------------------------------------
* Feature prototyping
*/
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 604aa7d..f121a95 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -17,6 +17,7 @@
defaults: ["surfaceflinger_defaults"],
test_suites: ["device-tests"],
srcs: [
+ "BufferGenerator.cpp",
"Credentials_test.cpp",
"Stress_test.cpp",
"SurfaceInterceptor_test.cpp",
diff --git a/services/surfaceflinger/tests/BufferGenerator.cpp b/services/surfaceflinger/tests/BufferGenerator.cpp
new file mode 100644
index 0000000..8ddda60
--- /dev/null
+++ b/services/surfaceflinger/tests/BufferGenerator.cpp
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2018 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 <gui/BufferItemConsumer.h>
+#include <gui/Surface.h>
+
+#include <GLES3/gl3.h>
+#include <math/vec2.h>
+#include <math/vec3.h>
+#include <math/vec4.h>
+
+#include "BufferGenerator.h"
+#include "BufferGeneratorShader.h"
+
+namespace android {
+
+/* Used to receive the surfaces and fences from egl. The egl buffers are thrown
+ * away. The fences are sent to the requester via a callback */
+class SurfaceManager {
+public:
+ /* Returns a fence from egl */
+ using BufferCallback = std::function<void(const sp<GraphicBuffer>& buffer, int32_t fence)>;
+
+ /* Listens for a new frame, detaches the buffer and returns the fence
+ * through saved callback. */
+ class BufferListener : public ConsumerBase::FrameAvailableListener {
+ public:
+ BufferListener(sp<IGraphicBufferConsumer> consumer, BufferCallback callback)
+ : mConsumer(consumer), mCallback(callback) {}
+
+ void onFrameAvailable(const BufferItem& /*item*/) {
+ BufferItem item;
+
+ if (mConsumer->acquireBuffer(&item, 0)) return;
+ if (mConsumer->detachBuffer(item.mSlot)) return;
+
+ mCallback(item.mGraphicBuffer, item.mFence->dup());
+ }
+
+ private:
+ sp<IGraphicBufferConsumer> mConsumer;
+ BufferCallback mCallback;
+ };
+
+ /* Creates a buffer listener that waits on a new frame from the buffer
+ * queue. */
+ void initialize(uint32_t width, uint32_t height, android_pixel_format_t format,
+ BufferCallback callback) {
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+
+ consumer->setDefaultBufferSize(width, height);
+ consumer->setDefaultBufferFormat(format);
+
+ mBufferItemConsumer = new BufferItemConsumer(consumer, 0);
+
+ mListener = new BufferListener(consumer, callback);
+ mBufferItemConsumer->setFrameAvailableListener(mListener);
+
+ mSurface = new Surface(producer, true);
+ }
+
+ /* Used by Egl manager. The surface is never displayed. */
+ sp<Surface> getSurface() const { return mSurface; }
+
+private:
+ sp<BufferItemConsumer> mBufferItemConsumer;
+ sp<BufferListener> mListener;
+ /* Used by Egl manager. The surface is never displayed */
+ sp<Surface> mSurface;
+};
+
+/* Used to generate valid fences. It is not possible to create a dummy sync
+ * fence for testing. Egl can generate buffers along with a valid fence.
+ * The buffer cannot be guaranteed to be the same format across all devices so
+ * a CPU filled buffer is used instead. The Egl fence is used along with the
+ * CPU filled buffer. */
+class EglManager {
+public:
+ EglManager()
+ : mEglDisplay(EGL_NO_DISPLAY), mEglSurface(EGL_NO_SURFACE), mEglContext(EGL_NO_CONTEXT) {}
+
+ ~EglManager() { cleanup(); }
+
+ int initialize(sp<Surface> surface) {
+ mSurface = surface;
+
+ mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ if (mEglDisplay == EGL_NO_DISPLAY) return false;
+
+ EGLint major;
+ EGLint minor;
+ if (!eglInitialize(mEglDisplay, &major, &minor)) {
+ ALOGW("Could not initialize EGL");
+ return false;
+ }
+
+ /* We're going to use a 1x1 pbuffer surface later on
+ * The configuration distance doesn't really matter for what we're
+ * trying to do */
+ EGLint configAttrs[] = {EGL_RENDERABLE_TYPE,
+ EGL_OPENGL_ES2_BIT,
+ EGL_RED_SIZE,
+ 8,
+ EGL_GREEN_SIZE,
+ 8,
+ EGL_BLUE_SIZE,
+ 8,
+ EGL_ALPHA_SIZE,
+ 0,
+ EGL_DEPTH_SIZE,
+ 24,
+ EGL_STENCIL_SIZE,
+ 0,
+ EGL_NONE};
+
+ EGLConfig configs[1];
+ EGLint configCnt;
+ if (!eglChooseConfig(mEglDisplay, configAttrs, configs, 1, &configCnt)) {
+ ALOGW("Could not select EGL configuration");
+ eglReleaseThread();
+ eglTerminate(mEglDisplay);
+ return false;
+ }
+
+ if (configCnt <= 0) {
+ ALOGW("Could not find EGL configuration");
+ eglReleaseThread();
+ eglTerminate(mEglDisplay);
+ return false;
+ }
+
+ /* These objects are initialized below but the default "null" values are
+ * used to cleanup properly at any point in the initialization sequence */
+ EGLint attrs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
+ mEglContext = eglCreateContext(mEglDisplay, configs[0], EGL_NO_CONTEXT, attrs);
+ if (mEglContext == EGL_NO_CONTEXT) {
+ ALOGW("Could not create EGL context");
+ cleanup();
+ return false;
+ }
+
+ EGLint majorVersion;
+ if (!eglQueryContext(mEglDisplay, mEglContext, EGL_CONTEXT_CLIENT_VERSION, &majorVersion)) {
+ ALOGW("Could not query EGL version");
+ cleanup();
+ return false;
+ }
+
+ if (majorVersion != 3) {
+ ALOGW("Unsupported EGL version");
+ cleanup();
+ return false;
+ }
+
+ EGLint surfaceAttrs[] = {EGL_NONE};
+ mEglSurface = eglCreateWindowSurface(mEglDisplay, configs[0], mSurface.get(), surfaceAttrs);
+ if (mEglSurface == EGL_NO_SURFACE) {
+ ALOGW("Could not create EGL surface");
+ cleanup();
+ return false;
+ }
+
+ if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
+ ALOGW("Could not change current EGL context");
+ cleanup();
+ return false;
+ }
+
+ return true;
+ }
+
+ void makeCurrent() const { eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); }
+
+ void present() const { eglSwapBuffers(mEglDisplay, mEglSurface); }
+
+private:
+ void cleanup() {
+ if (mEglDisplay == EGL_NO_DISPLAY) return;
+ if (mEglSurface != EGL_NO_SURFACE) eglDestroySurface(mEglDisplay, mEglSurface);
+ if (mEglContext != EGL_NO_CONTEXT) eglDestroyContext(mEglDisplay, mEglContext);
+
+ eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglReleaseThread();
+ eglTerminate(mEglDisplay);
+ }
+
+ sp<Surface> mSurface;
+ EGLDisplay mEglDisplay;
+ EGLSurface mEglSurface;
+ EGLContext mEglContext;
+};
+
+class Program {
+public:
+ ~Program() {
+ if (mInitialized) {
+ glDetachShader(mProgram, mVertexShader);
+ glDetachShader(mProgram, mFragmentShader);
+
+ glDeleteShader(mVertexShader);
+ glDeleteShader(mFragmentShader);
+
+ glDeleteProgram(mProgram);
+ }
+ }
+
+ bool initialize(const char* vertex, const char* fragment) {
+ mVertexShader = buildShader(vertex, GL_VERTEX_SHADER);
+ if (!mVertexShader) {
+ return false;
+ }
+
+ mFragmentShader = buildShader(fragment, GL_FRAGMENT_SHADER);
+ if (!mFragmentShader) {
+ return false;
+ }
+
+ mProgram = glCreateProgram();
+ glAttachShader(mProgram, mVertexShader);
+ glAttachShader(mProgram, mFragmentShader);
+
+ glLinkProgram(mProgram);
+
+ GLint status;
+ glGetProgramiv(mProgram, GL_LINK_STATUS, &status);
+ if (status != GL_TRUE) {
+ GLint length = 0;
+ glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &length);
+ if (length > 1) {
+ GLchar log[length];
+ glGetProgramInfoLog(mProgram, length, nullptr, &log[0]);
+ ALOGE("%s", log);
+ }
+ ALOGE("Error while linking shaders");
+ return false;
+ }
+ mInitialized = true;
+ return true;
+ }
+
+ void use() const { glUseProgram(mProgram); }
+
+ void bindVec4(GLint location, vec4 v) const { glUniform4f(location, v.x, v.y, v.z, v.w); }
+
+ void bindVec3(GLint location, const vec3* v, uint32_t count) const {
+ glUniform3fv(location, count, &(v->x));
+ }
+
+ void bindFloat(GLint location, float v) { glUniform1f(location, v); }
+
+private:
+ GLuint buildShader(const char* source, GLenum type) const {
+ GLuint shader = glCreateShader(type);
+ glShaderSource(shader, 1, &source, nullptr);
+ glCompileShader(shader);
+
+ GLint status;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
+ if (status != GL_TRUE) {
+ ALOGE("Error while compiling shader of type 0x%x:\n===\n%s\n===", type, source);
+ // Some drivers return wrong values for GL_INFO_LOG_LENGTH
+ // use a fixed size instead
+ GLchar log[512];
+ glGetShaderInfoLog(shader, sizeof(log), nullptr, &log[0]);
+ ALOGE("Shader info log: %s", log);
+ return 0;
+ }
+
+ return shader;
+ }
+
+ GLuint mProgram = 0;
+ GLuint mVertexShader = 0;
+ GLuint mFragmentShader = 0;
+ bool mInitialized = false;
+};
+
+BufferGenerator::BufferGenerator()
+ : mSurfaceManager(new SurfaceManager), mEglManager(new EglManager), mProgram(new Program) {
+ const float width = 1000.0;
+ const float height = 1000.0;
+
+ auto setBufferWithContext =
+ std::bind(setBuffer, std::placeholders::_1, std::placeholders::_2, this);
+ mSurfaceManager->initialize(width, height, HAL_PIXEL_FORMAT_RGBA_8888, setBufferWithContext);
+
+ if (!mEglManager->initialize(mSurfaceManager->getSurface())) return;
+
+ mEglManager->makeCurrent();
+
+ if (!mProgram->initialize(VERTEX_SHADER, FRAGMENT_SHADER)) return;
+ mProgram->use();
+ mProgram->bindVec4(0, vec4{width, height, 1.0f / width, 1.0f / height});
+ mProgram->bindVec3(2, &SPHERICAL_HARMONICS[0], 4);
+
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, &TRIANGLE[0]);
+
+ mInitialized = true;
+}
+
+BufferGenerator::~BufferGenerator() {
+ mEglManager->makeCurrent();
+}
+
+status_t BufferGenerator::get(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {
+ // mMutex is used to protect get() from getting called by multiple threads at the same time
+ static std::mutex mMutex;
+ std::lock_guard lock(mMutex);
+
+ if (!mInitialized) {
+ if (outBuffer) {
+ *outBuffer = nullptr;
+ }
+ if (*outFence) {
+ *outFence = nullptr;
+ }
+ return -EINVAL;
+ }
+
+ // Generate a buffer and fence. They will be returned through the setBuffer callback
+ mEglManager->makeCurrent();
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ const std::chrono::duration<float> time = std::chrono::steady_clock::now() - mEpoch;
+ mProgram->bindFloat(1, time.count());
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ mPending = true;
+ mEglManager->present();
+
+ // Wait for the setBuffer callback
+ if (!mConditionVariable.wait_for(mMutex, std::chrono::seconds(2),
+ [this] { return !mPending; })) {
+ ALOGE("failed to set buffer and fence");
+ return -ETIME;
+ }
+
+ // Return buffer and fence
+ if (outBuffer) {
+ *outBuffer = mGraphicBuffer;
+ }
+ if (outFence) {
+ *outFence = new Fence(mFence);
+ } else {
+ close(mFence);
+ }
+ mGraphicBuffer = nullptr;
+ mFence = -1;
+
+ return NO_ERROR;
+}
+
+// static
+void BufferGenerator::setBuffer(const sp<GraphicBuffer>& buffer, int32_t fence,
+ void* bufferGenerator) {
+ BufferGenerator* generator = static_cast<BufferGenerator*>(bufferGenerator);
+ generator->mGraphicBuffer = buffer;
+ generator->mFence = fence;
+ generator->mPending = false;
+ generator->mConditionVariable.notify_all();
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/tests/BufferGenerator.h b/services/surfaceflinger/tests/BufferGenerator.h
new file mode 100644
index 0000000..a3ffe86
--- /dev/null
+++ b/services/surfaceflinger/tests/BufferGenerator.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#include <condition_variable>
+#include <mutex>
+
+#include <ui/GraphicBuffer.h>
+
+namespace android {
+
+class SurfaceManager;
+class EglManager;
+class Program;
+
+class BufferGenerator {
+public:
+ BufferGenerator();
+ ~BufferGenerator();
+
+ /* Get a new fence */
+ status_t get(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence);
+
+ /* Static callback that sets the fence on a particular instance */
+ static void setBuffer(const sp<GraphicBuffer>& buffer, int32_t fence, void* fenceGenerator);
+
+private:
+ bool mInitialized = false;
+
+ std::unique_ptr<SurfaceManager> mSurfaceManager;
+ std::unique_ptr<EglManager> mEglManager;
+ std::unique_ptr<Program> mProgram;
+
+ std::condition_variable_any mConditionVariable;
+
+ sp<GraphicBuffer> mGraphicBuffer;
+ int32_t mFence = -1;
+ bool mPending = false;
+
+ using Epoch = std::chrono::time_point<std::chrono::steady_clock>;
+ Epoch mEpoch = std::chrono::steady_clock::now();
+};
+
+} // namespace android
diff --git a/services/surfaceflinger/tests/BufferGeneratorShader.h b/services/surfaceflinger/tests/BufferGeneratorShader.h
new file mode 100644
index 0000000..564cda3
--- /dev/null
+++ b/services/surfaceflinger/tests/BufferGeneratorShader.h
@@ -0,0 +1,355 @@
+/*
+ * Copyright 2018 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.
+ */
+
+#pragma once
+
+#include <GLES3/gl3.h>
+#include <math/vec2.h>
+#include <math/vec3.h>
+#include <math/vec4.h>
+
+static const char* VERTEX_SHADER = R"SHADER__(#version 300 es
+precision highp float;
+
+layout(location = 0) in vec4 mesh_position;
+
+void main() {
+ gl_Position = mesh_position;
+}
+)SHADER__";
+
+static const char* FRAGMENT_SHADER = R"SHADER__(#version 300 es
+precision highp float;
+
+layout(location = 0) uniform vec4 resolution;
+layout(location = 1) uniform float time;
+layout(location = 2) uniform vec3[4] SPHERICAL_HARMONICS;
+
+layout(location = 0) out vec4 fragColor;
+
+#define saturate(x) clamp(x, 0.0, 1.0)
+#define PI 3.14159265359
+
+//------------------------------------------------------------------------------
+// Distance field functions
+//------------------------------------------------------------------------------
+
+float sdPlane(in vec3 p) {
+ return p.y;
+}
+
+float sdSphere(in vec3 p, float s) {
+ return length(p) - s;
+}
+
+float sdTorus(in vec3 p, in vec2 t) {
+ return length(vec2(length(p.xz) - t.x, p.y)) - t.y;
+}
+
+vec2 opUnion(vec2 d1, vec2 d2) {
+ return d1.x < d2.x ? d1 : d2;
+}
+
+vec2 scene(in vec3 position) {
+ vec2 scene = opUnion(
+ vec2(sdPlane(position), 1.0),
+ vec2(sdSphere(position - vec3(0.0, 0.4, 0.0), 0.4), 12.0)
+ );
+ return scene;
+}
+
+//------------------------------------------------------------------------------
+// Ray casting
+//------------------------------------------------------------------------------
+
+float shadow(in vec3 origin, in vec3 direction, in float tmin, in float tmax) {
+ float hit = 1.0;
+
+ for (float t = tmin; t < tmax; ) {
+ float h = scene(origin + direction * t).x;
+ if (h < 0.001) return 0.0;
+ t += h;
+ hit = min(hit, 10.0 * h / t);
+ }
+
+ return clamp(hit, 0.0, 1.0);
+}
+
+vec2 traceRay(in vec3 origin, in vec3 direction) {
+ float tmin = 0.02;
+ float tmax = 20.0;
+
+ float material = -1.0;
+ float t = tmin;
+
+ for ( ; t < tmax; ) {
+ vec2 hit = scene(origin + direction * t);
+ if (hit.x < 0.002 || t > tmax) break;
+ t += hit.x;
+ material = hit.y;
+ }
+
+ if (t > tmax) {
+ material = -1.0;
+ }
+
+ return vec2(t, material);
+}
+
+vec3 normal(in vec3 position) {
+ vec3 epsilon = vec3(0.001, 0.0, 0.0);
+ vec3 n = vec3(
+ scene(position + epsilon.xyy).x - scene(position - epsilon.xyy).x,
+ scene(position + epsilon.yxy).x - scene(position - epsilon.yxy).x,
+ scene(position + epsilon.yyx).x - scene(position - epsilon.yyx).x);
+ return normalize(n);
+}
+
+//------------------------------------------------------------------------------
+// BRDF
+//------------------------------------------------------------------------------
+
+float pow5(float x) {
+ float x2 = x * x;
+ return x2 * x2 * x;
+}
+
+float D_GGX(float linearRoughness, float NoH, const vec3 h) {
+ // Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces"
+ float oneMinusNoHSquared = 1.0 - NoH * NoH;
+ float a = NoH * linearRoughness;
+ float k = linearRoughness / (oneMinusNoHSquared + a * a);
+ float d = k * k * (1.0 / PI);
+ return d;
+}
+
+float V_SmithGGXCorrelated(float linearRoughness, float NoV, float NoL) {
+ // Heitz 2014, "Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs"
+ float a2 = linearRoughness * linearRoughness;
+ float GGXV = NoL * sqrt((NoV - a2 * NoV) * NoV + a2);
+ float GGXL = NoV * sqrt((NoL - a2 * NoL) * NoL + a2);
+ return 0.5 / (GGXV + GGXL);
+}
+
+vec3 F_Schlick(const vec3 f0, float VoH) {
+ // Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"
+ return f0 + (vec3(1.0) - f0) * pow5(1.0 - VoH);
+}
+
+float F_Schlick(float f0, float f90, float VoH) {
+ return f0 + (f90 - f0) * pow5(1.0 - VoH);
+}
+
+float Fd_Burley(float linearRoughness, float NoV, float NoL, float LoH) {
+ // Burley 2012, "Physically-Based Shading at Disney"
+ float f90 = 0.5 + 2.0 * linearRoughness * LoH * LoH;
+ float lightScatter = F_Schlick(1.0, f90, NoL);
+ float viewScatter = F_Schlick(1.0, f90, NoV);
+ return lightScatter * viewScatter * (1.0 / PI);
+}
+
+float Fd_Lambert() {
+ return 1.0 / PI;
+}
+
+//------------------------------------------------------------------------------
+// Indirect lighting
+//------------------------------------------------------------------------------
+
+vec3 Irradiance_SphericalHarmonics(const vec3 n) {
+ return max(
+ SPHERICAL_HARMONICS[0]
+ + SPHERICAL_HARMONICS[1] * (n.y)
+ + SPHERICAL_HARMONICS[2] * (n.z)
+ + SPHERICAL_HARMONICS[3] * (n.x)
+ , 0.0);
+}
+
+vec2 PrefilteredDFG_Karis(float roughness, float NoV) {
+ // Karis 2014, "Physically Based Material on Mobile"
+ const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
+ const vec4 c1 = vec4( 1.0, 0.0425, 1.040, -0.040);
+
+ vec4 r = roughness * c0 + c1;
+ float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;
+
+ return vec2(-1.04, 1.04) * a004 + r.zw;
+}
+
+//------------------------------------------------------------------------------
+// Tone mapping and transfer functions
+//------------------------------------------------------------------------------
+
+vec3 Tonemap_ACES(const vec3 x) {
+ // Narkowicz 2015, "ACES Filmic Tone Mapping Curve"
+ const float a = 2.51;
+ const float b = 0.03;
+ const float c = 2.43;
+ const float d = 0.59;
+ const float e = 0.14;
+ return (x * (a * x + b)) / (x * (c * x + d) + e);
+}
+
+vec3 OECF_sRGBFast(const vec3 linear) {
+ return pow(linear, vec3(1.0 / 2.2));
+}
+
+//------------------------------------------------------------------------------
+// Rendering
+//------------------------------------------------------------------------------
+
+vec3 render(in vec3 origin, in vec3 direction, out float distance) {
+ // Sky gradient
+ vec3 color = vec3(0.65, 0.85, 1.0) + direction.y * 0.72;
+
+ // (distance, material)
+ vec2 hit = traceRay(origin, direction);
+ distance = hit.x;
+ float material = hit.y;
+
+ // We've hit something in the scene
+ if (material > 0.0) {
+ vec3 position = origin + distance * direction;
+
+ vec3 v = normalize(-direction);
+ vec3 n = normal(position);
+ vec3 l = normalize(vec3(0.6, 0.7, -0.7));
+ vec3 h = normalize(v + l);
+ vec3 r = normalize(reflect(direction, n));
+
+ float NoV = abs(dot(n, v)) + 1e-5;
+ float NoL = saturate(dot(n, l));
+ float NoH = saturate(dot(n, h));
+ float LoH = saturate(dot(l, h));
+
+ vec3 baseColor = vec3(0.0);
+ float roughness = 0.0;
+ float metallic = 0.0;
+
+ float intensity = 2.0;
+ float indirectIntensity = 0.64;
+
+ if (material < 4.0) {
+ // Checkerboard floor
+ float f = mod(floor(6.0 * position.z) + floor(6.0 * position.x), 2.0);
+ baseColor = 0.4 + f * vec3(0.6);
+ roughness = 0.1;
+ } else if (material < 16.0) {
+ // Metallic objects
+ baseColor = vec3(0.3, 0.0, 0.0);
+ roughness = 0.2;
+ }
+
+ float linearRoughness = roughness * roughness;
+ vec3 diffuseColor = (1.0 - metallic) * baseColor.rgb;
+ vec3 f0 = 0.04 * (1.0 - metallic) + baseColor.rgb * metallic;
+
+ float attenuation = shadow(position, l, 0.02, 2.5);
+
+ // specular BRDF
+ float D = D_GGX(linearRoughness, NoH, h);
+ float V = V_SmithGGXCorrelated(linearRoughness, NoV, NoL);
+ vec3 F = F_Schlick(f0, LoH);
+ vec3 Fr = (D * V) * F;
+
+ // diffuse BRDF
+ vec3 Fd = diffuseColor * Fd_Burley(linearRoughness, NoV, NoL, LoH);
+
+ color = Fd + Fr;
+ color *= (intensity * attenuation * NoL) * vec3(0.98, 0.92, 0.89);
+
+ // diffuse indirect
+ vec3 indirectDiffuse = Irradiance_SphericalHarmonics(n) * Fd_Lambert();
+
+ vec2 indirectHit = traceRay(position, r);
+ vec3 indirectSpecular = vec3(0.65, 0.85, 1.0) + r.y * 0.72;
+ if (indirectHit.y > 0.0) {
+ if (indirectHit.y < 4.0) {
+ vec3 indirectPosition = position + indirectHit.x * r;
+ // Checkerboard floor
+ float f = mod(floor(6.0 * indirectPosition.z) + floor(6.0 * indirectPosition.x), 2.0);
+ indirectSpecular = 0.4 + f * vec3(0.6);
+ } else if (indirectHit.y < 16.0) {
+ // Metallic objects
+ indirectSpecular = vec3(0.3, 0.0, 0.0);
+ }
+ }
+
+ // indirect contribution
+ vec2 dfg = PrefilteredDFG_Karis(roughness, NoV);
+ vec3 specularColor = f0 * dfg.x + dfg.y;
+ vec3 ibl = diffuseColor * indirectDiffuse + indirectSpecular * specularColor;
+
+ color += ibl * indirectIntensity;
+ }
+
+ return color;
+}
+
+//------------------------------------------------------------------------------
+// Setup and execution
+//------------------------------------------------------------------------------
+
+mat3 setCamera(in vec3 origin, in vec3 target, float rotation) {
+ vec3 forward = normalize(target - origin);
+ vec3 orientation = vec3(sin(rotation), cos(rotation), 0.0);
+ vec3 left = normalize(cross(forward, orientation));
+ vec3 up = normalize(cross(left, forward));
+ return mat3(left, up, forward);
+}
+
+void main() {
+ // Normalized coordinates
+ vec2 p = -1.0 + 2.0 * gl_FragCoord.xy / resolution.xy;
+ // Aspect ratio
+ p.x *= resolution.x / resolution.y;
+
+ // Camera position and "look at"
+ vec3 origin = vec3(0.0, 1.0, 0.0);
+ vec3 target = vec3(0.0);
+
+ origin.x += 2.0 * cos(time * 0.2);
+ origin.z += 2.0 * sin(time * 0.2);
+
+ mat3 toWorld = setCamera(origin, target, 0.0);
+ vec3 direction = toWorld * normalize(vec3(p.xy, 2.0));
+
+ // Render scene
+ float distance;
+ vec3 color = render(origin, direction, distance);
+
+ // Tone mapping
+ color = Tonemap_ACES(color);
+
+ // Exponential distance fog
+ color = mix(color, 0.8 * vec3(0.7, 0.8, 1.0), 1.0 - exp2(-0.011 * distance * distance));
+
+ // Gamma compression
+ color = OECF_sRGBFast(color);
+
+ fragColor = vec4(color, 1.0);
+}
+)SHADER__";
+
+static const android::vec3 SPHERICAL_HARMONICS[4] =
+ {{0.754554516862612, 0.748542953903366, 0.790921515418539},
+ {-0.083856548007422, 0.092533500963210, 0.322764661032516},
+ {0.308152705331738, 0.366796330467391, 0.466698181299906},
+ {-0.188884931542396, -0.277402551592231, -0.377844212327557}};
+
+static const android::vec4 TRIANGLE[3] = {{-1.0f, -1.0f, 1.0f, 1.0f},
+ {3.0f, -1.0f, 1.0f, 1.0f},
+ {-1.0f, 3.0f, 1.0f, 1.0f}};
diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp
index 037d32f..d118ad6 100644
--- a/services/surfaceflinger/tests/Transaction_test.cpp
+++ b/services/surfaceflinger/tests/Transaction_test.cpp
@@ -28,7 +28,6 @@
#include <gui/ISurfaceComposer.h>
#include <gui/LayerState.h>
-
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#include <private/gui/ComposerService.h>
@@ -41,6 +40,8 @@
#include <math.h>
#include <math/vec3.h>
+#include "BufferGenerator.h"
+
namespace android {
namespace {
@@ -478,6 +479,11 @@
return screenshot;
}
+ static status_t getBuffer(sp<GraphicBuffer>* outBuffer, sp<Fence>* outFence) {
+ static BufferGenerator bufferGenerator;
+ return bufferGenerator.get(outBuffer, outFence);
+ }
+
sp<SurfaceComposerClient> mClient;
sp<IBinder> mDisplay;
@@ -2164,6 +2170,36 @@
TEST_F(LayerTransactionTest, SetFenceBasic_BufferState) {
sp<SurfaceControl> layer;
+ Transaction transaction;
+ ASSERT_NO_FATAL_FAILURE(
+ layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
+
+ sp<GraphicBuffer> buffer =
+ new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1,
+ BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
+ BufferUsage::COMPOSER_OVERLAY,
+ "test");
+ fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
+
+ sp<Fence> fence;
+ if (getBuffer(nullptr, &fence) != NO_ERROR) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+
+ Transaction().setBuffer(layer, buffer).setAcquireFence(layer, fence).apply();
+
+ status_t status = fence->wait(1000);
+ ASSERT_NE(static_cast<status_t>(Fence::Status::Unsignaled), status);
+ std::this_thread::sleep_for(200ms);
+
+ auto shot = screenshot();
+ shot->expectColor(Rect(0, 0, 32, 32), Color::RED);
+ shot->expectBorder(Rect(0, 0, 32, 32), Color::BLACK);
+}
+
+TEST_F(LayerTransactionTest, SetFenceNull_BufferState) {
+ sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(
layer = createLayer("test", 32, 32, ISurfaceComposerClient::eFXSurfaceBufferState));
@@ -2514,7 +2550,7 @@
}
void addSurface(ExpectedResult::Transaction transactionResult, const sp<SurfaceControl>& layer,
- ExpectedResult::Buffer bufferResult = NOT_ACQUIRED,
+ ExpectedResult::Buffer bufferResult = ACQUIRED,
ExpectedResult::PreviousBuffer previousBufferResult = NOT_RELEASED) {
mTransactionResult = transactionResult;
mExpectedSurfaceResults.emplace(std::piecewise_construct,
@@ -2524,7 +2560,7 @@
void addSurfaces(ExpectedResult::Transaction transactionResult,
const std::vector<sp<SurfaceControl>>& layers,
- ExpectedResult::Buffer bufferResult = NOT_ACQUIRED,
+ ExpectedResult::Buffer bufferResult = ACQUIRED,
ExpectedResult::PreviousBuffer previousBufferResult = NOT_RELEASED) {
for (const auto& layer : layers) {
addSurface(transactionResult, layer, bufferResult, previousBufferResult);
@@ -2631,24 +2667,22 @@
return createLayer(mClient, "test", 0, 0, ISurfaceComposerClient::eFXSurfaceBufferState);
}
- static void fillTransaction(Transaction& transaction, CallbackHelper* callbackHelper,
- const sp<SurfaceControl>& layer = nullptr) {
+ static int fillTransaction(Transaction& transaction, CallbackHelper* callbackHelper,
+ const sp<SurfaceControl>& layer = nullptr) {
if (layer) {
- sp<GraphicBuffer> buffer =
- new GraphicBuffer(32, 32, PIXEL_FORMAT_RGBA_8888, 1,
- BufferUsage::CPU_READ_OFTEN | BufferUsage::CPU_WRITE_OFTEN |
- BufferUsage::COMPOSER_OVERLAY |
- BufferUsage::GPU_TEXTURE,
- "test");
- fillGraphicBufferColor(buffer, Rect(0, 0, 32, 32), Color::RED);
-
- sp<Fence> fence = new Fence(-1);
+ sp<GraphicBuffer> buffer;
+ sp<Fence> fence;
+ int err = getBuffer(&buffer, &fence);
+ if (err != NO_ERROR) {
+ return err;
+ }
transaction.setBuffer(layer, buffer).setAcquireFence(layer, fence);
}
transaction.addTransactionCompletedCallback(callbackHelper->function,
callbackHelper->getContext());
+ return NO_ERROR;
}
static void waitForCallback(CallbackHelper& helper, const ExpectedResult& expectedResult,
@@ -2680,7 +2714,11 @@
Transaction transaction;
CallbackHelper callback;
- fillTransaction(transaction, &callback, layer);
+ int err = fillTransaction(transaction, &callback, layer);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction.apply();
@@ -2695,19 +2733,28 @@
Transaction transaction;
CallbackHelper callback;
- fillTransaction(transaction, &callback);
+ int err = fillTransaction(transaction, &callback);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply();
ExpectedResult expected;
- expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer);
+ expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer,
+ ExpectedResult::Buffer::NOT_ACQUIRED);
EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
}
TEST_F(LayerCallbackTest, NoStateChange) {
Transaction transaction;
CallbackHelper callback;
- fillTransaction(transaction, &callback);
+ int err = fillTransaction(transaction, &callback);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction.apply();
@@ -2721,7 +2768,11 @@
Transaction transaction;
CallbackHelper callback;
- fillTransaction(transaction, &callback, layer);
+ int err = fillTransaction(transaction, &callback, layer);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction.setFrame(layer, Rect(-100, -100, 100, 100)).apply();
@@ -2737,8 +2788,16 @@
Transaction transaction1, transaction2;
CallbackHelper callback1, callback2;
- fillTransaction(transaction1, &callback1, layer1);
- fillTransaction(transaction2, &callback2, layer2);
+ int err = fillTransaction(transaction1, &callback1, layer1);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ err = fillTransaction(transaction2, &callback2, layer2);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction1.setFrame(layer1, Rect(0, 0, 32, 32));
transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply();
@@ -2756,8 +2815,16 @@
Transaction transaction1, transaction2;
CallbackHelper callback;
- fillTransaction(transaction1, &callback, layer1);
- fillTransaction(transaction2, &callback, layer2);
+ int err = fillTransaction(transaction1, &callback, layer1);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ err = fillTransaction(transaction2, &callback, layer2);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction2.merge(std::move(transaction1)).apply();
@@ -2773,8 +2840,16 @@
Transaction transaction1, transaction2;
CallbackHelper callback1, callback2;
- fillTransaction(transaction1, &callback1, layer);
- fillTransaction(transaction2, &callback2, layer);
+ int err = fillTransaction(transaction1, &callback1, layer);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ err = fillTransaction(transaction2, &callback2, layer);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction2.merge(std::move(transaction1)).apply();
@@ -2784,25 +2859,6 @@
EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
}
-TEST_F(LayerCallbackTest, Merge_SingleBuffer) {
- sp<SurfaceControl> layer1, layer2;
- ASSERT_NO_FATAL_FAILURE(layer1 = createBufferStateLayer());
- ASSERT_NO_FATAL_FAILURE(layer2 = createBufferStateLayer());
-
- Transaction transaction1, transaction2;
- CallbackHelper callback1, callback2;
- fillTransaction(transaction1, &callback1, layer1);
- fillTransaction(transaction2, &callback2);
-
- transaction1.setFrame(layer1, Rect(0, 0, 32, 32));
- transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply();
-
- ExpectedResult expected;
- expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2});
- EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
- EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
-}
-
TEST_F(LayerCallbackTest, Merge_DifferentClients) {
sp<SurfaceComposerClient> client1(new SurfaceComposerClient),
client2(new SurfaceComposerClient);
@@ -2818,8 +2874,16 @@
Transaction transaction1, transaction2;
CallbackHelper callback1, callback2;
- fillTransaction(transaction1, &callback1, layer1);
- fillTransaction(transaction2, &callback2, layer2);
+ int err = fillTransaction(transaction1, &callback1, layer1);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ err = fillTransaction(transaction2, &callback2, layer2);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction1.setFrame(layer1, Rect(0, 0, 32, 32));
transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply();
@@ -2837,13 +2901,17 @@
Transaction transaction;
CallbackHelper callback;
for (size_t i = 0; i < 10; i++) {
- fillTransaction(transaction, &callback, layer);
+ int err = fillTransaction(transaction, &callback, layer);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction.apply();
ExpectedResult expected;
expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
- ExpectedResult::Buffer::NOT_ACQUIRED,
+ ExpectedResult::Buffer::ACQUIRED,
(i == 0) ? ExpectedResult::PreviousBuffer::NOT_RELEASED
: ExpectedResult::PreviousBuffer::RELEASED);
EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected));
@@ -2861,10 +2929,18 @@
ExpectedResult expected;
if (i == 0) {
- fillTransaction(transaction, &callback, layer);
+ int err = fillTransaction(transaction, &callback, layer);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
} else {
- fillTransaction(transaction, &callback);
+ int err = fillTransaction(transaction, &callback);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
}
transaction.apply();
@@ -2882,9 +2958,17 @@
CallbackHelper callback;
for (size_t i = 0; i < 10; i++) {
if (i == 0) {
- fillTransaction(transaction, &callback, layer);
+ int err = fillTransaction(transaction, &callback, layer);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
} else {
- fillTransaction(transaction, &callback);
+ int err = fillTransaction(transaction, &callback);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
}
transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply();
@@ -2892,7 +2976,9 @@
ExpectedResult expected;
expected.addSurface((i == 0) ? ExpectedResult::Transaction::PRESENTED
: ExpectedResult::Transaction::NOT_PRESENTED,
- layer);
+ layer,
+ (i == 0) ? ExpectedResult::Buffer::ACQUIRED
+ : ExpectedResult::Buffer::NOT_ACQUIRED);
EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, i == 0));
}
ASSERT_NO_FATAL_FAILURE(callback.verifyFinalState());
@@ -2906,15 +2992,23 @@
Transaction transaction1, transaction2;
CallbackHelper callback1, callback2;
for (size_t i = 0; i < 10; i++) {
- fillTransaction(transaction1, &callback1, layer1);
- fillTransaction(transaction2, &callback2, layer2);
+ int err = fillTransaction(transaction1, &callback1, layer1);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ err = fillTransaction(transaction2, &callback2, layer2);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction1.setFrame(layer1, Rect(0, 0, 32, 32));
transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply();
ExpectedResult expected;
expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2},
- ExpectedResult::Buffer::NOT_ACQUIRED,
+ ExpectedResult::Buffer::ACQUIRED,
(i == 0) ? ExpectedResult::PreviousBuffer::NOT_RELEASED
: ExpectedResult::PreviousBuffer::RELEASED);
EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected));
@@ -2939,15 +3033,23 @@
Transaction transaction1, transaction2;
CallbackHelper callback1, callback2;
for (size_t i = 0; i < 10; i++) {
- fillTransaction(transaction1, &callback1, layer1);
- fillTransaction(transaction2, &callback2, layer2);
+ int err = fillTransaction(transaction1, &callback1, layer1);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ err = fillTransaction(transaction2, &callback2, layer2);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction1.setFrame(layer1, Rect(0, 0, 32, 32));
transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply();
ExpectedResult expected;
expected.addSurfaces(ExpectedResult::Transaction::PRESENTED, {layer1, layer2},
- ExpectedResult::Buffer::NOT_ACQUIRED,
+ ExpectedResult::Buffer::ACQUIRED,
(i == 0) ? ExpectedResult::PreviousBuffer::NOT_RELEASED
: ExpectedResult::PreviousBuffer::RELEASED);
EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected));
@@ -2973,8 +3075,16 @@
CallbackHelper callback1, callback2;
// Normal call to set up test
- fillTransaction(transaction1, &callback1, layer1);
- fillTransaction(transaction2, &callback2, layer2);
+ int err = fillTransaction(transaction1, &callback1, layer1);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ err = fillTransaction(transaction2, &callback2, layer2);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction1.setFrame(layer1, Rect(0, 0, 32, 32));
transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply();
@@ -2986,8 +3096,16 @@
expected.reset();
// Test
- fillTransaction(transaction1, &callback1);
- fillTransaction(transaction2, &callback2);
+ err = fillTransaction(transaction1, &callback1);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ err = fillTransaction(transaction2, &callback2);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction2.merge(std::move(transaction1)).apply();
@@ -3012,8 +3130,16 @@
CallbackHelper callback1, callback2;
// Normal call to set up test
- fillTransaction(transaction1, &callback1, layer1);
- fillTransaction(transaction2, &callback2, layer2);
+ int err = fillTransaction(transaction1, &callback1, layer1);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ err = fillTransaction(transaction2, &callback2, layer2);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction1.setFrame(layer1, Rect(0, 0, 32, 32));
transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply();
@@ -3025,12 +3151,21 @@
expected.reset();
// Test
- fillTransaction(transaction1, &callback1);
- fillTransaction(transaction2, &callback2);
+ err = fillTransaction(transaction1, &callback1);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+ err = fillTransaction(transaction2, &callback2);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction2.setFrame(layer2, Rect(32, 32, 64, 64)).merge(std::move(transaction1)).apply();
- expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer2);
+ expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer2,
+ ExpectedResult::Buffer::NOT_ACQUIRED);
EXPECT_NO_FATAL_FAILURE(waitForCallback(callback1, expected, true));
EXPECT_NO_FATAL_FAILURE(waitForCallback(callback2, expected, true));
}
@@ -3047,13 +3182,16 @@
for (auto& expected : expectedResults) {
expected.reset();
expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer,
- ExpectedResult::Buffer::NOT_ACQUIRED, previousBufferResult);
+ ExpectedResult::Buffer::ACQUIRED, previousBufferResult);
previousBufferResult = ExpectedResult::PreviousBuffer::RELEASED;
- fillTransaction(transaction, &callback, layer);
+ int err = fillTransaction(transaction, &callback, layer);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction.apply();
- std::this_thread::sleep_for(200ms);
}
EXPECT_NO_FATAL_FAILURE(waitForCallbacks(callback, expectedResults, true));
}
@@ -3062,23 +3200,33 @@
sp<SurfaceControl> layer;
ASSERT_NO_FATAL_FAILURE(layer = createBufferStateLayer());
+ // Normal call to set up test
Transaction transaction;
CallbackHelper callback;
+ int err = fillTransaction(transaction, &callback, layer);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
+
+ transaction.apply();
+
+ ExpectedResult expected;
+ expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
+ EXPECT_NO_FATAL_FAILURE(waitForCallback(callback, expected, true));
+
+ // Test
std::vector<ExpectedResult> expectedResults(50);
- bool first = true;
for (auto& expected : expectedResults) {
expected.reset();
- if (first) {
- fillTransaction(transaction, &callback, layer);
- expected.addSurface(ExpectedResult::Transaction::PRESENTED, layer);
- first = false;
- } else {
- fillTransaction(transaction, &callback);
+ err = fillTransaction(transaction, &callback);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
}
transaction.apply();
- std::this_thread::sleep_for(200ms);
}
EXPECT_NO_FATAL_FAILURE(waitForCallbacks(callback, expectedResults, true));
}
@@ -3090,7 +3238,11 @@
// Normal call to set up test
Transaction transaction;
CallbackHelper callback;
- fillTransaction(transaction, &callback, layer);
+ int err = fillTransaction(transaction, &callback, layer);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply();
@@ -3102,13 +3254,16 @@
std::vector<ExpectedResult> expectedResults(50);
for (auto& expected : expectedResults) {
expected.reset();
- expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer);
+ expected.addSurface(ExpectedResult::Transaction::NOT_PRESENTED, layer,
+ ExpectedResult::Buffer::NOT_ACQUIRED);
- fillTransaction(transaction, &callback);
+ err = fillTransaction(transaction, &callback);
+ if (err) {
+ GTEST_SUCCEED() << "test not supported";
+ return;
+ }
transaction.setFrame(layer, Rect(0, 0, 32, 32)).apply();
-
- std::this_thread::sleep_for(200ms);
}
EXPECT_NO_FATAL_FAILURE(waitForCallbacks(callback, expectedResults, true));
}
diff --git a/services/vr/bufferhubd/include/private/dvr/buffer_hub.h b/services/vr/bufferhubd/include/private/dvr/buffer_hub.h
index 676617d..01520fc 100644
--- a/services/vr/bufferhubd/include/private/dvr/buffer_hub.h
+++ b/services/vr/bufferhubd/include/private/dvr/buffer_hub.h
@@ -41,12 +41,12 @@
// Captures buffer info for use by BufferHubService::DumpState().
struct BufferInfo {
- // Common data field shared by BufferProducer and ProducerQueue.
+ // Common data field shared by ProducerBuffer and ProducerQueue.
int id = -1;
int type = -1;
size_t consumer_count = 0;
- // Data field for buffer producer.
+ // Data field for producer buffer.
uint32_t width = 0;
uint32_t height = 0;
uint32_t layer_count = 0;
diff --git a/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h b/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
index c4003da..0456ad8 100644
--- a/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
+++ b/services/vr/bufferhubd/include/private/dvr/producer_queue_channel.h
@@ -37,11 +37,11 @@
uint32_t format, uint64_t usage,
size_t buffer_count);
- // Inserts a BufferProducer into the queue. Note that the buffer must be in
+ // Inserts a ProducerBuffer into the queue. Note that the buffer must be in
// Gain'ed state for the operation to succeed.
pdx::Status<size_t> OnProducerQueueInsertBuffer(pdx::Message& message, int buffer_cid);
- // Removes a BufferProducer indicated by |slot|. Note that the buffer must be
+ // Removes a ProducerBuffer indicated by |slot|. Note that the buffer must be
// in Gain'ed state for the operation to succeed.
pdx::Status<void> OnProducerQueueRemoveBuffer(pdx::Message& message,
size_t slot);
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index 5c484b8..2a6e9da 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -455,7 +455,7 @@
uint32_t buffer_state = buffer_state_->load(std::memory_order_acquire);
if (!BufferHubDefs::IsClientGained(
buffer_state, BufferHubDefs::kFirstClientStateMask)) {
- // Can only detach a BufferProducer when it's in gained state.
+ // Can only detach a ProducerBuffer when it's in gained state.
ALOGW(
"ProducerChannel::OnProducerDetach: The buffer (id=%d, state=%"
PRIx32