Merge changes from topic 'presentFenceNotReliable' into oc-dev
* changes:
egl: Use reserved values for eglGetFrameTimestamps
egl: Differentiate pending vs invalid timestamps.
egl: Avoid use of retire as present
diff --git a/cmds/installd/Android.mk b/cmds/installd/Android.mk
index be1a434..1d21b3c 100644
--- a/cmds/installd/Android.mk
+++ b/cmds/installd/Android.mk
@@ -24,6 +24,7 @@
LOCAL_CFLAGS += -DART_BASE_ADDRESS_MAX_DELTA=$(LOCAL_LIBART_IMG_HOST_MAX_BASE_ADDRESS_DELTA)
LOCAL_SRC_FILES := otapreopt.cpp globals.cpp utils.cpp dexopt.cpp
+LOCAL_HEADER_LIBRARIES := dex2oat_headers
LOCAL_SHARED_LIBRARIES := \
libbase \
libcutils \
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 82b8cc2..e8e6b56 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -33,6 +33,7 @@
#include <android-base/strings.h>
#include <cutils/fs.h>
#include <cutils/properties.h>
+#include <dex2oat_return_codes.h>
#include <log/log.h>
#include <private/android_filesystem_config.h>
@@ -576,7 +577,11 @@
}
// If the dexopt failed, we may have a stale boot image from a previous OTA run.
- // Try to delete and retry.
+ // Then regenerate and retry.
+ if (WEXITSTATUS(dexopt_result) !=
+ static_cast<int>(art::dex2oat::ReturnCode::kCreateRuntime)) {
+ return dexopt_result;
+ }
if (!PrepareBootImage(/* force */ true)) {
LOG(ERROR) << "Forced boot image creating failed. Original error return was "
diff --git a/cmds/servicemanager/Android.bp b/cmds/servicemanager/Android.bp
index 68d39db..39d92a7 100644
--- a/cmds/servicemanager/Android.bp
+++ b/cmds/servicemanager/Android.bp
@@ -38,7 +38,7 @@
cc_binary {
name: "vndservicemanager",
defaults: ["servicemanager_flags"],
- proprietary: true,
+ vendor: true,
srcs: [
"service_manager.c",
"binder.c",
@@ -46,6 +46,7 @@
cflags: [
"-DVENDORSERVICEMANAGER=1",
],
- shared_libs: ["libcutils", "libselinux"],
+ shared_libs: ["libcutils"],
+ static_libs: ["libselinux"],
init_rc: ["vndservicemanager.rc"],
}
diff --git a/cmds/vr/vrscreencap/Android.mk b/cmds/vr/vrscreencap/Android.mk
index bd0b224..804afc9 100644
--- a/cmds/vr/vrscreencap/Android.mk
+++ b/cmds/vr/vrscreencap/Android.mk
@@ -6,6 +6,7 @@
vrscreencap.cpp
LOCAL_STATIC_LIBRARIES := \
+ libbufferhub \
libdisplay \
libimageio \
libpdx_default_transport \
@@ -14,7 +15,8 @@
libcutils \
liblog \
libpng \
- libsync
+ libsync \
+ libui \
LOCAL_MODULE := vrscreencap
diff --git a/data/etc/android.software.cts.xml b/data/etc/android.software.cts.xml
new file mode 100644
index 0000000..0414c9a
--- /dev/null
+++ b/data/etc/android.software.cts.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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.
+-->
+
+<permissions>
+ <!-- This is Android and fully CTS compatible. Basically this is for CTS tests to use. -->
+ <feature name="android.software.cts" />
+</permissions>
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index cf2fa47..5d36526 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -72,6 +72,8 @@
status_t appendFrom(const Parcel *parcel,
size_t start, size_t len);
+ int compareData(const Parcel& other);
+
bool allowFds() const;
bool pushAllowFds(bool allowFds);
void restoreAllowFds(bool lastValue);
diff --git a/include/binder/ProcessState.h b/include/binder/ProcessState.h
index 05e9d09..1ef045d 100644
--- a/include/binder/ProcessState.h
+++ b/include/binder/ProcessState.h
@@ -69,6 +69,8 @@
status_t setThreadPoolMaxThreadCount(size_t maxThreads);
void giveThreadPoolName();
+ String8 getDriverName();
+
private:
friend class IPCThreadState;
@@ -86,6 +88,7 @@
handle_entry* lookupHandleLocked(int32_t handle);
+ String8 mDriverName;
int mDriverFD;
void* mVMStart;
diff --git a/include/ui/Gralloc2.h b/include/ui/Gralloc2.h
new file mode 100644
index 0000000..c59d327
--- /dev/null
+++ b/include/ui/Gralloc2.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2016 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.
+ */
+
+#ifndef ANDROID_UI_GRALLOC2_H
+#define ANDROID_UI_GRALLOC2_H
+
+#include <string>
+
+#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
+#include <android/hardware/graphics/mapper/2.0/IMapper.h>
+#include <system/window.h>
+#include <utils/StrongPointer.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+using hardware::graphics::allocator::V2_0::IAllocator;
+using hardware::graphics::common::V1_0::BufferUsage;
+using hardware::graphics::common::V1_0::PixelFormat;
+using hardware::graphics::mapper::V2_0::BufferDescriptor;
+using hardware::graphics::mapper::V2_0::Error;
+using hardware::graphics::mapper::V2_0::IMapper;
+using hardware::graphics::mapper::V2_0::YCbCrLayout;
+
+// A wrapper to IMapper
+class Mapper {
+public:
+ Mapper();
+
+ // this will be removed and Mapper will be always valid
+ bool valid() const { return (mMapper != nullptr); }
+
+ Error createDescriptor(
+ const IMapper::BufferDescriptorInfo& descriptorInfo,
+ BufferDescriptor* outDescriptor) const;
+
+ // Import a buffer that is from another HAL, another process, or is
+ // cloned.
+ //
+ // The returned handle must be freed with freeBuffer.
+ Error importBuffer(const hardware::hidl_handle& rawHandle,
+ buffer_handle_t* outBufferHandle) const;
+
+ void freeBuffer(buffer_handle_t bufferHandle) const;
+
+ // The ownership of acquireFence is always transferred to the callee, even
+ // on errors.
+ Error lock(buffer_handle_t bufferHandle, uint64_t usage,
+ const IMapper::Rect& accessRegion,
+ int acquireFence, void** outData) const;
+
+ // The ownership of acquireFence is always transferred to the callee, even
+ // on errors.
+ Error lock(buffer_handle_t bufferHandle, uint64_t usage,
+ const IMapper::Rect& accessRegion,
+ int acquireFence, YCbCrLayout* outLayout) const;
+
+ // unlock returns a fence sync object (or -1) and the fence sync object is
+ // owned by the caller
+ int unlock(buffer_handle_t bufferHandle) const;
+
+private:
+ sp<IMapper> mMapper;
+};
+
+// A wrapper to IAllocator
+class Allocator {
+public:
+ // An allocator relies on a mapper, and that mapper must be alive at all
+ // time.
+ Allocator(const Mapper& mapper);
+
+ // this will be removed and Allocator will be always valid
+ bool valid() const { return (mAllocator != nullptr); }
+
+ std::string dumpDebugInfo() const;
+
+ /*
+ * The returned buffers are already imported and must not be imported
+ * again. outBufferHandles must point to a space that can contain at
+ * least "count" buffer_handle_t.
+ */
+ Error allocate(BufferDescriptor descriptor, uint32_t count,
+ uint32_t* outStride, buffer_handle_t* outBufferHandles) const;
+
+ Error allocate(BufferDescriptor descriptor,
+ uint32_t* outStride, buffer_handle_t* outBufferHandle) const
+ {
+ return allocate(descriptor, 1, outStride, outBufferHandle);
+ }
+
+ Error allocate(const IMapper::BufferDescriptorInfo& descriptorInfo, uint32_t count,
+ uint32_t* outStride, buffer_handle_t* outBufferHandles) const
+ {
+ BufferDescriptor descriptor;
+ Error error = mMapper.createDescriptor(descriptorInfo, &descriptor);
+ if (error == Error::NONE) {
+ error = allocate(descriptor, count, outStride, outBufferHandles);
+ }
+ return error;
+ }
+
+ Error allocate(const IMapper::BufferDescriptorInfo& descriptorInfo,
+ uint32_t* outStride, buffer_handle_t* outBufferHandle) const
+ {
+ return allocate(descriptorInfo, 1, outStride, outBufferHandle);
+ }
+
+private:
+ const Mapper& mMapper;
+ sp<IAllocator> mAllocator;
+};
+
+} // namespace Gralloc2
+
+} // namespace android
+
+#endif // ANDROID_UI_GRALLOC2_H
diff --git a/include/ui/GrallocAllocator.h b/include/ui/GrallocAllocator.h
deleted file mode 100644
index dd0f9e0..0000000
--- a/include/ui/GrallocAllocator.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2016 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.
- */
-
-#ifndef ANDROID_UI_GRALLOC_ALLOCATOR_H
-#define ANDROID_UI_GRALLOC_ALLOCATOR_H
-
-#include <string>
-
-#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
-#include <utils/StrongPointer.h>
-
-namespace android {
-
-namespace Gralloc2 {
-
-using hardware::graphics::allocator::V2_0::Error;
-using hardware::graphics::allocator::V2_0::ProducerUsage;
-using hardware::graphics::allocator::V2_0::ConsumerUsage;
-using hardware::graphics::allocator::V2_0::BufferDescriptor;
-using hardware::graphics::allocator::V2_0::Buffer;
-using hardware::graphics::allocator::V2_0::IAllocator;
-using hardware::graphics::allocator::V2_0::IAllocatorClient;
-using hardware::graphics::common::V1_0::PixelFormat;
-
-// Allocator is a wrapper to IAllocator, a proxy to server-side allocator.
-class Allocator {
-public:
- Allocator();
-
- // this will be removed and Allocator will be always valid
- bool valid() const { return (mAllocator != nullptr); }
-
- std::string dumpDebugInfo() const;
-
- Error createBufferDescriptor(
- const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
- BufferDescriptor* outDescriptor) const;
- void destroyBufferDescriptor(BufferDescriptor descriptor) const;
-
- Error allocate(BufferDescriptor descriptor, Buffer* outBuffer) const;
- void free(Buffer buffer) const;
-
- Error exportHandle(BufferDescriptor descriptor, Buffer buffer,
- native_handle_t** outBufferHandle) const;
-
-private:
- sp<IAllocator> mAllocator;
- sp<IAllocatorClient> mClient;
-};
-
-} // namespace Gralloc2
-
-} // namespace android
-
-#endif // ANDROID_UI_GRALLOC_ALLOCATOR_H
diff --git a/include/ui/GrallocMapper.h b/include/ui/GrallocMapper.h
deleted file mode 100644
index 5a0d64b..0000000
--- a/include/ui/GrallocMapper.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright 2016 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.
- */
-
-#ifndef ANDROID_UI_GRALLOC_MAPPER_H
-#define ANDROID_UI_GRALLOC_MAPPER_H
-
-#include <android/hardware/graphics/mapper/2.0/IMapper.h>
-#include <system/window.h>
-
-namespace android {
-
-namespace Gralloc2 {
-
-using hardware::graphics::allocator::V2_0::Error;
-using hardware::graphics::allocator::V2_0::ProducerUsage;
-using hardware::graphics::allocator::V2_0::ConsumerUsage;
-using hardware::graphics::common::V1_0::PixelFormat;
-using hardware::graphics::mapper::V2_0::FlexLayout;
-using hardware::graphics::mapper::V2_0::BackingStore;
-using hardware::graphics::mapper::V2_0::IMapper;
-
-// Mapper is a wrapper to IMapper, a client-side graphics buffer mapper.
-class Mapper {
-public:
- Mapper();
-
- // this will be removed and Mapper will be always valid
- bool valid() const { return (mMapper != nullptr); }
-
- Error retain(buffer_handle_t handle) const;
- void release(buffer_handle_t handle) const;
-
- Error getDimensions(buffer_handle_t handle,
- uint32_t* outWidth, uint32_t* outHeight) const;
- Error getFormat(buffer_handle_t handle, int32_t* outFormat) const;
- Error getLayerCount(buffer_handle_t handle, uint32_t* outLayerCount) const;
- Error getProducerUsage(buffer_handle_t handle,
- uint64_t* outProducerUsage) const;
- Error getConsumerUsage(buffer_handle_t handle,
- uint64_t* outConsumerUsage) const;
- Error getBackingStore(buffer_handle_t handle,
- uint64_t* outBackingStore) const;
- Error getStride(buffer_handle_t handle, uint32_t* outStride) const;
-
- Error lock(buffer_handle_t handle, uint64_t producerUsage,
- uint64_t consumerUsage, const IMapper::Rect& accessRegion,
- int acquireFence, void** outData) const;
- Error lock(buffer_handle_t handle, uint64_t producerUsage,
- uint64_t consumerUsage, const IMapper::Rect& accessRegion,
- int acquireFence, FlexLayout* outLayout) const;
- int unlock(buffer_handle_t handle) const;
-
-private:
- sp<IMapper> mMapper;
-};
-
-} // namespace Gralloc2
-
-} // namespace android
-
-#endif // ANDROID_UI_GRALLOC_MAPPER_H
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index e97122b..95eb8fd 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -96,8 +96,8 @@
GraphicBufferAllocator();
~GraphicBufferAllocator();
- const std::unique_ptr<const Gralloc2::Allocator> mAllocator;
GraphicBufferMapper& mMapper;
+ const std::unique_ptr<const Gralloc2::Allocator> mAllocator;
std::unique_ptr<Gralloc1::Loader> mLoader;
std::unique_ptr<Gralloc1::Device> mDevice;
diff --git a/include/ui/GraphicBufferMapper.h b/include/ui/GraphicBufferMapper.h
index b6d4021..d69f8fc 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -47,31 +47,15 @@
public:
static inline GraphicBufferMapper& get() { return getInstance(); }
- // This may NOT work on devices without a valid Gralloc2::Mapper.
- status_t registerBuffer(buffer_handle_t handle);
+ // The imported outHandle must be freed with freeBuffer when no longer
+ // needed. rawHandle is owned by the caller.
+ status_t importBuffer(buffer_handle_t rawHandle,
+ buffer_handle_t* outHandle);
- status_t registerBuffer(const GraphicBuffer* buffer);
+ // This is temporary and will be removed soon
+ status_t importBuffer(const GraphicBuffer* buffer);
- status_t unregisterBuffer(buffer_handle_t handle);
-
- status_t getDimensions(buffer_handle_t handle,
- uint32_t* outWidth, uint32_t* outHeight) const;
-
- status_t getFormat(buffer_handle_t handle, int32_t* outFormat) const;
-
- status_t getLayerCount(buffer_handle_t handle,
- uint32_t* outLayerCount) const;
-
- status_t getProducerUsage(buffer_handle_t handle,
- uint64_t* outProducerUsage) const;
-
- status_t getConsumerUsage(buffer_handle_t handle,
- uint64_t* outConsumerUsage) const;
-
- status_t getBackingStore(buffer_handle_t handle,
- uint64_t* outBackingStore) const;
-
- status_t getStride(buffer_handle_t handle, uint32_t* outStride) const;
+ status_t freeBuffer(buffer_handle_t handle);
status_t lock(buffer_handle_t handle,
uint32_t usage, const Rect& bounds, void** vaddr);
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 3aeff2e..c7a0f43 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -23,6 +23,7 @@
#include <binder/Parcel.h>
#include <utils/String8.h>
#include <utils/SystemClock.h>
+#include <utils/CallStack.h>
#include <private/binder/Static.h>
@@ -136,7 +137,12 @@
unsigned n;
for (n = 0; n < 5; n++){
if (n > 0) {
- ALOGI("Waiting for service %s...", String8(name).string());
+ if (!strcmp(ProcessState::self()->getDriverName().c_str(), "/dev/vndbinder")) {
+ ALOGI("Waiting for vendor service %s...", String8(name).string());
+ CallStack stack(LOG_TAG);
+ } else {
+ ALOGI("Waiting for service %s...", String8(name).string());
+ }
sleep(1);
}
sp<IBinder> svc = checkService(name);
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index da94305..39bb078 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -553,6 +553,14 @@
return err;
}
+int Parcel::compareData(const Parcel& other) {
+ size_t size = dataSize();
+ if (size != other.dataSize()) {
+ return size < other.dataSize() ? -1 : 1;
+ }
+ return memcmp(data(), other.data(), size);
+}
+
bool Parcel::allowFds() const
{
return mAllowFds;
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 5c4cfe2..9ccf07c 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -317,6 +317,10 @@
androidSetThreadName( makeBinderThreadName().string() );
}
+String8 ProcessState::getDriverName() {
+ return mDriverName;
+}
+
static int open_driver(const char *driver)
{
int fd = open(driver, O_RDWR | O_CLOEXEC);
@@ -346,7 +350,8 @@
}
ProcessState::ProcessState(const char *driver)
- : mDriverFD(open_driver(driver))
+ : mDriverName(String8(driver))
+ , mDriverFD(open_driver(driver))
, mVMStart(MAP_FAILED)
, mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
, mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
@@ -367,6 +372,7 @@
ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
close(mDriverFD);
mDriverFD = -1;
+ mDriverName.clear();
}
}
diff --git a/libs/nativewindow/Android.bp b/libs/nativewindow/Android.bp
index 90fb4b6..6c8221d 100644
--- a/libs/nativewindow/Android.bp
+++ b/libs/nativewindow/Android.bp
@@ -21,7 +21,7 @@
}
ndk_library {
- name: "libnativewindow.ndk",
+ name: "libnativewindow",
symbol_file: "libnativewindow.map.txt",
// Android O
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 310d25e..ba37391 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -51,8 +51,7 @@
"FrameStats.cpp",
"Gralloc1.cpp",
"Gralloc1On0Adapter.cpp",
- "GrallocAllocator.cpp",
- "GrallocMapper.cpp",
+ "Gralloc2.cpp",
"GraphicBuffer.cpp",
"GraphicBufferAllocator.cpp",
"GraphicBufferMapper.cpp",
diff --git a/libs/ui/Gralloc1On0Adapter.cpp b/libs/ui/Gralloc1On0Adapter.cpp
index bd7c6a1..9ee9838 100644
--- a/libs/ui/Gralloc1On0Adapter.cpp
+++ b/libs/ui/Gralloc1On0Adapter.cpp
@@ -20,6 +20,9 @@
#include <ui/Gralloc1On0Adapter.h>
+#include <algorithm>
+#include <array>
+
#include <grallocusage/GrallocUsageConversion.h>
#include <hardware/gralloc.h>
@@ -67,13 +70,18 @@
void Gralloc1On0Adapter::doGetCapabilities(uint32_t* outCount,
int32_t* outCapabilities)
{
+ constexpr std::array<int32_t, 2> supportedCapabilities = {{
+ GRALLOC1_CAPABILITY_ON_ADAPTER,
+ GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE,
+ }};
+
if (outCapabilities == nullptr) {
- *outCount = 1;
- return;
- }
- if (*outCount >= 1) {
- *outCapabilities = GRALLOC1_CAPABILITY_ON_ADAPTER;
- *outCount = 1;
+ *outCount = supportedCapabilities.size();
+ } else {
+ *outCount = std::min(*outCount, static_cast<uint32_t>(
+ supportedCapabilities.size()));
+ std::copy_n(supportedCapabilities.begin(),
+ *outCount, outCapabilities);
}
}
@@ -325,6 +333,9 @@
if (result != 0) {
ALOGE("gralloc0 unregister failed: %d", result);
}
+
+ native_handle_close(handle);
+ native_handle_delete(const_cast<native_handle_t*>(handle));
}
mBuffers.erase(handle);
diff --git a/libs/ui/Gralloc2.cpp b/libs/ui/Gralloc2.cpp
new file mode 100644
index 0000000..75f5686
--- /dev/null
+++ b/libs/ui/Gralloc2.cpp
@@ -0,0 +1,248 @@
+/*
+ * Copyright 2016 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 "Gralloc2"
+
+#include <ui/Gralloc2.h>
+
+#include <log/log.h>
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wzero-length-array"
+#include <sync/sync.h>
+#pragma clang diagnostic pop
+
+namespace android {
+
+namespace Gralloc2 {
+
+static constexpr Error kTransactionError = Error::NO_RESOURCES;
+
+Mapper::Mapper()
+{
+ mMapper = IMapper::getService();
+ if (mMapper != nullptr && mMapper->isRemote()) {
+ LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
+ }
+}
+
+Error Mapper::createDescriptor(
+ const IMapper::BufferDescriptorInfo& descriptorInfo,
+ BufferDescriptor* outDescriptor) const
+{
+ Error error;
+ auto ret = mMapper->createDescriptor(descriptorInfo,
+ [&](const auto& tmpError, const auto& tmpDescriptor)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outDescriptor = tmpDescriptor;
+ });
+
+ return (ret.isOk()) ? error : kTransactionError;
+}
+
+Error Mapper::importBuffer(const hardware::hidl_handle& rawHandle,
+ buffer_handle_t* outBufferHandle) const
+{
+ Error error;
+ auto ret = mMapper->importBuffer(rawHandle,
+ [&](const auto& tmpError, const auto& tmpBuffer)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outBufferHandle = static_cast<buffer_handle_t>(tmpBuffer);
+ });
+
+ return (ret.isOk()) ? error : kTransactionError;
+}
+
+void Mapper::freeBuffer(buffer_handle_t bufferHandle) const
+{
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+ auto ret = mMapper->freeBuffer(buffer);
+
+ auto error = (ret.isOk()) ? static_cast<Error>(ret) : kTransactionError;
+ ALOGE_IF(error != Error::NONE, "freeBuffer(%p) failed with %d",
+ buffer, error);
+}
+
+Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage,
+ const IMapper::Rect& accessRegion,
+ int acquireFence, void** outData) const
+{
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ // put acquireFence in a hidl_handle
+ hardware::hidl_handle acquireFenceHandle;
+ NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+ if (acquireFence >= 0) {
+ auto h = native_handle_init(acquireFenceStorage, 1, 0);
+ h->data[0] = acquireFence;
+ acquireFenceHandle = h;
+ }
+
+ Error error;
+ auto ret = mMapper->lock(buffer, usage, accessRegion, acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpData)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outData = tmpData;
+ });
+
+ // we own acquireFence even on errors
+ if (acquireFence >= 0) {
+ close(acquireFence);
+ }
+
+ return (ret.isOk()) ? error : kTransactionError;
+}
+
+Error Mapper::lock(buffer_handle_t bufferHandle, uint64_t usage,
+ const IMapper::Rect& accessRegion,
+ int acquireFence, YCbCrLayout* outLayout) const
+{
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ // put acquireFence in a hidl_handle
+ hardware::hidl_handle acquireFenceHandle;
+ NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
+ if (acquireFence >= 0) {
+ auto h = native_handle_init(acquireFenceStorage, 1, 0);
+ h->data[0] = acquireFence;
+ acquireFenceHandle = h;
+ }
+
+ Error error;
+ auto ret = mMapper->lockYCbCr(buffer, usage, accessRegion,
+ acquireFenceHandle,
+ [&](const auto& tmpError, const auto& tmpLayout)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ *outLayout = tmpLayout;
+ });
+
+ // we own acquireFence even on errors
+ if (acquireFence >= 0) {
+ close(acquireFence);
+ }
+
+ return (ret.isOk()) ? error : kTransactionError;
+}
+
+int Mapper::unlock(buffer_handle_t bufferHandle) const
+{
+ auto buffer = const_cast<native_handle_t*>(bufferHandle);
+
+ int releaseFence = -1;
+ Error error;
+ auto ret = mMapper->unlock(buffer,
+ [&](const auto& tmpError, const auto& tmpReleaseFence)
+ {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ auto fenceHandle = tmpReleaseFence.getNativeHandle();
+ if (fenceHandle && fenceHandle->numFds == 1) {
+ int fd = dup(fenceHandle->data[0]);
+ if (fd >= 0) {
+ releaseFence = fd;
+ } else {
+ ALOGD("failed to dup unlock release fence");
+ sync_wait(fenceHandle->data[0], -1);
+ }
+ }
+ });
+
+ if (!ret.isOk()) {
+ error = kTransactionError;
+ }
+
+ if (error != Error::NONE) {
+ ALOGE("unlock(%p) failed with %d", buffer, error);
+ }
+
+ return releaseFence;
+}
+
+Allocator::Allocator(const Mapper& mapper)
+ : mMapper(mapper)
+{
+ if (mMapper.valid()) {
+ mAllocator = IAllocator::getService();
+ }
+}
+
+std::string Allocator::dumpDebugInfo() const
+{
+ std::string debugInfo;
+
+ mAllocator->dumpDebugInfo([&](const auto& tmpDebugInfo) {
+ debugInfo = tmpDebugInfo.c_str();
+ });
+
+ return debugInfo;
+}
+
+Error Allocator::allocate(BufferDescriptor descriptor, uint32_t count,
+ uint32_t* outStride, buffer_handle_t* outBufferHandles) const
+{
+ Error error;
+ auto ret = mAllocator->allocate(descriptor, count,
+ [&](const auto& tmpError, const auto& tmpStride,
+ const auto& tmpBuffers) {
+ error = tmpError;
+ if (tmpError != Error::NONE) {
+ return;
+ }
+
+ // import buffers
+ for (uint32_t i = 0; i < count; i++) {
+ error = mMapper.importBuffer(tmpBuffers[i],
+ &outBufferHandles[i]);
+ if (error != Error::NONE) {
+ for (uint32_t j = 0; j < i; j++) {
+ mMapper.freeBuffer(outBufferHandles[j]);
+ outBufferHandles[j] = nullptr;
+ }
+ return;
+ }
+ }
+
+ *outStride = tmpStride;
+ });
+
+ return (ret.isOk()) ? error : kTransactionError;
+}
+
+} // namespace Gralloc2
+
+} // namespace android
diff --git a/libs/ui/GrallocAllocator.cpp b/libs/ui/GrallocAllocator.cpp
deleted file mode 100644
index 7af55e7..0000000
--- a/libs/ui/GrallocAllocator.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * Copyright 2016 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 "GrallocAllocator"
-
-#include <ui/GrallocAllocator.h>
-
-#include <log/log.h>
-
-namespace android {
-
-namespace Gralloc2 {
-
-// assume NO_RESOURCES when Status::isOk returns false
-constexpr Error kDefaultError = Error::NO_RESOURCES;
-
-Allocator::Allocator()
-{
- mAllocator = IAllocator::getService();
- if (mAllocator != nullptr) {
- mAllocator->createClient(
- [&](const auto& tmpError, const auto& tmpClient) {
- if (tmpError == Error::NONE) {
- mClient = tmpClient;
- }
- });
- if (mClient == nullptr) {
- mAllocator.clear();
- }
- }
-}
-
-std::string Allocator::dumpDebugInfo() const
-{
- std::string info;
-
- mAllocator->dumpDebugInfo([&](const auto& tmpInfo) {
- info = tmpInfo.c_str();
- });
-
- return info;
-}
-
-Error Allocator::createBufferDescriptor(
- const IAllocatorClient::BufferDescriptorInfo& descriptorInfo,
- BufferDescriptor* outDescriptor) const
-{
- Error error = kDefaultError;
- mClient->createDescriptor(descriptorInfo,
- [&](const auto& tmpError, const auto& tmpDescriptor) {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outDescriptor = tmpDescriptor;
- });
-
- return error;
-}
-
-void Allocator::destroyBufferDescriptor(BufferDescriptor descriptor) const
-{
- mClient->destroyDescriptor(descriptor);
-}
-
-Error Allocator::allocate(BufferDescriptor descriptor,
- Buffer* outBuffer) const
-{
- hardware::hidl_vec<BufferDescriptor> descriptors;
- descriptors.setToExternal(&descriptor, 1);
-
- Error error = kDefaultError;
- auto status = mClient->allocate(descriptors,
- [&](const auto& tmpError, const auto& tmpBuffers) {
- error = tmpError;
- if (tmpError != Error::NONE) {
- return;
- }
-
- *outBuffer = tmpBuffers[0];
- });
-
- return error;
-}
-
-void Allocator::free(Buffer buffer) const
-{
- mClient->free(buffer);
-}
-
-Error Allocator::exportHandle(BufferDescriptor descriptor, Buffer buffer,
- native_handle_t** outBufferHandle) const
-{
- Error error = kDefaultError;
- auto status = mClient->exportHandle(descriptor, buffer,
- [&](const auto& tmpError, const auto& tmpBufferHandle) {
- error = tmpError;
- if (tmpError != Error::NONE) {
- return;
- }
-
- *outBufferHandle = native_handle_clone(tmpBufferHandle);
- if (!*outBufferHandle) {
- error = Error::NO_RESOURCES;
- }
- });
-
- return error;
-}
-
-} // namespace Gralloc2
-
-} // namespace android
diff --git a/libs/ui/GrallocMapper.cpp b/libs/ui/GrallocMapper.cpp
deleted file mode 100644
index 8095247..0000000
--- a/libs/ui/GrallocMapper.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright 2016 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 "GrallocMapper"
-
-#include <ui/GrallocMapper.h>
-
-#include <log/log.h>
-
-namespace android {
-
-namespace Gralloc2 {
-
-static constexpr Error kDefaultError = Error::NO_RESOURCES;
-
-Mapper::Mapper()
-{
- mMapper = IMapper::getService();
- if (mMapper != nullptr && mMapper->isRemote()) {
- LOG_ALWAYS_FATAL("gralloc-mapper must be in passthrough mode");
- }
-}
-
-Error Mapper::retain(buffer_handle_t handle) const
-{
- auto ret = mMapper->retain(handle);
- return (ret.isOk()) ? static_cast<Error>(ret) : kDefaultError;
-}
-
-void Mapper::release(buffer_handle_t handle) const
-{
- auto ret = mMapper->release(handle);
-
- auto error = (ret.isOk()) ? static_cast<Error>(ret) : kDefaultError;
- ALOGE_IF(error != Error::NONE,
- "release(%p) failed with %d", handle, error);
-}
-
-Error Mapper::getDimensions(buffer_handle_t handle,
- uint32_t* outWidth, uint32_t* outHeight) const
-{
- Error error = kDefaultError;
- mMapper->getDimensions(handle,
- [&](const auto& tmpError, const auto& tmpWidth,
- const auto& tmpHeight)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outWidth = tmpWidth;
- *outHeight = tmpHeight;
- });
-
- return error;
-}
-
-Error Mapper::getFormat(buffer_handle_t handle, int32_t* outFormat) const
-{
- Error error = kDefaultError;
- mMapper->getFormat(handle,
- [&](const auto& tmpError, const auto& tmpFormat)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outFormat = static_cast<int32_t>(tmpFormat);
- });
-
- return error;
-}
-
-Error Mapper::getLayerCount(buffer_handle_t handle,
- uint32_t* outLayerCount) const
-{
- Error error = kDefaultError;
- mMapper->getLayerCount(handle,
- [&](const auto& tmpError, const auto& tmpLayerCount)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outLayerCount = tmpLayerCount;
- });
-
- return error;
-}
-
-Error Mapper::getProducerUsage(buffer_handle_t handle,
- uint64_t* outProducerUsage) const
-{
- Error error = kDefaultError;
- mMapper->getProducerUsageMask(handle,
- [&](const auto& tmpError, const auto& tmpProducerUsage)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outProducerUsage = tmpProducerUsage;
- });
-
- return error;
-}
-
-Error Mapper::getConsumerUsage(buffer_handle_t handle,
- uint64_t* outConsumerUsage) const
-{
- Error error = kDefaultError;
- mMapper->getConsumerUsageMask(handle,
- [&](const auto& tmpError, const auto& tmpConsumerUsage)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outConsumerUsage = tmpConsumerUsage;
- });
-
- return error;
-}
-
-Error Mapper::getBackingStore(buffer_handle_t handle,
- uint64_t* outBackingStore) const
-{
- Error error = kDefaultError;
- mMapper->getBackingStore(handle,
- [&](const auto& tmpError, const auto& tmpStore)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outBackingStore = tmpStore;
- });
-
- return error;
-}
-
-Error Mapper::getStride(buffer_handle_t handle, uint32_t* outStride) const
-{
- Error error = kDefaultError;
- mMapper->getStride(handle,
- [&](const auto& tmpError, const auto& tmpStride)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outStride = tmpStride;
- });
-
- return error;
-}
-
-Error Mapper::lock(buffer_handle_t handle,
- uint64_t producerUsage,
- uint64_t consumerUsage,
- const IMapper::Rect& accessRegion,
- int acquireFence, void** outData) const
-{
- hardware::hidl_handle acquireFenceHandle;
-
- NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
- if (acquireFence >= 0) {
- auto h = native_handle_init(acquireFenceStorage, 1, 0);
- h->data[0] = acquireFence;
- acquireFenceHandle = h;
- }
-
- Error error = kDefaultError;
- mMapper->lock(handle, producerUsage, consumerUsage,
- accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpData)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outData = tmpData;
- });
-
- if (error == Error::NONE && acquireFence >= 0) {
- close(acquireFence);
- }
-
- return error;
-}
-
-Error Mapper::lock(buffer_handle_t handle,
- uint64_t producerUsage,
- uint64_t consumerUsage,
- const IMapper::Rect& accessRegion,
- int acquireFence, FlexLayout* outLayout) const
-{
- hardware::hidl_handle acquireFenceHandle;
-
- NATIVE_HANDLE_DECLARE_STORAGE(acquireFenceStorage, 1, 0);
- if (acquireFence >= 0) {
- auto h = native_handle_init(acquireFenceStorage, 1, 0);
- h->data[0] = acquireFence;
- acquireFenceHandle = h;
- }
-
- Error error = kDefaultError;
- mMapper->lockFlex(handle, producerUsage, consumerUsage,
- accessRegion, acquireFenceHandle,
- [&](const auto& tmpError, const auto& tmpLayout)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- *outLayout = tmpLayout;
- });
-
- if (error == Error::NONE && acquireFence >= 0) {
- close(acquireFence);
- }
-
- return error;
-}
-
-int Mapper::unlock(buffer_handle_t handle) const
-{
- int releaseFence = -1;
-
- Error error = kDefaultError;
- mMapper->unlock(handle,
- [&](const auto& tmpError, const auto& tmpReleaseFence)
- {
- error = tmpError;
- if (error != Error::NONE) {
- return;
- }
-
- auto fenceHandle = tmpReleaseFence.getNativeHandle();
- if (fenceHandle && fenceHandle->numFds == 1) {
- int fd = dup(fenceHandle->data[0]);
- if (fd >= 0) {
- releaseFence = fd;
- } else {
- error = Error::NO_RESOURCES;
- }
- } else {
- releaseFence = -1;
- }
- });
-
- if (error != Error::NONE) {
- ALOGE("unlock(%p) failed with %d", handle, error);
- releaseFence = -1;
- }
-
- return releaseFence;
-}
-
-} // namespace Gralloc2
-
-} // namespace android
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index d21758d..eb5c7b6 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -22,7 +22,7 @@
#include <grallocusage/GrallocUsageConversion.h>
-#include <ui/GrallocMapper.h>
+#include <ui/Gralloc2.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/GraphicBufferMapper.h>
@@ -104,11 +104,7 @@
void GraphicBuffer::free_handle()
{
if (mOwner == ownHandle) {
- mBufferMapper.unregisterBuffer(handle);
- if (!mBufferMapper.getGrallocMapper().valid()) {
- native_handle_close(handle);
- native_handle_delete(const_cast<native_handle*>(handle));
- }
+ mBufferMapper.freeBuffer(handle);
} else if (mOwner == ownData) {
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
allocator.free(handle);
@@ -217,7 +213,7 @@
mOwner = (method == WRAP_HANDLE) ? ownNone : ownHandle;
if (method == TAKE_UNREGISTERED_HANDLE) {
- status_t err = mBufferMapper.registerBuffer(this);
+ status_t err = mBufferMapper.importBuffer(this);
if (err != NO_ERROR) {
// clean up cloned handle
if (clone) {
@@ -451,7 +447,7 @@
mOwner = ownHandle;
if (handle != 0) {
- status_t err = mBufferMapper.registerBuffer(this);
+ status_t err = mBufferMapper.importBuffer(this);
if (err != NO_ERROR) {
width = height = stride = format = layerCount = usage = 0;
handle = NULL;
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index 3f18bbc..1f6c537 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -22,13 +22,14 @@
#include <stdio.h>
+#include <grallocusage/GrallocUsageConversion.h>
+
#include <log/log.h>
#include <utils/Singleton.h>
#include <utils/String8.h>
#include <utils/Trace.h>
-#include <ui/GrallocAllocator.h>
-#include <ui/GrallocMapper.h>
+#include <ui/Gralloc2.h>
#include <ui/GraphicBufferMapper.h>
namespace android {
@@ -41,8 +42,9 @@
GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
GraphicBufferAllocator::GraphicBufferAllocator()
- : mAllocator(std::make_unique<Gralloc2::Allocator>()),
- mMapper(GraphicBufferMapper::getInstance())
+ : mMapper(GraphicBufferMapper::getInstance()),
+ mAllocator(std::make_unique<Gralloc2::Allocator>(
+ mMapper.getGrallocMapper()))
{
if (!mAllocator->valid()) {
mLoader = std::make_unique<Gralloc1::Loader>();
@@ -102,109 +104,6 @@
ALOGD("%s", s.string());
}
-namespace {
-
-class HalBuffer {
-public:
- HalBuffer(const Gralloc2::Allocator* allocator,
- uint32_t width, uint32_t height,
- PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
- uint64_t consumerUsage)
- : mAllocator(allocator), mBufferValid(false)
- {
- Gralloc2::IAllocatorClient::BufferDescriptorInfo info = {};
- info.width = width;
- info.height = height;
- info.format = static_cast<Gralloc2::PixelFormat>(format);
- info.layerCount = layerCount;
- info.producerUsageMask = producerUsage;
- info.consumerUsageMask = consumerUsage;
-
- Gralloc2::BufferDescriptor descriptor;
- auto error = mAllocator->createBufferDescriptor(info, &descriptor);
- if (error != Gralloc2::Error::NONE) {
- ALOGE("Failed to create desc (%u x %u) layerCount %u format %d producerUsage %" PRIx64
- " consumerUsage %" PRIx64 ": %d",
- width, height, layerCount, format, producerUsage,
- consumerUsage, error);
- return;
- }
-
- error = mAllocator->allocate(descriptor, &mBuffer);
- if (error == Gralloc2::Error::NOT_SHARED) {
- error = Gralloc2::Error::NONE;
- }
-
- if (error != Gralloc2::Error::NONE) {
- ALOGE("Failed to allocate (%u x %u) layerCount %u format %d producerUsage %" PRIx64
- " consumerUsage %" PRIx64 ": %d",
- width, height, layerCount, format, producerUsage,
- consumerUsage, error);
- mAllocator->destroyBufferDescriptor(descriptor);
- return;
- }
-
- error = mAllocator->exportHandle(descriptor, mBuffer, &mHandle);
- if (error != Gralloc2::Error::NONE) {
- ALOGE("Failed to export handle");
- mAllocator->free(mBuffer);
- mAllocator->destroyBufferDescriptor(descriptor);
- return;
- }
-
- mAllocator->destroyBufferDescriptor(descriptor);
-
- mBufferValid = true;
- }
-
- ~HalBuffer()
- {
- if (mBufferValid) {
- if (mHandle) {
- native_handle_close(mHandle);
- native_handle_delete(mHandle);
- }
-
- mAllocator->free(mBuffer);
- }
- }
-
- bool exportHandle(GraphicBufferMapper& mapper,
- buffer_handle_t* handle, uint32_t* stride)
- {
- if (!mBufferValid) {
- return false;
- }
-
- if (mapper.registerBuffer(mHandle)) {
- return false;
- }
-
- *handle = mHandle;
-
- auto error = mapper.getGrallocMapper().getStride(mHandle, stride);
- if (error != Gralloc2::Error::NONE) {
- ALOGW("Failed to get stride from buffer: %d", error);
- *stride = 0;
- }
-
- mHandle = nullptr;
- mAllocator->free(mBuffer);
- mBufferValid = false;
-
- return true;
- }
-
-private:
- const Gralloc2::Allocator* mAllocator;
-
- bool mBufferValid;
- Gralloc2::Buffer mBuffer;
- native_handle_t* mHandle;
-};
-
-} // namespace
-
status_t GraphicBufferAllocator::allocate(uint32_t width, uint32_t height,
PixelFormat format, uint32_t layerCount, uint64_t producerUsage,
uint64_t consumerUsage, buffer_handle_t* handle, uint32_t* stride,
@@ -223,12 +122,18 @@
gralloc1_error_t error;
if (mAllocator->valid()) {
- HalBuffer buffer(mAllocator.get(), width, height, format, layerCount,
- producerUsage, consumerUsage);
- if (!buffer.exportHandle(mMapper, handle, stride)) {
+ Gralloc2::IMapper::BufferDescriptorInfo info = {};
+ info.width = width;
+ info.height = height;
+ info.layerCount = layerCount;
+ info.format = static_cast<Gralloc2::PixelFormat>(format);
+ info.usage = static_cast<uint64_t>(android_convertGralloc1To0Usage(
+ producerUsage, consumerUsage));
+ error = static_cast<gralloc1_error_t>(mAllocator->allocate(info,
+ stride, handle));
+ if (error != GRALLOC1_ERROR_NONE) {
return NO_MEMORY;
}
- error = GRALLOC1_ERROR_NONE;
} else {
auto descriptor = mDevice->createDescriptor();
error = descriptor->setDimensions(width, height);
@@ -310,8 +215,7 @@
gralloc1_error_t error;
if (mAllocator->valid()) {
- error = static_cast<gralloc1_error_t>(
- mMapper.unregisterBuffer(handle));
+ error = static_cast<gralloc1_error_t>(mMapper.freeBuffer(handle));
} else {
error = mDevice->release(handle);
}
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 656472f..87519bf 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -20,6 +20,8 @@
#include <ui/GraphicBufferMapper.h>
+#include <grallocusage/GrallocUsageConversion.h>
+
// We would eliminate the non-conforming zero-length array, but we can't since
// this is effectively included from the Linux kernel
#pragma clang diagnostic push
@@ -30,7 +32,7 @@
#include <utils/Log.h>
#include <utils/Trace.h>
-#include <ui/GrallocMapper.h>
+#include <ui/Gralloc2.h>
#include <ui/GraphicBuffer.h>
#include <system/graphics.h>
@@ -49,63 +51,84 @@
}
}
-
-
-status_t GraphicBufferMapper::registerBuffer(buffer_handle_t handle)
+status_t GraphicBufferMapper::importBuffer(buffer_handle_t rawHandle,
+ buffer_handle_t* outHandle)
{
ATRACE_CALL();
+ Gralloc2::Error error;
+ if (mMapper->valid()) {
+ error = mMapper->importBuffer(hardware::hidl_handle(rawHandle),
+ outHandle);
+ } else {
+ error = Gralloc2::Error::UNSUPPORTED;
+ }
+
+ ALOGW_IF(error != Gralloc2::Error::NONE, "importBuffer(%p) failed: %d",
+ rawHandle, error);
+
+ return static_cast<status_t>(error);
+}
+
+status_t GraphicBufferMapper::importBuffer(const GraphicBuffer* buffer)
+{
+ ATRACE_CALL();
+
+ ANativeWindowBuffer* nativeBuffer = buffer->getNativeBuffer();
+ buffer_handle_t rawHandle = nativeBuffer->handle;
+
gralloc1_error_t error;
if (mMapper->valid()) {
- error = static_cast<gralloc1_error_t>(mMapper->retain(handle));
+ buffer_handle_t importedHandle;
+ error = static_cast<gralloc1_error_t>(mMapper->importBuffer(
+ hardware::hidl_handle(rawHandle), &importedHandle));
+ if (error == GRALLOC1_ERROR_NONE) {
+ nativeBuffer->handle = importedHandle;
+ }
} else {
- // This always returns GRALLOC1_BAD_HANDLE when handle is from a
- // remote process and mDevice is backed by Gralloc1On0Adapter.
- error = mDevice->retain(handle);
- if (error == GRALLOC1_ERROR_BAD_HANDLE &&
- mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
- ALOGE("registerBuffer by handle is not supported with "
- "Gralloc1On0Adapter");
+ native_handle_t* clonedHandle = native_handle_clone(rawHandle);
+ if (clonedHandle) {
+ nativeBuffer->handle = clonedHandle;
+ error = mDevice->retain(buffer);
+ if (error != GRALLOC1_ERROR_NONE) {
+ nativeBuffer->handle = rawHandle;
+ native_handle_close(clonedHandle);
+ native_handle_delete(clonedHandle);
+ }
+ } else {
+ error = GRALLOC1_ERROR_NO_RESOURCES;
}
}
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
- handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::registerBuffer(const GraphicBuffer* buffer)
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- error = static_cast<gralloc1_error_t>(
- mMapper->retain(buffer->getNativeBuffer()->handle));
- } else {
- error = mDevice->retain(buffer);
+ // the raw handle is owned by GraphicBuffer and is now replaced
+ if (error == GRALLOC1_ERROR_NONE) {
+ native_handle_close(rawHandle);
+ native_handle_delete(const_cast<native_handle_t*>(rawHandle));
}
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
- buffer->getNativeBuffer()->handle, error);
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "importBuffer(%p) failed: %d",
+ rawHandle, error);
return error;
}
-status_t GraphicBufferMapper::unregisterBuffer(buffer_handle_t handle)
+status_t GraphicBufferMapper::freeBuffer(buffer_handle_t handle)
{
ATRACE_CALL();
gralloc1_error_t error;
if (mMapper->valid()) {
- mMapper->release(handle);
+ mMapper->freeBuffer(handle);
error = GRALLOC1_ERROR_NONE;
} else {
error = mDevice->release(handle);
+ if (!mDevice->hasCapability(GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE)) {
+ native_handle_close(handle);
+ native_handle_delete(const_cast<native_handle_t*>(handle));
+ }
}
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "unregisterBuffer(%p): failed %d",
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE, "freeBuffer(%p): failed %d",
handle, error);
return error;
@@ -120,138 +143,13 @@
return outRect;
}
-
-status_t GraphicBufferMapper::getDimensions(buffer_handle_t handle,
- uint32_t* outWidth, uint32_t* outHeight) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getDimensions(handle, outWidth, outHeight);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getDimensions(handle, outWidth, outHeight);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getDimensions(%p, ...): failed %d",
- handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getFormat(buffer_handle_t handle,
- int32_t* outFormat) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getFormat(handle, outFormat);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getFormat(handle, outFormat);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getFormat(%p, ...): failed %d",
- handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getLayerCount(buffer_handle_t handle,
- uint32_t* outLayerCount) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getLayerCount(handle, outLayerCount);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getLayerCount(handle, outLayerCount);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getLayerCount(%p, ...): failed %d",
- handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getProducerUsage(buffer_handle_t handle,
- uint64_t* outProducerUsage) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getProducerUsage(handle, outProducerUsage);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getProducerUsage(handle, outProducerUsage);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE,
- "getProducerUsage(%p, ...): failed %d", handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getConsumerUsage(buffer_handle_t handle,
- uint64_t* outConsumerUsage) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getConsumerUsage(handle, outConsumerUsage);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getConsumerUsage(handle, outConsumerUsage);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE,
- "getConsumerUsage(%p, ...): failed %d", handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getBackingStore(buffer_handle_t handle,
- uint64_t* outBackingStore) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getBackingStore(handle, outBackingStore);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getBackingStore(handle, outBackingStore);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE,
- "getBackingStore(%p, ...): failed %d", handle, error);
-
- return error;
-}
-
-status_t GraphicBufferMapper::getStride(buffer_handle_t handle,
- uint32_t* outStride) const
-{
- ATRACE_CALL();
-
- gralloc1_error_t error;
- if (mMapper->valid()) {
- mMapper->getStride(handle, outStride);
- error = GRALLOC1_ERROR_NONE;
- } else {
- error = mDevice->getStride(handle, outStride);
- }
-
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "getStride(%p, ...): failed %d",
- handle, error);
-
- return error;
+static inline Gralloc2::IMapper::Rect asGralloc2Rect(const Rect& rect) {
+ Gralloc2::IMapper::Rect outRect{};
+ outRect.left = rect.left;
+ outRect.top = rect.top;
+ outRect.width = rect.width();
+ outRect.height = rect.height();
+ return outRect;
}
status_t GraphicBufferMapper::lock(buffer_handle_t handle, uint32_t usage,
@@ -289,15 +187,15 @@
{
ATRACE_CALL();
- gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
gralloc1_error_t error;
if (mMapper->valid()) {
- const Gralloc2::IMapper::Rect& accessRect =
- *reinterpret_cast<Gralloc2::IMapper::Rect*>(&accessRegion);
- error = static_cast<gralloc1_error_t>(mMapper->lock(
- handle, producerUsage, consumerUsage, accessRect,
- fenceFd, vaddr));
+ const uint64_t usage =
+ static_cast<uint64_t>(android_convertGralloc1To0Usage(
+ producerUsage, consumerUsage));
+ error = static_cast<gralloc1_error_t>(mMapper->lock(handle,
+ usage, asGralloc2Rect(bounds), fenceFd, vaddr));
} else {
+ gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
sp<Fence> fence = new Fence(fenceFd);
error = mDevice->lock(handle,
static_cast<gralloc1_producer_usage_t>(producerUsage),
@@ -346,22 +244,19 @@
gralloc1_error_t error;
if (mMapper->valid()) {
- const Gralloc2::IMapper::Rect& accessRect =
- *reinterpret_cast<Gralloc2::IMapper::Rect*>(&accessRegion);
- Gralloc2::FlexLayout layout{};
- error = static_cast<gralloc1_error_t>(mMapper->lock(
- handle, usage, usage, accessRect, fenceFd, &layout));
-
+ Gralloc2::YCbCrLayout layout;
+ error = static_cast<gralloc1_error_t>(mMapper->lock(handle, usage,
+ asGralloc2Rect(bounds), fenceFd, &layout));
if (error == GRALLOC1_ERROR_NONE) {
- planes.resize(layout.planes.size());
- memcpy(planes.data(), layout.planes.data(),
- sizeof(planes[0]) * planes.size());
-
- flexLayout.format = static_cast<android_flex_format_t>(
- layout.format);
- flexLayout.num_planes = static_cast<uint32_t>(planes.size());
- flexLayout.planes = planes.data();
+ ycbcr->y = layout.y;
+ ycbcr->cb = layout.cb;
+ ycbcr->cr = layout.cr;
+ ycbcr->ystride = static_cast<size_t>(layout.yStride);
+ ycbcr->cstride = static_cast<size_t>(layout.cStride);
+ ycbcr->chroma_step = static_cast<size_t>(layout.chromaStep);
}
+
+ return error;
} else {
sp<Fence> fence = new Fence(fenceFd);
diff --git a/libs/ui/tests/Android.bp b/libs/ui/tests/Android.bp
index b55c212..6733505 100644
--- a/libs/ui/tests/Android.bp
+++ b/libs/ui/tests/Android.bp
@@ -25,9 +25,3 @@
shared_libs: ["libui"],
srcs: ["colorspace_test.cpp"],
}
-
-cc_test {
- name: "Gralloc1Mapper_test",
- shared_libs: ["libui", "libutils"],
- srcs: ["Gralloc1Mapper_test.cpp"],
-}
diff --git a/libs/ui/tests/Gralloc1Mapper_test.cpp b/libs/ui/tests/Gralloc1Mapper_test.cpp
deleted file mode 100644
index b7c9f0f..0000000
--- a/libs/ui/tests/Gralloc1Mapper_test.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2017 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 "Gralloc1Mapper_test"
-//#define LOG_NDEBUG 0
-
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#include <ui/GraphicBuffer.h>
-#include <ui/GraphicBufferMapper.h>
-#include <utils/Errors.h>
-
-#include <gtest/gtest.h>
-
-using namespace android;
-
-class Gralloc1MapperTest : public ::testing::Test
-{
-public:
- ~Gralloc1MapperTest() override = default;
-
-protected:
- void SetUp() override {
- buffer = new GraphicBuffer(4, 8, HAL_PIXEL_FORMAT_RGBA_8888, 1,
- GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN,
- GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN, "Gralloc1MapperTest");
- ASSERT_NE(nullptr, buffer.get());
-
- handle = static_cast<buffer_handle_t>(buffer->handle);
-
- mapper = &GraphicBufferMapper::get();
- }
-
- sp<GraphicBuffer> buffer;
- buffer_handle_t handle;
- GraphicBufferMapper* mapper;
-};
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getDimensions) {
- uint32_t width = 0;
- uint32_t height = 0;
- status_t err = mapper->getDimensions(handle, &width, &height);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
- EXPECT_EQ(4U, width);
- EXPECT_EQ(8U, height);
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getFormat) {
- int32_t value = 0;
- status_t err = mapper->getFormat(handle, &value);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
- EXPECT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, value);
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getLayerCount) {
- uint32_t value = 0;
- status_t err = mapper->getLayerCount(handle, &value);
- if (err != GRALLOC1_ERROR_UNSUPPORTED) {
- EXPECT_EQ(1U, value);
- }
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getProducerUsage) {
- uint64_t value = 0;
- status_t err = mapper->getProducerUsage(handle, &value);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
- EXPECT_EQ(GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN, value);
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getConsumerUsage) {
- uint64_t value = 0;
- status_t err = mapper->getConsumerUsage(handle, &value);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
- EXPECT_EQ(GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN, value);
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getBackingStore) {
- uint64_t value = 0;
- status_t err = mapper->getBackingStore(handle, &value);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
-}
-
-TEST_F(Gralloc1MapperTest, Gralloc1MapperTest_getStride) {
- uint32_t value = 0;
- status_t err = mapper->getStride(handle, &value);
- ASSERT_EQ(GRALLOC1_ERROR_NONE, err);
- // The stride should be at least the width of the buffer.
- EXPECT_LE(4U, value);
-}
diff --git a/libs/vr/libbufferhub/buffer_hub_client.cpp b/libs/vr/libbufferhub/buffer_hub_client.cpp
index 2749fd1..a1f952e 100644
--- a/libs/vr/libbufferhub/buffer_hub_client.cpp
+++ b/libs/vr/libbufferhub/buffer_hub_client.cpp
@@ -20,6 +20,7 @@
namespace {
+// TODO(hendrikw): These flags can not be hard coded.
constexpr int kUncachedBlobUsageFlags = GRALLOC_USAGE_SW_READ_RARELY |
GRALLOC_USAGE_SW_WRITE_RARELY |
GRALLOC_USAGE_PRIVATE_UNCACHED;
@@ -110,6 +111,7 @@
int BufferHubBuffer::GetBlobReadWritePointer(size_t size, void** addr) {
int width = static_cast<int>(size);
int height = 1;
+ // TODO(hendrikw): These flags can not be hard coded.
constexpr int usage = GRALLOC_USAGE_SW_READ_RARELY |
GRALLOC_USAGE_SW_WRITE_RARELY |
GRALLOC_USAGE_PRIVATE_UNCACHED;
@@ -196,18 +198,27 @@
InvokeRemoteMethod<BufferHubRPC::ConsumerSetIgnore>(ignore));
}
-BufferProducer::BufferProducer(int width, int height, int format, int usage,
+BufferProducer::BufferProducer(uint32_t width, uint32_t height, uint32_t format,
+ uint32_t usage, size_t metadata_size,
+ size_t slice_count)
+ : BufferProducer(width, height, format, usage, usage, metadata_size,
+ slice_count) {}
+
+BufferProducer::BufferProducer(uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage,
size_t metadata_size, size_t slice_count)
: BASE(BufferHubRPC::kClientPath) {
ATRACE_NAME("BufferProducer::BufferProducer");
ALOGD_IF(TRACE,
- "BufferProducer::BufferProducer: fd=%d width=%d height=%d format=%d "
- "usage=%d, metadata_size=%zu, slice_count=%zu",
- event_fd(), width, height, format, usage, metadata_size,
- slice_count);
+ "BufferProducer::BufferProducer: fd=%d width=%u height=%u format=%u "
+ "producer_usage=%" PRIx64 " consumer_usage=%" PRIx64
+ " metadata_size=%zu slice_count=%zu",
+ event_fd(), width, height, format, producer_usage, consumer_usage,
+ metadata_size, slice_count);
auto status = InvokeRemoteMethod<BufferHubRPC::CreateBuffer>(
- width, height, format, usage, metadata_size, slice_count);
+ width, height, format, producer_usage, consumer_usage, metadata_size,
+ slice_count);
if (!status) {
ALOGE(
"BufferProducer::BufferProducer: Failed to create producer buffer: %s",
@@ -226,21 +237,29 @@
}
BufferProducer::BufferProducer(const std::string& name, int user_id,
- int group_id, int width, int height, int format,
- int usage, size_t meta_size_bytes,
+ int group_id, uint32_t width, uint32_t height,
+ uint32_t format, uint32_t usage,
+ size_t meta_size_bytes, size_t slice_count)
+ : BufferProducer(name, user_id, group_id, width, height, format, usage,
+ usage, meta_size_bytes, slice_count) {}
+
+BufferProducer::BufferProducer(const std::string& name, int user_id,
+ int group_id, uint32_t width, uint32_t height,
+ uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage, size_t meta_size_bytes,
size_t slice_count)
: BASE(BufferHubRPC::kClientPath) {
ATRACE_NAME("BufferProducer::BufferProducer");
ALOGD_IF(TRACE,
"BufferProducer::BufferProducer: fd=%d name=%s user_id=%d "
- "group_id=%d width=%d height=%d format=%d usage=%d, "
- "meta_size_bytes=%zu, slice_count=%zu",
+ "group_id=%d width=%u height=%u format=%u producer_usage=%" PRIx64
+ " consumer_usage=%" PRIx64 " meta_size_bytes=%zu slice_count=%zu",
event_fd(), name.c_str(), user_id, group_id, width, height, format,
- usage, meta_size_bytes, slice_count);
+ producer_usage, consumer_usage, meta_size_bytes, slice_count);
auto status = InvokeRemoteMethod<BufferHubRPC::CreatePersistentBuffer>(
- name, user_id, group_id, width, height, format, usage, meta_size_bytes,
- slice_count);
+ name, user_id, group_id, width, height, format, producer_usage,
+ consumer_usage, meta_size_bytes, slice_count);
if (!status) {
ALOGE(
"BufferProducer::BufferProducer: Failed to create/get persistent "
@@ -260,18 +279,25 @@
}
}
-BufferProducer::BufferProducer(int usage, size_t size)
+BufferProducer::BufferProducer(uint32_t usage, size_t size)
+ : BufferProducer(usage, usage, size) {}
+
+BufferProducer::BufferProducer(uint64_t producer_usage, uint64_t consumer_usage,
+ size_t size)
: BASE(BufferHubRPC::kClientPath) {
ATRACE_NAME("BufferProducer::BufferProducer");
- ALOGD_IF(TRACE, "BufferProducer::BufferProducer: usage=%d size=%zu", usage,
- size);
+ ALOGD_IF(TRACE,
+ "BufferProducer::BufferProducer: producer_usage=%" PRIx64
+ " consumer_usage=%" PRIx64 " size=%zu",
+ producer_usage, consumer_usage, size);
const int width = static_cast<int>(size);
const int height = 1;
const int format = HAL_PIXEL_FORMAT_BLOB;
const size_t meta_size_bytes = 0;
const size_t slice_count = 1;
auto status = InvokeRemoteMethod<BufferHubRPC::CreateBuffer>(
- width, height, format, usage, meta_size_bytes, slice_count);
+ width, height, format, producer_usage, consumer_usage, meta_size_bytes,
+ slice_count);
if (!status) {
ALOGE("BufferProducer::BufferProducer: Failed to create blob: %s",
status.GetErrorMessage().c_str());
@@ -289,21 +315,27 @@
}
BufferProducer::BufferProducer(const std::string& name, int user_id,
- int group_id, int usage, size_t size)
+ int group_id, uint32_t usage, size_t size)
+ : BufferProducer(name, user_id, group_id, usage, usage, size) {}
+
+BufferProducer::BufferProducer(const std::string& name, int user_id,
+ int group_id, uint64_t producer_usage,
+ uint64_t consumer_usage, size_t size)
: BASE(BufferHubRPC::kClientPath) {
ATRACE_NAME("BufferProducer::BufferProducer");
ALOGD_IF(TRACE,
"BufferProducer::BufferProducer: name=%s user_id=%d group=%d "
- "usage=%d size=%zu",
- name.c_str(), user_id, group_id, usage, size);
+ "producer_usage=%" PRIx64 " consumer_usage=%" PRIx64 " size=%zu",
+ name.c_str(), user_id, group_id, producer_usage, consumer_usage,
+ size);
const int width = static_cast<int>(size);
const int height = 1;
const int format = HAL_PIXEL_FORMAT_BLOB;
const size_t meta_size_bytes = 0;
const size_t slice_count = 1;
auto status = InvokeRemoteMethod<BufferHubRPC::CreatePersistentBuffer>(
- name, user_id, group_id, width, height, format, usage, meta_size_bytes,
- slice_count);
+ name, user_id, group_id, width, height, format, producer_usage,
+ consumer_usage, meta_size_bytes, slice_count);
if (!status) {
ALOGE(
"BufferProducer::BufferProducer: Failed to create persistent "
diff --git a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
index dfeed50..c772ed3 100644
--- a/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
+++ b/libs/vr/libbufferhub/include/private/dvr/buffer_hub_client.h
@@ -107,11 +107,14 @@
// The following methods return settings of the first buffer. Currently,
// it is only possible to create multi-buffer BufferHubBuffers with the same
// settings.
- int width() const { return slices_[0].width(); }
- int height() const { return slices_[0].height(); }
- int stride() const { return slices_[0].stride(); }
- int format() const { return slices_[0].format(); }
- int usage() const { return slices_[0].usage(); }
+ uint32_t width() const { return slices_[0].width(); }
+ uint32_t height() const { return slices_[0].height(); }
+ uint32_t stride() const { return slices_[0].stride(); }
+ uint32_t format() const { return slices_[0].format(); }
+ uint32_t usage() const { return slices_[0].usage(); }
+ uint32_t layer_count() const { return slices_[0].layer_count(); }
+ uint64_t producer_usage() const { return slices_[0].producer_usage(); }
+ uint64_t consumer_usage() const { return slices_[0].consumer_usage(); }
protected:
explicit BufferHubBuffer(LocalChannelHandle channel);
@@ -218,8 +221,12 @@
// arguments as the constructors.
// Constructs a buffer with the given geometry and parameters.
- BufferProducer(int width, int height, int format, int usage,
- size_t metadata_size = 0, size_t slice_count = 1);
+ BufferProducer(uint32_t width, uint32_t height, uint32_t format,
+ uint32_t usage, size_t metadata_size = 0,
+ size_t slice_count = 1);
+ BufferProducer(uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage,
+ size_t metadata_size, size_t slice_count);
// Constructs a persistent buffer with the given geometry and parameters and
// binds it to |name| in one shot. If a persistent buffer with the same name
@@ -233,16 +240,24 @@
// created and cannot be changed. A user or group id of -1 disables checks for
// that respective id. A user or group id of 0 is substituted with the
// effective user or group id of the calling process.
- BufferProducer(const std::string& name, int user_id, int group_id, int width,
- int height, int format, int usage, size_t metadata_size = 0,
+ BufferProducer(const std::string& name, int user_id, int group_id,
+ uint32_t width, uint32_t height, uint32_t format,
+ uint32_t usage, size_t metadata_size = 0,
size_t slice_count = 1);
+ BufferProducer(const std::string& name, int user_id, int group_id,
+ uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage,
+ size_t metadata_size, size_t slice_count);
// Constructs a blob (flat) buffer with the given usage flags.
- BufferProducer(int usage, size_t size);
+ BufferProducer(uint32_t usage, size_t size);
+ BufferProducer(uint64_t producer_usage, uint64_t consumer_usage, size_t size);
// Constructs a persistent blob (flat) buffer and binds it to |name|.
- BufferProducer(const std::string& name, int user_id, int group_id, int usage,
- size_t size);
+ BufferProducer(const std::string& name, int user_id, int group_id,
+ uint32_t usage, size_t size);
+ BufferProducer(const std::string& name, int user_id, int group_id,
+ uint64_t producer_usage, uint64_t consumer_usage, size_t size);
// Constructs a channel to persistent buffer by name only. The buffer must
// have been previously created or made persistent.
diff --git a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
index 7ed024f..b6302f1 100644
--- a/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
+++ b/libs/vr/libbufferhub/include/private/dvr/bufferhub_rpc.h
@@ -24,7 +24,8 @@
width_(buffer.width()),
height_(buffer.height()),
format_(buffer.format()),
- usage_(buffer.usage()) {
+ producer_usage_(buffer.producer_usage()),
+ consumer_usage_(buffer.consumer_usage()) {
// Populate the fd and int vectors: native_handle->data[] is an array of fds
// followed by an array of opaque ints.
const int fd_count = buffer.handle()->numFds;
@@ -37,6 +38,7 @@
}
}
NativeBufferHandle(NativeBufferHandle&& other) = default;
+ NativeBufferHandle& operator=(NativeBufferHandle&& other) = default;
// Imports the native handle into the given IonBuffer instance.
int Import(IonBuffer* buffer) {
@@ -46,9 +48,10 @@
for (const auto& fd : fds_)
fd_ints.push_back(fd.Get());
- const int ret = buffer->Import(fd_ints.data(), fd_ints.size(),
- opaque_ints_.data(), opaque_ints_.size(),
- width_, height_, stride_, format_, usage_);
+ const int ret =
+ buffer->Import(fd_ints.data(), fd_ints.size(), opaque_ints_.data(),
+ opaque_ints_.size(), width_, height_, stride_, format_,
+ producer_usage_, consumer_usage_);
if (ret < 0)
return ret;
@@ -68,24 +71,32 @@
private:
int id_;
- int stride_;
- int width_;
- int height_;
- int format_;
- int usage_;
+ uint32_t stride_;
+ uint32_t width_;
+ uint32_t height_;
+ uint32_t format_;
+ uint64_t producer_usage_;
+ uint64_t consumer_usage_;
std::vector<int> opaque_ints_;
std::vector<FileHandleType> fds_;
- void Clear() { id_ = stride_ = width_ = height_ = format_ = usage_ = -1; }
+ void Clear() {
+ id_ = -1;
+ stride_ = width_ = height_ = format_ = producer_usage_ = consumer_usage_ =
+ 0;
+ }
PDX_SERIALIZABLE_MEMBERS(NativeBufferHandle<FileHandleType>, id_, stride_,
- width_, height_, format_, usage_, opaque_ints_,
- fds_);
+ width_, height_, format_, producer_usage_,
+ consumer_usage_, opaque_ints_, fds_);
NativeBufferHandle(const NativeBufferHandle&) = delete;
void operator=(const NativeBufferHandle&) = delete;
};
+using BorrowedNativeBufferHandle = NativeBufferHandle<pdx::BorrowedHandle>;
+using LocalNativeBufferHandle = NativeBufferHandle<pdx::LocalHandle>;
+
template <typename FileHandleType>
class FenceHandle {
public:
@@ -127,6 +138,23 @@
PDX_SERIALIZABLE_MEMBERS(QueueInfo, meta_size_bytes, id);
};
+struct UsagePolicy {
+ uint64_t producer_set_mask;
+ uint64_t producer_clear_mask;
+ uint64_t producer_deny_set_mask;
+ uint64_t producer_deny_clear_mask;
+ uint64_t consumer_set_mask;
+ uint64_t consumer_clear_mask;
+ uint64_t consumer_deny_set_mask;
+ uint64_t consumer_deny_clear_mask;
+
+ private:
+ PDX_SERIALIZABLE_MEMBERS(UsagePolicy, producer_set_mask, producer_clear_mask,
+ producer_deny_set_mask, producer_deny_clear_mask,
+ consumer_set_mask, consumer_clear_mask,
+ consumer_deny_set_mask, consumer_deny_clear_mask);
+};
+
// BufferHub Service RPC interface. Defines the endpoints, op codes, and method
// type signatures supported by bufferhubd.
struct BufferHubRPC {
@@ -173,44 +201,46 @@
// Methods.
PDX_REMOTE_METHOD(CreateBuffer, kOpCreateBuffer,
- int(int width, int height, int format, int usage,
- size_t meta_size_bytes, size_t slice_count));
+ void(uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage,
+ size_t meta_size_bytes, size_t slice_count));
PDX_REMOTE_METHOD(CreatePersistentBuffer, kOpCreatePersistentBuffer,
- int(const std::string& name, int user_id, int group_id,
- int width, int height, int format, int usage,
- size_t meta_size_bytes, size_t slice_count));
+ void(const std::string& name, int user_id, int group_id,
+ uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage,
+ size_t meta_size_bytes, size_t slice_count));
PDX_REMOTE_METHOD(GetPersistentBuffer, kOpGetPersistentBuffer,
- int(const std::string& name));
+ void(const std::string& name));
PDX_REMOTE_METHOD(GetBuffer, kOpGetBuffer,
NativeBufferHandle<LocalHandle>(unsigned index));
PDX_REMOTE_METHOD(GetBuffers, kOpGetBuffers,
std::vector<NativeBufferHandle<LocalHandle>>(Void));
PDX_REMOTE_METHOD(NewConsumer, kOpNewConsumer, LocalChannelHandle(Void));
PDX_REMOTE_METHOD(ProducerMakePersistent, kOpProducerMakePersistent,
- int(const std::string& name, int user_id, int group_id));
+ void(const std::string& name, int user_id, int group_id));
PDX_REMOTE_METHOD(ProducerRemovePersistence, kOpProducerRemovePersistence,
- int(Void));
+ void(Void));
PDX_REMOTE_METHOD(ProducerPost, kOpProducerPost,
- int(LocalFence acquire_fence, MetaData));
+ void(LocalFence acquire_fence, MetaData));
PDX_REMOTE_METHOD(ProducerGain, kOpProducerGain, LocalFence(Void));
PDX_REMOTE_METHOD(ConsumerAcquire, kOpConsumerAcquire,
std::pair<LocalFence, MetaData>(std::size_t metadata_size));
PDX_REMOTE_METHOD(ConsumerRelease, kOpConsumerRelease,
- int(LocalFence release_fence));
- PDX_REMOTE_METHOD(ConsumerSetIgnore, kOpConsumerSetIgnore, int(bool ignore));
+ void(LocalFence release_fence));
+ PDX_REMOTE_METHOD(ConsumerSetIgnore, kOpConsumerSetIgnore, void(bool ignore));
// Buffer Queue Methods.
PDX_REMOTE_METHOD(CreateProducerQueue, kOpCreateProducerQueue,
- QueueInfo(size_t meta_size_bytes, int usage_set_mask,
- int usage_clear_mask, int usage_deny_set_mask,
- int usage_deny_clear_mask));
+ QueueInfo(size_t meta_size_bytes,
+ const UsagePolicy& usage_policy));
PDX_REMOTE_METHOD(CreateConsumerQueue, kOpCreateConsumerQueue,
LocalChannelHandle(Void));
PDX_REMOTE_METHOD(GetQueueInfo, kOpGetQueueInfo, QueueInfo(Void));
PDX_REMOTE_METHOD(ProducerQueueAllocateBuffers,
kOpProducerQueueAllocateBuffers,
std::vector<std::pair<LocalChannelHandle, size_t>>(
- int width, int height, int format, int usage,
+ uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage,
size_t slice_count, size_t buffer_count));
PDX_REMOTE_METHOD(ProducerQueueDetachBuffer, kOpProducerQueueDetachBuffer,
void(size_t slot));
diff --git a/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h b/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
index ffc42d6..e167a17 100644
--- a/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
+++ b/libs/vr/libbufferhub/include/private/dvr/ion_buffer.h
@@ -12,11 +12,20 @@
class IonBuffer {
public:
IonBuffer();
- IonBuffer(int width, int height, int format, int usage);
- IonBuffer(buffer_handle_t handle, int width, int height, int stride,
- int format, int usage);
- IonBuffer(buffer_handle_t handle, int width, int height, int layer_count,
- int stride, int layer_stride, int format, int usage);
+ IonBuffer(uint32_t width, uint32_t height, uint32_t format, uint32_t usage);
+ IonBuffer(uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage);
+ IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint32_t usage);
+ IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage);
+ IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t layer_count, uint32_t stride, uint32_t layer_stride,
+ uint32_t format, uint32_t usage);
+ IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t layer_count, uint32_t stride, uint32_t layer_stride,
+ uint32_t format, uint64_t producer_usage, uint64_t consumer_usage);
~IonBuffer();
IonBuffer(IonBuffer&& other);
@@ -30,25 +39,36 @@
// previous native handle if necessary. Returns 0 on success or a negative
// errno code otherwise. If allocation fails the previous native handle is
// left intact.
- int Alloc(int width, int height, int format, int usage);
+ int Alloc(uint32_t width, uint32_t height, uint32_t format, uint32_t usage);
+ int Alloc(uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage);
// Resets the underlying native handle and parameters, freeing the previous
// native handle if necessary.
- void Reset(buffer_handle_t handle, int width, int height, int stride,
- int format, int usage);
+ void Reset(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint32_t usage);
+ void Reset(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage);
// Like Reset but also registers the native handle, which is necessary for
// native handles received over IPC. Returns 0 on success or a negative errno
// code otherwise. If import fails the previous native handle is left intact.
- int Import(buffer_handle_t handle, int width, int height, int stride,
- int format, int usage);
+ int Import(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint32_t usage);
+ int Import(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage);
// Like Reset but imports a native handle from raw fd and int arrays. Returns
// 0 on success or a negative errno code otherwise. If import fails the
// previous native handle is left intact.
int Import(const int* fd_array, int fd_count, const int* int_array,
- int int_count, int width, int height, int stride, int format,
- int usage);
+ int int_count, uint32_t width, uint32_t height, uint32_t stride,
+ uint32_t format, uint32_t usage);
+ int Import(const int* fd_array, int fd_count, const int* int_array,
+ int int_count, uint32_t width, uint32_t height, uint32_t stride,
+ uint32_t format, uint64_t producer_usage, uint64_t consumer_usage);
// Duplicates the native handle underlying |other| and then imports it. This
// is useful for creating multiple, independent views of the same Ion/Gralloc
@@ -56,8 +76,8 @@
// duplication or import fail the previous native handle is left intact.
int Duplicate(const IonBuffer* other);
- int Lock(int usage, int x, int y, int width, int height, void** address);
- int LockYUV(int usage, int x, int y, int width, int height,
+ int Lock(uint32_t usage, int x, int y, int width, int height, void** address);
+ int LockYUV(uint32_t usage, int x, int y, int width, int height,
struct android_ycbcr* yuv);
int Unlock();
@@ -65,19 +85,29 @@
buffer_handle_t handle() const {
return buffer_.get() ? buffer_->handle : nullptr;
}
- int width() const { return buffer_.get() ? buffer_->getWidth() : 0; }
- int height() const { return buffer_.get() ? buffer_->getHeight() : 0; }
- int layer_count() const {
+ uint32_t width() const { return buffer_.get() ? buffer_->getWidth() : 0; }
+ uint32_t height() const { return buffer_.get() ? buffer_->getHeight() : 0; }
+ uint32_t layer_count() const {
return buffer_.get() ? buffer_->getLayerCount() : 0;
}
- int stride() const { return buffer_.get() ? buffer_->getStride() : 0; }
- int layer_stride() const { return 0; }
- int format() const { return buffer_.get() ? buffer_->getPixelFormat() : 0; }
- int usage() const { return buffer_.get() ? buffer_->getUsage() : 0; }
+ uint32_t stride() const { return buffer_.get() ? buffer_->getStride() : 0; }
+ uint32_t layer_stride() const { return 0; }
+ uint32_t format() const {
+ return buffer_.get() ? buffer_->getPixelFormat() : 0;
+ }
+ uint64_t producer_usage() const { return producer_usage_; }
+ uint64_t consumer_usage() const { return consumer_usage_; }
+ uint32_t usage() const { return buffer_.get() ? buffer_->getUsage() : 0; }
private:
sp<GraphicBuffer> buffer_;
+ // GraphicBuffer doesn't expose these separately. Keep these values cached for
+ // BufferHub to check policy against. Clients that import these buffers won't
+ // get the full picture, which is okay.
+ uint64_t producer_usage_;
+ uint64_t consumer_usage_;
+
IonBuffer(const IonBuffer&) = delete;
void operator=(const IonBuffer&) = delete;
};
diff --git a/libs/vr/libbufferhub/ion_buffer.cpp b/libs/vr/libbufferhub/ion_buffer.cpp
index e5a56c1..df9ae81 100644
--- a/libs/vr/libbufferhub/ion_buffer.cpp
+++ b/libs/vr/libbufferhub/ion_buffer.cpp
@@ -6,40 +6,59 @@
#include <mutex>
+namespace {
+
+constexpr uint32_t kDefaultGraphicBufferLayerCount = 1;
+
+} // anonymous namespace
+
namespace android {
namespace dvr {
IonBuffer::IonBuffer() : IonBuffer(nullptr, 0, 0, 0, 0, 0, 0, 0) {}
-IonBuffer::IonBuffer(int width, int height, int format, int usage)
+IonBuffer::IonBuffer(uint32_t width, uint32_t height, uint32_t format,
+ uint32_t usage)
+ : IonBuffer(width, height, format, usage, usage) {}
+
+IonBuffer::IonBuffer(uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage)
: IonBuffer() {
- Alloc(width, height, format, usage);
+ Alloc(width, height, format, producer_usage, consumer_usage);
}
-IonBuffer::IonBuffer(buffer_handle_t handle, int width, int height, int stride,
- int format, int usage)
+IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint32_t usage)
: IonBuffer(handle, width, height, 1, stride, 0, format, usage) {}
+IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t layer_count, uint32_t stride,
+ uint32_t layer_stride, uint32_t format, uint32_t usage)
+ : IonBuffer(handle, width, height, layer_count, stride, layer_stride,
+ format, usage, usage) {}
-IonBuffer::IonBuffer(buffer_handle_t handle, int width, int height,
- int layer_count, int stride, int layer_stride, int format,
- int usage)
+IonBuffer::IonBuffer(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t layer_count, uint32_t stride,
+ uint32_t layer_stride, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage)
: buffer_(nullptr) {
ALOGD_IF(TRACE,
- "IonBuffer::IonBuffer: handle=%p width=%d height=%d layer_count=%d "
- "stride=%d layer stride=%d format=%d usage=%d",
- handle, width, height, layer_count, stride, layer_stride,
- format, usage);
+ "IonBuffer::IonBuffer: handle=%p width=%u height=%u layer_count=%u "
+ "stride=%u layer stride=%u format=%u producer_usage=%" PRIx64
+ " consumer_usage=%" PRIx64,
+ handle, width, height, layer_count, stride, layer_stride, format,
+ producer_usage, consumer_usage);
if (handle != 0) {
- Import(handle, width, height, stride, format, usage);
+ Import(handle, width, height, stride, format, producer_usage,
+ consumer_usage);
}
}
IonBuffer::~IonBuffer() {
ALOGD_IF(TRACE,
- "IonBuffer::~IonBuffer: handle=%p width=%d height=%d stride=%d "
- "format=%d usage=%d",
- handle() , width(), height(), stride(), format(), usage());
+ "IonBuffer::~IonBuffer: handle=%p width=%u height=%u stride=%u "
+ "format=%u usage=%x",
+ handle(), width(), height(), stride(), format(), usage());
FreeHandle();
}
@@ -62,55 +81,101 @@
if (buffer_.get()) {
// GraphicBuffer unregisters and cleans up the handle if needed
buffer_ = nullptr;
+ producer_usage_ = 0;
+ consumer_usage_ = 0;
}
}
-int IonBuffer::Alloc(int width, int height, int format, int usage) {
- ALOGD_IF(TRACE, "IonBuffer::Alloc: width=%d height=%d format=%d usage=%d",
- width, height, format, usage);
+int IonBuffer::Alloc(uint32_t width, uint32_t height, uint32_t format,
+ uint32_t usage) {
+ return Alloc(width, height, format, usage, usage);
+}
- buffer_ = new GraphicBuffer(width, height, format, usage);
- if (buffer_->initCheck() != OK) {
+int IonBuffer::Alloc(uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage) {
+ ALOGD_IF(
+ TRACE,
+ "IonBuffer::Alloc: width=%u height=%u format=%u producer_usage=%" PRIx64
+ " consumer_usage=%" PRIx64,
+ width, height, format, producer_usage, consumer_usage);
+
+ sp<GraphicBuffer> buffer =
+ new GraphicBuffer(width, height, format, kDefaultGraphicBufferLayerCount,
+ producer_usage, consumer_usage);
+ if (buffer->initCheck() != OK) {
ALOGE("IonBuffer::Aloc: Failed to allocate buffer");
+ return -EINVAL;
+ } else {
+ buffer_ = buffer;
+ producer_usage_ = producer_usage;
+ consumer_usage_ = consumer_usage;
+ return 0;
}
- return 0;
}
-void IonBuffer::Reset(buffer_handle_t handle, int width, int height, int stride,
- int format, int usage) {
+void IonBuffer::Reset(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint32_t usage) {
+ Reset(handle, width, height, stride, format, usage, usage);
+}
+
+void IonBuffer::Reset(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage) {
ALOGD_IF(TRACE,
- "IonBuffer::Reset: handle=%p width=%d height=%d stride=%d format=%d "
- "usage=%d",
- handle, width, height, stride, format, usage);
- Import(handle, width, height, stride, format, usage);
+ "IonBuffer::Reset: handle=%p width=%u height=%u stride=%u format=%u "
+ "producer_usage=%" PRIx64 " consumer_usage=%" PRIx64,
+ handle, width, height, stride, format, producer_usage,
+ consumer_usage);
+ Import(handle, width, height, stride, format, producer_usage, consumer_usage);
}
-int IonBuffer::Import(buffer_handle_t handle, int width, int height, int stride,
- int format, int usage) {
+int IonBuffer::Import(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint32_t usage) {
+ return Import(handle, width, height, stride, format, usage, usage);
+}
+
+int IonBuffer::Import(buffer_handle_t handle, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage) {
ATRACE_NAME("IonBuffer::Import1");
ALOGD_IF(
TRACE,
- "IonBuffer::Import: handle=%p width=%d height=%d stride=%d format=%d "
- "usage=%d",
- handle, width, height, stride, format, usage);
+ "IonBuffer::Import: handle=%p width=%u height=%u stride=%u format=%u "
+ "producer_usage=%" PRIx64 " consumer_usage=%" PRIx64,
+ handle, width, height, stride, format, producer_usage, consumer_usage);
FreeHandle();
- buffer_ = new GraphicBuffer(handle, GraphicBuffer::TAKE_UNREGISTERED_HANDLE,
- width, height, format, 1, usage, stride);
- if (buffer_->initCheck() != OK) {
+ sp<GraphicBuffer> buffer = new GraphicBuffer(
+ handle, GraphicBuffer::TAKE_UNREGISTERED_HANDLE, width, height, format,
+ kDefaultGraphicBufferLayerCount, producer_usage, consumer_usage, stride);
+ if (buffer->initCheck() != OK) {
ALOGE("IonBuffer::Import: Failed to import buffer");
return -EINVAL;
+ } else {
+ buffer_ = buffer;
+ producer_usage_ = producer_usage;
+ consumer_usage_ = consumer_usage;
+ return 0;
}
- return 0;
}
int IonBuffer::Import(const int* fd_array, int fd_count, const int* int_array,
- int int_count, int width, int height, int stride,
- int format, int usage) {
+ int int_count, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint32_t usage) {
+ return Import(fd_array, fd_count, int_array, int_count, width, height, stride,
+ format, usage, usage);
+}
+
+int IonBuffer::Import(const int* fd_array, int fd_count, const int* int_array,
+ int int_count, uint32_t width, uint32_t height,
+ uint32_t stride, uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage) {
ATRACE_NAME("IonBuffer::Import2");
ALOGD_IF(TRACE,
- "IonBuffer::Import: fd_count=%d int_count=%d width=%d height=%d "
- "stride=%d format=%d usage=%d",
- fd_count, int_count, width, height, stride, format, usage);
+ "IonBuffer::Import: fd_count=%d int_count=%d width=%u height=%u "
+ "stride=%u format=%u producer_usage=%" PRIx64
+ " consumer_usage=%" PRIx64,
+ fd_count, int_count, width, height, stride, format, producer_usage,
+ consumer_usage);
if (fd_count < 0 || int_count < 0) {
ALOGE("IonBuffer::Import: invalid arguments.");
@@ -128,7 +193,8 @@
memcpy(handle->data, fd_array, sizeof(int) * fd_count);
memcpy(handle->data + fd_count, int_array, sizeof(int) * int_count);
- int ret = Import(handle, width, height, stride, format, usage);
+ const int ret = Import(handle, width, height, stride, format, producer_usage,
+ consumer_usage);
if (ret < 0) {
ALOGE("IonBuffer::Import: failed to import raw native handle: %s",
strerror(-ret));
@@ -163,8 +229,9 @@
memcpy(handle->data + fd_count, other->handle()->data + fd_count,
sizeof(int) * int_count);
- const int ret = Import(handle, other->width(), other->height(),
- other->stride(), other->format(), other->usage());
+ const int ret =
+ Import(handle, other->width(), other->height(), other->stride(),
+ other->format(), other->producer_usage(), other->consumer_usage());
if (ret < 0) {
ALOGE("IonBuffer::Duplicate: Failed to import duplicate native handle: %s",
strerror(-ret));
@@ -175,7 +242,7 @@
return ret;
}
-int IonBuffer::Lock(int usage, int x, int y, int width, int height,
+int IonBuffer::Lock(uint32_t usage, int x, int y, int width, int height,
void** address) {
ATRACE_NAME("IonBuffer::Lock");
ALOGD_IF(TRACE,
@@ -183,23 +250,23 @@
"address=%p",
handle(), usage, x, y, width, height, address);
- status_t err = buffer_->lock(usage, Rect(x, y, x + width, y + height),
- address);
+ status_t err =
+ buffer_->lock(usage, Rect(x, y, x + width, y + height), address);
if (err != NO_ERROR)
return -EINVAL;
else
return 0;
}
-int IonBuffer::LockYUV(int usage, int x, int y, int width, int height,
+int IonBuffer::LockYUV(uint32_t usage, int x, int y, int width, int height,
struct android_ycbcr* yuv) {
ATRACE_NAME("IonBuffer::LockYUV");
ALOGD_IF(TRACE,
"IonBuffer::Lock: handle=%p usage=%d x=%d y=%d width=%d height=%d",
handle(), usage, x, y, width, height);
- status_t err = buffer_->lockYCbCr(usage, Rect(x, y, x + width, y + height),
- yuv);
+ status_t err =
+ buffer_->lockYCbCr(usage, Rect(x, y, x + width, y + height), yuv);
if (err != NO_ERROR)
return -EINVAL;
else
@@ -216,5 +283,5 @@
else
return 0;
}
-} // namespace dvr
-} // namespace android
+} // namespace dvr
+} // namespace android
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
index e491abc..b431d2f 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_client.cpp
@@ -317,7 +317,7 @@
}
ProducerQueue::ProducerQueue(size_t meta_size)
- : ProducerQueue(meta_size, 0, 0, 0, 0) {}
+ : ProducerQueue(meta_size, 0, 0, 0, 0, 0, 0, 0, 0) {}
ProducerQueue::ProducerQueue(LocalChannelHandle handle)
: BASE(std::move(handle)) {
@@ -329,13 +329,22 @@
}
}
-ProducerQueue::ProducerQueue(size_t meta_size, int usage_set_mask,
- int usage_clear_mask, int usage_deny_set_mask,
- int usage_deny_clear_mask)
+ProducerQueue::ProducerQueue(size_t meta_size, uint64_t producer_usage_set_mask,
+ uint64_t producer_usage_clear_mask,
+ uint64_t producer_usage_deny_set_mask,
+ uint64_t producer_usage_deny_clear_mask,
+ uint64_t consumer_usage_set_mask,
+ uint64_t consumer_usage_clear_mask,
+ uint64_t consumer_usage_deny_set_mask,
+ uint64_t consumer_usage_deny_clear_mask)
: BASE(BufferHubRPC::kClientPath) {
auto status = InvokeRemoteMethod<BufferHubRPC::CreateProducerQueue>(
- meta_size, usage_set_mask, usage_clear_mask, usage_deny_set_mask,
- usage_deny_clear_mask);
+ meta_size,
+ UsagePolicy{producer_usage_set_mask, producer_usage_clear_mask,
+ producer_usage_deny_set_mask, producer_usage_deny_clear_mask,
+ consumer_usage_set_mask, consumer_usage_clear_mask,
+ consumer_usage_deny_set_mask,
+ consumer_usage_deny_clear_mask});
if (!status) {
ALOGE("ProducerQueue::ProducerQueue: Failed to create producer queue: %s",
status.GetErrorMessage().c_str());
@@ -346,8 +355,17 @@
SetupQueue(status.get().meta_size_bytes, status.get().id);
}
-int ProducerQueue::AllocateBuffer(int width, int height, int format, int usage,
+int ProducerQueue::AllocateBuffer(uint32_t width, uint32_t height,
+ uint32_t format, uint32_t usage,
size_t slice_count, size_t* out_slot) {
+ return AllocateBuffer(width, height, format, usage, usage, slice_count,
+ out_slot);
+}
+
+int ProducerQueue::AllocateBuffer(uint32_t width, uint32_t height,
+ uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage, size_t slice_count,
+ size_t* out_slot) {
if (out_slot == nullptr) {
ALOGE("ProducerQueue::AllocateBuffer: Parameter out_slot cannot be null.");
return -EINVAL;
@@ -363,7 +381,8 @@
Status<std::vector<std::pair<LocalChannelHandle, size_t>>> status =
InvokeRemoteMethod<BufferHubRPC::ProducerQueueAllocateBuffers>(
- width, height, format, usage, slice_count, kBufferCount);
+ width, height, format, producer_usage, consumer_usage, slice_count,
+ kBufferCount);
if (!status) {
ALOGE(
"ProducerQueue::AllocateBuffer failed to create producer buffer "
diff --git a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
index 3fe7642..ebd7da0 100644
--- a/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
+++ b/libs/vr/libbufferhubqueue/buffer_hub_queue_producer.cpp
@@ -38,22 +38,8 @@
}
const auto& buffer_producer = core_->buffers_[slot].mBufferProducer;
+ sp<GraphicBuffer> graphic_buffer = buffer_producer->buffer()->buffer();
- // Create new GraphicBuffer based on the newly created |buffer_producer|. Here
- // we have to cast |buffer_handle_t| to |native_handle_t|, it's OK because
- // internally, GraphicBuffer is still an |ANativeWindowBuffer| and |handle|
- // is still type of |buffer_handle_t| and bears const property.
- sp<GraphicBuffer> graphic_buffer(new GraphicBuffer(
- buffer_producer->width(), buffer_producer->height(),
- buffer_producer->format(),
- 1, /* layer count */
- buffer_producer->usage(),
- buffer_producer->stride(),
- const_cast<native_handle_t*>(buffer_producer->buffer()->handle()),
- false));
-
- LOG_ALWAYS_FATAL_IF(NO_ERROR != graphic_buffer->initCheck(),
- "Failed to init GraphicBuffer.");
core_->buffers_[slot].mGraphicBuffer = graphic_buffer;
core_->buffers_[slot].mRequestBufferCalled = true;
@@ -155,9 +141,9 @@
if (!buffer_producer)
return NO_MEMORY;
- if (static_cast<int>(width) == buffer_producer->width() &&
- static_cast<int>(height) == buffer_producer->height() &&
- static_cast<int>(format) == buffer_producer->format()) {
+ if (width == buffer_producer->width() &&
+ height == buffer_producer->height() &&
+ static_cast<uint32_t>(format) == buffer_producer->format()) {
// The producer queue returns a buffer producer matches the request.
break;
}
@@ -165,8 +151,8 @@
// Needs reallocation.
// TODO(jwcai) Consider use VLOG instead if we find this log is not useful.
ALOGI(
- "dequeueBuffer: requested buffer (w=%u, h=%u, format=%d) is different "
- "from the buffer returned at slot: %zu (w=%d, h=%d, format=%d). Need "
+ "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());
@@ -322,7 +308,7 @@
output->width = buffer_producer->width();
output->height = buffer_producer->height();
- output->transformHint = 0; // default value, we don't use it yet.
+ output->transformHint = 0; // default value, we don't use it yet.
// |numPendingBuffers| counts of the number of buffers that has been enqueued
// by the producer but not yet acquired by the consumer. Due to the nature
@@ -456,7 +442,7 @@
return NO_ERROR;
}
-status_t BufferHubQueueProducer::disconnect(int api, DisconnectMode mode) {
+status_t BufferHubQueueProducer::disconnect(int api, DisconnectMode /*mode*/) {
// Consumer interaction are actually handled by buffer hub, and we need
// to maintain consumer operations here. We only need to perform basic input
// parameter checks here.
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 2b70c5b..255793f 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
@@ -274,12 +274,27 @@
// |usage_deny_clear_mask| shall not conflict with each other. Such
// configuration will be treated as invalid input on creation.
template <typename Meta>
- static std::unique_ptr<ProducerQueue> Create(int usage_set_mask,
- int usage_clear_mask,
- int usage_deny_set_mask,
- int usage_deny_clear_mask) {
+ static std::unique_ptr<ProducerQueue> Create(uint32_t usage_set_mask,
+ uint32_t usage_clear_mask,
+ uint32_t usage_deny_set_mask,
+ uint32_t usage_deny_clear_mask) {
return BASE::Create(sizeof(Meta), usage_set_mask, usage_clear_mask,
- usage_deny_set_mask, usage_deny_clear_mask);
+ usage_deny_set_mask, usage_deny_clear_mask,
+ usage_set_mask, usage_clear_mask, usage_deny_set_mask,
+ usage_deny_clear_mask);
+ }
+ template <typename Meta>
+ static std::unique_ptr<ProducerQueue> Create(
+ uint64_t producer_usage_set_mask, uint64_t producer_usage_clear_mask,
+ uint64_t producer_usage_deny_set_mask,
+ uint64_t producer_usage_deny_clear_mask, uint64_t consumer_usage_set_mask,
+ uint64_t consumer_usage_clear_mask, uint64_t consumer_usage_deny_set_mask,
+ uint64_t consumer_usage_deny_clear_mask) {
+ return BASE::Create(sizeof(Meta), producer_usage_set_mask,
+ producer_usage_clear_mask, producer_usage_deny_set_mask,
+ producer_usage_deny_clear_mask, consumer_usage_set_mask,
+ consumer_usage_clear_mask, consumer_usage_deny_set_mask,
+ consumer_usage_deny_clear_mask);
}
// Import a |ProducerQueue| from a channel handle.
@@ -301,7 +316,10 @@
// use (i.e. in |Gain|'ed mode).
// Returns Zero on success and negative error code when buffer allocation
// fails.
- int AllocateBuffer(int width, int height, int format, int usage,
+ int AllocateBuffer(uint32_t width, uint32_t height, uint32_t format,
+ uint32_t usage, size_t slice_count, size_t* out_slot);
+ int AllocateBuffer(uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage,
size_t slice_count, size_t* out_slot);
// Add a producer buffer to populate the queue. Once added, a producer buffer
@@ -327,8 +345,14 @@
// arguments as the constructors.
explicit ProducerQueue(size_t meta_size);
ProducerQueue(LocalChannelHandle handle);
- ProducerQueue(size_t meta_size, int usage_set_mask, int usage_clear_mask,
- int usage_deny_set_mask, int usage_deny_clear_mask);
+ ProducerQueue(size_t meta_size, uint64_t producer_usage_set_mask,
+ uint64_t producer_usage_clear_mask,
+ uint64_t producer_usage_deny_set_mask,
+ uint64_t producer_usage_deny_clear_mask,
+ uint64_t consumer_usage_set_mask,
+ uint64_t consumer_usage_clear_mask,
+ uint64_t consumer_usage_deny_set_mask,
+ uint64_t consumer_usage_deny_clear_mask);
int OnBufferReady(std::shared_ptr<BufferHubBuffer> buf,
LocalHandle* release_fence) override;
diff --git a/libs/vr/libdisplay/display_client.cpp b/libs/vr/libdisplay/display_client.cpp
index 6d39cdb..ef50a0f 100644
--- a/libs/vr/libdisplay/display_client.cpp
+++ b/libs/vr/libdisplay/display_client.cpp
@@ -216,7 +216,8 @@
return 0;
}
-pdx::Status<void> DisplayClient::SetViewerParams(const ViewerParams& viewer_params) {
+pdx::Status<void> DisplayClient::SetViewerParams(
+ const ViewerParams& viewer_params) {
auto status = InvokeRemoteMethod<DisplayRPC::SetViewerParams>(viewer_params);
if (!status) {
ALOGE("DisplayClient::SetViewerParams: Failed to set viewer params: %s",
@@ -252,16 +253,20 @@
return DisplaySurfaceClient::Create(width, height, format, usage, flags);
}
-std::unique_ptr<BufferConsumer> DisplayClient::GetPoseBuffer() {
- auto status = InvokeRemoteMethod<DisplayRPC::GetPoseBuffer>();
+std::unique_ptr<IonBuffer> DisplayClient::GetNamedBuffer(
+ const std::string& name) {
+ auto status = InvokeRemoteMethod<DisplayRPC::GetNamedBuffer>(name);
if (!status) {
ALOGE(
- "DisplayClient::GetPoseBuffer: Failed to get pose buffer %s",
- status.GetErrorMessage().c_str());
+ "DisplayClient::GetNamedBuffer: Failed to get pose buffer. name=%s, "
+ "error=%s",
+ name.c_str(), status.GetErrorMessage().c_str());
return nullptr;
}
- return BufferConsumer::Import(std::move(status));
+ auto ion_buffer = std::make_unique<IonBuffer>();
+ status.take().Import(ion_buffer.get());
+ return ion_buffer;
}
bool DisplayClient::IsVrAppRunning() {
diff --git a/libs/vr/libdisplay/display_manager_client_impl.cpp b/libs/vr/libdisplay/display_manager_client_impl.cpp
index 7993fce..44b3c4b 100644
--- a/libs/vr/libdisplay/display_manager_client_impl.cpp
+++ b/libs/vr/libdisplay/display_manager_client_impl.cpp
@@ -31,19 +31,22 @@
return 0;
}
-std::unique_ptr<BufferProducer> DisplayManagerClient::SetupPoseBuffer(
- size_t extended_region_size, int usage) {
- auto status = InvokeRemoteMethod<DisplayManagerRPC::SetupPoseBuffer>(
- extended_region_size, usage);
+std::unique_ptr<IonBuffer> DisplayManagerClient::SetupNamedBuffer(
+ const std::string& name, size_t size, uint64_t producer_usage,
+ uint64_t consumer_usage) {
+ auto status = InvokeRemoteMethod<DisplayManagerRPC::SetupNamedBuffer>(
+ name, size, producer_usage, consumer_usage);
if (!status) {
ALOGE(
- "DisplayManagerClient::SetupPoseBuffer: Failed to create the pose "
- "buffer %s",
- status.GetErrorMessage().c_str());
+ "DisplayManagerClient::SetupNamedBuffer: Failed to create the named "
+ "buffer: name=%s, error=%s",
+ name.c_str(), status.GetErrorMessage().c_str());
return {};
}
- return BufferProducer::Import(std::move(status));
+ auto ion_buffer = std::make_unique<IonBuffer>();
+ status.take().Import(ion_buffer.get());
+ return ion_buffer;
}
} // namespace dvr
diff --git a/libs/vr/libdisplay/include/private/dvr/display_client.h b/libs/vr/libdisplay/include/private/dvr/display_client.h
index 378f67c..fec2ea5 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_client.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_client.h
@@ -108,7 +108,7 @@
std::unique_ptr<DisplaySurfaceClient> CreateDisplaySurface(
int width, int height, int format, int usage, int flags);
- std::unique_ptr<BufferConsumer> GetPoseBuffer();
+ std::unique_ptr<IonBuffer> GetNamedBuffer(const std::string& name);
// Temporary query for current VR status. Will be removed later.
bool IsVrAppRunning();
diff --git a/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h b/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h
index 144cd3b..b0a7d13 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_manager_client_impl.h
@@ -17,8 +17,10 @@
int GetSurfaceList(std::vector<DisplaySurfaceInfo>* surface_list);
- std::unique_ptr<BufferProducer> SetupPoseBuffer(size_t extended_region_size,
- int usage);
+ std::unique_ptr<IonBuffer> SetupNamedBuffer(const std::string& name,
+ size_t size,
+ uint64_t producer_usage,
+ uint64_t consumer_usage);
using Client::event_fd;
using Client::GetChannel;
diff --git a/libs/vr/libdisplay/include/private/dvr/display_rpc.h b/libs/vr/libdisplay/include/private/dvr/display_rpc.h
index ac08650..c12b090 100644
--- a/libs/vr/libdisplay/include/private/dvr/display_rpc.h
+++ b/libs/vr/libdisplay/include/private/dvr/display_rpc.h
@@ -9,6 +9,7 @@
#include <pdx/rpc/remote_method.h>
#include <pdx/rpc/serializable.h>
#include <pdx/rpc/variant.h>
+#include <private/dvr/bufferhub_rpc.h>
#include <private/dvr/display_types.h>
namespace android {
@@ -218,7 +219,7 @@
kOpCreateVideoMeshSurface,
kOpVideoMeshSurfaceCreateProducerQueue,
kOpSetViewerParams,
- kOpGetPoseBuffer,
+ kOpGetNamedBuffer,
kOpIsVrAppRunning,
};
@@ -247,8 +248,8 @@
LocalChannelHandle(Void));
PDX_REMOTE_METHOD(SetViewerParams, kOpSetViewerParams,
void(const ViewerParams& viewer_params));
- PDX_REMOTE_METHOD(GetPoseBuffer, kOpGetPoseBuffer,
- LocalChannelHandle(Void));
+ PDX_REMOTE_METHOD(GetNamedBuffer, kOpGetNamedBuffer,
+ LocalNativeBufferHandle(const std::string& name));
PDX_REMOTE_METHOD(IsVrAppRunning, kOpIsVrAppRunning, int(Void));
};
@@ -260,7 +261,7 @@
enum {
kOpGetSurfaceList = 0,
kOpUpdateSurfaces,
- kOpSetupPoseBuffer,
+ kOpSetupNamedBuffer,
};
// Aliases.
@@ -273,8 +274,11 @@
PDX_REMOTE_METHOD(
UpdateSurfaces, kOpUpdateSurfaces,
int(const std::map<int, DisplaySurfaceAttributes>& updates));
- PDX_REMOTE_METHOD(SetupPoseBuffer, kOpSetupPoseBuffer,
- LocalChannelHandle(size_t extended_region_size, int usage));
+ PDX_REMOTE_METHOD(SetupNamedBuffer, kOpSetupNamedBuffer,
+ LocalNativeBufferHandle(const std::string& name,
+ size_t size,
+ uint64_t producer_usage,
+ uint64_t consumer_usage));
};
struct ScreenshotData {
diff --git a/libs/vr/libdvr/display_manager_client.cpp b/libs/vr/libdvr/display_manager_client.cpp
index 7cbfc21..9247d53 100644
--- a/libs/vr/libdvr/display_manager_client.cpp
+++ b/libs/vr/libdvr/display_manager_client.cpp
@@ -42,14 +42,16 @@
delete client;
}
-DvrWriteBuffer* dvrDisplayManagerSetupPoseBuffer(
- DvrDisplayManagerClient* client, size_t extended_region_size,
- uint64_t usage0, uint64_t usage1) {
- // TODO(hendrikw): When we move to gralloc1, pass both usage0 and usage1 down.
- auto buffer_producer = client->client->SetupPoseBuffer(
- extended_region_size, static_cast<int>(usage0));
- if (buffer_producer) {
- return CreateDvrWriteBufferFromBufferProducer(std::move(buffer_producer));
+DvrBuffer* dvrDisplayManagerSetupNamedBuffer(DvrDisplayManagerClient* client,
+ const char* name, size_t size,
+ uint64_t producer_usage,
+ uint64_t consumer_usage) {
+ // TODO(hendrikw): When we move to gralloc1, pass both producer_usage and
+ // consumer_usage down.
+ auto ion_buffer = client->client->SetupNamedBuffer(name, size, producer_usage,
+ consumer_usage);
+ if (ion_buffer) {
+ return CreateDvrBufferFromIonBuffer(std::move(ion_buffer));
}
return nullptr;
}
diff --git a/libs/vr/libdvr/dvr_api.cpp b/libs/vr/libdvr/dvr_api.cpp
index 49702fd..b91de8f 100644
--- a/libs/vr/libdvr/dvr_api.cpp
+++ b/libs/vr/libdvr/dvr_api.cpp
@@ -31,8 +31,8 @@
dvrDisplayManagerClientGetSurfaceList;
dvr_api->display_manager_client_surface_list_destroy =
dvrDisplayManagerClientSurfaceListDestroy;
- dvr_api->display_manager_setup_pose_buffer =
- dvrDisplayManagerSetupPoseBuffer;
+ dvr_api->display_manager_setup_named_buffer =
+ dvrDisplayManagerSetupNamedBuffer;
dvr_api->display_manager_client_surface_list_get_size =
dvrDisplayManagerClientSurfaceListGetSize;
dvr_api->display_manager_client_surface_list_get_surface_id =
@@ -48,7 +48,6 @@
// dvr_buffer.h
dvr_api->write_buffer_destroy = dvrWriteBufferDestroy;
- dvr_api->write_buffer_get_blob_fds = dvrWriteBufferGetBlobFds;
dvr_api->write_buffer_get_ahardwarebuffer =
dvrWriteBufferGetAHardwareBuffer;
dvr_api->write_buffer_post = dvrWriteBufferPost;
@@ -56,11 +55,12 @@
dvr_api->write_buffer_gain_async = dvrWriteBufferGainAsync;
dvr_api->read_buffer_destroy = dvrReadBufferDestroy;
- dvr_api->read_buffer_get_blob_fds = dvrReadBufferGetBlobFds;
dvr_api->read_buffer_get_ahardwarebuffer = dvrReadBufferGetAHardwareBuffer;
dvr_api->read_buffer_acquire = dvrReadBufferAcquire;
dvr_api->read_buffer_release = dvrReadBufferRelease;
dvr_api->read_buffer_release_async = dvrReadBufferReleaseAsync;
+ dvr_api->buffer_destroy = dvrBufferDestroy;
+ dvr_api->buffer_get_ahardwarebuffer = dvrBufferGetAHardwareBuffer;
// dvr_buffer_queue.h
dvr_api->write_buffer_queue_destroy = dvrWriteBufferQueueDestroy;
@@ -77,7 +77,7 @@
dvr_api->read_buffer_queue_dequeue = dvrReadBufferQueueDequeue;
// dvr_surface.h
- dvr_api->get_pose_buffer = dvrGetPoseBuffer;
+ dvr_api->get_named_buffer = dvrGetNamedBuffer;
dvr_api->surface_create = dvrSurfaceCreate;
dvr_api->surface_get_write_buffer_queue = dvrSurfaceGetWriteBufferQueue;
diff --git a/libs/vr/libdvr/dvr_buffer.cpp b/libs/vr/libdvr/dvr_buffer.cpp
index 25128a6..0942b3d 100644
--- a/libs/vr/libdvr/dvr_buffer.cpp
+++ b/libs/vr/libdvr/dvr_buffer.cpp
@@ -6,13 +6,15 @@
using namespace android;
struct DvrWriteBuffer {
- std::shared_ptr<dvr::BufferProducer> write_buffer_;
- sp<GraphicBuffer> graphic_buffer_;
+ std::shared_ptr<dvr::BufferProducer> write_buffer;
};
struct DvrReadBuffer {
- std::shared_ptr<dvr::BufferConsumer> read_buffer_;
- sp<GraphicBuffer> graphic_buffer_;
+ std::shared_ptr<dvr::BufferConsumer> read_buffer;
+};
+
+struct DvrBuffer {
+ std::shared_ptr<dvr::IonBuffer> buffer;
};
namespace android {
@@ -20,16 +22,23 @@
DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
const std::shared_ptr<dvr::BufferProducer>& buffer_producer) {
- DvrWriteBuffer* write_buffer = new DvrWriteBuffer;
- write_buffer->write_buffer_ = std::move(buffer_producer);
- return write_buffer;
+ if (!buffer_producer)
+ return nullptr;
+ return new DvrWriteBuffer{std::move(buffer_producer)};
}
DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
const std::shared_ptr<dvr::BufferConsumer>& buffer_consumer) {
- DvrReadBuffer* read_buffer = new DvrReadBuffer;
- read_buffer->read_buffer_ = std::move(buffer_consumer);
- return read_buffer;
+ if (!buffer_consumer)
+ return nullptr;
+ return new DvrReadBuffer{std::move(buffer_consumer)};
+}
+
+DvrBuffer* CreateDvrBufferFromIonBuffer(
+ const std::shared_ptr<IonBuffer>& ion_buffer) {
+ if (!ion_buffer)
+ return nullptr;
+ return new DvrBuffer{std::move(ion_buffer)};
}
} // namespace dvr
@@ -49,79 +58,82 @@
extern "C" {
-void dvrWriteBufferDestroy(DvrWriteBuffer* client) { delete client; }
-
-void dvrWriteBufferGetBlobFds(DvrWriteBuffer* client, int* fds,
- size_t* fds_count, size_t max_fds_count) {
- client->write_buffer_->GetBlobFds(fds, fds_count, max_fds_count);
+void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer) {
+ delete write_buffer;
}
-int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* client,
+int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer) {
+ return write_buffer->write_buffer->id();
+}
+
+int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
AHardwareBuffer** hardware_buffer) {
- if (!client->graphic_buffer_.get()) {
- InitializeGraphicBuffer(client->write_buffer_.get(),
- &client->graphic_buffer_);
- }
- *hardware_buffer =
- reinterpret_cast<AHardwareBuffer*>(client->graphic_buffer_.get());
+ *hardware_buffer = reinterpret_cast<AHardwareBuffer*>(
+ write_buffer->write_buffer->buffer()->buffer().get());
return 0;
}
-int dvrWriteBufferPost(DvrWriteBuffer* client, int ready_fence_fd,
+int dvrWriteBufferPost(DvrWriteBuffer* write_buffer, int ready_fence_fd,
const void* meta, size_t meta_size_bytes) {
pdx::LocalHandle fence(ready_fence_fd);
- int result = client->write_buffer_->Post(fence, meta, meta_size_bytes);
- fence.Release();
+ int result = write_buffer->write_buffer->Post(fence, meta, meta_size_bytes);
return result;
}
-int dvrWriteBufferGain(DvrWriteBuffer* client, int* release_fence_fd) {
+int dvrWriteBufferGain(DvrWriteBuffer* write_buffer, int* release_fence_fd) {
pdx::LocalHandle release_fence;
- int result = client->write_buffer_->Gain(&release_fence);
+ int result = write_buffer->write_buffer->Gain(&release_fence);
*release_fence_fd = release_fence.Release();
return result;
}
-int dvrWriteBufferGainAsync(DvrWriteBuffer* client) {
- return client->write_buffer_->GainAsync();
+int dvrWriteBufferGainAsync(DvrWriteBuffer* write_buffer) {
+ return write_buffer->write_buffer->GainAsync();
}
-void dvrReadBufferDestroy(DvrReadBuffer* client) { delete client; }
+void dvrReadBufferDestroy(DvrReadBuffer* read_buffer) { delete read_buffer; }
-void dvrReadBufferGetBlobFds(DvrReadBuffer* client, int* fds, size_t* fds_count,
- size_t max_fds_count) {
- client->read_buffer_->GetBlobFds(fds, fds_count, max_fds_count);
+int dvrReadBufferGetId(DvrReadBuffer* read_buffer) {
+ return read_buffer->read_buffer->id();
}
-int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* client,
+int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
AHardwareBuffer** hardware_buffer) {
- if (!client->graphic_buffer_.get()) {
- InitializeGraphicBuffer(client->read_buffer_.get(),
- &client->graphic_buffer_);
- }
- *hardware_buffer =
- reinterpret_cast<AHardwareBuffer*>(client->graphic_buffer_.get());
+ *hardware_buffer = reinterpret_cast<AHardwareBuffer*>(
+ read_buffer->read_buffer->buffer()->buffer().get());
return 0;
}
-int dvrReadBufferAcquire(DvrReadBuffer* client, int* ready_fence_fd, void* meta,
- size_t meta_size_bytes) {
+int dvrReadBufferAcquire(DvrReadBuffer* read_buffer, int* ready_fence_fd,
+ void* meta, size_t meta_size_bytes) {
pdx::LocalHandle ready_fence;
int result =
- client->read_buffer_->Acquire(&ready_fence, meta, meta_size_bytes);
+ read_buffer->read_buffer->Acquire(&ready_fence, meta, meta_size_bytes);
*ready_fence_fd = ready_fence.Release();
return result;
}
-int dvrReadBufferRelease(DvrReadBuffer* client, int release_fence_fd) {
+int dvrReadBufferRelease(DvrReadBuffer* read_buffer, int release_fence_fd) {
pdx::LocalHandle fence(release_fence_fd);
- int result = client->read_buffer_->Release(fence);
- fence.Release();
+ int result = read_buffer->read_buffer->Release(fence);
return result;
}
-int dvrReadBufferReleaseAsync(DvrReadBuffer* client) {
- return client->read_buffer_->ReleaseAsync();
+int dvrReadBufferReleaseAsync(DvrReadBuffer* read_buffer) {
+ return read_buffer->read_buffer->ReleaseAsync();
+}
+
+void dvrBufferDestroy(DvrBuffer* buffer) { delete buffer; }
+
+int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
+ AHardwareBuffer** hardware_buffer) {
+ if (!hardware_buffer) {
+ return -EINVAL;
+ }
+
+ *hardware_buffer =
+ reinterpret_cast<AHardwareBuffer*>(buffer->buffer->buffer().get());
+ return 0;
}
} // extern "C"
diff --git a/libs/vr/libdvr/dvr_surface.cpp b/libs/vr/libdvr/dvr_surface.cpp
index a3cbba5..a04ed50 100644
--- a/libs/vr/libdvr/dvr_surface.cpp
+++ b/libs/vr/libdvr/dvr_surface.cpp
@@ -58,14 +58,25 @@
return 0;
}
-int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer) {
+int dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer) {
auto client = android::dvr::DisplayClient::Create();
if (!client) {
- ALOGE("Failed to create display client!");
+ ALOGE("dvrGetNamedBuffer: Failed to create display client!");
return -ECOMM;
}
- *pose_buffer = CreateDvrReadBufferFromBufferConsumer(client->GetPoseBuffer());
+ if (out_buffer == nullptr || name == nullptr) {
+ ALOGE("dvrGetNamedBuffer: Invalid inputs: name=%p, out_buffer=%p.", name,
+ out_buffer);
+ return -EINVAL;
+ }
+
+ auto named_buffer = client->GetNamedBuffer(name);
+ if (!named_buffer) {
+ ALOGE("dvrGetNamedBuffer: Failed to find named buffer: %s.", name);
+ return -EINVAL;
+ }
+ *out_buffer = CreateDvrBufferFromIonBuffer(std::move(named_buffer));
return 0;
}
diff --git a/libs/vr/libdvr/include/dvr/display_manager_client.h b/libs/vr/libdvr/include/dvr/display_manager_client.h
index 0928d43..4e1f227 100644
--- a/libs/vr/libdvr/include/dvr/display_manager_client.h
+++ b/libs/vr/libdvr/include/dvr/display_manager_client.h
@@ -14,15 +14,16 @@
DvrDisplayManagerClientSurfaceList;
typedef struct DvrDisplayManagerClientSurfaceBuffers
DvrDisplayManagerClientSurfaceBuffers;
-typedef struct DvrWriteBuffer DvrWriteBuffer;
+typedef struct DvrBuffer DvrBuffer;
DvrDisplayManagerClient* dvrDisplayManagerClientCreate();
void dvrDisplayManagerClientDestroy(DvrDisplayManagerClient* client);
-DvrWriteBuffer* dvrDisplayManagerSetupPoseBuffer(
- DvrDisplayManagerClient* client, size_t extended_region_size,
- uint64_t usage0, uint64_t usage1);
+DvrBuffer* dvrDisplayManagerSetupNamedBuffer(DvrDisplayManagerClient* client,
+ const char* name, size_t size,
+ uint64_t producer_usage,
+ uint64_t consumer_usage);
// Return an event fd for checking if there was an event on the server
// Note that the only event which will be flagged is POLLIN. You must use
diff --git a/libs/vr/libdvr/include/dvr/dvr_api.h b/libs/vr/libdvr/include/dvr/dvr_api.h
index a4fef19..c46684b 100644
--- a/libs/vr/libdvr/include/dvr/dvr_api.h
+++ b/libs/vr/libdvr/include/dvr/dvr_api.h
@@ -30,6 +30,7 @@
typedef struct DvrWriteBuffer DvrWriteBuffer;
typedef struct DvrReadBuffer DvrReadBuffer;
+typedef struct DvrBuffer DvrBuffer;
typedef struct AHardwareBuffer AHardwareBuffer;
typedef struct DvrWriteBufferQueue DvrWriteBufferQueue;
@@ -43,9 +44,9 @@
DvrDisplayManagerClientSurfaceList** surface_list);
typedef void (*DvrDisplayManagerClientSurfaceListDestroyPtr)(
DvrDisplayManagerClientSurfaceList* surface_list);
-typedef DvrWriteBuffer* (*DvrDisplayManagerSetupPoseBufferPtr)(
- DvrDisplayManagerClient* client, size_t extended_region_size,
- uint64_t usage0, uint64_t usage1);
+typedef DvrBuffer* (*DvrDisplayManagerSetupNamedBufferPtr)(
+ DvrDisplayManagerClient* client, const char* name, size_t size,
+ uint64_t producer_usage, uint64_t consumer_usage);
typedef size_t (*DvrDisplayManagerClientSurfaceListGetSizePtr)(
DvrDisplayManagerClientSurfaceList* surface_list);
typedef int (*DvrDisplayManagerClientSurfaceListGetSurfaceIdPtr)(
@@ -62,9 +63,6 @@
// dvr_buffer.h
typedef void (*DvrWriteBufferDestroyPtr)(DvrWriteBuffer* client);
-typedef void (*DvrWriteBufferGetBlobFdsPtr)(DvrWriteBuffer* client, int* fds,
- size_t* fds_count,
- size_t max_fds_count);
typedef int (*DvrWriteBufferGetAHardwareBufferPtr)(
DvrWriteBuffer* client, AHardwareBuffer** hardware_buffer);
typedef int (*DvrWriteBufferPostPtr)(DvrWriteBuffer* client, int ready_fence_fd,
@@ -74,9 +72,6 @@
typedef int (*DvrWriteBufferGainAsyncPtr)(DvrWriteBuffer* client);
typedef void (*DvrReadBufferDestroyPtr)(DvrReadBuffer* client);
-typedef void (*DvrReadBufferGetBlobFdsPtr)(DvrReadBuffer* client, int* fds,
- size_t* fds_count,
- size_t max_fds_count);
typedef int (*DvrReadBufferGetAHardwareBufferPtr)(
DvrReadBuffer* client, AHardwareBuffer** hardware_buffer);
typedef int (*DvrReadBufferAcquirePtr)(DvrReadBuffer* client,
@@ -85,6 +80,9 @@
typedef int (*DvrReadBufferReleasePtr)(DvrReadBuffer* client,
int release_fence_fd);
typedef int (*DvrReadBufferReleaseAsyncPtr)(DvrReadBuffer* client);
+typedef void (*DvrBufferDestroy)(DvrBuffer* buffer);
+typedef int (*DvrBufferGetAHardwareBuffer)(DvrBuffer* buffer,
+ AHardwareBuffer** hardware_buffer);
// dvr_buffer_queue.h
typedef void (*DvrWriteBufferQueueDestroyPtr)(DvrWriteBufferQueue* write_queue);
@@ -110,7 +108,7 @@
size_t meta_size_bytes);
// dvr_surface.h
-typedef int (*DvrGetPoseBufferPtr)(DvrReadBuffer** pose_buffer);
+typedef int (*DvrGetNamedBufferPtr)(const char* name, DvrBuffer** out_buffer);
typedef int (*DvrSurfaceCreatePtr)(int width, int height, int format,
uint64_t usage0, uint64_t usage1, int flags,
DvrSurface** out_surface);
@@ -149,7 +147,7 @@
// dvr_hardware_composer_client.h
typedef struct DvrHwcClient DvrHwcClient;
typedef struct DvrHwcFrame DvrHwcFrame;
-typedef int(*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
+typedef int (*DvrHwcOnFrameCallback)(void* client_state, DvrHwcFrame* frame);
typedef DvrHwcClient* (*DvrHwcClientCreatePtr)(DvrHwcOnFrameCallback callback,
void* client_state);
typedef void (*DvrHwcClientDestroyPtr)(DvrHwcClient* client);
@@ -159,7 +157,8 @@
typedef int32_t (*DvrHwcFrameGetDisplayHeightPtr)(DvrHwcFrame* frame);
typedef bool (*DvrHwcFrameGetDisplayRemovedPtr)(DvrHwcFrame* frame);
typedef size_t (*DvrHwcFrameGetLayerCountPtr)(DvrHwcFrame* frame);
-typedef Layer (*DvrHwcFrameGetLayerIdPtr)(DvrHwcFrame* frame, size_t layer_index);
+typedef Layer (*DvrHwcFrameGetLayerIdPtr)(DvrHwcFrame* frame,
+ size_t layer_index);
typedef AHardwareBuffer* (*DvrHwcFrameGetLayerBufferPtr)(DvrHwcFrame* frame,
size_t layer_index);
typedef int (*DvrHwcFrameGetLayerFencePtr)(DvrHwcFrame* frame,
@@ -185,7 +184,7 @@
display_manager_client_get_surface_list;
DvrDisplayManagerClientSurfaceListDestroyPtr
display_manager_client_surface_list_destroy;
- DvrDisplayManagerSetupPoseBufferPtr display_manager_setup_pose_buffer;
+ DvrDisplayManagerSetupNamedBufferPtr display_manager_setup_named_buffer;
DvrDisplayManagerClientSurfaceListGetSizePtr
display_manager_client_surface_list_get_size;
DvrDisplayManagerClientSurfaceListGetSurfaceIdPtr
@@ -201,7 +200,6 @@
// Write buffer
DvrWriteBufferDestroyPtr write_buffer_destroy;
- DvrWriteBufferGetBlobFdsPtr write_buffer_get_blob_fds;
DvrWriteBufferGetAHardwareBufferPtr write_buffer_get_ahardwarebuffer;
DvrWriteBufferPostPtr write_buffer_post;
DvrWriteBufferGainPtr write_buffer_gain;
@@ -209,11 +207,12 @@
// Read buffer
DvrReadBufferDestroyPtr read_buffer_destroy;
- DvrReadBufferGetBlobFdsPtr read_buffer_get_blob_fds;
DvrReadBufferGetAHardwareBufferPtr read_buffer_get_ahardwarebuffer;
DvrReadBufferAcquirePtr read_buffer_acquire;
DvrReadBufferReleasePtr read_buffer_release;
DvrReadBufferReleaseAsyncPtr read_buffer_release_async;
+ DvrBufferDestroy buffer_destroy;
+ DvrBufferGetAHardwareBuffer buffer_get_ahardwarebuffer;
// Write buffer queue
DvrWriteBufferQueueDestroyPtr write_buffer_queue_destroy;
@@ -235,7 +234,7 @@
DvrVSyncClientGetSchedInfoPtr vsync_client_get_sched_info;
// Display surface
- DvrGetPoseBufferPtr get_pose_buffer;
+ DvrGetNamedBufferPtr get_named_buffer;
DvrSurfaceCreatePtr surface_create;
DvrSurfaceGetWriteBufferQueuePtr surface_get_write_buffer_queue;
diff --git a/libs/vr/libdvr/include/dvr/dvr_buffer.h b/libs/vr/libdvr/include/dvr/dvr_buffer.h
index bbfbb00..6c9c4d3 100644
--- a/libs/vr/libdvr/include/dvr/dvr_buffer.h
+++ b/libs/vr/libdvr/include/dvr/dvr_buffer.h
@@ -1,9 +1,9 @@
#ifndef ANDROID_DVR_BUFFER_H_
#define ANDROID_DVR_BUFFER_H_
-#include <memory>
#include <stdbool.h>
#include <stdint.h>
+#include <memory>
#ifdef __cplusplus
extern "C" {
@@ -11,29 +11,33 @@
typedef struct DvrWriteBuffer DvrWriteBuffer;
typedef struct DvrReadBuffer DvrReadBuffer;
+typedef struct DvrBuffer DvrBuffer;
typedef struct AHardwareBuffer AHardwareBuffer;
// Write buffer
-void dvrWriteBufferDestroy(DvrWriteBuffer* client);
-void dvrWriteBufferGetBlobFds(DvrWriteBuffer* client, int* fds,
- size_t* fds_count, size_t max_fds_count);
-int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* client,
+void dvrWriteBufferDestroy(DvrWriteBuffer* write_buffer);
+int dvrWriteBufferGetId(DvrWriteBuffer* write_buffer);
+int dvrWriteBufferGetAHardwareBuffer(DvrWriteBuffer* write_buffer,
AHardwareBuffer** hardware_buffer);
-int dvrWriteBufferPost(DvrWriteBuffer* client, int ready_fence_fd,
+int dvrWriteBufferPost(DvrWriteBuffer* write_buffer, int ready_fence_fd,
const void* meta, size_t meta_size_bytes);
-int dvrWriteBufferGain(DvrWriteBuffer* client, int* release_fence_fd);
-int dvrWriteBufferGainAsync(DvrWriteBuffer* client);
+int dvrWriteBufferGain(DvrWriteBuffer* write_buffer, int* release_fence_fd);
+int dvrWriteBufferGainAsync(DvrWriteBuffer* write_buffer);
// Read buffer
-void dvrReadBufferDestroy(DvrReadBuffer* client);
-void dvrReadBufferGetBlobFds(DvrReadBuffer* client, int* fds, size_t* fds_count,
- size_t max_fds_count);
-int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* client,
+void dvrReadBufferDestroy(DvrReadBuffer* read_buffer);
+int dvrReadBufferGetId(DvrReadBuffer* read_buffer);
+int dvrReadBufferGetAHardwareBuffer(DvrReadBuffer* read_buffer,
AHardwareBuffer** hardware_buffer);
-int dvrReadBufferAcquire(DvrReadBuffer* client, int* ready_fence_fd, void* meta,
- size_t meta_size_bytes);
-int dvrReadBufferRelease(DvrReadBuffer* client, int release_fence_fd);
-int dvrReadBufferReleaseAsync(DvrReadBuffer* client);
+int dvrReadBufferAcquire(DvrReadBuffer* read_buffer, int* ready_fence_fd,
+ void* meta, size_t meta_size_bytes);
+int dvrReadBufferRelease(DvrReadBuffer* read_buffer, int release_fence_fd);
+int dvrReadBufferReleaseAsync(DvrReadBuffer* read_buffer);
+
+// Buffer
+void dvrBufferDestroy(DvrBuffer* buffer);
+int dvrBufferGetAHardwareBuffer(DvrBuffer* buffer,
+ AHardwareBuffer** hardware_buffer);
#ifdef __cplusplus
} // extern "C"
@@ -44,11 +48,14 @@
class BufferProducer;
class BufferConsumer;
+class IonBuffer;
DvrWriteBuffer* CreateDvrWriteBufferFromBufferProducer(
const std::shared_ptr<BufferProducer>& buffer_producer);
DvrReadBuffer* CreateDvrReadBufferFromBufferConsumer(
const std::shared_ptr<BufferConsumer>& buffer_consumer);
+DvrBuffer* CreateDvrBufferFromIonBuffer(
+ const std::shared_ptr<IonBuffer>& ion_buffer);
} // namespace dvr
} // namespace android
diff --git a/libs/vr/libdvr/include/dvr/dvr_surface.h b/libs/vr/libdvr/include/dvr/dvr_surface.h
index 2712f24..e5228d6 100644
--- a/libs/vr/libdvr/include/dvr/dvr_surface.h
+++ b/libs/vr/libdvr/include/dvr/dvr_surface.h
@@ -12,7 +12,7 @@
typedef struct DvrSurfaceParameter DvrSurfaceParameter;
// Get a pointer to the global pose buffer.
-int dvrGetPoseBuffer(DvrReadBuffer** pose_buffer);
+int dvrGetNamedBuffer(const char* name, DvrBuffer** out_buffer);
int dvrSurfaceCreate(int width, int height, int format, uint64_t usage0,
uint64_t usage1, int flags, DvrSurface** out_surface);
diff --git a/libs/vr/libdvr/tests/Android.mk b/libs/vr/libdvr/tests/Android.mk
index 75e2a7d..29cdc13 100644
--- a/libs/vr/libdvr/tests/Android.mk
+++ b/libs/vr/libdvr/tests/Android.mk
@@ -17,14 +17,18 @@
libbufferhub \
libchrome \
libdvrcommon \
+ libdisplay \
libpdx_default_transport \
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := dvr_buffer_queue-test.cpp
+LOCAL_SRC_FILES := \
+ dvr_buffer_queue-test.cpp \
+ dvr_named_buffer-test.cpp \
+
LOCAL_STATIC_LIBRARIES := $(static_libraries)
LOCAL_SHARED_LIBRARIES := $(shared_libraries)
LOCAL_EXPORT_C_INCLUDE_DIRS := ${LOCAL_C_INCLUDES}
-LOCAL_CFLAGS := -DLOG_TAG=\"dvr_buffer_queue-test\" -DTRACE=0 -O0 -g
-LOCAL_MODULE := dvr_buffer_queue-test
+LOCAL_CFLAGS := -DLOG_TAG=\"dvr_api-test\" -DTRACE=0 -O0 -g
+LOCAL_MODULE := dvr_api-test
LOCAL_MODULE_TAGS := optional
include $(BUILD_NATIVE_TEST)
diff --git a/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
new file mode 100644
index 0000000..cd3285f
--- /dev/null
+++ b/libs/vr/libdvr/tests/dvr_named_buffer-test.cpp
@@ -0,0 +1,122 @@
+#include <android/hardware_buffer.h>
+#include <dvr/display_manager_client.h>
+#include <dvr/dvr_buffer.h>
+#include <dvr/dvr_surface.h>
+#include <system/graphics.h>
+
+#include <base/logging.h>
+#include <gtest/gtest.h>
+
+namespace android {
+namespace dvr {
+
+namespace {
+
+class DvrNamedBufferTest : public ::testing::Test {
+ protected:
+ void SetUp() override {
+ client_ = dvrDisplayManagerClientCreate();
+ ASSERT_NE(nullptr, client_);
+ }
+
+ void TearDown() override {
+ if (client_ != nullptr) {
+ dvrDisplayManagerClientDestroy(client_);
+ client_ = nullptr;
+ }
+ }
+
+ DvrDisplayManagerClient* client_ = nullptr;
+};
+
+TEST_F(DvrNamedBufferTest, TestNamedBuffersSameName) {
+ const char* buffer_name = "same_name";
+ DvrBuffer* buffer1 =
+ dvrDisplayManagerSetupNamedBuffer(client_, buffer_name, 10, 0, 0);
+ ASSERT_NE(nullptr, buffer1);
+
+ DvrBuffer* buffer2 =
+ dvrDisplayManagerSetupNamedBuffer(client_, buffer_name, 10, 0, 0);
+ ASSERT_NE(nullptr, buffer2);
+
+ AHardwareBuffer* hardware_buffer1 = nullptr;
+ int e1 = dvrBufferGetAHardwareBuffer(buffer1, &hardware_buffer1);
+ ASSERT_EQ(0, e1);
+
+ AHardwareBuffer* hardware_buffer2 = nullptr;
+ int e2 = dvrBufferGetAHardwareBuffer(buffer2, &hardware_buffer2);
+ ASSERT_EQ(0, e2);
+ ASSERT_NE(nullptr, hardware_buffer1);
+
+ AHardwareBuffer_Desc desc1 = {};
+ AHardwareBuffer_describe(hardware_buffer1, &desc1);
+ AHardwareBuffer_Desc desc2 = {};
+ AHardwareBuffer_describe(hardware_buffer2, &desc2);
+ ASSERT_EQ(desc1.width, 10u);
+ ASSERT_EQ(desc1.height, 1u);
+ ASSERT_EQ(desc1.layers, 1u);
+ ASSERT_EQ(desc1.format, HAL_PIXEL_FORMAT_BLOB);
+ ASSERT_EQ(desc1.usage0, 0u);
+ ASSERT_EQ(desc1.usage1, 0u);
+ ASSERT_EQ(desc2.width, 10u);
+ ASSERT_EQ(desc2.height, 1u);
+ ASSERT_EQ(desc2.layers, 1u);
+ ASSERT_EQ(desc2.format, HAL_PIXEL_FORMAT_BLOB);
+ ASSERT_EQ(desc2.usage0, 0u);
+ ASSERT_EQ(desc2.usage1, 0u);
+
+ dvrBufferDestroy(buffer1);
+ dvrBufferDestroy(buffer2);
+
+ DvrBuffer* buffer3 = nullptr;
+ int e3 = dvrGetNamedBuffer(buffer_name, &buffer3);
+ ASSERT_NE(nullptr, buffer3);
+ ASSERT_EQ(0, e3);
+
+ AHardwareBuffer* hardware_buffer3 = nullptr;
+ int e4 = dvrBufferGetAHardwareBuffer(buffer2, &hardware_buffer3);
+ ASSERT_EQ(0, e4);
+ ASSERT_NE(nullptr, hardware_buffer3);
+
+ AHardwareBuffer_Desc desc3 = {};
+ AHardwareBuffer_describe(hardware_buffer3, &desc3);
+ ASSERT_EQ(desc3.width, 10u);
+ ASSERT_EQ(desc3.height, 1u);
+ ASSERT_EQ(desc3.layers, 1u);
+ ASSERT_EQ(desc3.format, HAL_PIXEL_FORMAT_BLOB);
+ ASSERT_EQ(desc3.usage0, 0u);
+ ASSERT_EQ(desc3.usage1, 0u);
+
+ dvrBufferDestroy(buffer3);
+}
+
+TEST_F(DvrNamedBufferTest, TestMultipleNamedBuffers) {
+ const char* buffer_name1 = "test1";
+ const char* buffer_name2 = "test2";
+ DvrBuffer* setup_buffer1 =
+ dvrDisplayManagerSetupNamedBuffer(client_, buffer_name1, 10, 0, 0);
+ ASSERT_NE(nullptr, setup_buffer1);
+ dvrBufferDestroy(setup_buffer1);
+
+ DvrBuffer* setup_buffer2 =
+ dvrDisplayManagerSetupNamedBuffer(client_, buffer_name2, 10, 0, 0);
+ ASSERT_NE(nullptr, setup_buffer2);
+ dvrBufferDestroy(setup_buffer2);
+
+ DvrBuffer* buffer1 = nullptr;
+ int e1 = dvrGetNamedBuffer(buffer_name1, &buffer1);
+ ASSERT_NE(nullptr, buffer1);
+ ASSERT_EQ(0, e1);
+ dvrBufferDestroy(buffer1);
+
+ DvrBuffer* buffer2 = nullptr;
+ int e2 = dvrGetNamedBuffer(buffer_name2, &buffer2);
+ ASSERT_NE(nullptr, buffer2);
+ ASSERT_EQ(0, e2);
+ dvrBufferDestroy(buffer2);
+}
+
+} // namespace
+
+} // namespace dvr
+} // namespace android
diff --git a/libs/vr/libvrflinger/Android.bp b/libs/vr/libvrflinger/Android.bp
index 0daab64..632978b 100644
--- a/libs/vr/libvrflinger/Android.bp
+++ b/libs/vr/libvrflinger/Android.bp
@@ -47,6 +47,7 @@
]
sharedLibraries = [
+ "android.frameworks.vr.composer@1.0",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
"libbinder",
@@ -75,7 +76,7 @@
cflags: [
"-DLOG_TAG=\"vr_flinger\"",
"-DTRACE=0",
- "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
+ "-DATRACE_TAG=ATRACE_TAG_GRAPHICS",
"-DGL_GLEXT_PROTOTYPES",
"-DEGL_EGLEXT_PROTOTYPES",
],
diff --git a/libs/vr/libvrflinger/display_manager_service.cpp b/libs/vr/libvrflinger/display_manager_service.cpp
index 49b6f09..99f93bf 100644
--- a/libs/vr/libvrflinger/display_manager_service.cpp
+++ b/libs/vr/libvrflinger/display_manager_service.cpp
@@ -2,7 +2,9 @@
#include <pdx/channel_handle.h>
#include <pdx/default_transport/service_endpoint.h>
+#include <private/android_filesystem_config.h>
#include <private/dvr/display_rpc.h>
+#include <private/dvr/trusted_uids.h>
#include <sys/poll.h>
#include <array>
@@ -82,9 +84,9 @@
*this, &DisplayManagerService::OnUpdateSurfaces, message);
return {};
- case DisplayManagerRPC::SetupPoseBuffer::Opcode:
- DispatchRemoteMethod<DisplayManagerRPC::SetupPoseBuffer>(
- *this, &DisplayManagerService::OnSetupPoseBuffer, message);
+ case DisplayManagerRPC::SetupNamedBuffer::Opcode:
+ DispatchRemoteMethod<DisplayManagerRPC::SetupNamedBuffer>(
+ *this, &DisplayManagerService::OnSetupNamedBuffer, message);
return {};
default:
@@ -188,9 +190,20 @@
return 0;
}
-pdx::BorrowedChannelHandle DisplayManagerService::OnSetupPoseBuffer(
- pdx::Message& /*message*/, size_t extended_region_size, int usage) {
- return display_service_->SetupPoseBuffer(extended_region_size, usage);
+pdx::Status<BorrowedNativeBufferHandle>
+DisplayManagerService::OnSetupNamedBuffer(pdx::Message& message,
+ const std::string& name, size_t size,
+ uint64_t producer_usage,
+ uint64_t consumer_usage) {
+ if (message.GetEffectiveUserId() != AID_ROOT &&
+ !IsTrustedUid(message.GetEffectiveUserId())) {
+ // Only trusted users can setup named buffers.
+ ALOGE("DisplayService::SetupNamedBuffer: Called by untrusted user: uid=%d.",
+ message.GetEffectiveUserId());
+ return {};
+ }
+ return display_service_->SetupNamedBuffer(name, size, producer_usage,
+ consumer_usage);
}
void DisplayManagerService::OnDisplaySurfaceChange() {
diff --git a/libs/vr/libvrflinger/display_manager_service.h b/libs/vr/libvrflinger/display_manager_service.h
index 80324fd..7b037de 100644
--- a/libs/vr/libvrflinger/display_manager_service.h
+++ b/libs/vr/libvrflinger/display_manager_service.h
@@ -54,9 +54,9 @@
int OnUpdateSurfaces(pdx::Message& message,
const std::map<int, DisplaySurfaceAttributes>& updates);
- pdx::BorrowedChannelHandle OnSetupPoseBuffer(pdx::Message& message,
- size_t extended_region_size,
- int usage);
+ pdx::Status<BorrowedNativeBufferHandle> OnSetupNamedBuffer(
+ pdx::Message& message, const std::string& name, size_t size,
+ uint64_t producer_usage, uint64_t consumer_usage);
// Called by the display service to indicate changes to display surfaces that
// the display manager should evaluate.
diff --git a/libs/vr/libvrflinger/display_service.cpp b/libs/vr/libvrflinger/display_service.cpp
index bb8613c..8cf9d64 100644
--- a/libs/vr/libvrflinger/display_service.cpp
+++ b/libs/vr/libvrflinger/display_service.cpp
@@ -1,5 +1,6 @@
#include "display_service.h"
+#include <unistd.h>
#include <vector>
#include <pdx/default_transport/service_endpoint.h>
@@ -18,20 +19,10 @@
using android::pdx::rpc::DispatchRemoteMethod;
using android::pdx::rpc::WrapBuffer;
-namespace {
-
-constexpr char kPersistentPoseBufferName[] = "DvrPersistentPoseBuffer";
-const int kPersistentPoseBufferUserId = 0;
-const int kPersistentPoseBufferGroupId = 0;
-const size_t kTimingDataSizeOffset = 128;
-
-} // anonymous namespace
-
namespace android {
namespace dvr {
-DisplayService::DisplayService()
- : DisplayService(nullptr) {}
+DisplayService::DisplayService() : DisplayService(nullptr) {}
DisplayService::DisplayService(Hwc2::Composer* hidl)
: BASE("DisplayService", Endpoint::Create(DisplayRPC::kClientPath)),
@@ -89,9 +80,9 @@
*this, &DisplayService::OnSetViewerParams, message);
return {};
- case DisplayRPC::GetPoseBuffer::Opcode:
- DispatchRemoteMethod<DisplayRPC::GetPoseBuffer>(
- *this, &DisplayService::OnGetPoseBuffer, message);
+ case DisplayRPC::GetNamedBuffer::Opcode:
+ DispatchRemoteMethod<DisplayRPC::GetNamedBuffer>(
+ *this, &DisplayService::OnGetNamedBuffer, message);
return {};
case DisplayRPC::IsVrAppRunning::Opcode:
@@ -254,13 +245,14 @@
compositor->UpdateHeadMountMetrics(head_mount_metrics);
}
-pdx::LocalChannelHandle DisplayService::OnGetPoseBuffer(pdx::Message& message) {
- if (pose_buffer_) {
- return pose_buffer_->CreateConsumer().take();
+pdx::Status<BorrowedNativeBufferHandle> DisplayService::OnGetNamedBuffer(
+ pdx::Message& /* message */, const std::string& name) {
+ auto named_buffer = named_buffers_.find(name);
+ if (named_buffer != named_buffers_.end()) {
+ return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
}
- pdx::rpc::RemoteMethodError(message, EAGAIN);
- return {};
+ return pdx::ErrorStatus(EINVAL);
}
// Calls the message handler for the DisplaySurface associated with this
@@ -334,16 +326,22 @@
hardware_composer_.SetDisplaySurfaces(std::move(visible_surfaces));
}
-pdx::BorrowedChannelHandle DisplayService::SetupPoseBuffer(
- size_t extended_region_size, int usage) {
- if (!pose_buffer_) {
- pose_buffer_ = BufferProducer::Create(
- kPersistentPoseBufferName, kPersistentPoseBufferUserId,
- kPersistentPoseBufferGroupId, usage,
- extended_region_size + kTimingDataSizeOffset);
+pdx::Status<BorrowedNativeBufferHandle> DisplayService::SetupNamedBuffer(
+ const std::string& name, size_t size, int producer_usage,
+ int consumer_usage) {
+ auto named_buffer = named_buffers_.find(name);
+ if (named_buffer == named_buffers_.end()) {
+ // TODO(hendrikw): Update BufferProducer to take producer_usage and
+ // consumer_usage flags.
+ auto ion_buffer = std::make_unique<IonBuffer>(
+ static_cast<int>(size), 1, HAL_PIXEL_FORMAT_BLOB,
+ producer_usage | consumer_usage);
+ named_buffer =
+ named_buffers_.insert(std::make_pair(name, std::move(ion_buffer)))
+ .first;
}
- return pose_buffer_->GetChannelHandle().Borrow();
+ return {BorrowedNativeBufferHandle(*named_buffer->second, 0)};
}
void DisplayService::OnHardwareComposerRefresh() {
@@ -362,10 +360,11 @@
int DisplayService::IsVrAppRunning(pdx::Message& message) {
bool visible = false;
- ForEachDisplaySurface([&visible](const std::shared_ptr<DisplaySurface>& surface) {
- if (surface->client_z_order() == 0 && surface->IsVisible())
- visible = true;
- });
+ ForEachDisplaySurface(
+ [&visible](const std::shared_ptr<DisplaySurface>& surface) {
+ if (surface->client_z_order() == 0 && surface->IsVisible())
+ visible = true;
+ });
REPLY_SUCCESS_RETURN(message, visible, 0);
}
diff --git a/libs/vr/libvrflinger/display_service.h b/libs/vr/libvrflinger/display_service.h
index da80a84..db89064 100644
--- a/libs/vr/libvrflinger/display_service.h
+++ b/libs/vr/libvrflinger/display_service.h
@@ -3,6 +3,7 @@
#include <pdx/service.h>
#include <private/dvr/buffer_hub_client.h>
+#include <private/dvr/bufferhub_rpc.h>
#include <private/dvr/display_rpc.h>
#include <private/dvr/late_latch.h>
@@ -38,8 +39,9 @@
// any change to client/manager attributes that affect visibility or z order.
void UpdateActiveDisplaySurfaces();
- pdx::BorrowedChannelHandle SetupPoseBuffer(size_t extended_region_size,
- int usage);
+ pdx::Status<BorrowedNativeBufferHandle> SetupNamedBuffer(
+ const std::string& name, size_t size, int producer_usage,
+ int consumer_usage);
template <class A>
void ForEachDisplaySurface(A action) const {
@@ -85,7 +87,8 @@
void OnSetViewerParams(pdx::Message& message,
const ViewerParams& view_params);
- pdx::LocalChannelHandle OnGetPoseBuffer(pdx::Message& message);
+ pdx::Status<BorrowedNativeBufferHandle> OnGetNamedBuffer(
+ pdx::Message& message, const std::string& name);
// Temporary query for current VR status. Will be removed later.
int IsVrAppRunning(pdx::Message& message);
@@ -102,7 +105,7 @@
HardwareComposer hardware_composer_;
DisplayConfigurationUpdateNotifier update_notifier_;
- std::unique_ptr<BufferProducer> pose_buffer_;
+ std::unordered_map<std::string, std::unique_ptr<IonBuffer>> named_buffers_;
};
} // namespace dvr
diff --git a/libs/vr/libvrflinger/hardware_composer.cpp b/libs/vr/libvrflinger/hardware_composer.cpp
index 542bbd9..6602d78 100644
--- a/libs/vr/libvrflinger/hardware_composer.cpp
+++ b/libs/vr/libvrflinger/hardware_composer.cpp
@@ -1416,7 +1416,7 @@
void Layer::Prepare() {
int right, bottom;
- buffer_handle_t handle;
+ sp<GraphicBuffer> handle;
if (surface_) {
// Only update the acquired buffer when one is either available or this is
@@ -1465,14 +1465,14 @@
}
right = acquired_buffer_.buffer()->width();
bottom = acquired_buffer_.buffer()->height();
- handle = acquired_buffer_.buffer()->native_handle();
+ handle = acquired_buffer_.buffer()->buffer()->buffer();
acquire_fence_fd_.Reset(acquired_buffer_.ClaimAcquireFence().Release());
} else {
// TODO(jwcai) Note: this is the GPU compositor's layer, and we need the
// mechanism to accept distorted layers from VrCore.
right = direct_buffer_->width();
bottom = direct_buffer_->height();
- handle = direct_buffer_->handle();
+ handle = direct_buffer_->buffer();
acquire_fence_fd_.Close();
}
diff --git a/opengl/libs/Android.bp b/opengl/libs/Android.bp
index 6a62e8d..a895e63 100644
--- a/opengl/libs/Android.bp
+++ b/opengl/libs/Android.bp
@@ -23,28 +23,28 @@
// The headers modules are in frameworks/native/opengl/Android.bp.
ndk_library {
- name: "libEGL.ndk",
+ name: "libEGL",
symbol_file: "libEGL.map.txt",
first_version: "9",
unversioned_until: "current",
}
ndk_library {
- name: "libGLESv1_CM.ndk",
+ name: "libGLESv1_CM",
symbol_file: "libGLESv1_CM.map.txt",
first_version: "9",
unversioned_until: "current",
}
ndk_library {
- name: "libGLESv2.ndk",
+ name: "libGLESv2",
symbol_file: "libGLESv2.map.txt",
first_version: "9",
unversioned_until: "current",
}
ndk_library {
- name: "libGLESv3.ndk",
+ name: "libGLESv3",
symbol_file: "libGLESv3.map.txt",
first_version: "18",
unversioned_until: "current",
diff --git a/services/schedulerservice/SchedulingPolicyService.cpp b/services/schedulerservice/SchedulingPolicyService.cpp
index 522a8c0..a1106cf 100644
--- a/services/schedulerservice/SchedulingPolicyService.cpp
+++ b/services/schedulerservice/SchedulingPolicyService.cpp
@@ -29,23 +29,37 @@
namespace V1_0 {
namespace implementation {
-Return<bool> SchedulingPolicyService::requestPriority(int32_t pid, int32_t tid, int32_t priority) {
+bool SchedulingPolicyService::isAllowed() {
using ::android::hardware::IPCThreadState;
+ return IPCThreadState::self()->getCallingUid() == AID_CAMERASERVER;
+}
+
+Return<bool> SchedulingPolicyService::requestPriority(int32_t pid, int32_t tid, int32_t priority) {
if (priority < static_cast<int32_t>(Priority::MIN) ||
priority > static_cast<int32_t>(Priority::MAX)) {
return false;
}
- if (IPCThreadState::self()->getCallingUid() != AID_CAMERASERVER) {
+ if (!isAllowed()) {
return false;
}
+ // TODO(b/37226359): decouple from and remove AIDL service
// this should always be allowed since we are in system_server.
int value = ::android::requestPriority(pid, tid, priority, false /* isForApp */);
return value == 0 /* success */;
}
+Return<int32_t> SchedulingPolicyService::getMaxAllowedPriority() {
+ if (!isAllowed()) {
+ return 0;
+ }
+
+ // TODO(b/37226359): decouple from and remove AIDL service
+ return 3;
+}
+
} // namespace implementation
} // namespace V1_0
} // namespace schedulerservice
diff --git a/services/schedulerservice/include/schedulerservice/SchedulingPolicyService.h b/services/schedulerservice/include/schedulerservice/SchedulingPolicyService.h
index eb5a4ae..7d1c478 100644
--- a/services/schedulerservice/include/schedulerservice/SchedulingPolicyService.h
+++ b/services/schedulerservice/include/schedulerservice/SchedulingPolicyService.h
@@ -38,6 +38,9 @@
struct SchedulingPolicyService : public ISchedulingPolicyService {
Return<bool> requestPriority(int32_t pid, int32_t tid, int32_t priority) override;
+ Return<int32_t> getMaxAllowedPriority() override;
+private:
+ bool isAllowed();
};
} // namespace implementation
diff --git a/services/sensorservice/hidl/DirectReportChannel.cpp b/services/sensorservice/hidl/DirectReportChannel.cpp
index 773ce8c..adc4675 100644
--- a/services/sensorservice/hidl/DirectReportChannel.cpp
+++ b/services/sensorservice/hidl/DirectReportChannel.cpp
@@ -31,10 +31,13 @@
}
// Methods from ::android::frameworks::sensorservice::V1_0::IDirectReportChannel follow.
-Return<Result> DirectReportChannel::configure(int32_t sensorHandle, RateLevel rate) {
+Return<void> DirectReportChannel::configure(int32_t sensorHandle, RateLevel rate,
+ configure_cb _hidl_cb) {
int token = mManager.configureDirectChannel(mId,
static_cast<int>(sensorHandle), static_cast<int>(rate));
- return token <= 0 ? convertResult(token) : Result::OK;
+ _hidl_cb(token <= 0 ? 0 : token,
+ token <= 0 ? convertResult(token) : Result::OK);
+ return Void();
}
diff --git a/services/sensorservice/hidl/DirectReportChannel.h b/services/sensorservice/hidl/DirectReportChannel.h
index 9134944..dd67827 100644
--- a/services/sensorservice/hidl/DirectReportChannel.h
+++ b/services/sensorservice/hidl/DirectReportChannel.h
@@ -47,7 +47,8 @@
~DirectReportChannel();
// Methods from ::android::frameworks::sensorservice::V1_0::IDirectReportChannel follow.
- Return<Result> configure(int32_t sensorHandle, RateLevel rate) override;
+ Return<void> configure(int32_t sensorHandle, RateLevel rate,
+ configure_cb _hidl_cb) override;
private:
::android::SensorManager& mManager;
diff --git a/services/sensorservice/hidl/EventQueue.cpp b/services/sensorservice/hidl/EventQueue.cpp
index 86d365c..c0365e5 100644
--- a/services/sensorservice/hidl/EventQueue.cpp
+++ b/services/sensorservice/hidl/EventQueue.cpp
@@ -39,7 +39,8 @@
while ((actual = internalQueue->read(&event, 1 /* count */)) > 0) {
internalQueue->sendAck(&event, actual);
- mCallback->onEvent(convertEvent(event));
+ Return<void> ret = mCallback->onEvent(convertEvent(event));
+ (void)ret.isOk(); // ignored
}
return 1; // continue to receive callbacks
diff --git a/services/sensorservice/hidl/SensorManager.cpp b/services/sensorservice/hidl/SensorManager.cpp
index 0743fc3..06ff95c 100644
--- a/services/sensorservice/hidl/SensorManager.cpp
+++ b/services/sensorservice/hidl/SensorManager.cpp
@@ -22,12 +22,14 @@
#include "SensorManager.h"
+#include <sched.h>
+
+#include <thread>
+
#include "EventQueue.h"
#include "DirectReportChannel.h"
#include "utils.h"
-#include <thread>
-
namespace android {
namespace frameworks {
namespace sensorservice {
@@ -131,6 +133,14 @@
std::condition_variable looperSet;
std::thread{[&mutex = mLooperMutex, &looper = mLooper, &looperSet] {
+
+ struct sched_param p = {0};
+ p.sched_priority = 10;
+ if (sched_setscheduler(0 /* current thread*/, SCHED_FIFO, &p) != 0) {
+ LOG(WARNING) << "Could not use SCHED_FIFO for looper thread: "
+ << strerror(errno);
+ }
+
std::unique_lock<std::mutex> lock(mutex);
looper = Looper::prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS /* opts */);
lock.unlock();
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
index 33aa759..262ab62 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp
@@ -17,7 +17,6 @@
#undef LOG_TAG
#define LOG_TAG "HwcComposer"
-#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
#include <inttypes.h>
#include <log/log.h>
#include <gui/BufferQueue.h>
@@ -26,7 +25,6 @@
namespace android {
-using frameworks::vr::composer::V1_0::IVrComposerClient;
using hardware::Return;
using hardware::hidl_vec;
using hardware::hidl_handle;
@@ -124,6 +122,41 @@
endCommand();
}
+void Composer::CommandWriter::setClientTargetMetadata(
+ const IVrComposerClient::BufferMetadata& metadata)
+{
+ constexpr uint16_t kSetClientTargetMetadataLength = 7;
+ beginCommand(
+ static_cast<IComposerClient::Command>(
+ IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA),
+ kSetClientTargetMetadataLength);
+ writeBufferMetadata(metadata);
+ endCommand();
+}
+
+void Composer::CommandWriter::setLayerBufferMetadata(
+ const IVrComposerClient::BufferMetadata& metadata)
+{
+ constexpr uint16_t kSetLayerBufferMetadataLength = 7;
+ beginCommand(
+ static_cast<IComposerClient::Command>(
+ IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA),
+ kSetLayerBufferMetadataLength);
+ writeBufferMetadata(metadata);
+ endCommand();
+}
+
+void Composer::CommandWriter::writeBufferMetadata(
+ const IVrComposerClient::BufferMetadata& metadata)
+{
+ write(metadata.width);
+ write(metadata.height);
+ write(metadata.stride);
+ write(metadata.layerCount);
+ writeSigned(static_cast<int32_t>(metadata.format));
+ write64(metadata.usage);
+}
+
Composer::Composer(bool useVrComposer)
: mWriter(kWriterInitialSize),
mIsUsingVrComposer(useVrComposer)
@@ -426,12 +459,29 @@
}
Error Composer::setClientTarget(Display display, uint32_t slot,
- const native_handle_t* target,
+ const sp<GraphicBuffer>& target,
int acquireFence, Dataspace dataspace,
const std::vector<IComposerClient::Rect>& damage)
{
mWriter.selectDisplay(display);
- mWriter.setClientTarget(slot, target, acquireFence, dataspace, damage);
+ if (mIsUsingVrComposer && target.get()) {
+ IVrComposerClient::BufferMetadata metadata = {
+ .width = target->getWidth(),
+ .height = target->getHeight(),
+ .stride = target->getStride(),
+ .layerCount = target->getLayerCount(),
+ .format = static_cast<PixelFormat>(target->getPixelFormat()),
+ .usage = target->getUsage(),
+ };
+ mWriter.setClientTargetMetadata(metadata);
+ }
+
+ const native_handle_t* handle = nullptr;
+ if (target.get()) {
+ handle = target->getNativeBuffer()->handle;
+ }
+
+ mWriter.setClientTarget(slot, handle, acquireFence, dataspace, damage);
return Error::NONE;
}
@@ -502,11 +552,28 @@
}
Error Composer::setLayerBuffer(Display display, Layer layer,
- uint32_t slot, const native_handle_t* buffer, int acquireFence)
+ uint32_t slot, const sp<GraphicBuffer>& buffer, int acquireFence)
{
mWriter.selectDisplay(display);
mWriter.selectLayer(layer);
- mWriter.setLayerBuffer(slot, buffer, acquireFence);
+ if (mIsUsingVrComposer && buffer.get()) {
+ IVrComposerClient::BufferMetadata metadata = {
+ .width = buffer->getWidth(),
+ .height = buffer->getHeight(),
+ .stride = buffer->getStride(),
+ .layerCount = buffer->getLayerCount(),
+ .format = static_cast<PixelFormat>(buffer->getPixelFormat()),
+ .usage = buffer->getUsage(),
+ };
+ mWriter.setLayerBufferMetadata(metadata);
+ }
+
+ const native_handle_t* handle = nullptr;
+ if (buffer.get()) {
+ handle = buffer->getNativeBuffer()->handle;
+ }
+
+ mWriter.setLayerBuffer(slot, handle, acquireFence);
return Error::NONE;
}
diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h
index 18af9dd..37b7766 100644
--- a/services/surfaceflinger/DisplayHardware/ComposerHal.h
+++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h
@@ -23,6 +23,7 @@
#include <utility>
#include <vector>
+#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <utils/StrongPointer.h>
#include <IComposerCommandBuffer.h>
@@ -31,6 +32,8 @@
namespace Hwc2 {
+using android::frameworks::vr::composer::V1_0::IVrComposerClient;
+
using android::hardware::graphics::common::V1_0::ColorMode;
using android::hardware::graphics::common::V1_0::ColorTransform;
using android::hardware::graphics::common::V1_0::Dataspace;
@@ -179,7 +182,7 @@
* When target is not nullptr, the cache is updated with the new target.
*/
Error setClientTarget(Display display, uint32_t slot,
- const native_handle_t* target,
+ const sp<GraphicBuffer>& target,
int acquireFence, Dataspace dataspace,
const std::vector<IComposerClient::Rect>& damage);
Error setColorMode(Display display, ColorMode mode);
@@ -199,7 +202,7 @@
int32_t x, int32_t y);
/* see setClientTarget for the purpose of slot */
Error setLayerBuffer(Display display, Layer layer, uint32_t slot,
- const native_handle_t* buffer, int acquireFence);
+ const sp<GraphicBuffer>& buffer, int acquireFence);
Error setLayerSurfaceDamage(Display display, Layer layer,
const std::vector<IComposerClient::Rect>& damage);
Error setLayerBlendMode(Display display, Layer layer,
@@ -232,6 +235,14 @@
~CommandWriter() override;
void setLayerInfo(uint32_t type, uint32_t appId);
+ void setClientTargetMetadata(
+ const IVrComposerClient::BufferMetadata& metadata);
+ void setLayerBufferMetadata(
+ const IVrComposerClient::BufferMetadata& metadata);
+
+ private:
+ void writeBufferMetadata(
+ const IVrComposerClient::BufferMetadata& metadata);
};
// Many public functions above simply write a command into the command
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp
index e49e734..8270c39 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp
@@ -244,7 +244,7 @@
ALOGE("Failed to get display by id");
return Error::BadDisplay;
}
- (*outDisplay)->setVirtual();
+ (*outDisplay)->setConnected(true);
return Error::None;
}
@@ -531,15 +531,28 @@
: mDevice(device),
mId(id),
mIsConnected(false),
- mIsVirtual(false)
+ mType(DisplayType::Invalid)
{
ALOGV("Created display %" PRIu64, id);
+
+#ifdef BYPASS_IHWC
+ int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId,
+ reinterpret_cast<int32_t *>(&mType));
+#else
+ auto intError = mDevice.mComposer->getDisplayType(mId,
+ reinterpret_cast<Hwc2::IComposerClient::DisplayType *>(&mType));
+#endif
+ auto error = static_cast<Error>(intError);
+ if (error != Error::None) {
+ ALOGE("getDisplayType(%" PRIu64 ") failed: %s (%d)",
+ id, to_string(error).c_str(), intError);
+ }
}
Display::~Display()
{
ALOGV("Destroyed display %" PRIu64, mId);
- if (mIsVirtual) {
+ if (mType == DisplayType::Virtual) {
mDevice.destroyVirtualDisplay(mId);
}
}
@@ -802,21 +815,7 @@
Error Display::getType(DisplayType* outType) const
{
-#ifdef BYPASS_IHWC
- int32_t intType = 0;
- int32_t intError = mDevice.mGetDisplayType(mDevice.mHwcDevice, mId,
- &intType);
-#else
- Hwc2::IComposerClient::DisplayType intType =
- Hwc2::IComposerClient::DisplayType::INVALID;
- auto intError = mDevice.mComposer->getDisplayType(mId, &intType);
-#endif
- auto error = static_cast<Error>(intError);
- if (error != Error::None) {
- return error;
- }
-
- *outType = static_cast<DisplayType>(intType);
+ *outType = mType;
return Error::None;
}
@@ -961,14 +960,19 @@
return static_cast<Error>(intError);
}
-Error Display::setClientTarget(uint32_t slot, buffer_handle_t target,
+Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target,
const sp<Fence>& acquireFence, android_dataspace_t dataspace)
{
// TODO: Properly encode client target surface damage
int32_t fenceFd = acquireFence->dup();
#ifdef BYPASS_IHWC
(void) slot;
- int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, target,
+ buffer_handle_t handle = nullptr;
+ if (target.get() && target->getNativeBuffer()) {
+ handle = target->getNativeBuffer()->handle;
+ }
+
+ int32_t intError = mDevice.mSetClientTarget(mDevice.mHwcDevice, mId, handle,
fenceFd, static_cast<int32_t>(dataspace), {0, nullptr});
#else
auto intError = mDevice.mComposer->setClientTarget(mId, slot, target,
@@ -1195,14 +1199,19 @@
return static_cast<Error>(intError);
}
-Error Layer::setBuffer(uint32_t slot, buffer_handle_t buffer,
+Error Layer::setBuffer(uint32_t slot, const sp<GraphicBuffer>& buffer,
const sp<Fence>& acquireFence)
{
int32_t fenceFd = acquireFence->dup();
#ifdef BYPASS_IHWC
(void) slot;
+ buffer_handle_t handle = nullptr;
+ if (buffer.get() && buffer->getNativeBuffer()) {
+ handle = buffer->getNativeBuffer()->handle;
+ }
+
int32_t intError = mDevice.mSetLayerBuffer(mDevice.mHwcDevice, mDisplayId,
- mId, buffer, fenceFd);
+ mId, handle, fenceFd);
#else
auto intError = mDevice.mComposer->setLayerBuffer(mDisplayId,
mId, slot, buffer, fenceFd);
diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h
index 4419dc1..643b1e0 100644
--- a/services/surfaceflinger/DisplayHardware/HWC2.h
+++ b/services/surfaceflinger/DisplayHardware/HWC2.h
@@ -329,7 +329,7 @@
[[clang::warn_unused_result]] Error setActiveConfig(
const std::shared_ptr<const Config>& config);
[[clang::warn_unused_result]] Error setClientTarget(
- uint32_t slot, buffer_handle_t target,
+ uint32_t slot, const android::sp<android::GraphicBuffer>& target,
const android::sp<android::Fence>& acquireFence,
android_dataspace_t dataspace);
[[clang::warn_unused_result]] Error setColorMode(android_color_mode_t mode);
@@ -352,12 +352,6 @@
private:
// For use by Device
- // Virtual displays are always connected
- void setVirtual() {
- mIsVirtual = true;
- mIsConnected = true;
- }
-
void setConnected(bool connected) { mIsConnected = connected; }
int32_t getAttribute(hwc2_config_t configId, Attribute attribute);
void loadConfig(hwc2_config_t configId);
@@ -375,7 +369,7 @@
Device& mDevice;
hwc2_display_t mId;
bool mIsConnected;
- bool mIsVirtual;
+ DisplayType mType;
std::unordered_map<hwc2_layer_t, std::weak_ptr<Layer>> mLayers;
std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
};
@@ -392,7 +386,7 @@
[[clang::warn_unused_result]] Error setCursorPosition(int32_t x, int32_t y);
[[clang::warn_unused_result]] Error setBuffer(uint32_t slot,
- buffer_handle_t buffer,
+ const android::sp<android::GraphicBuffer>& buffer,
const android::sp<android::Fence>& acquireFence);
[[clang::warn_unused_result]] Error setSurfaceDamage(
const android::Region& damage);
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 09434f6..40979c9 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -206,7 +206,7 @@
}
disp = DisplayDevice::DISPLAY_EXTERNAL;
}
- mEventHandler->onHotplugReceived(disp,
+ mEventHandler->onHotplugReceived(this, disp,
connected == HWC2::Connection::Connected);
}
@@ -465,12 +465,7 @@
ALOGV("setClientTarget for display %d", displayId);
auto& hwcDisplay = mDisplayData[displayId].hwcDisplay;
- buffer_handle_t handle = nullptr;
- if ((target != nullptr) && target->getNativeBuffer()) {
- handle = target->getNativeBuffer()->handle;
- }
- auto error = hwcDisplay->setClientTarget(slot, handle,
- acquireFence, dataspace);
+ auto error = hwcDisplay->setClientTarget(slot, target, acquireFence, dataspace);
if (error != HWC2::Error::None) {
ALOGE("Failed to set client target for display %d: %s (%d)", displayId,
to_string(error).c_str(), static_cast<int32_t>(error));
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 81f1619..78d0307 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -70,7 +70,7 @@
friend class HWComposer;
virtual void onVSyncReceived(
HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
- virtual void onHotplugReceived(int32_t disp, bool connected) = 0;
+ virtual void onHotplugReceived(HWComposer* composer, int32_t disp, bool connected) = 0;
virtual void onInvalidateReceived(HWComposer* composer) = 0;
protected:
virtual ~EventHandler() {}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
index 5b5f1cf..dcb2913 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.cpp
@@ -315,7 +315,7 @@
queryDisplayProperties(disp);
// Do not teardown or recreate the primary display
if (disp != HWC_DISPLAY_PRIMARY) {
- mEventHandler.onHotplugReceived(disp, bool(connected));
+ mEventHandler.onHotplugReceived(this, disp, bool(connected));
}
}
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
index f64d69a..4bc63bb 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer_hwc1.h
@@ -62,7 +62,7 @@
friend class HWComposer;
virtual void onVSyncReceived(
HWComposer* composer, int32_t disp, nsecs_t timestamp) = 0;
- virtual void onHotplugReceived(int disp, bool connected) = 0;
+ virtual void onHotplugReceived(HWComposer* composer, int disp, bool connected) = 0;
virtual void onInvalidateReceived(HWComposer* composer) = 0;
protected:
virtual ~EventHandler() {}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index c211c7b..598a65a 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -852,18 +852,12 @@
}
uint32_t hwcSlot = 0;
- buffer_handle_t hwcHandle = nullptr;
- {
- sp<GraphicBuffer> hwcBuffer;
- hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer,
- &hwcSlot, &hwcBuffer);
- if (hwcBuffer != nullptr) {
- hwcHandle = hwcBuffer->handle;
- }
- }
+ sp<GraphicBuffer> hwcBuffer;
+ hwcInfo.bufferCache.getHwcBuffer(mActiveBufferSlot, mActiveBuffer,
+ &hwcSlot, &hwcBuffer);
auto acquireFence = mSurfaceFlingerConsumer->getCurrentFence();
- error = hwcLayer->setBuffer(hwcSlot, hwcHandle, acquireFence);
+ error = hwcLayer->setBuffer(hwcSlot, hwcBuffer, acquireFence);
if (error != HWC2::Error::None) {
ALOGE("[%s] Failed to set buffer %p: %s (%d)", mName.string(),
mActiveBuffer->handle, to_string(error).c_str(),
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index c523407..d72b3b5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -598,7 +598,7 @@
// make the GLContext current so that we can create textures when creating
// Layers (which may happens before we render something)
- getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
+ getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
@@ -733,8 +733,11 @@
info.density = density;
// TODO: this needs to go away (currently needed only by webkit)
- sp<const DisplayDevice> hw(getDefaultDisplayDevice());
- info.orientation = hw->getOrientation();
+ {
+ Mutex::Autolock _l(mStateLock);
+ sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
+ info.orientation = hw->getOrientation();
+ }
} else {
// TODO: where should this value come from?
static const int TV_DENSITY = 213;
@@ -791,10 +794,13 @@
ALOGE("%s : display is NULL", __func__);
return BAD_VALUE;
}
+
+ Mutex::Autolock _l(mStateLock);
sp<DisplayDevice> device(getDisplayDevice(display));
if (device != NULL) {
return device->getActiveConfig();
}
+
return BAD_VALUE;
}
@@ -882,6 +888,7 @@
}
android_color_mode_t SurfaceFlinger::getActiveColorMode(const sp<IBinder>& display) {
+ Mutex::Autolock _l(mStateLock);
sp<DisplayDevice> device(getDisplayDevice(display));
if (device != nullptr) {
return device->getActiveColorMode();
@@ -1143,55 +1150,60 @@
*compositorTiming = mCompositorTiming;
}
-void SurfaceFlinger::onHotplugReceived(int32_t disp, bool connected) {
+void SurfaceFlinger::createDefaultDisplayDevice() {
+ const int32_t type = DisplayDevice::DISPLAY_PRIMARY;
+ wp<IBinder> token = mBuiltinDisplays[type];
+
+ // All non-virtual displays are currently considered secure.
+ const bool isSecure = true;
+
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer, new GraphicBufferAlloc());
+
+ sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc, type, consumer);
+
+ bool hasWideColorModes = false;
+ std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(
+ type);
+ for (android_color_mode_t colorMode : modes) {
+ switch (colorMode) {
+ case HAL_COLOR_MODE_DISPLAY_P3:
+ case HAL_COLOR_MODE_ADOBE_RGB:
+ case HAL_COLOR_MODE_DCI_P3:
+ hasWideColorModes = true;
+ break;
+ default:
+ break;
+ }
+ }
+ sp<DisplayDevice> hw = new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, type, isSecure,
+ token, fbs, producer, mRenderEngine->getEGLConfig(),
+ hasWideColorModes && hasWideColorDisplay);
+ mDisplays.add(token, hw);
+ android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
+ if (hasWideColorModes && hasWideColorDisplay) {
+ defaultColorMode = HAL_COLOR_MODE_SRGB;
+ }
+ setActiveColorModeInternal(hw, defaultColorMode);
+}
+
+void SurfaceFlinger::onHotplugReceived(HWComposer* composer, int32_t disp, bool connected) {
ALOGV("onHotplugReceived(%d, %s)", disp, connected ? "true" : "false");
+
+ if (composer->isUsingVrComposer()) {
+ // We handle initializing the primary display device for the VR
+ // window manager hwc explicitly at the time of transition.
+ if (disp != DisplayDevice::DISPLAY_PRIMARY) {
+ ALOGE("External displays are not supported by the vr hardware composer.");
+ }
+ return;
+ }
+
if (disp == DisplayDevice::DISPLAY_PRIMARY) {
Mutex::Autolock lock(mStateLock);
-
- // All non-virtual displays are currently considered secure.
- bool isSecure = true;
-
- int32_t type = DisplayDevice::DISPLAY_PRIMARY;
-
- // When we're using the vr composer, the assumption is that we've
- // already created the IBinder object for the primary display.
- if (!mHwc->isUsingVrComposer()) {
- createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
- }
-
- wp<IBinder> token = mBuiltinDisplays[type];
-
- sp<IGraphicBufferProducer> producer;
- sp<IGraphicBufferConsumer> consumer;
- BufferQueue::createBufferQueue(&producer, &consumer,
- new GraphicBufferAlloc());
-
- sp<FramebufferSurface> fbs = new FramebufferSurface(*mHwc,
- DisplayDevice::DISPLAY_PRIMARY, consumer);
-
- bool hasWideColorModes = false;
- std::vector<android_color_mode_t> modes = getHwComposer().getColorModes(type);
- for (android_color_mode_t colorMode : modes) {
- switch (colorMode) {
- case HAL_COLOR_MODE_DISPLAY_P3:
- case HAL_COLOR_MODE_ADOBE_RGB:
- case HAL_COLOR_MODE_DCI_P3:
- hasWideColorModes = true;
- break;
- default:
- break;
- }
- }
- sp<DisplayDevice> hw =
- new DisplayDevice(this, DisplayDevice::DISPLAY_PRIMARY, disp, isSecure, token, fbs,
- producer, mRenderEngine->getEGLConfig(),
- hasWideColorModes && hasWideColorDisplay);
- mDisplays.add(token, hw);
- android_color_mode defaultColorMode = HAL_COLOR_MODE_NATIVE;
- if (hasWideColorModes && hasWideColorDisplay) {
- defaultColorMode = HAL_COLOR_MODE_SRGB;
- }
- setActiveColorModeInternal(hw, defaultColorMode);
+ createBuiltinDisplayLocked(DisplayDevice::DISPLAY_PRIMARY);
+ createDefaultDisplayDevice();
} else {
auto type = DisplayDevice::DISPLAY_EXTERNAL;
Mutex::Autolock _l(mStateLock);
@@ -1233,6 +1245,7 @@
}
}
+// Note: it is assumed the caller holds |mStateLock| when this is called
void SurfaceFlinger::resetHwc() {
disableHardwareVsync(true);
clearHwcLayers(mDrawingState.layersSortedByZ);
@@ -1253,36 +1266,46 @@
if (vrFlingerRequestsDisplay == mHwc->isUsingVrComposer()) {
return;
}
+
+ bool vrHwcNewlyInitialized = false;
+
if (vrFlingerRequestsDisplay && !mVrHwc) {
// Construct new HWComposer without holding any locks.
mVrHwc = new HWComposer(true);
+ vrHwcNewlyInitialized = true;
ALOGV("Vr HWC created");
}
- {
- Mutex::Autolock _l(mStateLock);
- if (vrFlingerRequestsDisplay) {
- resetHwc();
+ Mutex::Autolock _l(mStateLock);
- mHwc = mVrHwc;
- mVrFlinger->GrantDisplayOwnership();
- } else {
- mVrFlinger->SeizeDisplayOwnership();
+ if (vrFlingerRequestsDisplay) {
+ resetHwc();
- resetHwc();
+ mHwc = mVrHwc;
+ mVrFlinger->GrantDisplayOwnership();
- mHwc = mRealHwc;
- enableHardwareVsync();
+ if (vrHwcNewlyInitialized) {
+ mVrHwc->setEventHandler(
+ static_cast<HWComposer::EventHandler*>(this));
}
+ } else {
+ mVrFlinger->SeizeDisplayOwnership();
- mVisibleRegionsDirty = true;
- invalidateHwcGeometry();
- android_atomic_or(1, &mRepaintEverything);
- setTransactionFlags(eDisplayTransactionNeeded);
+ resetHwc();
+
+ mHwc = mRealHwc;
+ enableHardwareVsync();
}
- if (mVrHwc) {
- mVrHwc->setEventHandler(static_cast<HWComposer::EventHandler*>(this));
- }
+
+ mVisibleRegionsDirty = true;
+ invalidateHwcGeometry();
+
+ // Explicitly re-initialize the primary display. This is because some other
+ // parts of this class rely on the primary display always being available.
+ createDefaultDisplayDevice();
+
+ android_atomic_or(1, &mRepaintEverything);
+ setTransactionFlags(eDisplayTransactionNeeded);
}
void SurfaceFlinger::onMessageReceived(int32_t what) {
@@ -1492,7 +1515,8 @@
layer->releasePendingBuffer(dequeueReadyTime);
}
- const sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+ // |mStateLock| not needed as we are on the main thread
+ const sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
std::shared_ptr<FenceTime> glCompositionDoneFenceTime;
if (mHwc->hasClientComposition(HWC_DISPLAY_PRIMARY)) {
@@ -1840,7 +1864,8 @@
mLastSwapBufferTime = systemTime() - now;
mDebugInSwapBuffers = 0;
- uint32_t flipCount = getDefaultDisplayDevice()->getPageFlipCount();
+ // |mStateLock| not needed as we are on the main thread
+ uint32_t flipCount = getDefaultDisplayDeviceLocked()->getPageFlipCount();
if (flipCount % LOG_FRAME_STATS_PERIOD == 0) {
logFrameStats();
}
@@ -1925,7 +1950,7 @@
// Call makeCurrent() on the primary display so we can
// be sure that nothing associated with this display
// is current.
- const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
+ const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDeviceLocked());
defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
if (hw != NULL)
@@ -2115,7 +2140,7 @@
// could be null when this layer is using a layerStack
// that is not visible on any display. Also can occur at
// screen off/on times.
- disp = getDefaultDisplayDevice();
+ disp = getDefaultDisplayDeviceLocked();
}
layer->updateTransformHint(disp);
@@ -2471,7 +2496,9 @@
ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
displayDevice->getDisplayName().string());
eglMakeCurrent(mEGLDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if(!getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext)) {
+
+ // |mStateLock| not needed as we are on the main thread
+ if(!getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext)) {
ALOGE("DisplayDevice::makeCurrent on default display failed. Aborting.");
}
return false;
@@ -3558,7 +3585,7 @@
colorizer.reset(result);
HWComposer& hwc(getHwComposer());
- sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+ sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
colorizer.bold(result);
result.appendFormat("EGL implementation : %s\n",
@@ -3788,7 +3815,7 @@
return NO_ERROR;
case 1013: {
Mutex::Autolock _l(mStateLock);
- sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+ sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
reply->writeInt32(hw->getPageFlipCount());
return NO_ERROR;
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 69655ed..e15c6ff 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -184,8 +184,9 @@
void repaintEverything();
// returns the default Display
- sp<const DisplayDevice> getDefaultDisplayDevice() const {
- return getDisplayDevice(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]);
+ sp<const DisplayDevice> getDefaultDisplayDevice() {
+ Mutex::Autolock _l(mStateLock);
+ return getDefaultDisplayDeviceLocked();
}
// utility function to delete a texture on the main thread
@@ -306,7 +307,7 @@
* HWComposer::EventHandler interface
*/
virtual void onVSyncReceived(HWComposer* composer, int type, nsecs_t timestamp);
- virtual void onHotplugReceived(int disp, bool connected);
+ virtual void onHotplugReceived(HWComposer* composer, int disp, bool connected);
virtual void onInvalidateReceived(HWComposer* composer);
/* ------------------------------------------------------------------------
@@ -441,6 +442,12 @@
return mDisplays.valueFor(dpy);
}
+ sp<const DisplayDevice> getDefaultDisplayDeviceLocked() const {
+ return getDisplayDevice(mBuiltinDisplays[DisplayDevice::DISPLAY_PRIMARY]);
+ }
+
+ void createDefaultDisplayDevice();
+
int32_t getDisplayType(const sp<IBinder>& display) {
if (!display.get()) return NAME_NOT_FOUND;
for (int i = 0; i < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES; ++i) {
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index a237ae3..a9000c0 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -584,7 +584,7 @@
// make the GLContext current so that we can create textures when creating Layers
// (which may happens before we render something)
- getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
+ getDefaultDisplayDeviceLocked()->makeCurrent(mEGLDisplay, mEGLContext);
mEventControlThread = new EventControlThread(this);
mEventControlThread->run("EventControl", PRIORITY_URGENT_DISPLAY);
@@ -1055,7 +1055,7 @@
*compositorTiming = mCompositorTiming;
}
-void SurfaceFlinger::onHotplugReceived(int type, bool connected) {
+void SurfaceFlinger::onHotplugReceived(HWComposer* /*composer*/, int type, bool connected) {
if (mEventThread == NULL) {
// This is a temporary workaround for b/7145521. A non-null pointer
// does not mean EventThread has finished initializing, so this
@@ -3237,7 +3237,7 @@
colorizer.reset(result);
HWComposer& hwc(getHwComposer());
- sp<const DisplayDevice> hw(getDefaultDisplayDevice());
+ sp<const DisplayDevice> hw(getDefaultDisplayDeviceLocked());
colorizer.bold(result);
result.appendFormat("EGL implementation : %s\n",
diff --git a/services/vr/bufferhubd/buffer_hub.cpp b/services/vr/bufferhubd/buffer_hub.cpp
index 2ce60e5..4b1a522 100644
--- a/services/vr/bufferhubd/buffer_hub.cpp
+++ b/services/vr/bufferhubd/buffer_hub.cpp
@@ -1,5 +1,6 @@
#include "buffer_hub.h"
+#include <inttypes.h>
#include <log/log.h>
#include <poll.h>
#include <utils/Trace.h>
@@ -52,7 +53,7 @@
stream << " ";
stream << std::setw(6) << "Format";
stream << " ";
- stream << std::setw(10) << "Usage";
+ stream << std::setw(21) << "Usage";
stream << " ";
stream << "Name";
stream << std::endl;
@@ -79,7 +80,9 @@
stream << std::setw(6) << info.format;
stream << " ";
stream << "0x" << std::hex << std::setfill('0');
- stream << std::setw(8) << info.usage;
+ stream << std::setw(8) << info.producer_usage;
+ stream << "0x";
+ stream << std::setw(8) << info.consumer_usage;
stream << std::dec << std::setfill(' ');
stream << " ";
stream << info.name;
@@ -137,6 +140,10 @@
stream << " UsageClearMask";
stream << " UsageDenySetMask";
stream << " UsageDenyClearMask";
+ stream << " UsageSetMask";
+ stream << " UsageClearMask";
+ stream << " UsageDenySetMask";
+ stream << " UsageDenyClearMask";
stream << " ";
stream << std::endl;
@@ -150,16 +157,30 @@
stream << std::right << std::setw(12) << info.consumer_count;
stream << std::setw(5) << std::setfill(' ') << "0x";
stream << std::hex << std::setfill('0');
- stream << std::setw(8) << info.usage_set_mask;
+ stream << std::setw(8) << info.usage_policy.producer_set_mask;
stream << std::setw(7) << std::setfill(' ') << "0x";
stream << std::hex << std::setfill('0');
- stream << std::setw(8) << info.usage_clear_mask;
+ stream << std::setw(8) << info.usage_policy.producer_clear_mask;
stream << std::setw(9) << std::setfill(' ') << "0x";
stream << std::hex << std::setfill('0');
- stream << std::setw(8) << info.usage_deny_set_mask;
+ stream << std::setw(8) << info.usage_policy.producer_deny_set_mask;
stream << std::setw(11) << std::setfill(' ') << "0x";
stream << std::hex << std::setfill('0');
- stream << std::setw(8) << info.usage_deny_clear_mask;
+ stream << std::setw(8) << info.usage_policy.producer_deny_clear_mask;
+ stream << std::setw(5) << std::setfill(' ') << "0x";
+ stream << std::hex << std::setfill('0');
+ stream << std::setw(8) << info.usage_policy.consumer_set_mask;
+ stream << std::setw(7) << std::setfill(' ') << "0x";
+ stream << std::hex << std::setfill('0');
+ stream << std::setw(8) << info.usage_policy.consumer_clear_mask;
+ stream << std::setw(9) << std::setfill(' ') << "0x";
+ stream << std::hex << std::setfill('0');
+ stream << std::setw(8) << info.usage_policy.consumer_deny_set_mask;
+ stream << std::setw(11) << std::setfill(' ') << "0x";
+ stream << std::hex << std::setfill('0');
+ stream << std::setw(8) << info.usage_policy.consumer_deny_clear_mask;
+ stream << std::hex << std::setfill('0');
+ stream << std::endl;
}
}
@@ -177,6 +198,7 @@
stream << std::right << std::setw(6) << info.id;
stream << std::right << std::setw(12) << info.capacity;
+ stream << std::endl;
}
}
@@ -235,48 +257,53 @@
buffer->Detach();
}
-int BufferHubService::OnCreateBuffer(Message& message, int width, int height,
- int format, int usage,
- size_t meta_size_bytes,
- size_t slice_count) {
+Status<void> BufferHubService::OnCreateBuffer(Message& message, uint32_t width,
+ uint32_t height, uint32_t format,
+ uint64_t producer_usage,
+ uint64_t consumer_usage,
+ size_t meta_size_bytes,
+ size_t slice_count) {
// Use the producer channel id as the global buffer id.
const int buffer_id = message.GetChannelId();
ALOGD_IF(TRACE,
- "BufferHubService::OnCreateBuffer: buffer_id=%d width=%d height=%d "
- "format=%d usage=%d meta_size_bytes=%zu slice_count=%zu",
- buffer_id, width, height, format, usage, meta_size_bytes,
- slice_count);
+ "BufferHubService::OnCreateBuffer: buffer_id=%d width=%u height=%u "
+ "format=%u producer_usage=%" PRIx64 " consumer_usage=%" PRIx64
+ " meta_size_bytes=%zu slice_count=%zu",
+ buffer_id, width, height, format, producer_usage, consumer_usage,
+ meta_size_bytes, slice_count);
// See if this channel is already attached to a buffer.
if (const auto channel = message.GetChannel<BufferHubChannel>()) {
ALOGE("BufferHubService::OnCreateBuffer: Buffer already created: buffer=%d",
buffer_id);
- return -EALREADY;
+ return ErrorStatus(EALREADY);
}
- int error;
- if (const auto producer_channel =
- ProducerChannel::Create(this, buffer_id, width, height, format, usage,
- meta_size_bytes, slice_count, &error)) {
- message.SetChannel(producer_channel);
- return 0;
+ auto status = ProducerChannel::Create(this, buffer_id, width, height, format,
+ producer_usage, consumer_usage,
+ meta_size_bytes, slice_count);
+ if (status) {
+ message.SetChannel(status.take());
+ return {};
} else {
- ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
- return error;
+ ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer: %s",
+ status.GetErrorMessage().c_str());
+ return status.error_status();
}
}
-int BufferHubService::OnCreatePersistentBuffer(
+Status<void> BufferHubService::OnCreatePersistentBuffer(
Message& message, const std::string& name, int user_id, int group_id,
- int width, int height, int format, int usage, size_t meta_size_bytes,
- size_t slice_count) {
+ uint32_t width, uint32_t height, uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage, size_t meta_size_bytes, size_t slice_count) {
const int channel_id = message.GetChannelId();
ALOGD_IF(TRACE,
"BufferHubService::OnCreatePersistentBuffer: channel_id=%d name=%s "
- "user_id=%d group_id=%d width=%d height=%d format=%d usage=%d "
- "meta_size_bytes=%zu slice_count=%zu",
+ "user_id=%d group_id=%d width=%u height=%u format=%u "
+ "producer_usage=%" PRIx64 " consumer_usage=%" PRIx64
+ " meta_size_bytes=%zu slice_count=%zu",
channel_id, name.c_str(), user_id, group_id, width, height, format,
- usage, meta_size_bytes, slice_count);
+ producer_usage, consumer_usage, meta_size_bytes, slice_count);
// See if this channel is already attached to a buffer.
if (const auto channel = message.GetChannel<BufferHubChannel>()) {
@@ -284,12 +311,11 @@
"BufferHubService::OnCreatePersistentBuffer: Channel already attached "
"to buffer: channel_id=%d buffer_id=%d",
channel_id, channel->buffer_id());
- return -EALREADY;
+ return ErrorStatus(EALREADY);
}
const int euid = message.GetEffectiveUserId();
const int egid = message.GetEffectiveGroupId();
- int error;
if (auto buffer = GetNamedBuffer(name)) {
if (!buffer->CheckAccess(euid, egid)) {
@@ -297,41 +323,45 @@
"BufferHubService::OnCreatePersistentBuffer: Requesting process does "
"not have permission to access named buffer: name=%s euid=%d egid=%d",
name.c_str(), euid, euid);
- return -EPERM;
- } else if (!buffer->CheckParameters(width, height, format, usage,
- meta_size_bytes, slice_count)) {
+ return ErrorStatus(EPERM);
+ } else if (!buffer->CheckParameters(width, height, format, producer_usage,
+ consumer_usage, meta_size_bytes,
+ slice_count)) {
ALOGE(
"BufferHubService::OnCreatePersistentBuffer: Requested an existing "
"buffer with different parameters: name=%s",
name.c_str());
- return -EINVAL;
+ return ErrorStatus(EINVAL);
} else if (!buffer->IsDetached()) {
ALOGE(
"BufferHubService::OnCreatePersistentBuffer: Requesting a persistent "
"buffer that is already attached to a channel: name=%s",
name.c_str());
- return -EINVAL;
+ return ErrorStatus(EINVAL);
} else {
buffer->Attach(channel_id);
message.SetChannel(buffer);
- return 0;
+ return {};
}
- } else if (auto buffer = ProducerChannel::Create(
- this, channel_id, width, height, format, usage,
- meta_size_bytes, slice_count, &error)) {
- const int ret =
- buffer->OnProducerMakePersistent(message, name, user_id, group_id);
- if (!ret)
- message.SetChannel(buffer);
- return ret;
} else {
- ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
- return error;
+ auto status = ProducerChannel::Create(
+ this, channel_id, width, height, format, producer_usage, consumer_usage,
+ meta_size_bytes, slice_count);
+ if (!status) {
+ ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
+ return status.error_status();
+ }
+ auto persistent_buffer = status.take();
+ auto make_persistent_status = persistent_buffer->OnProducerMakePersistent(
+ message, name, user_id, group_id);
+ if (make_persistent_status)
+ message.SetChannel(persistent_buffer);
+ return make_persistent_status;
}
}
-int BufferHubService::OnGetPersistentBuffer(Message& message,
- const std::string& name) {
+Status<void> BufferHubService::OnGetPersistentBuffer(Message& message,
+ const std::string& name) {
const int channel_id = message.GetChannelId();
ALOGD_IF(TRACE,
"BufferHubService::OnGetPersistentBuffer: channel_id=%d name=%s",
@@ -343,7 +373,7 @@
"BufferHubService::OnGetPersistentBuffer: Channel already attached to "
"buffer: channel_id=%d buffer_id=%d",
channel_id, channel->buffer_id());
- return -EALREADY;
+ return ErrorStatus(EALREADY);
}
const int euid = message.GetEffectiveUserId();
@@ -355,28 +385,28 @@
"BufferHubService::OnGetPersistentBuffer: Requesting process does "
"not have permission to access named buffer: name=%s euid=%d egid=%d",
name.c_str(), euid, egid);
- return -EPERM;
+ return ErrorStatus(EPERM);
} else if (!buffer->IsDetached()) {
ALOGE(
"BufferHubService::OnGetPersistentBuffer: Requesting a persistent "
"buffer that is already attached to a channel: name=%s",
name.c_str());
- return -EINVAL;
+ return ErrorStatus(EINVAL);
} else {
buffer->Attach(channel_id);
message.SetChannel(buffer);
- return 0;
+ return {};
}
} else {
ALOGE("BufferHubService::OnGetPersistentBuffer: Buffer \"%s\" not found!",
name.c_str());
- return -ENOENT;
+ return ErrorStatus(ENOENT);
}
}
Status<QueueInfo> BufferHubService::OnCreateProducerQueue(
- pdx::Message& message, size_t meta_size_bytes, int usage_set_mask,
- int usage_clear_mask, int usage_deny_set_mask, int usage_deny_clear_mask) {
+ pdx::Message& message, size_t meta_size_bytes,
+ const UsagePolicy& usage_policy) {
// Use the producer channel id as the global queue id.
const int queue_id = message.GetChannelId();
ALOGD_IF(TRACE, "BufferHubService::OnCreateProducerQueue: queue_id=%d",
@@ -389,15 +419,14 @@
return ErrorStatus(EALREADY);
}
- int error;
- if (const auto producer_channel = ProducerQueueChannel::Create(
- this, queue_id, meta_size_bytes, usage_set_mask, usage_clear_mask,
- usage_deny_set_mask, usage_deny_clear_mask, &error)) {
- message.SetChannel(producer_channel);
+ auto status = ProducerQueueChannel::Create(this, queue_id, meta_size_bytes,
+ usage_policy);
+ if (status) {
+ message.SetChannel(status.take());
return {{meta_size_bytes, queue_id}};
} else {
ALOGE("BufferHubService::OnCreateBuffer: Failed to create producer!!");
- return ErrorStatus(-error);
+ return status.error_status();
}
}
diff --git a/services/vr/bufferhubd/buffer_hub.h b/services/vr/bufferhubd/buffer_hub.h
index 150e399..4cb1eb9 100644
--- a/services/vr/bufferhubd/buffer_hub.h
+++ b/services/vr/bufferhubd/buffer_hub.h
@@ -48,43 +48,40 @@
size_t consumer_count = 0;
// Data field for buffer producer.
- int width = 0;
- int height = 0;
- int format = 0;
- int usage = 0;
+ uint32_t width = 0;
+ uint32_t height = 0;
+ uint32_t format = 0;
+ uint64_t producer_usage = 0;
+ uint64_t consumer_usage = 0;
size_t slice_count = 0;
std::string name;
// Data filed for producer queue.
size_t capacity = 0;
- int usage_set_mask = 0;
- int usage_clear_mask = 0;
- int usage_deny_set_mask = 0;
- int usage_deny_clear_mask = 0;
+ UsagePolicy usage_policy{0, 0, 0, 0, 0, 0, 0, 0};
- BufferInfo(int id, size_t consumer_count, int width, int height, int format,
- int usage, size_t slice_count, const std::string& name)
+ BufferInfo(int id, size_t consumer_count, uint32_t width, uint32_t height,
+ uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage, size_t slice_count,
+ const std::string& name)
: id(id),
type(kProducerType),
consumer_count(consumer_count),
width(width),
height(height),
format(format),
- usage(usage),
+ producer_usage(producer_usage),
+ consumer_usage(consumer_usage),
slice_count(slice_count),
name(name) {}
BufferInfo(int id, size_t consumer_count, size_t capacity,
- int usage_set_mask, int usage_clear_mask,
- int usage_deny_set_mask, int usage_deny_clear_mask)
+ const UsagePolicy& usage_policy)
: id(id),
type(kProducerQueueType),
consumer_count(consumer_count),
capacity(capacity),
- usage_set_mask(usage_set_mask),
- usage_clear_mask(usage_clear_mask),
- usage_deny_set_mask(usage_deny_set_mask),
- usage_deny_clear_mask(usage_deny_clear_mask) {}
+ usage_policy(usage_policy) {}
BufferInfo() {}
};
@@ -162,16 +159,19 @@
std::unordered_map<std::string, std::shared_ptr<ProducerChannel>>
named_buffers_;
- int OnCreateBuffer(pdx::Message& message, int width, int height, int format,
- int usage, size_t meta_size_bytes, size_t slice_count);
- int OnCreatePersistentBuffer(pdx::Message& message, const std::string& name,
- int user_id, int group_id, int width, int height,
- int format, int usage, size_t meta_size_bytes,
- size_t slice_count);
- int OnGetPersistentBuffer(pdx::Message& message, const std::string& name);
- pdx::Status<QueueInfo> OnCreateProducerQueue(
- pdx::Message& message, size_t meta_size_bytes, int usage_set_mask,
- int usage_clear_mask, int usage_deny_set_mask, int usage_deny_clear_mask);
+ pdx::Status<void> OnCreateBuffer(pdx::Message& message, uint32_t width, uint32_t height,
+ uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage, size_t meta_size_bytes,
+ size_t slice_count);
+ pdx::Status<void> OnCreatePersistentBuffer(pdx::Message& message, const std::string& name,
+ int user_id, int group_id, uint32_t width,
+ uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage,
+ size_t meta_size_bytes, size_t slice_count);
+ pdx::Status<void> OnGetPersistentBuffer(pdx::Message& message, const std::string& name);
+ pdx::Status<QueueInfo> OnCreateProducerQueue(pdx::Message& message,
+ size_t meta_size_bytes,
+ const UsagePolicy& usage_policy);
BufferHubService(const BufferHubService&) = delete;
void operator=(const BufferHubService&) = delete;
diff --git a/services/vr/bufferhubd/consumer_channel.cpp b/services/vr/bufferhubd/consumer_channel.cpp
index 2264cef..311f5c6 100644
--- a/services/vr/bufferhubd/consumer_channel.cpp
+++ b/services/vr/bufferhubd/consumer_channel.cpp
@@ -8,9 +8,11 @@
#include <private/dvr/bufferhub_rpc.h>
#include "producer_channel.h"
+using android::pdx::ErrorStatus;
using android::pdx::BorrowedHandle;
using android::pdx::Channel;
using android::pdx::Message;
+using android::pdx::Status;
using android::pdx::rpc::DispatchRemoteMethod;
namespace android {
@@ -103,53 +105,53 @@
}
}
-std::pair<BorrowedFence, ConsumerChannel::MetaData>
+Status<std::pair<BorrowedFence, ConsumerChannel::MetaData>>
ConsumerChannel::OnConsumerAcquire(Message& message,
std::size_t metadata_size) {
ATRACE_NAME("ConsumerChannel::OnConsumerAcquire");
auto producer = GetProducer();
if (!producer)
- REPLY_ERROR_RETURN(message, EPIPE, {});
+ return ErrorStatus(EPIPE);
if (ignored_ || handled_) {
ALOGE(
"ConsumerChannel::OnConsumerAcquire: Acquire when not posted: "
"ignored=%d handled=%d channel_id=%d buffer_id=%d",
ignored_, handled_, message.GetChannelId(), producer->buffer_id());
- REPLY_ERROR_RETURN(message, EBUSY, {});
+ return ErrorStatus(EBUSY);
} else {
ClearAvailable();
return producer->OnConsumerAcquire(message, metadata_size);
}
}
-int ConsumerChannel::OnConsumerRelease(Message& message,
- LocalFence release_fence) {
+Status<void> ConsumerChannel::OnConsumerRelease(Message& message,
+ LocalFence release_fence) {
ATRACE_NAME("ConsumerChannel::OnConsumerRelease");
auto producer = GetProducer();
if (!producer)
- return -EPIPE;
+ return ErrorStatus(EPIPE);
if (ignored_ || handled_) {
ALOGE(
"ConsumerChannel::OnConsumerRelease: Release when not acquired: "
"ignored=%d handled=%d channel_id=%d buffer_id=%d",
ignored_, handled_, message.GetChannelId(), producer->buffer_id());
- return -EBUSY;
+ return ErrorStatus(EBUSY);
} else {
ClearAvailable();
- const int ret =
+ auto status =
producer->OnConsumerRelease(message, std::move(release_fence));
- handled_ = ret == 0;
- return ret;
+ handled_ = !!status;
+ return status;
}
}
-int ConsumerChannel::OnConsumerSetIgnore(Message&, bool ignored) {
+Status<void> ConsumerChannel::OnConsumerSetIgnore(Message&, bool ignored) {
ATRACE_NAME("ConsumerChannel::OnConsumerSetIgnore");
auto producer = GetProducer();
if (!producer)
- return -EPIPE;
+ return ErrorStatus(EPIPE);
ignored_ = ignored;
if (ignored_ && !handled_) {
@@ -160,7 +162,7 @@
handled_ = false;
}
- return 0;
+ return {};
}
bool ConsumerChannel::OnProducerPosted() {
diff --git a/services/vr/bufferhubd/consumer_channel.h b/services/vr/bufferhubd/consumer_channel.h
index d2a078f..d84055c 100644
--- a/services/vr/bufferhubd/consumer_channel.h
+++ b/services/vr/bufferhubd/consumer_channel.h
@@ -32,10 +32,11 @@
std::shared_ptr<ProducerChannel> GetProducer() const;
- std::pair<BorrowedFence, MetaData> OnConsumerAcquire(
+ pdx::Status<std::pair<BorrowedFence, MetaData>> OnConsumerAcquire(
Message& message, std::size_t metadata_size);
- int OnConsumerRelease(Message& message, LocalFence release_fence);
- int OnConsumerSetIgnore(Message& message, bool ignore);
+ pdx::Status<void> OnConsumerRelease(Message& message,
+ LocalFence release_fence);
+ pdx::Status<void> OnConsumerSetIgnore(Message& message, bool ignore);
bool handled_; // True if we have processed RELEASE.
bool ignored_; // True if we are ignoring events.
diff --git a/services/vr/bufferhubd/consumer_queue_channel.cpp b/services/vr/bufferhubd/consumer_queue_channel.cpp
index cc16f1f..7422751 100644
--- a/services/vr/bufferhubd/consumer_queue_channel.cpp
+++ b/services/vr/bufferhubd/consumer_queue_channel.cpp
@@ -4,7 +4,9 @@
#include "producer_channel.h"
+using android::pdx::ErrorStatus;
using android::pdx::RemoteChannelHandle;
+using android::pdx::Status;
using android::pdx::rpc::DispatchRemoteMethod;
namespace android {
@@ -83,7 +85,7 @@
SignalAvailable();
}
-std::vector<std::pair<RemoteChannelHandle, size_t>>
+Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
ConsumerQueueChannel::OnConsumerQueueImportBuffers(Message& message) {
std::vector<std::pair<RemoteChannelHandle, size_t>> buffer_handles;
ATRACE_NAME("ConsumerQueueChannel::OnConsumerQueueImportBuffers");
@@ -106,31 +108,30 @@
continue;
}
- RemoteChannelHandle consumer_handle(
- producer_channel->CreateConsumer(message));
+ auto status = producer_channel->CreateConsumer(message);
// If no buffers are imported successfully, clear available and return an
// error. Otherwise, return all consumer handles already imported
// successfully, but keep available bits on, so that the client can retry
// importing remaining consumer buffers.
- if (!consumer_handle.valid()) {
+ if (!status) {
ALOGE(
- "ConsumerQueueChannel::OnConsumerQueueImportBuffers: imported "
- "consumer handle is invalid.");
+ "ConsumerQueueChannel::OnConsumerQueueImportBuffers: Failed create "
+ "consumer: %s",
+ status.GetErrorMessage().c_str());
if (buffer_handles.empty()) {
ClearAvailable();
- REPLY_ERROR_RETURN(message, EIO, {});
+ return status.error_status();
} else {
- return buffer_handles;
+ return {std::move(buffer_handles)};
}
}
- // Move consumer_handle into buffer_handles.
- buffer_handles.emplace_back(std::move(consumer_handle), producer_slot);
+ buffer_handles.emplace_back(status.take(), producer_slot);
}
ClearAvailable();
- return buffer_handles;
+ return {std::move(buffer_handles)};
}
} // namespace dvr
diff --git a/services/vr/bufferhubd/consumer_queue_channel.h b/services/vr/bufferhubd/consumer_queue_channel.h
index b345595..e1005e4 100644
--- a/services/vr/bufferhubd/consumer_queue_channel.h
+++ b/services/vr/bufferhubd/consumer_queue_channel.h
@@ -36,7 +36,7 @@
// allocated. Clients uses kOpConsumerQueueImportBuffers to import new
// consumer buffers and this handler returns a vector of fd representing
// BufferConsumers that clients can import.
- std::vector<std::pair<RemoteChannelHandle, size_t>>
+ pdx::Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
OnConsumerQueueImportBuffers(Message& message);
private:
diff --git a/services/vr/bufferhubd/producer_channel.cpp b/services/vr/bufferhubd/producer_channel.cpp
index 903d174..c946a8d 100644
--- a/services/vr/bufferhubd/producer_channel.cpp
+++ b/services/vr/bufferhubd/producer_channel.cpp
@@ -13,8 +13,10 @@
#include "consumer_channel.h"
using android::pdx::BorrowedHandle;
+using android::pdx::ErrorStatus;
using android::pdx::Message;
using android::pdx::RemoteChannelHandle;
+using android::pdx::Status;
using android::pdx::rpc::BufferWrapper;
using android::pdx::rpc::DispatchRemoteMethod;
using android::pdx::rpc::WrapBuffer;
@@ -23,7 +25,9 @@
namespace dvr {
ProducerChannel::ProducerChannel(BufferHubService* service, int channel_id,
- int width, int height, int format, int usage,
+ uint32_t width, uint32_t height,
+ uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage,
size_t meta_size_bytes, size_t slice_count,
int* error)
: BufferHubChannel(service, channel_id, channel_id, kProducerType),
@@ -33,7 +37,8 @@
meta_size_bytes_(meta_size_bytes),
meta_(meta_size_bytes ? new uint8_t[meta_size_bytes] : nullptr) {
for (auto& ion_buffer : slices_) {
- const int ret = ion_buffer.Alloc(width, height, format, usage);
+ const int ret =
+ ion_buffer.Alloc(width, height, format, producer_usage, consumer_usage);
if (ret < 0) {
ALOGE("ProducerChannel::ProducerChannel: Failed to allocate buffer: %s",
strerror(-ret));
@@ -46,17 +51,18 @@
*error = 0;
}
-std::shared_ptr<ProducerChannel> ProducerChannel::Create(
- BufferHubService* service, int channel_id, int width, int height,
- int format, int usage, size_t meta_size_bytes, size_t slice_count,
- int* error) {
- std::shared_ptr<ProducerChannel> producer(
- new ProducerChannel(service, channel_id, width, height, format, usage,
- meta_size_bytes, slice_count, error));
- if (*error < 0)
- return nullptr;
+Status<std::shared_ptr<ProducerChannel>> ProducerChannel::Create(
+ BufferHubService* service, int channel_id, uint32_t width, uint32_t height,
+ uint32_t format, uint64_t producer_usage, uint64_t consumer_usage,
+ size_t meta_size_bytes, size_t slice_count) {
+ int error;
+ std::shared_ptr<ProducerChannel> producer(new ProducerChannel(
+ service, channel_id, width, height, format, producer_usage,
+ consumer_usage, meta_size_bytes, slice_count, &error));
+ if (error < 0)
+ return ErrorStatus(-error);
else
- return producer;
+ return {std::move(producer)};
}
ProducerChannel::~ProducerChannel() {
@@ -70,7 +76,8 @@
BufferHubChannel::BufferInfo ProducerChannel::GetBufferInfo() const {
return BufferInfo(buffer_id(), consumer_channels_.size(), slices_[0].width(),
slices_[0].height(), slices_[0].format(),
- slices_[0].usage(), slices_.size(), name_);
+ slices_[0].producer_usage(), slices_[0].consumer_usage(),
+ slices_.size(), name_);
}
void ProducerChannel::HandleImpulse(Message& message) {
@@ -125,28 +132,28 @@
}
}
-NativeBufferHandle<BorrowedHandle> ProducerChannel::OnGetBuffer(
+Status<NativeBufferHandle<BorrowedHandle>> ProducerChannel::OnGetBuffer(
Message& message, unsigned index) {
ATRACE_NAME("ProducerChannel::OnGetBuffer");
ALOGD_IF(TRACE, "ProducerChannel::OnGetBuffer: buffer=%d", buffer_id());
if (index < slices_.size()) {
- return NativeBufferHandle<BorrowedHandle>(slices_[index], buffer_id());
+ return {NativeBufferHandle<BorrowedHandle>(slices_[index], buffer_id())};
} else {
- REPLY_ERROR_RETURN(message, EINVAL, NativeBufferHandle<BorrowedHandle>());
+ return ErrorStatus(EINVAL);
}
}
-std::vector<NativeBufferHandle<BorrowedHandle>> ProducerChannel::OnGetBuffers(
- Message&) {
+Status<std::vector<NativeBufferHandle<BorrowedHandle>>>
+ProducerChannel::OnGetBuffers(Message&) {
ATRACE_NAME("ProducerChannel::OnGetBuffers");
ALOGD_IF(TRACE, "ProducerChannel::OnGetBuffers: buffer_id=%d", buffer_id());
std::vector<NativeBufferHandle<BorrowedHandle>> buffer_handles;
for (const auto& buffer : slices_)
buffer_handles.emplace_back(buffer, buffer_id());
- return buffer_handles;
+ return {std::move(buffer_handles)};
}
-RemoteChannelHandle ProducerChannel::CreateConsumer(Message& message) {
+Status<RemoteChannelHandle> ProducerChannel::CreateConsumer(Message& message) {
ATRACE_NAME("ProducerChannel::CreateConsumer");
ALOGD_IF(TRACE, "ProducerChannel::CreateConsumer: buffer_id=%d", buffer_id());
@@ -154,9 +161,9 @@
auto status = message.PushChannel(0, nullptr, &channel_id);
if (!status) {
ALOGE(
- "ProducerChannel::CreateConsumer: failed to push consumer channel: %s",
+ "ProducerChannel::CreateConsumer: Failed to push consumer channel: %s",
status.GetErrorMessage().c_str());
- return RemoteChannelHandle();
+ return ErrorStatus(ENOMEM);
}
auto consumer = std::make_shared<ConsumerChannel>(
@@ -167,7 +174,7 @@
"ProducerChannel::CreateConsumer: failed to set new consumer channel: "
"%s",
channel_status.GetErrorMessage().c_str());
- return RemoteChannelHandle();
+ return ErrorStatus(ENOMEM);
}
if (!producer_owns_) {
@@ -176,33 +183,27 @@
pending_consumers_++;
}
- return status.take();
+ return {status.take()};
}
-RemoteChannelHandle ProducerChannel::OnNewConsumer(Message& message) {
+Status<RemoteChannelHandle> ProducerChannel::OnNewConsumer(Message& message) {
ATRACE_NAME("ProducerChannel::OnNewConsumer");
ALOGD_IF(TRACE, "ProducerChannel::OnNewConsumer: buffer_id=%d", buffer_id());
-
- RemoteChannelHandle consumer_handle(CreateConsumer(message));
-
- if (consumer_handle.valid())
- return consumer_handle;
- else
- REPLY_ERROR_RETURN(message, ENOMEM, RemoteChannelHandle());
+ return CreateConsumer(message);
}
-int ProducerChannel::OnProducerPost(
+Status<void> ProducerChannel::OnProducerPost(
Message&, LocalFence acquire_fence,
BufferWrapper<std::vector<std::uint8_t>> metadata) {
ATRACE_NAME("ProducerChannel::OnProducerPost");
ALOGD_IF(TRACE, "ProducerChannel::OnProducerPost: buffer_id=%d", buffer_id());
if (!producer_owns_) {
ALOGE("ProducerChannel::OnProducerPost: Not in gained state!");
- return -EBUSY;
+ return ErrorStatus(EBUSY);
}
if (meta_size_bytes_ != metadata.size())
- return -EINVAL;
+ return ErrorStatus(EINVAL);
std::copy(metadata.begin(), metadata.end(), meta_.get());
post_fence_ = std::move(acquire_fence);
@@ -220,29 +221,29 @@
ALOGD_IF(TRACE, "ProducerChannel::OnProducerPost: %d pending consumers",
pending_consumers_);
- return 0;
+ return {};
}
-LocalFence ProducerChannel::OnProducerGain(Message& message) {
+Status<LocalFence> ProducerChannel::OnProducerGain(Message& message) {
ATRACE_NAME("ProducerChannel::OnGain");
ALOGD_IF(TRACE, "ProducerChannel::OnGain: buffer_id=%d", buffer_id());
if (producer_owns_) {
ALOGE("ProducerChanneL::OnGain: Already in gained state: channel=%d",
channel_id());
- REPLY_ERROR_RETURN(message, EALREADY, {});
+ return ErrorStatus(EALREADY);
}
// There are still pending consumers, return busy.
if (pending_consumers_ > 0)
- REPLY_ERROR_RETURN(message, EBUSY, {});
+ return ErrorStatus(EBUSY);
ClearAvailable();
producer_owns_ = true;
post_fence_.close();
- return std::move(returned_fence_);
+ return {std::move(returned_fence_)};
}
-std::pair<BorrowedFence, BufferWrapper<std::uint8_t*>>
+Status<std::pair<BorrowedFence, BufferWrapper<std::uint8_t*>>>
ProducerChannel::OnConsumerAcquire(Message& message,
std::size_t metadata_size) {
ATRACE_NAME("ProducerChannel::OnConsumerAcquire");
@@ -250,26 +251,27 @@
buffer_id());
if (producer_owns_) {
ALOGE("ProducerChannel::OnConsumerAcquire: Not in posted state!");
- REPLY_ERROR_RETURN(message, EBUSY, {});
+ return ErrorStatus(EBUSY);
}
// Return a borrowed fd to avoid unnecessary duplication of the underlying fd.
// Serialization just needs to read the handle.
if (metadata_size == 0)
- return std::make_pair(post_fence_.borrow(),
- WrapBuffer<std::uint8_t>(nullptr, 0));
+ return {std::make_pair(post_fence_.borrow(),
+ WrapBuffer<std::uint8_t>(nullptr, 0))};
else
- return std::make_pair(post_fence_.borrow(),
- WrapBuffer(meta_.get(), meta_size_bytes_));
+ return {std::make_pair(post_fence_.borrow(),
+ WrapBuffer(meta_.get(), meta_size_bytes_))};
}
-int ProducerChannel::OnConsumerRelease(Message&, LocalFence release_fence) {
+Status<void> ProducerChannel::OnConsumerRelease(Message&,
+ LocalFence release_fence) {
ATRACE_NAME("ProducerChannel::OnConsumerRelease");
ALOGD_IF(TRACE, "ProducerChannel::OnConsumerRelease: buffer_id=%d",
buffer_id());
if (producer_owns_) {
ALOGE("ProducerChannel::OnConsumerRelease: Not in acquired state!");
- return -EBUSY;
+ return ErrorStatus(EBUSY);
}
// Attempt to merge the fences if necessary.
@@ -282,7 +284,7 @@
if (!merged_fence) {
ALOGE("ProducerChannel::OnConsumerRelease: Failed to merge fences: %s",
strerror(error));
- return -error;
+ return ErrorStatus(error);
}
returned_fence_ = std::move(merged_fence);
} else {
@@ -291,7 +293,7 @@
}
OnConsumerIgnored();
- return 0;
+ return {};
}
void ProducerChannel::OnConsumerIgnored() {
@@ -302,9 +304,10 @@
buffer_id(), pending_consumers_);
}
-int ProducerChannel::OnProducerMakePersistent(Message& message,
- const std::string& name,
- int user_id, int group_id) {
+Status<void> ProducerChannel::OnProducerMakePersistent(Message& message,
+ const std::string& name,
+ int user_id,
+ int group_id) {
ATRACE_NAME("ProducerChannel::OnProducerMakePersistent");
ALOGD_IF(TRACE,
"ProducerChannel::OnProducerMakePersistent: buffer_id=%d name=%s "
@@ -313,7 +316,7 @@
if (name.empty() || (user_id < 0 && user_id != kNoCheckId) ||
(group_id < 0 && group_id != kNoCheckId)) {
- return -EINVAL;
+ return ErrorStatus(EINVAL);
}
// Try to add this buffer with the requested name.
@@ -331,18 +334,18 @@
owner_user_id_ = user_id;
owner_group_id_ = group_id;
name_ = name;
- return 0;
+ return {};
} else {
// Otherwise a buffer with that name already exists.
- return -EALREADY;
+ return ErrorStatus(EALREADY);
}
}
-int ProducerChannel::OnRemovePersistence(Message&) {
+Status<void> ProducerChannel::OnRemovePersistence(Message&) {
if (service()->RemoveNamedBuffer(*this))
- return 0;
+ return {};
else
- return -ENOENT;
+ return ErrorStatus(ENOENT);
}
void ProducerChannel::AddConsumer(ConsumerChannel* channel) {
@@ -365,12 +368,16 @@
}
// Returns true if the given parameters match the underlying buffer parameters.
-bool ProducerChannel::CheckParameters(int width, int height, int format,
- int usage, size_t meta_size_bytes,
+bool ProducerChannel::CheckParameters(uint32_t width, uint32_t height,
+ uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage,
+ size_t meta_size_bytes,
size_t slice_count) {
return slices_.size() == slice_count && meta_size_bytes == meta_size_bytes_ &&
slices_[0].width() == width && slices_[0].height() == height &&
- slices_[0].format() == format && slices_[0].usage() == usage;
+ slices_[0].format() == format &&
+ slices_[0].producer_usage() == producer_usage &&
+ slices_[0].consumer_usage() == consumer_usage;
}
} // namespace dvr
diff --git a/services/vr/bufferhubd/producer_channel.h b/services/vr/bufferhubd/producer_channel.h
index e7ca459..f04c8a5 100644
--- a/services/vr/bufferhubd/producer_channel.h
+++ b/services/vr/bufferhubd/producer_channel.h
@@ -30,10 +30,10 @@
template <typename T>
using BufferWrapper = pdx::rpc::BufferWrapper<T>;
- static std::shared_ptr<ProducerChannel> Create(
- BufferHubService* service, int channel_id, int width, int height,
- int format, int usage, size_t meta_size_bytes, size_t slice_count,
- int* error);
+ static pdx::Status<std::shared_ptr<ProducerChannel>> Create(
+ BufferHubService* service, int channel_id, uint32_t width,
+ uint32_t height, uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage, size_t meta_size_bytes, size_t slice_count);
~ProducerChannel() override;
@@ -42,17 +42,18 @@
BufferInfo GetBufferInfo() const override;
- NativeBufferHandle<BorrowedHandle> OnGetBuffer(Message& message,
- unsigned index);
- std::vector<NativeBufferHandle<BorrowedHandle>> OnGetBuffers(
+ pdx::Status<NativeBufferHandle<BorrowedHandle>> OnGetBuffer(Message& message,
+ unsigned index);
+ pdx::Status<std::vector<NativeBufferHandle<BorrowedHandle>>> OnGetBuffers(
Message& message);
- RemoteChannelHandle CreateConsumer(Message& message);
- RemoteChannelHandle OnNewConsumer(Message& message);
+ pdx::Status<RemoteChannelHandle> CreateConsumer(Message& message);
+ pdx::Status<RemoteChannelHandle> OnNewConsumer(Message& message);
- std::pair<BorrowedFence, BufferWrapper<std::uint8_t*>> OnConsumerAcquire(
- Message& message, std::size_t metadata_size);
- int OnConsumerRelease(Message& message, LocalFence release_fence);
+ pdx::Status<std::pair<BorrowedFence, BufferWrapper<std::uint8_t*>>>
+ OnConsumerAcquire(Message& message, std::size_t metadata_size);
+ pdx::Status<void> OnConsumerRelease(Message& message,
+ LocalFence release_fence);
void OnConsumerIgnored();
@@ -60,12 +61,14 @@
void RemoveConsumer(ConsumerChannel* channel);
bool CheckAccess(int euid, int egid);
- bool CheckParameters(int width, int height, int format, int usage,
+ bool CheckParameters(uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage,
size_t meta_size_bytes, size_t slice_count);
- int OnProducerMakePersistent(Message& message, const std::string& name,
- int user_id, int group_id);
- int OnRemovePersistence(Message& message);
+ pdx::Status<void> OnProducerMakePersistent(Message& message,
+ const std::string& name,
+ int user_id, int group_id);
+ pdx::Status<void> OnRemovePersistence(Message& message);
private:
std::vector<ConsumerChannel*> consumer_channels_;
@@ -91,13 +94,15 @@
std::string name_;
- ProducerChannel(BufferHubService* service, int channel, int width, int height,
- int format, int usage, size_t meta_size_bytes,
+ ProducerChannel(BufferHubService* service, int channel, uint32_t width,
+ uint32_t height, uint32_t format, uint64_t producer_usage,
+ uint64_t consumer_usage, size_t meta_size_bytes,
size_t slice_count, int* error);
- int OnProducerPost(Message& message, LocalFence acquire_fence,
- BufferWrapper<std::vector<std::uint8_t>> metadata);
- LocalFence OnProducerGain(Message& message);
+ pdx::Status<void> OnProducerPost(
+ Message& message, LocalFence acquire_fence,
+ BufferWrapper<std::vector<std::uint8_t>> metadata);
+ pdx::Status<LocalFence> OnProducerGain(Message& message);
ProducerChannel(const ProducerChannel&) = delete;
void operator=(const ProducerChannel&) = delete;
diff --git a/services/vr/bufferhubd/producer_queue_channel.cpp b/services/vr/bufferhubd/producer_queue_channel.cpp
index 7741058..dc2a47e 100644
--- a/services/vr/bufferhubd/producer_queue_channel.cpp
+++ b/services/vr/bufferhubd/producer_queue_channel.cpp
@@ -1,5 +1,7 @@
#include "producer_queue_channel.h"
+#include <inttypes.h>
+
#include "consumer_queue_channel.h"
#include "producer_channel.h"
@@ -12,16 +14,14 @@
namespace android {
namespace dvr {
-ProducerQueueChannel::ProducerQueueChannel(
- BufferHubService* service, int channel_id, size_t meta_size_bytes,
- int usage_set_mask, int usage_clear_mask, int usage_deny_set_mask,
- int usage_deny_clear_mask, int* error)
+ProducerQueueChannel::ProducerQueueChannel(BufferHubService* service,
+ int channel_id,
+ size_t meta_size_bytes,
+ const UsagePolicy& usage_policy,
+ int* error)
: BufferHubChannel(service, channel_id, channel_id, kProducerQueueType),
meta_size_bytes_(meta_size_bytes),
- usage_set_mask_(usage_set_mask),
- usage_clear_mask_(usage_clear_mask),
- usage_deny_set_mask_(usage_deny_set_mask),
- usage_deny_clear_mask_(usage_deny_clear_mask),
+ usage_policy_(usage_policy),
capacity_(0) {
*error = 0;
}
@@ -29,28 +29,34 @@
ProducerQueueChannel::~ProducerQueueChannel() {}
/* static */
-std::shared_ptr<ProducerQueueChannel> ProducerQueueChannel::Create(
+Status<std::shared_ptr<ProducerQueueChannel>> ProducerQueueChannel::Create(
BufferHubService* service, int channel_id, size_t meta_size_bytes,
- int usage_set_mask, int usage_clear_mask, int usage_deny_set_mask,
- int usage_deny_clear_mask, int* error) {
+ const UsagePolicy& usage_policy) {
// Configuration between |usage_deny_set_mask| and |usage_deny_clear_mask|
// should be mutually exclusive.
- if (usage_deny_set_mask & usage_deny_clear_mask) {
+ if ((usage_policy.producer_deny_set_mask &
+ usage_policy.producer_deny_clear_mask) ||
+ (usage_policy.consumer_deny_set_mask &
+ usage_policy.consumer_deny_clear_mask)) {
ALOGE(
"BufferHubService::OnCreateProducerQueue: illegal usage mask "
- "configuration: usage_deny_set_mask=%d, usage_deny_clear_mask=%d",
- usage_deny_set_mask, usage_deny_clear_mask);
- *error = -EINVAL;
- return nullptr;
+ "configuration: producer_deny_set_mask=%" PRIx64
+ " producer_deny_clear_mask=%" PRIx64 " consumer_deny_set_mask=%" PRIx64
+ " consumer_deny_clear_mask=%" PRIx64,
+ usage_policy.producer_deny_set_mask,
+ usage_policy.producer_deny_clear_mask,
+ usage_policy.consumer_deny_set_mask,
+ usage_policy.consumer_deny_clear_mask);
+ return ErrorStatus(EINVAL);
}
+ int error = 0;
std::shared_ptr<ProducerQueueChannel> producer(new ProducerQueueChannel(
- service, channel_id, meta_size_bytes, usage_set_mask, usage_clear_mask,
- usage_deny_set_mask, usage_deny_clear_mask, error));
- if (*error < 0)
- return nullptr;
+ service, channel_id, meta_size_bytes, usage_policy, &error));
+ if (error < 0)
+ return ErrorStatus(-error);
else
- return producer;
+ return {std::move(producer)};
}
bool ProducerQueueChannel::HandleMessage(Message& message) {
@@ -88,8 +94,7 @@
BufferHubChannel::BufferInfo ProducerQueueChannel::GetBufferInfo() const {
return BufferInfo(channel_id(), consumer_channels_.size(), capacity_,
- usage_set_mask_, usage_clear_mask_, usage_deny_set_mask_,
- usage_deny_clear_mask_);
+ usage_policy_);
}
Status<RemoteChannelHandle> ProducerQueueChannel::OnCreateConsumerQueue(
@@ -127,11 +132,10 @@
}
Status<std::vector<std::pair<RemoteChannelHandle, size_t>>>
-ProducerQueueChannel::OnProducerQueueAllocateBuffers(Message& message,
- int width, int height,
- int format, int usage,
- size_t slice_count,
- size_t buffer_count) {
+ProducerQueueChannel::OnProducerQueueAllocateBuffers(
+ Message& message, uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage, size_t slice_count,
+ size_t buffer_count) {
ATRACE_NAME("ProducerQueueChannel::OnProducerQueueAllocateBuffers");
ALOGD_IF(TRACE,
"ProducerQueueChannel::OnProducerQueueAllocateBuffers: "
@@ -141,31 +145,58 @@
std::vector<std::pair<RemoteChannelHandle, size_t>> buffer_handles;
// Deny buffer allocation violating preset rules.
- if (usage & usage_deny_set_mask_) {
+ if (producer_usage & usage_policy_.producer_deny_set_mask) {
ALOGE(
- "ProducerQueueChannel::OnProducerQueueAllocateBuffers: usage: %d is "
- "not permitted. Violating usage_deny_set_mask, the following bits "
- "shall not be set: %d.",
- usage, usage_deny_set_mask_);
+ "ProducerQueueChannel::OnProducerQueueAllocateBuffers: producer_usage: "
+ "%" PRIx64
+ " is not permitted. Violating producer_deny_set_mask, the following "
+ "bits shall not be set: %" PRIx64 ".",
+ producer_usage, usage_policy_.producer_deny_set_mask);
return ErrorStatus(EINVAL);
}
- if (~usage & usage_deny_clear_mask_) {
+ if (consumer_usage & usage_policy_.consumer_deny_set_mask) {
ALOGE(
- "ProducerQueueChannel::OnProducerQueueAllocateBuffers: usage: %d is "
- "not permitted. Violating usage_deny_clear_mask, the following bits "
- "must be set: %d.",
- usage, usage_deny_clear_mask_);
+ "ProducerQueueChannel::OnProducerQueueAllocateBuffers: consumer_usage: "
+ "%" PRIx64
+ " is not permitted. Violating consumer_deny_set_mask, the following "
+ "bits shall not be set: %" PRIx64 ".",
+ consumer_usage, usage_policy_.consumer_deny_set_mask);
return ErrorStatus(EINVAL);
}
- // Force set mask and clear mask. Note that |usage_set_mask_| takes precedence
- // and will overwrite |usage_clear_mask_|.
- int effective_usage = (usage & ~usage_clear_mask_) | usage_set_mask_;
+ if (~producer_usage & usage_policy_.producer_deny_clear_mask) {
+ ALOGE(
+ "ProducerQueueChannel::OnProducerQueueAllocateBuffers: producer_usage: "
+ "%" PRIx64
+ " is not permitted. Violating producer_deny_clear_mask, the following "
+ "bits must be set: %" PRIx64 ".",
+ producer_usage, usage_policy_.producer_deny_clear_mask);
+ return ErrorStatus(EINVAL);
+ }
+
+ if (~consumer_usage & usage_policy_.consumer_deny_clear_mask) {
+ ALOGE(
+ "ProducerQueueChannel::OnProducerQueueAllocateBuffers: consumer_usage: "
+ "%" PRIx64
+ " is not permitted. Violating consumer_deny_clear_mask, the following "
+ "bits must be set: %" PRIx64 ".",
+ consumer_usage, usage_policy_.consumer_deny_clear_mask);
+ return ErrorStatus(EINVAL);
+ }
+ // Force set mask and clear mask. Note that |usage_policy_.X_set_mask_| takes
+ // precedence and will overwrite |usage_policy_.X_clear_mask|.
+ uint64_t effective_producer_usage =
+ (producer_usage & ~usage_policy_.producer_clear_mask) |
+ usage_policy_.producer_set_mask;
+ uint64_t effective_consumer_usage =
+ (consumer_usage & ~usage_policy_.consumer_clear_mask) |
+ usage_policy_.consumer_set_mask;
for (size_t i = 0; i < buffer_count; i++) {
- auto status = AllocateBuffer(message, width, height, format,
- effective_usage, slice_count);
+ auto status =
+ AllocateBuffer(message, width, height, format, effective_producer_usage,
+ effective_consumer_usage, slice_count);
if (!status) {
ALOGE(
"ProducerQueueChannel::OnProducerQueueAllocateBuffers: Failed to "
@@ -179,8 +210,10 @@
}
Status<std::pair<RemoteChannelHandle, size_t>>
-ProducerQueueChannel::AllocateBuffer(Message& message, int width, int height,
- int format, int usage,
+ProducerQueueChannel::AllocateBuffer(Message& message, uint32_t width,
+ uint32_t height, uint32_t format,
+ uint64_t producer_usage,
+ uint64_t consumer_usage,
size_t slice_count) {
ATRACE_NAME("ProducerQueueChannel::AllocateBuffer");
ALOGD_IF(TRACE,
@@ -205,21 +238,24 @@
}
ALOGD_IF(TRACE,
- "ProducerQueueChannel::AllocateBuffer: buffer_id=%d width=%d "
- "height=%d format=%d usage=%d slice_count=%zu",
- buffer_id, width, height, format, usage, slice_count);
+ "ProducerQueueChannel::AllocateBuffer: buffer_id=%d width=%u "
+ "height=%u format=%u producer_usage=%" PRIx64
+ " consumer_usage=%" PRIx64 " slice_count=%zu",
+ buffer_id, width, height, format, producer_usage, consumer_usage,
+ slice_count);
auto buffer_handle = status.take();
- int error;
- const auto producer_channel =
- ProducerChannel::Create(service(), buffer_id, width, height, format,
- usage, meta_size_bytes_, slice_count, &error);
- if (!producer_channel) {
+ auto producer_channel_status = ProducerChannel::Create(
+ service(), buffer_id, width, height, format, producer_usage,
+ consumer_usage, meta_size_bytes_, slice_count);
+ if (!producer_channel_status) {
ALOGE(
- "ProducerQueueChannel::AllocateBuffer: Failed to create "
- "BufferHubBuffer producer!!");
+ "ProducerQueueChannel::AllocateBuffer: Failed to create producer "
+ "buffer: %s",
+ producer_channel_status.GetErrorMessage().c_str());
return ErrorStatus(ENOMEM);
}
+ auto producer_channel = producer_channel_status.take();
ALOGD_IF(
TRACE,
diff --git a/services/vr/bufferhubd/producer_queue_channel.h b/services/vr/bufferhubd/producer_queue_channel.h
index a12a37d..09b0243 100644
--- a/services/vr/bufferhubd/producer_queue_channel.h
+++ b/services/vr/bufferhubd/producer_queue_channel.h
@@ -11,10 +11,9 @@
class ProducerQueueChannel : public BufferHubChannel {
public:
- static std::shared_ptr<ProducerQueueChannel> Create(
+ static pdx::Status<std::shared_ptr<ProducerQueueChannel>> Create(
BufferHubService* service, int channel_id, size_t meta_size_bytes,
- int usage_set_mask, int usage_clear_mask, int usage_deny_set_mask,
- int usage_deny_clear_mask, int* error);
+ const UsagePolicy& usage_policy);
~ProducerQueueChannel() override;
bool HandleMessage(pdx::Message& message) override;
@@ -34,8 +33,10 @@
// Allocate a new BufferHubProducer according to the input spec. Client may
// handle this as if a new producer is created through kOpCreateBuffer.
pdx::Status<std::vector<std::pair<pdx::RemoteChannelHandle, size_t>>>
- OnProducerQueueAllocateBuffers(pdx::Message& message, int width, int height,
- int format, int usage, size_t slice_count,
+ OnProducerQueueAllocateBuffers(pdx::Message& message, uint32_t width,
+ uint32_t height, uint32_t format,
+ uint64_t producer_usage,
+ uint64_t consumer_usage, size_t slice_count,
size_t buffer_count);
// Detach a BufferHubProducer indicated by |slot|. Note that the buffer must
@@ -48,18 +49,17 @@
private:
ProducerQueueChannel(BufferHubService* service, int channel_id,
- size_t meta_size_bytes, int usage_set_mask,
- int usage_clear_mask, int usage_deny_set_mask,
- int usage_deny_clear_mask, int* error);
+ size_t meta_size_bytes, const UsagePolicy& usage_policy,
+ int* error);
// Allocate one single producer buffer by |OnProducerQueueAllocateBuffers|.
// Note that the newly created buffer's file handle will be pushed to client
// and our return type is a RemoteChannelHandle.
- // Returns the remote channdel handle and the slot number for the newly
+ // Returns the remote channel handle and the slot number for the newly
// allocated buffer.
pdx::Status<std::pair<pdx::RemoteChannelHandle, size_t>> AllocateBuffer(
- pdx::Message& message, int width, int height, int format, int usage,
- size_t slice_count);
+ pdx::Message& message, uint32_t width, uint32_t height, uint32_t format,
+ uint64_t producer_usage, uint64_t consumer_usage, size_t slice_count);
// Size of the meta data associated with all the buffers allocated from the
// queue. Now we assume the metadata size is immutable once the queue is
@@ -68,10 +68,7 @@
// A set of variables to control what |usage| bits can this ProducerQueue
// allocate.
- int usage_set_mask_;
- int usage_clear_mask_;
- int usage_deny_set_mask_;
- int usage_deny_clear_mask_;
+ UsagePolicy usage_policy_;
// Provides access to the |channel_id| of all consumer channels associated
// with this producer.
diff --git a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
index 999d71e..15f63fa 100644
--- a/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
+++ b/services/vr/hardware_composer/aidl/android/dvr/parcelable_composer_layer.cpp
@@ -7,41 +7,6 @@
namespace android {
namespace dvr {
-namespace {
-
-sp<GraphicBuffer> GetBufferFromHandle(native_handle_t* handle) {
- uint32_t width = 0, height = 0, stride = 0, layer_count = 1;
- uint64_t producer_usage = 0, consumer_usage = 0;
- int32_t format = 0;
-
- GraphicBufferMapper& mapper = GraphicBufferMapper::get();
- // Need to register |handle| otherwise we can't read its properties.
- if (mapper.registerBuffer(handle) != OK) {
- ALOGE("Failed to register buffer");
- return nullptr;
- }
-
- if (mapper.getDimensions(handle, &width, &height) ||
- mapper.getStride(handle, &stride) ||
- mapper.getFormat(handle, &format) ||
- mapper.getProducerUsage(handle, &producer_usage) ||
- mapper.getConsumerUsage(handle, &consumer_usage)) {
- ALOGE("Failed to read handle properties");
- return nullptr;
- }
-
- // This will only succeed if gralloc has GRALLOC1_CAPABILITY_LAYERED_BUFFERS
- // capability. Otherwise assume a count of 1.
- mapper.getLayerCount(handle, &layer_count);
-
- sp<GraphicBuffer> buffer = new GraphicBuffer(handle,
- GraphicBuffer::TAKE_HANDLE, width, height, format, layer_count,
- producer_usage, consumer_usage, stride);
-
- return buffer;
-}
-
-} // namespace
ParcelableComposerLayer::ParcelableComposerLayer() {}
@@ -54,7 +19,7 @@
status_t ret = parcel->writeUint64(layer_.id);
if (ret != OK) return ret;
- ret = parcel->writeNativeHandle(layer_.buffer->getNativeBuffer()->handle);
+ ret = parcel->write(*layer_.buffer);
if (ret != OK) return ret;
ret = parcel->writeBool(layer_.fence->isValid());
@@ -108,11 +73,12 @@
status_t ret = parcel->readUint64(&layer_.id);
if (ret != OK) return ret;
- native_handle* handle = parcel->readNativeHandle();
- if (!handle) return BAD_VALUE;
-
- layer_.buffer = GetBufferFromHandle(handle);
- if (!layer_.buffer.get()) return BAD_VALUE;
+ layer_.buffer = new GraphicBuffer();
+ ret = parcel->read(*layer_.buffer);
+ if (ret != OK) {
+ layer_.buffer.clear();
+ return ret;
+ }
bool has_fence = 0;
ret = parcel->readBool(&has_fence);
diff --git a/services/vr/vr_window_manager/composer/Android.bp b/services/vr/vr_window_manager/composer/Android.bp
index 007251f..f01bb28 100644
--- a/services/vr/vr_window_manager/composer/Android.bp
+++ b/services/vr/vr_window_manager/composer/Android.bp
@@ -35,6 +35,7 @@
],
export_shared_lib_headers: [
+ "android.frameworks.vr.composer@1.0",
"android.hardware.graphics.composer@2.1",
],
diff --git a/services/vr/vr_window_manager/composer/impl/vr_composer_client.cpp b/services/vr/vr_window_manager/composer/impl/vr_composer_client.cpp
index acf0dac..e0bdf1c 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_composer_client.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_composer_client.cpp
@@ -50,6 +50,10 @@
switch (vrCommand) {
case IVrComposerClient::VrCommand::SET_LAYER_INFO:
return parseSetLayerInfo(length);
+ case IVrComposerClient::VrCommand::SET_CLIENT_TARGET_METADATA:
+ return parseSetClientTargetMetadata(length);
+ case IVrComposerClient::VrCommand::SET_LAYER_BUFFER_METADATA:
+ return parseSetLayerBufferMetadata(length);
default:
return CommandReader::parseCommand(command, length);
}
@@ -68,5 +72,43 @@
return true;
}
+bool VrComposerClient::VrCommandReader::parseSetClientTargetMetadata(
+ uint16_t length) {
+ if (length != 7)
+ return false;
+
+ auto err = mVrHal.setClientTargetMetadata(mDisplay, readBufferMetadata());
+ if (err != Error::NONE)
+ mWriter.setError(getCommandLoc(), err);
+
+ return true;
+}
+
+bool VrComposerClient::VrCommandReader::parseSetLayerBufferMetadata(
+ uint16_t length) {
+ if (length != 7)
+ return false;
+
+ auto err = mVrHal.setLayerBufferMetadata(mDisplay, mLayer,
+ readBufferMetadata());
+ if (err != Error::NONE)
+ mWriter.setError(getCommandLoc(), err);
+
+ return true;
+}
+
+IVrComposerClient::BufferMetadata
+VrComposerClient::VrCommandReader::readBufferMetadata() {
+ IVrComposerClient::BufferMetadata metadata = {
+ .width = read(),
+ .height = read(),
+ .stride = read(),
+ .layerCount = read(),
+ .format = static_cast<PixelFormat>(readSigned()),
+ .usage = read64(),
+ };
+ return metadata;
+}
+
} // namespace dvr
} // namespace android
diff --git a/services/vr/vr_window_manager/composer/impl/vr_composer_client.h b/services/vr/vr_window_manager/composer/impl/vr_composer_client.h
index 8f0c562..8d601ab 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_composer_client.h
+++ b/services/vr/vr_window_manager/composer/impl/vr_composer_client.h
@@ -17,6 +17,7 @@
#ifndef VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H_
#define VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H_
+#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
#include <ComposerClient.h>
#include <IComposerCommandBuffer.h>
@@ -44,6 +45,10 @@
private:
bool parseSetLayerInfo(uint16_t length);
+ bool parseSetClientTargetMetadata(uint16_t length);
+ bool parseSetLayerBufferMetadata(uint16_t length);
+
+ IVrComposerClient::BufferMetadata readBufferMetadata();
VrComposerClient& mVrClient;
android::dvr::VrHwc& mVrHal;
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
index 9ba01f9..5efc482 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp
@@ -16,8 +16,6 @@
#include "vr_hwc.h"
#include <ui/Fence.h>
-#include <ui/GraphicBuffer.h>
-#include <ui/GraphicBufferMapper.h>
#include <mutex>
@@ -43,35 +41,19 @@
const Display kDefaultDisplayId = 1;
const Config kDefaultConfigId = 1;
-sp<GraphicBuffer> GetBufferFromHandle(const native_handle_t* handle) {
- uint32_t width = 0, height = 0, stride = 0, layer_count = 1;
- uint64_t producer_usage = 0, consumer_usage = 0;
- int32_t format = 0;
+sp<GraphicBuffer> CreateGraphicBuffer(
+ const native_handle_t* handle,
+ const IVrComposerClient::BufferMetadata& metadata) {
+ sp<GraphicBuffer> buffer = new GraphicBuffer(
+ handle, GraphicBuffer::CLONE_HANDLE, metadata.width, metadata.height,
+ static_cast<int32_t>(metadata.format), metadata.layerCount,
+ metadata.usage, metadata.usage, metadata.stride);
+ if (buffer->initCheck() != OK) {
+ ALOGE("Failed to create graphic buffer");
+ return nullptr;
+ }
- GraphicBufferMapper& mapper = GraphicBufferMapper::get();
- if (mapper.getDimensions(handle, &width, &height) ||
- mapper.getStride(handle, &stride) ||
- mapper.getFormat(handle, &format) ||
- mapper.getProducerUsage(handle, &producer_usage) ||
- mapper.getConsumerUsage(handle, &consumer_usage)) {
- ALOGE("Failed to read handle properties");
- return nullptr;
- }
-
- // This will only succeed if gralloc has GRALLOC1_CAPABILITY_LAYERED_BUFFERS
- // capability. Otherwise assume a count of 1.
- mapper.getLayerCount(handle, &layer_count);
-
- // NOTE: Can't re-use |handle| since we don't own it.
- sp<GraphicBuffer> buffer = new GraphicBuffer(handle,
- GraphicBuffer::CLONE_HANDLE, width, height, format, layer_count,
- producer_usage, consumer_usage, stride);
- if (buffer->initCheck() != OK) {
- ALOGE("Failed to register cloned buffer");
- return nullptr;
- }
-
- return buffer;
+ return buffer;
}
void GetPrimaryDisplaySize(int32_t* width, int32_t* height) {
@@ -109,12 +91,17 @@
bool HwcDisplay::SetClientTarget(const native_handle_t* handle,
base::unique_fd fence) {
if (handle)
- buffer_ = GetBufferFromHandle(handle);
+ buffer_ = CreateGraphicBuffer(handle, buffer_metadata_);
fence_ = new Fence(fence.release());
return true;
}
+void HwcDisplay::SetClientTargetMetadata(
+ const IVrComposerClient::BufferMetadata& metadata) {
+ buffer_metadata_ = metadata;
+}
+
HwcLayer* HwcDisplay::CreateLayer() {
uint64_t layer_id = layer_ids_++;
layers_.push_back(HwcLayer(layer_id));
@@ -553,7 +540,8 @@
if (!hwc_layer)
return Error::BAD_LAYER;
- hwc_layer->info.buffer = GetBufferFromHandle(buffer);
+ hwc_layer->info.buffer = CreateGraphicBuffer(
+ buffer, hwc_layer->buffer_metadata);
hwc_layer->info.fence = new Fence(fence.release());
return Error::NONE;
@@ -719,6 +707,35 @@
return Error::NONE;
}
+Error VrHwc::setClientTargetMetadata(
+ Display display, const IVrComposerClient::BufferMetadata& metadata) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+
+ display_ptr->SetClientTargetMetadata(metadata);
+
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerBufferMetadata(
+ Display display, Layer layer,
+ const IVrComposerClient::BufferMetadata& metadata) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+
+ HwcLayer* hwc_layer = display_ptr->GetLayer(layer);
+ if (!hwc_layer)
+ return Error::BAD_LAYER;
+
+ hwc_layer->buffer_metadata = metadata;
+
+ return Error::NONE;
+}
+
Return<void> VrHwc::getCapabilities(getCapabilities_cb hidl_cb) {
hidl_cb(hidl_vec<Capability>());
return Void();
diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.h b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
index bfca9a6..3da2fb8 100644
--- a/services/vr/vr_window_manager/composer/impl/vr_hwc.h
+++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.h
@@ -17,6 +17,7 @@
#define VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_HWC_H_
#include <android-base/unique_fd.h>
+#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
#include <android/hardware/graphics/composer/2.1/IComposer.h>
#include <ComposerBase.h>
#include <ui/Fence.h>
@@ -26,6 +27,7 @@
#include <mutex>
#include <unordered_map>
+using namespace android::frameworks::vr::composer::V1_0;
using namespace android::hardware::graphics::common::V1_0;
using namespace android::hardware::graphics::composer::V2_1;
@@ -38,7 +40,6 @@
namespace android {
class Fence;
-class GraphicBuffer;
namespace dvr {
@@ -105,6 +106,7 @@
Composition composition_type;
uint32_t z_order;
ComposerView::ComposerLayer info;
+ IVrComposerClient::BufferMetadata buffer_metadata;
};
class HwcDisplay {
@@ -120,6 +122,8 @@
HwcLayer* GetLayer(Layer id);
bool SetClientTarget(const native_handle_t* handle, base::unique_fd fence);
+ void SetClientTargetMetadata(
+ const IVrComposerClient::BufferMetadata& metadata);
void GetChangedCompositionTypes(
std::vector<Layer>* layer_ids,
@@ -131,8 +135,8 @@
private:
// The client target buffer and the associated fence.
- // TODO(dnicoara): Replace this with a list of ComposerView::ComposerLayer.
sp<GraphicBuffer> buffer_;
+ IVrComposerClient::BufferMetadata buffer_metadata_;
sp<Fence> fence_;
// List of currently active layers.
@@ -159,6 +163,11 @@
Error setLayerInfo(Display display, Layer layer, uint32_t type,
uint32_t appId);
+ Error setClientTargetMetadata(
+ Display display, const IVrComposerClient::BufferMetadata& metadata);
+ Error setLayerBufferMetadata(
+ Display display, Layer layer,
+ const IVrComposerClient::BufferMetadata& metadata);
// ComposerBase
void removeClient() override;
diff --git a/vulkan/libvulkan/Android.bp b/vulkan/libvulkan/Android.bp
index a35fb98..6149894 100644
--- a/vulkan/libvulkan/Android.bp
+++ b/vulkan/libvulkan/Android.bp
@@ -14,7 +14,7 @@
// Headers module is in frameworks/native/vulkan/Android.bp.
ndk_library {
- name: "libvulkan.ndk",
+ name: "libvulkan",
symbol_file: "libvulkan.map.txt",
first_version: "24",
unversioned_until: "current",
diff --git a/vulkan/libvulkan/driver.cpp b/vulkan/libvulkan/driver.cpp
index 5fbf5f5..212d142 100644
--- a/vulkan/libvulkan/driver.cpp
+++ b/vulkan/libvulkan/driver.cpp
@@ -34,6 +34,11 @@
#include "driver.h"
#include "stubhal.h"
+// TODO(b/37049319) Get this from a header once one exists
+extern "C" {
+android_namespace_t* android_get_exported_namespace(const char*);
+}
+
// Set to true to enable exposing unratified extensions for development
static const bool kEnableUnratifiedExtensions = false;
@@ -150,14 +155,12 @@
"ro.board.platform",
}};
-int LoadUpdatedDriver(const hw_module_t** module) {
+int LoadDriver(android_namespace_t* library_namespace,
+ const hwvulkan_module_t** module) {
const android_dlextinfo dlextinfo = {
.flags = ANDROID_DLEXT_USE_NAMESPACE,
- .library_namespace = android::GraphicsEnv::getInstance().getDriverNamespace(),
+ .library_namespace = library_namespace,
};
- if (!dlextinfo.library_namespace)
- return -ENOENT;
-
void* so = nullptr;
char prop[PROPERTY_VALUE_MAX];
for (auto key : HAL_SUBNAME_KEY_PROPERTIES) {
@@ -171,7 +174,7 @@
if (!so)
return -ENOENT;
- hw_module_t* hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
+ auto hmi = static_cast<hw_module_t*>(dlsym(so, HAL_MODULE_INFO_SYM_AS_STR));
if (!hmi) {
ALOGE("couldn't find symbol '%s' in HAL library: %s", HAL_MODULE_INFO_SYM_AS_STR, dlerror());
dlclose(so);
@@ -183,11 +186,24 @@
return -EINVAL;
}
hmi->dso = so;
- *module = hmi;
- ALOGD("loaded updated driver");
+ *module = reinterpret_cast<const hwvulkan_module_t*>(hmi);
return 0;
}
+int LoadBuiltinDriver(const hwvulkan_module_t** module) {
+ auto ns = android_get_exported_namespace("sphal");
+ if (!ns)
+ return -ENOENT;
+ return LoadDriver(ns, module);
+}
+
+int LoadUpdatedDriver(const hwvulkan_module_t** module) {
+ auto ns = android::GraphicsEnv::getInstance().getDriverNamespace();
+ if (!ns)
+ return -ENOENT;
+ return LoadDriver(ns, module);
+}
+
bool Hal::Open() {
ALOG_ASSERT(!hal_.dev_, "OpenHAL called more than once");
@@ -197,9 +213,21 @@
int result;
const hwvulkan_module_t* module = nullptr;
- result = LoadUpdatedDriver(reinterpret_cast<const hw_module_t**>(&module));
+ result = LoadUpdatedDriver(&module);
if (result == -ENOENT) {
- result = hw_get_module(HWVULKAN_HARDWARE_MODULE_ID, reinterpret_cast<const hw_module_t**>(&module));
+ result = LoadBuiltinDriver(&module);
+ if (result != 0) {
+ // -ENOENT means the sphal namespace doesn't exist, not that there
+ // is a problem with the driver.
+ ALOGW_IF(
+ result != -ENOENT,
+ "Failed to load Vulkan driver into sphal namespace. This "
+ "usually means the driver has forbidden library dependencies."
+ "Please fix, this will soon stop working.");
+ result =
+ hw_get_module(HWVULKAN_HARDWARE_MODULE_ID,
+ reinterpret_cast<const hw_module_t**>(&module));
+ }
}
if (result != 0) {
ALOGV("unable to load Vulkan HAL, using stub HAL (result=%d)", result);