libgui: support 64-bit BQ consumer usage
Add NATIVE_WINDOW_GET_CONSUMER_USAGE64. Support 64-bit consumer
usage flags in BufferItemConsumer and GLConsumer.
In H2BGraphicBufferProducer::getConsumerUsage, however, we will
issue a warning and return 32-bit consumer usage. We will need a
HIDL interface version bump to fix it.
Bug: 35215313
Test: manual
Change-Id: I1f8884a7db71bbdb269d05b94443ddec2ff46f8a
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index d9d50db..da42956 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -19,6 +19,8 @@
//#define ATRACE_TAG ATRACE_TAG_GRAPHICS
#include <utils/Log.h>
+#include <inttypes.h>
+
#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
@@ -31,13 +33,13 @@
namespace android {
BufferItemConsumer::BufferItemConsumer(
- const sp<IGraphicBufferConsumer>& consumer, uint32_t consumerUsage,
+ const sp<IGraphicBufferConsumer>& consumer, uint64_t consumerUsage,
int bufferCount, bool controlledByApp) :
ConsumerBase(consumer, controlledByApp)
{
status_t err = mConsumer->setConsumerUsageBits(consumerUsage);
LOG_ALWAYS_FATAL_IF(err != OK,
- "Failed to set consumer usage bits to %#x", consumerUsage);
+ "Failed to set consumer usage bits to %#" PRIx64, consumerUsage);
if (bufferCount != DEFAULT_MAX_BUFFERS) {
err = mConsumer->setMaxAcquiredBufferCount(bufferCount);
LOG_ALWAYS_FATAL_IF(err != OK,
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 3424012..625dc5b 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -1102,6 +1102,7 @@
value = (mCore->mQueue.size() > 1);
break;
case NATIVE_WINDOW_CONSUMER_USAGE_BITS:
+ // deprecated; higher 32 bits are truncated
value = static_cast<int32_t>(mCore->mConsumerUsageBits);
break;
case NATIVE_WINDOW_DEFAULT_DATASPACE:
@@ -1547,4 +1548,12 @@
return NO_ERROR;
}
+status_t BufferQueueProducer::getConsumerUsage(uint64_t* outUsage) const {
+ BQ_LOGV("getConsumerUsage");
+
+ Mutex::Autolock lock(mCore->mMutex);
+ *outUsage = mCore->mConsumerUsageBits;
+ return NO_ERROR;
+}
+
} // namespace android
diff --git a/libs/gui/GLConsumer.cpp b/libs/gui/GLConsumer.cpp
index 34c9d78..b1994da 100644
--- a/libs/gui/GLConsumer.cpp
+++ b/libs/gui/GLConsumer.cpp
@@ -1115,7 +1115,7 @@
return mConsumer->setDefaultBufferDataSpace(defaultDataSpace);
}
-status_t GLConsumer::setConsumerUsageBits(uint32_t usage) {
+status_t GLConsumer::setConsumerUsageBits(uint64_t usage) {
Mutex::Autolock lock(mMutex);
if (mAbandoned) {
GLC_LOGE("setConsumerUsageBits: GLConsumer is abandoned!");
diff --git a/libs/gui/IGraphicBufferProducer.cpp b/libs/gui/IGraphicBufferProducer.cpp
index 8406a52..71e22ce 100644
--- a/libs/gui/IGraphicBufferProducer.cpp
+++ b/libs/gui/IGraphicBufferProducer.cpp
@@ -62,7 +62,8 @@
SET_DEQUEUE_TIMEOUT,
GET_LAST_QUEUED_BUFFER,
GET_FRAME_TIMESTAMPS,
- GET_UNIQUE_ID
+ GET_UNIQUE_ID,
+ GET_CONSUMER_USAGE,
};
class BpGraphicBufferProducer : public BpInterface<IGraphicBufferProducer>
@@ -504,6 +505,25 @@
}
return actualResult;
}
+
+ virtual status_t getConsumerUsage(uint64_t* outUsage) const {
+ Parcel data, reply;
+ data.writeInterfaceToken(IGraphicBufferProducer::getInterfaceDescriptor());
+ status_t result = remote()->transact(GET_CONSUMER_USAGE, data, &reply);
+ if (result != NO_ERROR) {
+ ALOGE("getConsumerUsage failed to transact: %d", result);
+ }
+ status_t actualResult = NO_ERROR;
+ result = reply.readInt32(&actualResult);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply.readUint64(outUsage);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ return actualResult;
+ }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -622,6 +642,10 @@
status_t getUniqueId(uint64_t* outId) const override {
return mBase->getUniqueId(outId);
}
+
+ status_t getConsumerUsage(uint64_t* outUsage) const override {
+ return mBase->getConsumerUsage(outUsage);
+ }
};
IMPLEMENT_HYBRID_META_INTERFACE(GraphicBufferProducer, HGraphicBufferProducer,
@@ -889,6 +913,20 @@
}
return NO_ERROR;
}
+ case GET_CONSUMER_USAGE: {
+ CHECK_INTERFACE(IGraphicBufferProducer, data, reply);
+ uint64_t outUsage = 0;
+ status_t actualResult = getConsumerUsage(&outUsage);
+ status_t result = reply->writeInt32(actualResult);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ result = reply->writeUint64(outUsage);
+ if (result != NO_ERROR) {
+ return result;
+ }
+ return NO_ERROR;
+ }
}
return BBinder::onTransact(code, data, reply, flags);
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 78eb69d..5b1c599 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -974,6 +974,9 @@
case NATIVE_WINDOW_SET_USAGE64:
res = dispatchSetUsage64(args);
break;
+ case NATIVE_WINDOW_GET_CONSUMER_USAGE64:
+ res = dispatchGetConsumerUsage64(args);
+ break;
default:
res = NAME_NOT_FOUND;
break;
@@ -1152,6 +1155,11 @@
return getHdrSupport(outSupport);
}
+int Surface::dispatchGetConsumerUsage64(va_list args) {
+ uint64_t* usage = va_arg(args, uint64_t*);
+ return getConsumerUsage(usage);
+}
+
int Surface::connect(int api) {
static sp<IProducerListener> listener = new DummyProducerListener();
return connect(api, listener);
@@ -1721,6 +1729,11 @@
return mGraphicBufferProducer->getUniqueId(outId);
}
+int Surface::getConsumerUsage(uint64_t* outUsage) const {
+ Mutex::Autolock lock(mMutex);
+ return mGraphicBufferProducer->getConsumerUsage(outUsage);
+}
+
nsecs_t Surface::getLastDequeueStartTime() const {
Mutex::Autolock lock(mMutex);
return mLastDequeueStartTime;
diff --git a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
index 4a023a6..3b89291 100644
--- a/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
+++ b/libs/gui/bufferqueue/1.0/H2BGraphicBufferProducer.cpp
@@ -21,6 +21,8 @@
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
#include <gui/bufferqueue/1.0/B2HProducerListener.h>
+#include <system/window.h>
+
namespace android {
namespace hardware {
namespace graphics {
@@ -1232,6 +1234,18 @@
return transStatus == NO_ERROR ? fnStatus : transStatus;
}
+status_t H2BGraphicBufferProducer::getConsumerUsage(uint64_t* outUsage) const {
+ ALOGW("getConsumerUsage is not fully supported");
+ int result;
+ status_t transStatus = toStatusT(mBase->query(
+ NATIVE_WINDOW_CONSUMER_USAGE_BITS,
+ [&result, outUsage] (int32_t tResult, int32_t tValue) {
+ result = static_cast<int>(tResult);
+ *outUsage = static_cast<uint64_t>(tValue);
+ }));
+ return transStatus == NO_ERROR ? result : static_cast<int>(transStatus);
+}
+
} // namespace utils
} // namespace V1_0
} // namespace bufferqueue
diff --git a/libs/gui/include/gui/BufferItemConsumer.h b/libs/gui/include/gui/BufferItemConsumer.h
index 217fe6a..d9c5775 100644
--- a/libs/gui/include/gui/BufferItemConsumer.h
+++ b/libs/gui/include/gui/BufferItemConsumer.h
@@ -52,7 +52,7 @@
// controlledByApp tells whether this consumer is controlled by the
// application.
BufferItemConsumer(const sp<IGraphicBufferConsumer>& consumer,
- uint32_t consumerUsage, int bufferCount = DEFAULT_MAX_BUFFERS,
+ uint64_t consumerUsage, int bufferCount = DEFAULT_MAX_BUFFERS,
bool controlledByApp = false);
~BufferItemConsumer() override;
diff --git a/libs/gui/include/gui/BufferQueueProducer.h b/libs/gui/include/gui/BufferQueueProducer.h
index d6f215e..5c7ffb4 100644
--- a/libs/gui/include/gui/BufferQueueProducer.h
+++ b/libs/gui/include/gui/BufferQueueProducer.h
@@ -183,6 +183,9 @@
// See IGraphicBufferProducer::getUniqueId
virtual status_t getUniqueId(uint64_t* outId) const override;
+ // See IGraphicBufferProducer::getConsumerUsage
+ virtual status_t getConsumerUsage(uint64_t* outUsage) const override;
+
private:
// This is required by the IBinder::DeathRecipient interface
virtual void binderDied(const wp<IBinder>& who);
diff --git a/libs/gui/include/gui/GLConsumer.h b/libs/gui/include/gui/GLConsumer.h
index 2cf6162..75f2cca 100644
--- a/libs/gui/include/gui/GLConsumer.h
+++ b/libs/gui/include/gui/GLConsumer.h
@@ -210,7 +210,7 @@
// so the refactoring can proceed smoothly
status_t setDefaultBufferFormat(PixelFormat defaultFormat);
status_t setDefaultBufferDataSpace(android_dataspace defaultDataSpace);
- status_t setConsumerUsageBits(uint32_t usage);
+ status_t setConsumerUsageBits(uint64_t usage);
status_t setTransformHint(uint32_t hint);
status_t setMaxAcquiredBufferCount(int maxAcquiredBuffers);
@@ -386,7 +386,7 @@
// BufferQueue instance; these will be OR:d with any additional flags passed
// from the GLConsumer user. In particular, GLConsumer will always
// consume buffers as hardware textures.
- static const uint32_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE;
+ static const uint64_t DEFAULT_USAGE_FLAGS = GraphicBuffer::USAGE_HW_TEXTURE;
// mCurrentTextureImage is the EglImage/buffer of the current texture. It's
// possible that this buffer is not associated with any buffer slot, so we
diff --git a/libs/gui/include/gui/IGraphicBufferProducer.h b/libs/gui/include/gui/IGraphicBufferProducer.h
index f231f95..039dc0d 100644
--- a/libs/gui/include/gui/IGraphicBufferProducer.h
+++ b/libs/gui/include/gui/IGraphicBufferProducer.h
@@ -593,6 +593,12 @@
// Returns a unique id for this BufferQueue
virtual status_t getUniqueId(uint64_t* outId) const = 0;
+
+ // Returns the consumer usage flags for this BufferQueue. This returns the
+ // full 64-bit usage flags, rather than the truncated 32-bit usage flags
+ // returned by querying the now deprecated
+ // NATIVE_WINDOW_CONSUMER_USAGE_BITS attribute.
+ virtual status_t getConsumerUsage(uint64_t* outUsage) const = 0;
};
// ----------------------------------------------------------------------------
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 60eac0c..55dd6bf 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -159,6 +159,7 @@
status_t getHdrSupport(bool* supported);
status_t getUniqueId(uint64_t* outId) const;
+ status_t getConsumerUsage(uint64_t* outUsage) const;
// Returns the CLOCK_MONOTONIC start time of the last dequeueBuffer call
nsecs_t getLastDequeueStartTime() const;
@@ -223,6 +224,7 @@
int dispatchGetFrameTimestamps(va_list args);
int dispatchGetWideColorSupport(va_list args);
int dispatchGetHdrSupport(va_list args);
+ int dispatchGetConsumerUsage64(va_list args);
protected:
virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
diff --git a/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h b/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
index c1c3ae7..74850b4 100644
--- a/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
+++ b/libs/gui/include/gui/bufferqueue/1.0/H2BGraphicBufferProducer.h
@@ -94,6 +94,7 @@
sp<Fence>* outFence, float outTransformMatrix[16]) override;
void getFrameTimestamps(FrameEventHistoryDelta* outDelta) override;
status_t getUniqueId(uint64_t* outId) const override;
+ status_t getConsumerUsage(uint64_t* outUsage) const override;
};
} // namespace utils
diff --git a/libs/gui/tests/Malicious.cpp b/libs/gui/tests/Malicious.cpp
index 2b9fd5d..bb6b8a5 100644
--- a/libs/gui/tests/Malicious.cpp
+++ b/libs/gui/tests/Malicious.cpp
@@ -92,6 +92,9 @@
}
void getFrameTimestamps(FrameEventHistoryDelta*) override {}
status_t getUniqueId(uint64_t* outId) const override { return mProducer->getUniqueId(outId); }
+ status_t getConsumerUsage(uint64_t* outUsage) const override {
+ return mProducer->getConsumerUsage(outUsage);
+ }
protected:
sp<IGraphicBufferProducer> mProducer;
diff --git a/libs/nativewindow/include/system/window.h b/libs/nativewindow/include/system/window.h
index 3df97a1..6490804 100644
--- a/libs/nativewindow/include/system/window.h
+++ b/libs/nativewindow/include/system/window.h
@@ -115,7 +115,7 @@
* The consumer gralloc usage bits currently set by the consumer.
* The values are defined in hardware/libhardware/include/gralloc.h.
*/
- NATIVE_WINDOW_CONSUMER_USAGE_BITS = 10,
+ NATIVE_WINDOW_CONSUMER_USAGE_BITS = 10, /* deprecated */
/**
* Transformation that will by applied to buffers by the hwcomposer.
@@ -224,6 +224,7 @@
NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT = 28,
NATIVE_WINDOW_GET_HDR_SUPPORT = 29,
NATIVE_WINDOW_SET_USAGE64 = 30,
+ NATIVE_WINDOW_GET_CONSUMER_USAGE64 = 31,
// clang-format on
};
@@ -900,13 +901,18 @@
static inline int native_window_get_wide_color_support(
struct ANativeWindow* window, bool* outSupport) {
- return window->perform(window, NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT,
- outSupport);
+ return window->perform(window, NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT,
+ outSupport);
}
static inline int native_window_get_hdr_support(struct ANativeWindow* window,
bool* outSupport) {
- return window->perform(window, NATIVE_WINDOW_GET_HDR_SUPPORT, outSupport);
+ return window->perform(window, NATIVE_WINDOW_GET_HDR_SUPPORT, outSupport);
+}
+
+static inline int native_window_get_consumer_usage(struct ANativeWindow* window,
+ uint64_t* outUsage) {
+ return window->perform(window, NATIVE_WINDOW_GET_CONSUMER_USAGE64, outUsage);
}
__END_DECLS
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
index 6613add..0b8479a 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
@@ -608,6 +608,14 @@
return NO_ERROR;
}
+status_t BufferHubQueueProducer::getConsumerUsage(uint64_t* out_usage) const {
+ ALOGD_IF(TRACE, __FUNCTION__);
+
+ // same value as returned by querying NATIVE_WINDOW_CONSUMER_USAGE_BITS
+ *out_usage = 0;
+ return NO_ERROR;
+}
+
status_t BufferHubQueueProducer::AllocateBuffer(uint32_t width, uint32_t height,
uint32_t layer_count,
PixelFormat format,
diff --git a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h
index d33a831..f4bb4ab 100644
--- a/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h
+++ b/libs/vr/libbufferhubqueue/include/private/dvr/buffer_hub_queue_producer.h
@@ -112,6 +112,9 @@
// See |IGraphicBufferProducer::getUniqueId|
status_t getUniqueId(uint64_t* out_id) const override;
+ // See |IGraphicBufferProducer::getConsumerUsage|
+ status_t getConsumerUsage(uint64_t* out_usage) const override;
+
private:
using LocalHandle = pdx::LocalHandle;
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
index 34f1cec..1de5e48 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.cpp
@@ -627,6 +627,10 @@
return INVALID_OPERATION;
}
+status_t VirtualDisplaySurface::getConsumerUsage(uint64_t* outUsage) const {
+ return mSource[SOURCE_SINK]->getConsumerUsage(outUsage);
+}
+
void VirtualDisplaySurface::updateQueueBufferOutput(
QueueBufferOutput&& qbo) {
mQueueBufferOutput = std::move(qbo);
diff --git a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
index ac200ca..1671aba 100644
--- a/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
+++ b/services/surfaceflinger/DisplayHardware/VirtualDisplaySurface.h
@@ -130,6 +130,7 @@
virtual status_t getLastQueuedBuffer(sp<GraphicBuffer>* outBuffer,
sp<Fence>* outFence, float outTransformMatrix[16]) override;
virtual status_t getUniqueId(uint64_t* outId) const override;
+ virtual status_t getConsumerUsage(uint64_t* outUsage) const override;
//
// Utility methods
diff --git a/services/surfaceflinger/MonitoredProducer.cpp b/services/surfaceflinger/MonitoredProducer.cpp
index d103820..1a5a85e 100644
--- a/services/surfaceflinger/MonitoredProducer.cpp
+++ b/services/surfaceflinger/MonitoredProducer.cpp
@@ -158,6 +158,10 @@
return mProducer->getUniqueId(outId);
}
+status_t MonitoredProducer::getConsumerUsage(uint64_t* outUsage) const {
+ return mProducer->getConsumerUsage(outUsage);
+}
+
IBinder* MonitoredProducer::onAsBinder() {
return this;
}
diff --git a/services/surfaceflinger/MonitoredProducer.h b/services/surfaceflinger/MonitoredProducer.h
index ff7f0f0..1246d14 100644
--- a/services/surfaceflinger/MonitoredProducer.h
+++ b/services/surfaceflinger/MonitoredProducer.h
@@ -68,6 +68,7 @@
virtual status_t setAutoRefresh(bool autoRefresh) override;
virtual void getFrameTimestamps(FrameEventHistoryDelta *outDelta) override;
virtual status_t getUniqueId(uint64_t* outId) const override;
+ virtual status_t getConsumerUsage(uint64_t* outUsage) const override;
// The Layer which created this producer, and on which queued Buffer's will be displayed.
sp<Layer> getLayer() const;