Create GraphicBuffer backed by BufferHubBuffer
The newly created GraphicBuffer shall own the BufferHubBuffer object
through out its life cycle.
Bug: 70912269
Bug: 111976433
Test: GraphicBuffer_test
Change-Id: I698573e26f85dd40d30c267aeea545e65a7e2a8b
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 0a0c8ca..f770975 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -109,6 +109,7 @@
// bufferhub is not used when building libgui for vendors
target: {
vendor: {
+ cflags: ["-DLIBUI_IN_VNDK"],
exclude_srcs: [
"BufferHubBuffer.cpp",
"BufferHubMetadata.cpp",
@@ -116,6 +117,7 @@
exclude_header_libs: [
"libbufferhub_headers",
"libdvr_headers",
+ "libnativewindow_headers",
],
exclude_shared_libs: [
"libpdx_default_transport",
@@ -128,6 +130,7 @@
"libbufferhub_headers",
"libdvr_headers",
"libnativebase_headers",
+ "libnativewindow_headers",
"libhardware_headers",
"libui_headers",
"libpdx_headers",
@@ -155,6 +158,7 @@
vendor_available: true,
target: {
vendor: {
+ cflags: ["-DLIBUI_IN_VNDK"],
override_export_include_dirs: ["include_vndk"],
},
},
diff --git a/libs/ui/BufferHubBuffer.cpp b/libs/ui/BufferHubBuffer.cpp
index dd79775..e747ee1 100644
--- a/libs/ui/BufferHubBuffer.cpp
+++ b/libs/ui/BufferHubBuffer.cpp
@@ -160,6 +160,16 @@
// GraphicBuffer instance can be created in future.
mBufferHandle = bufferTraits.take_buffer_handle();
+ // Populate buffer desc based on buffer traits.
+ mBufferDesc.width = bufferTraits.width();
+ mBufferDesc.height = bufferTraits.height();
+ mBufferDesc.layers = bufferTraits.layer_count();
+ mBufferDesc.format = bufferTraits.format();
+ mBufferDesc.usage = bufferTraits.usage();
+ mBufferDesc.stride = bufferTraits.stride();
+ mBufferDesc.rfu0 = 0U;
+ mBufferDesc.rfu1 = 0U;
+
// If all imports succeed, replace the previous buffer and id.
mId = bufferId;
mClientStateMask = bufferTraits.client_state_mask();
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 29deb01..e606e26 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -22,6 +22,10 @@
#include <grallocusage/GrallocUsageConversion.h>
+#ifndef LIBUI_IN_VNDK
+#include <ui/BufferHubBuffer.h>
+#endif // LIBUI_IN_VNDK
+
#include <ui/Gralloc2.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/GraphicBufferMapper.h>
@@ -89,6 +93,21 @@
inUsage, inStride);
}
+#ifndef LIBUI_IN_VNDK
+GraphicBuffer::GraphicBuffer(std::unique_ptr<BufferHubBuffer> buffer) : GraphicBuffer() {
+ if (buffer == nullptr) {
+ mInitCheck = BAD_VALUE;
+ return;
+ }
+
+ mInitCheck = initWithHandle(buffer->DuplicateHandle(), /*method=*/TAKE_UNREGISTERED_HANDLE,
+ buffer->desc().width, buffer->desc().height,
+ static_cast<PixelFormat>(buffer->desc().format),
+ buffer->desc().layers, buffer->desc().usage, buffer->desc().stride);
+ mBufferHubBuffer = std::move(buffer);
+}
+#endif // LIBUI_IN_VNDK
+
GraphicBuffer::~GraphicBuffer()
{
if (handle) {
@@ -483,6 +502,12 @@
return NO_ERROR;
}
+#ifndef LIBUI_IN_VNDK
+bool GraphicBuffer::isBufferHubBuffer() const {
+ return mBufferHubBuffer != nullptr;
+}
+#endif // LIBUI_IN_VNDK
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/libs/ui/include/ui/BufferHubBuffer.h b/libs/ui/include/ui/BufferHubBuffer.h
index daf6192..6850b43 100644
--- a/libs/ui/include/ui/BufferHubBuffer.h
+++ b/libs/ui/include/ui/BufferHubBuffer.h
@@ -38,6 +38,7 @@
#include <private/dvr/native_handle_wrapper.h>
#pragma clang diagnostic pop
+#include <android/hardware_buffer.h>
#include <ui/BufferHubMetadata.h>
namespace android {
@@ -62,9 +63,9 @@
// Allocates a standalone BufferHubBuffer not associated with any producer consumer set.
static std::unique_ptr<BufferHubBuffer> Create(uint32_t width, uint32_t height,
uint32_t layerCount, uint32_t format,
- uint64_t usage, size_t mUserMetadataSize) {
+ uint64_t usage, size_t userMetadataSize) {
return std::unique_ptr<BufferHubBuffer>(
- new BufferHubBuffer(width, height, layerCount, format, usage, mUserMetadataSize));
+ new BufferHubBuffer(width, height, layerCount, format, usage, userMetadataSize));
}
// Imports the given channel handle to a BufferHubBuffer, taking ownership.
@@ -79,6 +80,9 @@
// bufferhubd share the same buffer id.
int id() const { return mId; }
+ // Returns the buffer description, which is guaranteed to be faithful values from bufferhubd.
+ const AHardwareBuffer_Desc& desc() const { return mBufferDesc; }
+
const native_handle_t* DuplicateHandle() { return mBufferHandle.DuplicateHandle(); }
// Returns the current value of MetadataHeader::buffer_state.
@@ -118,7 +122,7 @@
private:
BufferHubBuffer(uint32_t width, uint32_t height, uint32_t layerCount, uint32_t format,
- uint64_t usage, size_t mUserMetadataSize);
+ uint64_t usage, size_t userMetadataSize);
BufferHubBuffer(pdx::LocalChannelHandle mChannelHandle);
@@ -128,6 +132,9 @@
int mId = -1;
uint64_t mClientStateMask = 0;
+ // Stores ground truth of the buffer.
+ AHardwareBuffer_Desc mBufferDesc;
+
// Wrapps the gralloc buffer handle of this buffer.
dvr::NativeHandleWrapper<pdx::LocalHandle> mBufferHandle;
diff --git a/libs/ui/include/ui/GraphicBuffer.h b/libs/ui/include/ui/GraphicBuffer.h
index fe6229a..81f6cd9 100644
--- a/libs/ui/include/ui/GraphicBuffer.h
+++ b/libs/ui/include/ui/GraphicBuffer.h
@@ -34,6 +34,10 @@
namespace android {
+#ifndef LIBUI_IN_VNDK
+class BufferHubBuffer;
+#endif // LIBUI_IN_VNDK
+
class GraphicBufferMapper;
// ===========================================================================
@@ -133,6 +137,11 @@
GraphicBuffer(uint32_t inWidth, uint32_t inHeight, PixelFormat inFormat,
uint32_t inUsage, std::string requestorName = "<Unknown>");
+#ifndef LIBUI_IN_VNDK
+ // Create a GraphicBuffer from an existing BufferHubBuffer.
+ GraphicBuffer(std::unique_ptr<BufferHubBuffer> buffer);
+#endif // LIBUI_IN_VNDK
+
// return status
status_t initCheck() const;
@@ -188,6 +197,11 @@
status_t flatten(void*& buffer, size_t& size, int*& fds, size_t& count) const;
status_t unflatten(void const*& buffer, size_t& size, int const*& fds, size_t& count);
+#ifndef LIBUI_IN_VNDK
+ // Returns whether this GraphicBuffer is backed by BufferHubBuffer.
+ bool isBufferHubBuffer() const;
+#endif // LIBUI_IN_VNDK
+
private:
~GraphicBuffer();
@@ -237,6 +251,11 @@
// match the BufferQueue's internal generation number (set through
// IGBP::setGenerationNumber), attempts to attach the buffer will fail.
uint32_t mGenerationNumber;
+
+#ifndef LIBUI_IN_VNDK
+ // Stores a BufferHubBuffer that handles buffer signaling, identification.
+ std::unique_ptr<BufferHubBuffer> mBufferHubBuffer;
+#endif // LIBUI_IN_VNDK
};
}; // namespace android
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index 4c9c176..b7ad4e5 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -29,6 +29,22 @@
}
cc_test {
+ name: "GraphicBuffer_test",
+ header_libs: [
+ "libbufferhub_headers",
+ "libdvr_headers",
+ "libnativewindow_headers",
+ ],
+ shared_libs: [
+ "libpdx_default_transport",
+ "libui",
+ "libutils",
+ ],
+ srcs: ["GraphicBuffer_test.cpp"],
+ cflags: ["-Wall", "-Werror"],
+}
+
+cc_test {
name: "BufferHubBuffer_test",
header_libs: [
"libbufferhub_headers",
diff --git a/libs/ui/tests/GraphicBuffer_test.cpp b/libs/ui/tests/GraphicBuffer_test.cpp
new file mode 100644
index 0000000..95ca2c1
--- /dev/null
+++ b/libs/ui/tests/GraphicBuffer_test.cpp
@@ -0,0 +1,54 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "GraphicBufferTest"
+
+#include <ui/BufferHubBuffer.h>
+#include <ui/GraphicBuffer.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+namespace {
+
+constexpr uint32_t kTestWidth = 1024;
+constexpr uint32_t kTestHeight = 1;
+constexpr uint32_t kTestFormat = HAL_PIXEL_FORMAT_BLOB;
+constexpr uint32_t kTestLayerCount = 1;
+constexpr uint64_t kTestUsage = GraphicBuffer::USAGE_SW_WRITE_OFTEN;
+
+} // namespace
+
+class GraphicBufferTest : public testing::Test {};
+
+TEST_F(GraphicBufferTest, CreateFromBufferHubBuffer) {
+ std::unique_ptr<BufferHubBuffer> b1 =
+ BufferHubBuffer::Create(kTestWidth, kTestHeight, kTestLayerCount, kTestFormat,
+ kTestUsage, /*userMetadataSize=*/0);
+ EXPECT_TRUE(b1->IsValid());
+
+ sp<GraphicBuffer> gb(new GraphicBuffer(std::move(b1)));
+ EXPECT_TRUE(gb->isBufferHubBuffer());
+
+ EXPECT_EQ(gb->getWidth(), kTestWidth);
+ EXPECT_EQ(gb->getHeight(), kTestHeight);
+ EXPECT_EQ(static_cast<uint32_t>(gb->getPixelFormat()), kTestFormat);
+ EXPECT_EQ(gb->getUsage(), kTestUsage);
+ EXPECT_EQ(gb->getLayerCount(), kTestLayerCount);
+}
+
+} // namespace android