Merge "Minor changes on dumpstate refactoring:"
diff --git a/cmds/atrace/atrace.rc b/cmds/atrace/atrace.rc
index f3b12b1..d486a3d 100644
--- a/cmds/atrace/atrace.rc
+++ b/cmds/atrace/atrace.rc
@@ -1,6 +1,6 @@
## Permissions to allow system-wide tracing to the kernel trace buffer.
##
-on boot
+on fs
# Allow writing to the kernel trace log.
chmod 0222 /sys/kernel/debug/tracing/trace_marker
diff --git a/include/ui/Fence.h b/include/ui/Fence.h
index d45ad76..2fbc9ef 100644
--- a/include/ui/Fence.h
+++ b/include/ui/Fence.h
@@ -96,6 +96,17 @@
// occurs then -1 is returned.
nsecs_t getSignalTime() const;
+ // hasSignaled returns whether the fence has signaled yet. Prefer this to
+ // getSignalTime() or wait() if all you care about is whether the fence has
+ // signaled.
+ inline bool hasSignaled() {
+ // The sync_wait call underlying wait() has been measured to be
+ // significantly faster than the sync_fence_info call underlying
+ // getSignalTime(), which might otherwise appear to be the more obvious
+ // way to check whether a fence has signaled.
+ return wait(0) == NO_ERROR;
+ }
+
// Flattenable interface
size_t getFlattenedSize() const;
size_t getFdCount() const;
diff --git a/include/ui/GrallocAllocator.h b/include/ui/GrallocAllocator.h
new file mode 100644
index 0000000..23b78ed
--- /dev/null
+++ b/include/ui/GrallocAllocator.h
@@ -0,0 +1,66 @@
+/*
+ * 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::PixelFormat;
+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;
+
+// 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 (mService != nullptr); }
+
+ std::string dumpDebugInfo() const;
+
+ Error createBufferDescriptor(
+ const IAllocator::BufferDescriptorInfo& descriptorInfo,
+ BufferDescriptor& descriptor) const;
+ void destroyBufferDescriptor(BufferDescriptor descriptor) const;
+
+ Error allocate(BufferDescriptor descriptor, Buffer& buffer) const;
+ void free(Buffer buffer) const;
+
+ Error exportHandle(BufferDescriptor descriptor, Buffer buffer,
+ native_handle_t*& bufferHandle) const;
+
+private:
+ sp<IAllocator> mService;
+};
+
+} // namespace Gralloc2
+
+} // namespace android
+
+#endif // ANDROID_UI_GRALLOC_ALLOCATOR_H
diff --git a/include/ui/GrallocMapper.h b/include/ui/GrallocMapper.h
new file mode 100644
index 0000000..5517449
--- /dev/null
+++ b/include/ui/GrallocMapper.h
@@ -0,0 +1,127 @@
+/*
+ * 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 <memory>
+
+#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::PixelFormat;
+using hardware::graphics::allocator::V2_0::ProducerUsage;
+using hardware::graphics::allocator::V2_0::ConsumerUsage;
+using hardware::graphics::mapper::V2_0::FlexLayout;
+using hardware::graphics::mapper::V2_0::BackingStore;
+using hardware::graphics::mapper::V2_0::Device;
+using hardware::graphics::mapper::V2_0::IMapper;
+
+// Mapper is a wrapper to IMapper, a client-side graphics buffer mapper.
+class Mapper {
+public:
+ Mapper();
+ ~Mapper();
+
+ // this will be removed and Mapper will be always valid
+ bool valid() const { return (mMapper != nullptr); }
+
+ Error retain(buffer_handle_t handle) const
+ {
+ return mMapper->retain(mDevice, handle);
+ }
+
+ void release(buffer_handle_t handle) const;
+
+ Error getDimensions(buffer_handle_t handle,
+ uint32_t& width, uint32_t& height) const
+ {
+ return mMapper->getDimensions(mDevice, handle, &width, &height);
+ }
+
+ Error getFormat(buffer_handle_t handle,
+ PixelFormat& format) const
+ {
+ return mMapper->getFormat(mDevice, handle, &format);
+ }
+
+ Error getProducerUsageMask(buffer_handle_t handle,
+ uint64_t& usageMask) const
+ {
+ return mMapper->getProducerUsageMask(mDevice, handle, &usageMask);
+ }
+
+ Error getConsumerUsageMask(buffer_handle_t handle,
+ uint64_t& usageMask) const
+ {
+ return mMapper->getConsumerUsageMask(mDevice, handle, &usageMask);
+ }
+
+ Error getBackingStore(buffer_handle_t handle,
+ BackingStore& store) const
+ {
+ return mMapper->getBackingStore(mDevice, handle, &store);
+ }
+
+ Error getStride(buffer_handle_t handle, uint32_t& stride) const
+ {
+ return mMapper->getStride(mDevice, handle, &stride);
+ }
+
+ Error getNumFlexPlanes(buffer_handle_t handle, uint32_t& numPlanes) const
+ {
+ return mMapper->getNumFlexPlanes(mDevice, handle, &numPlanes);
+ }
+
+ Error lock(buffer_handle_t handle,
+ uint64_t producerUsageMask,
+ uint64_t consumerUsageMask,
+ const Device::Rect& accessRegion,
+ int acquireFence, void*& data) const
+ {
+ return mMapper->lock(mDevice, handle,
+ producerUsageMask, consumerUsageMask,
+ &accessRegion, acquireFence, &data);
+ }
+
+ Error lock(buffer_handle_t handle,
+ uint64_t producerUsageMask,
+ uint64_t consumerUsageMask,
+ const Device::Rect& accessRegion,
+ int acquireFence, FlexLayout& flexLayout) const
+ {
+ return mMapper->lockFlex(mDevice, handle,
+ producerUsageMask, consumerUsageMask,
+ &accessRegion, acquireFence, &flexLayout);
+ }
+
+ int unlock(buffer_handle_t handle) const;
+
+private:
+ const IMapper* mMapper;
+ Device* mDevice;
+};
+
+} // namespace Gralloc2
+
+} // namespace android
+
+#endif // ANDROID_UI_GRALLOC_MAPPER_H
diff --git a/include/ui/GraphicBufferAllocator.h b/include/ui/GraphicBufferAllocator.h
index 28d0238..9cc5806 100644
--- a/include/ui/GraphicBufferAllocator.h
+++ b/include/ui/GraphicBufferAllocator.h
@@ -32,7 +32,12 @@
namespace android {
+namespace Gralloc2 {
+class Allocator;
+}
+
class Gralloc1Loader;
+class GraphicBufferMapper;
class String8;
class GraphicBufferAllocator : public Singleton<GraphicBufferAllocator>
@@ -86,6 +91,9 @@
GraphicBufferAllocator();
~GraphicBufferAllocator();
+ const std::unique_ptr<const Gralloc2::Allocator> mAllocator;
+ GraphicBufferMapper& mMapper;
+
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 a25809c..b6de1b2 100644
--- a/include/ui/GraphicBufferMapper.h
+++ b/include/ui/GraphicBufferMapper.h
@@ -28,6 +28,10 @@
// ---------------------------------------------------------------------------
+namespace Gralloc2 {
+class Mapper;
+}
+
class Rect;
class GraphicBufferMapper : public Singleton<GraphicBufferMapper>
@@ -57,11 +61,18 @@
status_t unlockAsync(buffer_handle_t handle, int *fenceFd);
+ const Gralloc2::Mapper& getGrallocMapper() const
+ {
+ return *mMapper;
+ }
+
private:
friend class Singleton<GraphicBufferMapper>;
GraphicBufferMapper();
+ const std::unique_ptr<const Gralloc2::Mapper> mMapper;
+
std::unique_ptr<Gralloc1::Loader> mLoader;
std::unique_ptr<Gralloc1::Device> mDevice;
};
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index 71b5cca..8371e9b 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -16,7 +16,7 @@
include $(CLEAR_VARS)
LOCAL_CLANG := true
-LOCAL_CPPFLAGS := -std=c++1y -Weverything -Werror
+LOCAL_CPPFLAGS := -Weverything -Werror
# The static constructors and destructors in this library have not been noted to
# introduce significant overheads
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 0777468..37b2873 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -17,7 +17,6 @@
clang: true,
cppflags: [
- "-std=c++1y",
"-Weverything",
"-Werror",
@@ -46,6 +45,8 @@
"FrameStats.cpp",
"Gralloc1.cpp",
"Gralloc1On0Adapter.cpp",
+ "GrallocAllocator.cpp",
+ "GrallocMapper.cpp",
"GraphicBuffer.cpp",
"GraphicBufferAllocator.cpp",
"GraphicBufferMapper.cpp",
@@ -56,10 +57,17 @@
"UiConfig.cpp",
],
+ static_libs: [
+ "android.hardware.graphics.mapper@2.0",
+ ],
+
shared_libs: [
+ "android.hardware.graphics.allocator@2.0",
"libbinder",
"libcutils",
"libhardware",
+ "libhidl",
+ "libhwbinder",
"libsync",
"libutils",
"liblog",
diff --git a/libs/ui/GrallocAllocator.cpp b/libs/ui/GrallocAllocator.cpp
new file mode 100644
index 0000000..2eb1988
--- /dev/null
+++ b/libs/ui/GrallocAllocator.cpp
@@ -0,0 +1,114 @@
+/*
+ * 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 <log/log.h>
+#include <ui/GrallocAllocator.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+// assume NO_RESOURCES when Status::isOk returns false
+constexpr Error kDefaultError = Error::NO_RESOURCES;
+
+Allocator::Allocator()
+{
+ mService = IAllocator::getService("gralloc");
+}
+
+std::string Allocator::dumpDebugInfo() const
+{
+ std::string info;
+
+ mService->dumpDebugInfo([&](const auto& tmpInfo) {
+ info = tmpInfo.c_str();
+ });
+
+ return info;
+}
+
+Error Allocator::createBufferDescriptor(
+ const IAllocator::BufferDescriptorInfo& descriptorInfo,
+ BufferDescriptor& descriptor) const
+{
+ Error error = kDefaultError;
+ mService->createDescriptor(descriptorInfo,
+ [&](const auto& tmpError, const auto& tmpDescriptor) {
+ error = tmpError;
+ if (error != Error::NONE) {
+ return;
+ }
+
+ descriptor = tmpDescriptor;
+ });
+
+ return error;
+}
+
+void Allocator::destroyBufferDescriptor(BufferDescriptor descriptor) const
+{
+ mService->destroyDescriptor(descriptor);
+}
+
+Error Allocator::allocate(BufferDescriptor descriptor, Buffer& buffer) const
+{
+ hardware::hidl_vec<BufferDescriptor> descriptors;
+ descriptors.setToExternal(&descriptor, 1);
+
+ Error error = kDefaultError;
+ auto status = mService->allocate(descriptors,
+ [&](const auto& tmpError, const auto& tmpBuffers) {
+ error = tmpError;
+ if (tmpError != Error::NONE) {
+ return;
+ }
+
+ buffer = tmpBuffers[0];
+ });
+
+ return error;
+}
+
+void Allocator::free(Buffer buffer) const
+{
+ mService->free(buffer);
+}
+
+Error Allocator::exportHandle(BufferDescriptor descriptor, Buffer buffer,
+ native_handle_t*& bufferHandle) const
+{
+ Error error = kDefaultError;
+ auto status = mService->exportHandle(descriptor, buffer,
+ [&](const auto& tmpError, const auto& tmpBufferHandle) {
+ error = tmpError;
+ if (tmpError != Error::NONE) {
+ return;
+ }
+
+ bufferHandle = native_handle_clone(tmpBufferHandle);
+ if (!bufferHandle) {
+ error = Error::NO_RESOURCES;
+ }
+ });
+
+ return error;
+}
+
+} // namespace Gralloc2
+
+} // namespace android
diff --git a/libs/ui/GrallocMapper.cpp b/libs/ui/GrallocMapper.cpp
new file mode 100644
index 0000000..d568b68
--- /dev/null
+++ b/libs/ui/GrallocMapper.cpp
@@ -0,0 +1,118 @@
+/*
+ * 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 <array>
+#include <string>
+
+#include <log/log.h>
+#include <ui/GrallocMapper.h>
+
+namespace android {
+
+namespace Gralloc2 {
+
+typedef const void*(*FetchInterface)(const char* name);
+
+static FetchInterface loadHalLib(const char* pkg_name)
+{
+ static const std::array<const char*, 3> sSearchDirs = {{
+ HAL_LIBRARY_PATH_ODM,
+ HAL_LIBRARY_PATH_VENDOR,
+ HAL_LIBRARY_PATH_SYSTEM,
+ }};
+ static const char sSymbolName[] = "HALLIB_FETCH_Interface";
+
+ void* handle = nullptr;
+ std::string path;
+ for (auto dir : sSearchDirs) {
+ path = dir;
+ path += pkg_name;
+ path += ".hallib.so";
+ handle = dlopen(path.c_str(), RTLD_LOCAL | RTLD_NOW);
+ if (handle) {
+ break;
+ }
+ }
+ if (!handle) {
+ return nullptr;
+ }
+
+ void* symbol = dlsym(handle, sSymbolName);
+ if (!symbol) {
+ ALOGE("%s is missing from %s", sSymbolName, path.c_str());
+ dlclose(handle);
+ return nullptr;
+ }
+
+ return reinterpret_cast<FetchInterface>(symbol);
+}
+
+Mapper::Mapper()
+ : mMapper(nullptr), mDevice(nullptr)
+{
+ static const char sHalLibName[] = "android.hardware.graphics.mapper";
+ static const char sSupportedInterface[] =
+ "android.hardware.graphics.mapper@2.0::IMapper";
+
+ FetchInterface fetchInterface = loadHalLib(sHalLibName);
+ if (!fetchInterface) {
+ return;
+ }
+
+ mMapper = static_cast<const IMapper*>(
+ fetchInterface(sSupportedInterface));
+ if (!mMapper) {
+ ALOGE("%s is not supported", sSupportedInterface);
+ return;
+ }
+
+ if (mMapper->createDevice(&mDevice) != Error::NONE) {
+ ALOGE("failed to create mapper device");
+ mMapper = nullptr;
+ }
+}
+
+Mapper::~Mapper()
+{
+ if (mMapper) {
+ mMapper->destroyDevice(mDevice);
+ }
+}
+
+void Mapper::release(buffer_handle_t handle) const
+{
+ auto error = mMapper->release(mDevice, handle);
+ ALOGE_IF(error != Error::NONE,
+ "release(%p) failed with %d", handle, error);
+}
+
+int Mapper::unlock(buffer_handle_t handle) const
+{
+ int releaseFence;
+ auto error = mMapper->unlock(mDevice, handle, &releaseFence);
+ 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 97b948d..6d72900 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -23,6 +23,7 @@
#include <utils/Errors.h>
#include <utils/Log.h>
+#include <ui/GrallocMapper.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/GraphicBufferMapper.h>
@@ -108,8 +109,10 @@
{
if (mOwner == ownHandle) {
mBufferMapper.unregisterBuffer(handle);
- native_handle_close(handle);
- native_handle_delete(const_cast<native_handle*>(handle));
+ if (!mBufferMapper.getGrallocMapper().valid()) {
+ native_handle_close(handle);
+ native_handle_delete(const_cast<native_handle*>(handle));
+ }
} else if (mOwner == ownData) {
GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
allocator.free(handle);
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index edfff4d..693c7cb 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -26,6 +26,9 @@
#include <ui/GraphicBufferAllocator.h>
#include <ui/Gralloc1On0Adapter.h>
+#include <ui/GrallocAllocator.h>
+#include <ui/GrallocMapper.h>
+#include <ui/GraphicBufferMapper.h>
namespace android {
// ---------------------------------------------------------------------------
@@ -37,8 +40,14 @@
GraphicBufferAllocator::alloc_rec_t> GraphicBufferAllocator::sAllocList;
GraphicBufferAllocator::GraphicBufferAllocator()
- : mLoader(std::make_unique<Gralloc1::Loader>()),
- mDevice(mLoader->getDevice()) {}
+ : mAllocator(std::make_unique<Gralloc2::Allocator>()),
+ mMapper(GraphicBufferMapper::getInstance())
+{
+ if (!mAllocator->valid()) {
+ mLoader = std::make_unique<Gralloc1::Loader>();
+ mDevice = mLoader->getDevice();
+ }
+}
GraphicBufferAllocator::~GraphicBufferAllocator() {}
@@ -70,7 +79,14 @@
}
snprintf(buffer, SIZE, "Total allocated (estimate): %.2f KB\n", total/1024.0f);
result.append(buffer);
- std::string deviceDump = mDevice->dump();
+
+ std::string deviceDump;
+ if (mAllocator->valid()) {
+ deviceDump = mAllocator->dumpDebugInfo();
+ } else {
+ deviceDump = mDevice->dump();
+ }
+
result.append(deviceDump.c_str(), deviceDump.size());
}
@@ -81,6 +97,103 @@
ALOGD("%s", s.string());
}
+namespace {
+
+class HalBuffer {
+public:
+ HalBuffer(const Gralloc2::Allocator* allocator,
+ uint32_t width, uint32_t height,
+ PixelFormat format, uint32_t usage)
+ : mAllocator(allocator), mBufferValid(false)
+ {
+ Gralloc2::IAllocator::BufferDescriptorInfo info = {};
+ info.width = width;
+ info.height = height;
+ info.format = static_cast<Gralloc2::PixelFormat>(format);
+ info.producerUsageMask = usage;
+ info.consumerUsageMask = usage;
+
+ Gralloc2::BufferDescriptor descriptor;
+ auto error = mAllocator->createBufferDescriptor(info, descriptor);
+ if (error != Gralloc2::Error::NONE) {
+ ALOGE("Failed to create desc (%u x %u) format %d usage %u: %d",
+ width, height, format, usage, 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) format %d usage %u: %d",
+ width, height, format, usage, 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 usage, buffer_handle_t* handle,
uint32_t* stride, uint64_t graphicBufferId, std::string requestorName)
@@ -95,40 +208,51 @@
// Filter out any usage bits that should not be passed to the gralloc module
usage &= GRALLOC_USAGE_ALLOC_MASK;
- auto descriptor = mDevice->createDescriptor();
- auto error = descriptor->setDimensions(width, height);
- if (error != GRALLOC1_ERROR_NONE) {
- ALOGE("Failed to set dimensions to (%u, %u): %d", width, height, error);
- return BAD_VALUE;
- }
- error = descriptor->setFormat(static_cast<android_pixel_format_t>(format));
- if (error != GRALLOC1_ERROR_NONE) {
- ALOGE("Failed to set format to %d: %d", format, error);
- return BAD_VALUE;
- }
- error = descriptor->setProducerUsage(
- static_cast<gralloc1_producer_usage_t>(usage));
- if (error != GRALLOC1_ERROR_NONE) {
- ALOGE("Failed to set producer usage to %u: %d", usage, error);
- return BAD_VALUE;
- }
- error = descriptor->setConsumerUsage(
- static_cast<gralloc1_consumer_usage_t>(usage));
- if (error != GRALLOC1_ERROR_NONE) {
- ALOGE("Failed to set consumer usage to %u: %d", usage, error);
- return BAD_VALUE;
- }
+ gralloc1_error_t error;
+ if (mAllocator->valid()) {
+ HalBuffer buffer(mAllocator.get(), width, height, format, usage);
+ if (!buffer.exportHandle(mMapper, handle, stride)) {
+ return NO_MEMORY;
+ }
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ auto descriptor = mDevice->createDescriptor();
+ error = descriptor->setDimensions(width, height);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("Failed to set dimensions to (%u, %u): %d",
+ width, height, error);
+ return BAD_VALUE;
+ }
+ error = descriptor->setFormat(
+ static_cast<android_pixel_format_t>(format));
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("Failed to set format to %d: %d", format, error);
+ return BAD_VALUE;
+ }
+ error = descriptor->setProducerUsage(
+ static_cast<gralloc1_producer_usage_t>(usage));
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("Failed to set producer usage to %u: %d", usage, error);
+ return BAD_VALUE;
+ }
+ error = descriptor->setConsumerUsage(
+ static_cast<gralloc1_consumer_usage_t>(usage));
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("Failed to set consumer usage to %u: %d", usage, error);
+ return BAD_VALUE;
+ }
- error = mDevice->allocate(descriptor, graphicBufferId, handle);
- if (error != GRALLOC1_ERROR_NONE) {
- ALOGE("Failed to allocate (%u x %u) format %d usage %u: %d",
- width, height, format, usage, error);
- return NO_MEMORY;
- }
+ error = mDevice->allocate(descriptor, graphicBufferId, handle);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("Failed to allocate (%u x %u) format %d usage %u: %d",
+ width, height, format, usage, error);
+ return NO_MEMORY;
+ }
- error = mDevice->getStride(*handle, stride);
- if (error != GRALLOC1_ERROR_NONE) {
- ALOGW("Failed to get stride from buffer: %d", error);
+ error = mDevice->getStride(*handle, stride);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGW("Failed to get stride from buffer: %d", error);
+ }
}
if (error == NO_ERROR) {
@@ -153,7 +277,14 @@
{
ATRACE_CALL();
- auto error = mDevice->release(handle);
+ gralloc1_error_t error;
+ if (mAllocator->valid()) {
+ error = static_cast<gralloc1_error_t>(
+ mMapper.unregisterBuffer(handle));
+ } else {
+ error = mDevice->release(handle);
+ }
+
if (error != GRALLOC1_ERROR_NONE) {
ALOGE("Failed to free buffer: %d", error);
}
diff --git a/libs/ui/GraphicBufferMapper.cpp b/libs/ui/GraphicBufferMapper.cpp
index 481d43c..fb55bf1 100644
--- a/libs/ui/GraphicBufferMapper.cpp
+++ b/libs/ui/GraphicBufferMapper.cpp
@@ -33,6 +33,7 @@
#include <utils/Trace.h>
#include <ui/Gralloc1On0Adapter.h>
+#include <ui/GrallocMapper.h>
#include <ui/GraphicBufferMapper.h>
#include <ui/Rect.h>
@@ -44,8 +45,13 @@
ANDROID_SINGLETON_STATIC_INSTANCE( GraphicBufferMapper )
GraphicBufferMapper::GraphicBufferMapper()
- : mLoader(std::make_unique<Gralloc1::Loader>()),
- mDevice(mLoader->getDevice()) {}
+ : mMapper(std::make_unique<const Gralloc2::Mapper>())
+{
+ if (!mMapper->valid()) {
+ mLoader = std::make_unique<Gralloc1::Loader>();
+ mDevice = mLoader->getDevice();
+ }
+}
@@ -53,7 +59,13 @@
{
ATRACE_CALL();
- gralloc1_error_t error = mDevice->retain(handle);
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ error = static_cast<gralloc1_error_t>(mMapper->retain(handle));
+ } else {
+ error = mDevice->retain(handle);
+ }
+
ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
handle, error);
@@ -64,7 +76,14 @@
{
ATRACE_CALL();
- gralloc1_error_t error = mDevice->retain(buffer);
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ error = static_cast<gralloc1_error_t>(
+ mMapper->retain(buffer->getNativeBuffer()->handle));
+ } else {
+ error = mDevice->retain(buffer);
+ }
+
ALOGW_IF(error != GRALLOC1_ERROR_NONE, "registerBuffer(%p) failed: %d",
buffer->getNativeBuffer()->handle, error);
@@ -75,7 +94,14 @@
{
ATRACE_CALL();
- gralloc1_error_t error = mDevice->release(handle);
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ mMapper->release(handle);
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ error = mDevice->release(handle);
+ }
+
ALOGW_IF(error != GRALLOC1_ERROR_NONE, "unregisterBuffer(%p): failed %d",
handle, error);
@@ -120,11 +146,20 @@
ATRACE_CALL();
gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
- sp<Fence> fence = new Fence(fenceFd);
- gralloc1_error_t error = mDevice->lock(handle,
- static_cast<gralloc1_producer_usage_t>(usage),
- static_cast<gralloc1_consumer_usage_t>(usage),
- &accessRegion, vaddr, fence);
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ const Gralloc2::Device::Rect& accessRect =
+ *reinterpret_cast<Gralloc2::Device::Rect*>(&accessRegion);
+ error = static_cast<gralloc1_error_t>(mMapper->lock(
+ handle, usage, usage, accessRect, fenceFd, *vaddr));
+ } else {
+ sp<Fence> fence = new Fence(fenceFd);
+ error = mDevice->lock(handle,
+ static_cast<gralloc1_producer_usage_t>(usage),
+ static_cast<gralloc1_consumer_usage_t>(usage),
+ &accessRegion, vaddr, fence);
+ }
+
ALOGW_IF(error != GRALLOC1_ERROR_NONE, "lock(%p, ...) failed: %d", handle,
error);
@@ -160,20 +195,29 @@
ATRACE_CALL();
gralloc1_rect_t accessRegion = asGralloc1Rect(bounds);
- sp<Fence> fence = new Fence(fenceFd);
- if (mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
- gralloc1_error_t error = mDevice->lockYCbCr(handle,
- static_cast<gralloc1_producer_usage_t>(usage),
- static_cast<gralloc1_consumer_usage_t>(usage),
- &accessRegion, ycbcr, fence);
- ALOGW_IF(error != GRALLOC1_ERROR_NONE, "lockYCbCr(%p, ...) failed: %d",
- handle, error);
- return error;
+ if (!mMapper->valid()) {
+ if (mDevice->hasCapability(GRALLOC1_CAPABILITY_ON_ADAPTER)) {
+ sp<Fence> fence = new Fence(fenceFd);
+ gralloc1_error_t error = mDevice->lockYCbCr(handle,
+ static_cast<gralloc1_producer_usage_t>(usage),
+ static_cast<gralloc1_consumer_usage_t>(usage),
+ &accessRegion, ycbcr, fence);
+ ALOGW_IF(error != GRALLOC1_ERROR_NONE,
+ "lockYCbCr(%p, ...) failed: %d", handle, error);
+ return error;
+ }
}
uint32_t numPlanes = 0;
- gralloc1_error_t error = mDevice->getNumFlexPlanes(handle, &numPlanes);
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ error = static_cast<gralloc1_error_t>(
+ mMapper->getNumFlexPlanes(handle, numPlanes));
+ } else {
+ error = mDevice->getNumFlexPlanes(handle, &numPlanes);
+ }
+
if (error != GRALLOC1_ERROR_NONE) {
ALOGV("Failed to retrieve number of flex planes: %d", error);
return error;
@@ -188,10 +232,21 @@
flexLayout.num_planes = numPlanes;
flexLayout.planes = planes.data();
- error = mDevice->lockFlex(handle,
- static_cast<gralloc1_producer_usage_t>(usage),
- static_cast<gralloc1_consumer_usage_t>(usage),
- &accessRegion, &flexLayout, fence);
+ if (mMapper->valid()) {
+ const Gralloc2::Device::Rect& accessRect =
+ *reinterpret_cast<Gralloc2::Device::Rect*>(&accessRegion);
+ Gralloc2::FlexLayout& layout =
+ *reinterpret_cast<Gralloc2::FlexLayout*>(&flexLayout);
+ error = static_cast<gralloc1_error_t>(mMapper->lock(
+ handle, usage, usage, accessRect, fenceFd, layout));
+ } else {
+ sp<Fence> fence = new Fence(fenceFd);
+ error = mDevice->lockFlex(handle,
+ static_cast<gralloc1_producer_usage_t>(usage),
+ static_cast<gralloc1_consumer_usage_t>(usage),
+ &accessRegion, &flexLayout, fence);
+ }
+
if (error != GRALLOC1_ERROR_NONE) {
ALOGW("lockFlex(%p, ...) failed: %d", handle, error);
return error;
@@ -276,14 +331,20 @@
{
ATRACE_CALL();
- sp<Fence> fence = Fence::NO_FENCE;
- gralloc1_error_t error = mDevice->unlock(handle, &fence);
- if (error != GRALLOC1_ERROR_NONE) {
- ALOGE("unlock(%p) failed: %d", handle, error);
- return error;
- }
+ gralloc1_error_t error;
+ if (mMapper->valid()) {
+ *fenceFd = mMapper->unlock(handle);
+ error = GRALLOC1_ERROR_NONE;
+ } else {
+ sp<Fence> fence = Fence::NO_FENCE;
+ error = mDevice->unlock(handle, &fence);
+ if (error != GRALLOC1_ERROR_NONE) {
+ ALOGE("unlock(%p) failed: %d", handle, error);
+ return error;
+ }
- *fenceFd = fence->dup();
+ *fenceFd = fence->dup();
+ }
return error;
}
diff --git a/opengl/libs/Android.mk b/opengl/libs/Android.mk
index f0ba728..4f7c7e4 100644
--- a/opengl/libs/Android.mk
+++ b/opengl/libs/Android.mk
@@ -42,9 +42,6 @@
LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES
LOCAL_CFLAGS += -fvisibility=hidden
-ifeq ($(BOARD_ALLOW_EGL_HIBERNATION),true)
- LOCAL_CFLAGS += -DBOARD_ALLOW_EGL_HIBERNATION
-endif
ifneq ($(MAX_EGL_CACHE_ENTRY_SIZE),)
LOCAL_CFLAGS += -DMAX_EGL_CACHE_ENTRY_SIZE=$(MAX_EGL_CACHE_ENTRY_SIZE)
endif
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 1e39aae..a32f037 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -215,8 +215,6 @@
*major = VERSION_MAJOR;
if (minor != NULL)
*minor = VERSION_MINOR;
-
- mHibernation.setDisplayValid(true);
}
{
@@ -265,8 +263,6 @@
res = EGL_TRUE;
}
- mHibernation.setDisplayValid(false);
-
// Reset the extension string since it will be regenerated if we get
// reinitialized.
mExtensionString.setTo("");
@@ -345,16 +341,12 @@
disp.dpy, impl_draw, impl_read, impl_ctx);
if (result == EGL_TRUE) {
c->onMakeCurrent(draw, read);
- if (!cur_c) {
- mHibernation.incWakeCount(HibernationMachine::STRONG);
- }
}
} else {
result = cur_c->cnx->egl.eglMakeCurrent(
disp.dpy, impl_draw, impl_read, impl_ctx);
if (result == EGL_TRUE) {
cur_c->onLooseCurrent();
- mHibernation.decWakeCount(HibernationMachine::STRONG);
}
}
}
@@ -379,63 +371,5 @@
}
// ----------------------------------------------------------------------------
-
-bool egl_display_t::HibernationMachine::incWakeCount(WakeRefStrength strength) {
- Mutex::Autolock _l(mLock);
- ALOGE_IF(mWakeCount < 0 || mWakeCount == INT32_MAX,
- "Invalid WakeCount (%d) on enter\n", mWakeCount);
-
- mWakeCount++;
- if (strength == STRONG)
- mAttemptHibernation = false;
-
- if (CC_UNLIKELY(mHibernating)) {
- ALOGV("Awakening\n");
- egl_connection_t* const cnx = &gEGLImpl;
-
- // These conditions should be guaranteed before entering hibernation;
- // we don't want to get into a state where we can't wake up.
- ALOGD_IF(!mDpyValid || !cnx->egl.eglAwakenProcessIMG,
- "Invalid hibernation state, unable to awaken\n");
-
- if (!cnx->egl.eglAwakenProcessIMG()) {
- ALOGE("Failed to awaken EGL implementation\n");
- return false;
- }
- mHibernating = false;
- }
- return true;
-}
-
-void egl_display_t::HibernationMachine::decWakeCount(WakeRefStrength strength) {
- Mutex::Autolock _l(mLock);
- ALOGE_IF(mWakeCount <= 0, "Invalid WakeCount (%d) on leave\n", mWakeCount);
-
- mWakeCount--;
- if (strength == STRONG)
- mAttemptHibernation = true;
-
- if (mWakeCount == 0 && CC_UNLIKELY(mAttemptHibernation)) {
- egl_connection_t* const cnx = &gEGLImpl;
- mAttemptHibernation = false;
- if (mAllowHibernation && mDpyValid &&
- cnx->egl.eglHibernateProcessIMG &&
- cnx->egl.eglAwakenProcessIMG) {
- ALOGV("Hibernating\n");
- if (!cnx->egl.eglHibernateProcessIMG()) {
- ALOGE("Failed to hibernate EGL implementation\n");
- return;
- }
- mHibernating = true;
- }
- }
-}
-
-void egl_display_t::HibernationMachine::setDisplayValid(bool valid) {
- Mutex::Autolock _l(mLock);
- mDpyValid = valid;
-}
-
-// ----------------------------------------------------------------------------
}; // namespace android
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index 2d86295..e17558c 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -68,20 +68,6 @@
// add reference to this object. returns true if this is a valid object.
bool getObject(egl_object_t* object) const;
- // These notifications allow the display to keep track of how many window
- // surfaces exist, which it uses to decide whether to hibernate the
- // underlying EGL implementation. They can be called by any thread without
- // holding a lock, but must be called via egl_display_ptr to ensure
- // proper hibernate/wakeup sequencing. If a surface destruction triggers
- // hibernation, hibernation will be delayed at least until the calling
- // thread's egl_display_ptr is destroyed.
- void onWindowSurfaceCreated() {
- mHibernation.incWakeCount(HibernationMachine::STRONG);
- }
- void onWindowSurfaceDestroyed() {
- mHibernation.decWakeCount(HibernationMachine::STRONG);
- }
-
static egl_display_t* get(EGLDisplay dpy);
static EGLDisplay getFromNativeDisplay(EGLNativeDisplayType disp);
@@ -127,8 +113,6 @@
private:
friend class egl_display_ptr;
- bool enter() { return mHibernation.incWakeCount(HibernationMachine::WEAK); }
- void leave() { return mHibernation.decWakeCount(HibernationMachine::WEAK); }
uint32_t refs;
bool eglIsInitialized;
@@ -139,47 +123,6 @@
String8 mVersionString;
String8 mClientApiString;
String8 mExtensionString;
-
- // HibernationMachine uses its own internal mutex to protect its own data.
- // The owning egl_display_t's lock may be but is not required to be held
- // when calling HibernationMachine methods. As a result, nothing in this
- // class may call back up to egl_display_t directly or indirectly.
- class HibernationMachine {
- public:
- // STRONG refs cancel (inc) or initiate (dec) a hibernation attempt
- // the next time the wakecount reaches zero. WEAK refs don't affect
- // whether a hibernation attempt will be made. Use STRONG refs only
- // for infrequent/heavy changes that are likely to indicate the
- // EGLDisplay is entering or leaving a long-term idle state.
- enum WakeRefStrength {
- WEAK = 0,
- STRONG = 1,
- };
-
- HibernationMachine(): mWakeCount(0), mHibernating(false),
- mAttemptHibernation(false), mDpyValid(false),
-#if BOARD_ALLOW_EGL_HIBERNATION
- mAllowHibernation(true)
-#else
- mAllowHibernation(false)
-#endif
- {}
- ~HibernationMachine() {}
-
- bool incWakeCount(WakeRefStrength strenth);
- void decWakeCount(WakeRefStrength strenth);
-
- void setDisplayValid(bool valid);
-
- private:
- Mutex mLock;
- int32_t mWakeCount;
- bool mHibernating;
- bool mAttemptHibernation;
- bool mDpyValid;
- const bool mAllowHibernation;
- };
- HibernationMachine mHibernation;
};
// ----------------------------------------------------------------------------
@@ -190,13 +133,7 @@
// as the egl_display_ptr exists.
class egl_display_ptr {
public:
- explicit egl_display_ptr(egl_display_t* dpy): mDpy(dpy) {
- if (mDpy) {
- if (CC_UNLIKELY(!mDpy->enter())) {
- mDpy = NULL;
- }
- }
- }
+ explicit egl_display_ptr(egl_display_t* dpy): mDpy(dpy) {}
// We only really need a C++11 move constructor, not a copy constructor.
// A move constructor would save an enter()/leave() pair on every EGL API
@@ -208,17 +145,9 @@
// other.mDpy = NULL;
// }
//
- egl_display_ptr(const egl_display_ptr& other): mDpy(other.mDpy) {
- if (mDpy) {
- mDpy->enter();
- }
- }
+ egl_display_ptr(const egl_display_ptr& other): mDpy(other.mDpy) {}
- ~egl_display_ptr() {
- if (mDpy) {
- mDpy->leave();
- }
- }
+ ~egl_display_ptr() {}
const egl_display_t* operator->() const { return mDpy; }
egl_display_t* operator->() { return mDpy; }
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index cfecf77..6a76737 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -69,17 +69,12 @@
egl_connection_t const* cnx) :
egl_object_t(dpy), surface(surface), config(config), win(win), cnx(cnx),
enableTimestamps(false), connected(true)
-{
- if (win) {
- getDisplay()->onWindowSurfaceCreated();
- }
-}
+{}
egl_surface_t::~egl_surface_t() {
ANativeWindow* const window = win.get();
if (window != NULL) {
disconnect();
- getDisplay()->onWindowSurfaceDestroyed();
}
}
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 3253056..f5a4114 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -142,7 +142,12 @@
libgui \
libpowermanager \
libvulkan \
- libprotobuf-cpp-full
+ libprotobuf-cpp-full \
+ libhidl \
+ libhwbinder \
+ libbase \
+ libutils \
+ android.hardware.power@1.0
LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
diff --git a/services/surfaceflinger/DisplayHardware/PowerHAL.cpp b/services/surfaceflinger/DisplayHardware/PowerHAL.cpp
index bd50b4a..1c0a1fe 100644
--- a/services/surfaceflinger/DisplayHardware/PowerHAL.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerHAL.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <android/hardware/power/1.0/IPower.h>
#include <stdint.h>
#include <sys/types.h>
@@ -26,6 +27,7 @@
#include "PowerHAL.h"
+using android::hardware::power::V1_0::PowerHint;
namespace android {
// ---------------------------------------------------------------------------
@@ -39,7 +41,9 @@
}
mPowerManager = interface_cast<IPowerManager>(bs);
}
- status_t status = mPowerManager->powerHint(POWER_HINT_VSYNC, enabled ? 1 : 0);
+ status_t status;
+ status = mPowerManager->powerHint(static_cast<int>(PowerHint::VSYNC),
+ enabled ? 1 : 0);
if(status == DEAD_OBJECT) {
mPowerManager = NULL;
}