Move VR HWC HAL impl to vr/hardware_composer and cleanup deps
VR HWC is no longer built into VR WM, but in VR HWC, so update its
location. Also cleanup dead code.
Bug: 36051907
Test: Compiled
Change-Id: I15763234fa93bf3b95b8df6461428fe65fd5f611
diff --git a/services/vr/hardware_composer/Android.bp b/services/vr/hardware_composer/Android.bp
index b94d333..25bb30b 100644
--- a/services/vr/hardware_composer/Android.bp
+++ b/services/vr/hardware_composer/Android.bp
@@ -1,3 +1,51 @@
+cc_library_shared {
+ name: "libvr_hwc-hal",
+
+ srcs: [
+ "impl/vr_hwc.cpp",
+ "impl/vr_composer_client.cpp",
+ ],
+
+ static_libs: [
+ "libhwcomposer-client",
+ "libdisplay",
+ "libbufferhubqueue",
+ "libbufferhub",
+ "libpdx_default_transport",
+ ],
+
+ shared_libs: [
+ "android.frameworks.vr.composer@1.0",
+ "android.hardware.graphics.composer@2.1",
+ "libbase",
+ "libcutils",
+ "libfmq",
+ "libhardware",
+ "libhidlbase",
+ "libhidltransport",
+ "liblog",
+ "libsync",
+ "libui",
+ "libutils",
+ ],
+
+ export_static_lib_headers: [
+ "libhwcomposer-client",
+ ],
+
+ export_shared_lib_headers: [
+ "android.frameworks.vr.composer@1.0",
+ "android.hardware.graphics.composer@2.1",
+ ],
+
+ export_include_dirs: ["."],
+
+ cflags: [
+ "-DLOG_TAG=\"vr_hwc\"",
+ ],
+
+}
+
cc_library_static {
name: "libvr_hwc-binder",
srcs: [
@@ -12,11 +60,12 @@
export_aidl_headers: true,
},
export_include_dirs: ["aidl"],
+
shared_libs: [
"libbinder",
"libui",
"libutils",
- "libvrhwc",
+ "libvr_hwc-hal",
],
}
@@ -34,10 +83,10 @@
"liblog",
"libui",
"libutils",
- "libvrhwc",
+ "libvr_hwc-hal",
],
export_shared_lib_headers: [
- "libvrhwc",
+ "libvr_hwc-hal",
],
cflags: [
"-DLOG_TAG=\"vr_hwc\"",
@@ -65,7 +114,7 @@
"libhwbinder",
"libui",
"libutils",
- "libvrhwc",
+ "libvr_hwc-hal",
],
cflags: [
"-DLOG_TAG=\"vr_hwc\"",
diff --git a/services/vr/hardware_composer/impl/vr_composer_client.cpp b/services/vr/hardware_composer/impl/vr_composer_client.cpp
new file mode 100644
index 0000000..ae54e56
--- /dev/null
+++ b/services/vr/hardware_composer/impl/vr_composer_client.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.
+ */
+
+#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
+#include <hardware/gralloc.h>
+#include <hardware/gralloc1.h>
+#include <log/log.h>
+
+#include "impl/vr_hwc.h"
+#include "impl/vr_composer_client.h"
+
+namespace android {
+namespace dvr {
+
+using android::hardware::graphics::common::V1_0::PixelFormat;
+using android::frameworks::vr::composer::V1_0::IVrComposerClient;
+
+VrComposerClient::VrComposerClient(dvr::VrHwc& hal)
+ : ComposerClient(hal), mVrHal(hal) {}
+
+VrComposerClient::~VrComposerClient() {}
+
+std::unique_ptr<ComposerClient::CommandReader>
+VrComposerClient::createCommandReader() {
+ return std::unique_ptr<CommandReader>(new VrCommandReader(*this));
+}
+
+VrComposerClient::VrCommandReader::VrCommandReader(VrComposerClient& client)
+ : CommandReader(client), mVrClient(client), mVrHal(client.mVrHal) {}
+
+VrComposerClient::VrCommandReader::~VrCommandReader() {}
+
+bool VrComposerClient::VrCommandReader::parseCommand(
+ IComposerClient::Command command, uint16_t length) {
+ IVrComposerClient::VrCommand vrCommand =
+ static_cast<IVrComposerClient::VrCommand>(command);
+ 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);
+ }
+}
+
+bool VrComposerClient::VrCommandReader::parseSetLayerInfo(uint16_t length) {
+ if (length != 2) {
+ return false;
+ }
+
+ auto err = mVrHal.setLayerInfo(mDisplay, mLayer, read(), read());
+ if (err != Error::NONE) {
+ mWriter.setError(getCommandLoc(), err);
+ }
+
+ 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/hardware_composer/impl/vr_composer_client.h b/services/vr/hardware_composer/impl/vr_composer_client.h
new file mode 100644
index 0000000..1236be9
--- /dev/null
+++ b/services/vr/hardware_composer/impl/vr_composer_client.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 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.
+ */
+
+#ifndef ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H
+#define ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H
+
+#include <android/frameworks/vr/composer/1.0/IVrComposerClient.h>
+#include <ComposerClient.h>
+#include <IComposerCommandBuffer.h>
+
+namespace android {
+namespace dvr {
+
+class VrHwc;
+
+using hardware::graphics::common::V1_0::PixelFormat;
+using hardware::graphics::composer::V2_1::implementation::ComposerClient;
+
+class VrComposerClient : public ComposerClient {
+ public:
+ VrComposerClient(android::dvr::VrHwc& hal);
+ virtual ~VrComposerClient();
+
+ private:
+ class VrCommandReader : public ComposerClient::CommandReader {
+ public:
+ VrCommandReader(VrComposerClient& client);
+ ~VrCommandReader() override;
+
+ bool parseCommand(IComposerClient::Command command,
+ uint16_t length) override;
+
+ 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;
+
+ VrCommandReader(const VrCommandReader&) = delete;
+ void operator=(const VrCommandReader&) = delete;
+ };
+
+ std::unique_ptr<CommandReader> createCommandReader() override;
+
+ dvr::VrHwc& mVrHal;
+
+ VrComposerClient(const VrComposerClient&) = delete;
+ void operator=(const VrComposerClient&) = delete;
+};
+
+} // namespace dvr
+} // namespace android
+
+#endif // ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H
diff --git a/services/vr/hardware_composer/impl/vr_hwc.cpp b/services/vr/hardware_composer/impl/vr_hwc.cpp
new file mode 100644
index 0000000..29983a7
--- /dev/null
+++ b/services/vr/hardware_composer/impl/vr_hwc.cpp
@@ -0,0 +1,865 @@
+/*
+ * 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.
+ */
+#include "impl/vr_hwc.h"
+
+#include <private/dvr/display_client.h>
+#include <ui/Fence.h>
+
+#include <mutex>
+
+#include "vr_composer_client.h"
+
+using namespace android::hardware::graphics::common::V1_0;
+using namespace android::hardware::graphics::composer::V2_1;
+
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Void;
+
+namespace android {
+namespace dvr {
+namespace {
+
+using android::hardware::graphics::common::V1_0::PixelFormat;
+
+const Display kDefaultDisplayId = 1;
+const Config kDefaultConfigId = 1;
+
+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;
+ }
+
+ return buffer;
+}
+
+void GetPrimaryDisplaySize(int32_t* width, int32_t* height) {
+ *width = 1080;
+ *height = 1920;
+
+ int error = 0;
+ auto display_client = DisplayClient::Create(&error);
+ SystemDisplayMetrics metrics;
+
+ if (error) {
+ ALOGE("Could not connect to display service : %s(%d)", strerror(error),
+ error);
+ return;
+ }
+
+ error = display_client->GetDisplayMetrics(&metrics);
+ if (error) {
+ ALOGE("Could not get display metrics from display service : %s(%d)",
+ strerror(error), error);
+ return;
+ }
+
+ *width = metrics.display_native_width;
+ *height = metrics.display_native_height;
+}
+
+} // namespace
+
+HwcDisplay::HwcDisplay(int32_t width, int32_t height)
+ : width_(width), height_(height) {}
+
+HwcDisplay::~HwcDisplay() {}
+
+bool HwcDisplay::SetClientTarget(const native_handle_t* handle,
+ base::unique_fd fence) {
+ if (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));
+ return &layers_.back();
+}
+
+HwcLayer* HwcDisplay::GetLayer(Layer id) {
+ for (size_t i = 0; i < layers_.size(); ++i)
+ if (layers_[i].info.id == id)
+ return &layers_[i];
+
+ return nullptr;
+}
+
+bool HwcDisplay::DestroyLayer(Layer id) {
+ for (auto it = layers_.begin(); it != layers_.end(); ++it) {
+ if (it->info.id == id) {
+ layers_.erase(it);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void HwcDisplay::GetChangedCompositionTypes(
+ std::vector<Layer>* layer_ids,
+ std::vector<IComposerClient::Composition>* types) {
+ std::sort(layers_.begin(), layers_.end(),
+ [](const auto& lhs, const auto& rhs) {
+ return lhs.info.z_order < rhs.info.z_order;
+ });
+
+ int first_client_layer = -1, last_client_layer = -1;
+ for (size_t i = 0; i < layers_.size(); ++i) {
+ switch (layers_[i].composition_type) {
+ case IComposerClient::Composition::SOLID_COLOR:
+ case IComposerClient::Composition::CURSOR:
+ case IComposerClient::Composition::SIDEBAND:
+ if (first_client_layer < 0)
+ first_client_layer = i;
+
+ last_client_layer = i;
+ break;
+ default:
+ break;
+ }
+ }
+
+ for (size_t i = 0; i < layers_.size(); ++i) {
+ if (i >= first_client_layer && i <= last_client_layer) {
+ if (layers_[i].composition_type != IComposerClient::Composition::CLIENT) {
+ layer_ids->push_back(layers_[i].info.id);
+ types->push_back(IComposerClient::Composition::CLIENT);
+ layers_[i].composition_type = IComposerClient::Composition::CLIENT;
+ }
+
+ continue;
+ }
+
+ if (layers_[i].composition_type != IComposerClient::Composition::DEVICE) {
+ layer_ids->push_back(layers_[i].info.id);
+ types->push_back(IComposerClient::Composition::DEVICE);
+ layers_[i].composition_type = IComposerClient::Composition::DEVICE;
+ }
+ }
+}
+
+Error HwcDisplay::GetFrame(
+ std::vector<ComposerView::ComposerLayer>* out_frames) {
+ bool queued_client_target = false;
+ std::vector<ComposerView::ComposerLayer> frame;
+ for (const auto& layer : layers_) {
+ if (layer.composition_type == IComposerClient::Composition::CLIENT) {
+ if (queued_client_target)
+ continue;
+
+ if (!buffer_.get()) {
+ ALOGE("Client composition requested but no client target buffer");
+ return Error::BAD_LAYER;
+ }
+
+ ComposerView::ComposerLayer client_target_layer = {
+ .buffer = buffer_,
+ .fence = fence_.get() ? fence_ : new Fence(-1),
+ .display_frame = {0, 0, static_cast<int32_t>(buffer_->getWidth()),
+ static_cast<int32_t>(buffer_->getHeight())},
+ .crop = {0.0f, 0.0f, static_cast<float>(buffer_->getWidth()),
+ static_cast<float>(buffer_->getHeight())},
+ .blend_mode = IComposerClient::BlendMode::NONE,
+ };
+
+ frame.push_back(client_target_layer);
+ queued_client_target = true;
+ } else {
+ if (!layer.info.buffer.get() || !layer.info.fence.get()) {
+ ALOGV("Layer requested without valid buffer");
+ continue;
+ }
+
+ frame.push_back(layer.info);
+ }
+ }
+
+ out_frames->swap(frame);
+ return Error::NONE;
+}
+
+std::vector<Layer> HwcDisplay::UpdateLastFrameAndGetLastFrameLayers() {
+ std::vector<Layer> last_frame_layers;
+ last_frame_layers.swap(last_frame_layers_ids_);
+
+ for (const auto& layer : layers_)
+ last_frame_layers_ids_.push_back(layer.info.id);
+
+ return last_frame_layers;
+}
+
+void HwcDisplay::SetColorTransform(const float* matrix, int32_t hint) {
+ color_transform_hint_ = hint;
+ if (matrix)
+ memcpy(color_transform_, matrix, sizeof(color_transform_));
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// VrHwcClient
+
+VrHwc::VrHwc() {}
+
+VrHwc::~VrHwc() {}
+
+bool VrHwc::hasCapability(Capability capability) const { return false; }
+
+void VrHwc::removeClient() {
+ std::lock_guard<std::mutex> guard(mutex_);
+ client_ = nullptr;
+}
+
+void VrHwc::enableCallback(bool enable) {
+ if (enable && client_ != nullptr) {
+ {
+ int32_t width, height;
+ GetPrimaryDisplaySize(&width, &height);
+ std::lock_guard<std::mutex> guard(mutex_);
+ // Create the primary display late to avoid initialization issues between
+ // VR HWC and SurfaceFlinger.
+ displays_[kDefaultDisplayId].reset(new HwcDisplay(width, height));
+ }
+ client_.promote()->onHotplug(kDefaultDisplayId,
+ IComposerCallback::Connection::CONNECTED);
+ }
+}
+
+uint32_t VrHwc::getMaxVirtualDisplayCount() { return 1; }
+
+Error VrHwc::createVirtualDisplay(uint32_t width, uint32_t height,
+ PixelFormat* format, Display* outDisplay) {
+ *format = PixelFormat::RGBA_8888;
+ *outDisplay = display_count_;
+ displays_[display_count_].reset(new HwcDisplay(width, height));
+ display_count_++;
+ return Error::NONE;
+}
+
+Error VrHwc::destroyVirtualDisplay(Display display) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ if (display == kDefaultDisplayId || displays_.erase(display) == 0)
+ return Error::BAD_DISPLAY;
+ ComposerView::Frame frame;
+ frame.display_id = display;
+ frame.removed = true;
+ if (observer_)
+ observer_->OnNewFrame(frame);
+ return Error::NONE;
+}
+
+Error VrHwc::createLayer(Display display, Layer* outLayer) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+
+ HwcLayer* layer = display_ptr->CreateLayer();
+ *outLayer = layer->info.id;
+ return Error::NONE;
+}
+
+Error VrHwc::destroyLayer(Display display, Layer layer) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr) {
+ return Error::BAD_DISPLAY;
+ }
+
+ return display_ptr->DestroyLayer(layer) ? Error::NONE : Error::BAD_LAYER;
+}
+
+Error VrHwc::getActiveConfig(Display display, Config* outConfig) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ if (!FindDisplay(display))
+ return Error::BAD_DISPLAY;
+ *outConfig = kDefaultConfigId;
+ return Error::NONE;
+}
+
+Error VrHwc::getClientTargetSupport(Display display, uint32_t width,
+ uint32_t height, PixelFormat format,
+ Dataspace dataspace) {
+ return Error::NONE;
+}
+
+Error VrHwc::getColorModes(Display display, hidl_vec<ColorMode>* outModes) {
+ std::vector<ColorMode> color_modes(1, ColorMode::NATIVE);
+ *outModes = hidl_vec<ColorMode>(color_modes);
+ return Error::NONE;
+}
+
+Error VrHwc::getDisplayAttribute(Display display, Config config,
+ IComposerClient::Attribute attribute,
+ int32_t* outValue) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr) {
+ return Error::BAD_DISPLAY;
+ }
+ if (config != kDefaultConfigId) {
+ return Error::BAD_CONFIG;
+ }
+
+ switch (attribute) {
+ case IComposerClient::Attribute::WIDTH:
+ *outValue = display_ptr->width();
+ break;
+ case IComposerClient::Attribute::HEIGHT:
+ *outValue = display_ptr->height();
+ break;
+ case IComposerClient::Attribute::VSYNC_PERIOD:
+ *outValue = 1000 * 1000 * 1000 / 30; // 30fps
+ break;
+ case IComposerClient::Attribute::DPI_X:
+ case IComposerClient::Attribute::DPI_Y:
+ *outValue = 300 * 1000; // 300dpi
+ break;
+ default:
+ return Error::BAD_PARAMETER;
+ }
+
+ return Error::NONE;
+}
+
+Error VrHwc::getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ if (!FindDisplay(display))
+ return Error::BAD_DISPLAY;
+ std::vector<Config> configs(1, kDefaultConfigId);
+ *outConfigs = hidl_vec<Config>(configs);
+ return Error::NONE;
+}
+
+Error VrHwc::getDisplayName(Display display, hidl_string* outName) {
+ *outName = hidl_string();
+ return Error::NONE;
+}
+
+Error VrHwc::getDisplayType(Display display,
+ IComposerClient::DisplayType* outType) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr) {
+ *outType = IComposerClient::DisplayType::INVALID;
+ return Error::BAD_DISPLAY;
+ }
+
+ if (display == kDefaultDisplayId)
+ *outType = IComposerClient::DisplayType::PHYSICAL;
+ else
+ *outType = IComposerClient::DisplayType::VIRTUAL;
+
+ return Error::NONE;
+}
+
+Error VrHwc::getDozeSupport(Display display, bool* outSupport) {
+ *outSupport = false;
+ std::lock_guard<std::mutex> guard(mutex_);
+ if (!FindDisplay(display))
+ return Error::BAD_DISPLAY;
+ return Error::NONE;
+}
+
+Error VrHwc::getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
+ float* outMaxLuminance,
+ float* outMaxAverageLuminance,
+ float* outMinLuminance) {
+ *outMaxLuminance = 0;
+ *outMaxAverageLuminance = 0;
+ *outMinLuminance = 0;
+ return Error::NONE;
+}
+
+Error VrHwc::setActiveConfig(Display display, Config config) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+ if (config != kDefaultConfigId)
+ return Error::BAD_CONFIG;
+
+ display_ptr->set_active_config(config);
+ return Error::NONE;
+}
+
+Error VrHwc::setColorMode(Display display, ColorMode mode) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+
+ display_ptr->set_color_mode(mode);
+ return Error::NONE;
+}
+
+Error VrHwc::setPowerMode(Display display, IComposerClient::PowerMode mode) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+
+ display_ptr->set_power_mode(mode);
+ return Error::NONE;
+}
+
+Error VrHwc::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+
+ display_ptr->set_vsync_enabled(enabled);
+ return Error::NONE;
+}
+
+Error VrHwc::setColorTransform(Display display, const float* matrix,
+ int32_t hint) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+
+ display_ptr->SetColorTransform(matrix, hint);
+ return Error::NONE;
+}
+
+Error VrHwc::setClientTarget(Display display, buffer_handle_t target,
+ int32_t acquireFence, int32_t dataspace,
+ const std::vector<hwc_rect_t>& damage) {
+ base::unique_fd fence(acquireFence);
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+
+ if (target == nullptr)
+ return Error::NONE;
+
+ if (!display_ptr->SetClientTarget(target, std::move(fence)))
+ return Error::BAD_PARAMETER;
+
+ return Error::NONE;
+}
+
+Error VrHwc::setOutputBuffer(Display display, buffer_handle_t buffer,
+ int32_t releaseFence) {
+ base::unique_fd fence(releaseFence);
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+
+ // TODO(dnicoara): Is it necessary to do anything here?
+ return Error::NONE;
+}
+
+Error VrHwc::validateDisplay(
+ Display display, std::vector<Layer>* outChangedLayers,
+ std::vector<IComposerClient::Composition>* outCompositionTypes,
+ uint32_t* outDisplayRequestMask, std::vector<Layer>* outRequestedLayers,
+ std::vector<uint32_t>* outRequestMasks) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+
+ display_ptr->GetChangedCompositionTypes(outChangedLayers,
+ outCompositionTypes);
+ return Error::NONE;
+}
+
+Error VrHwc::acceptDisplayChanges(Display display) { return Error::NONE; }
+
+Error VrHwc::presentDisplay(Display display, int32_t* outPresentFence,
+ std::vector<Layer>* outLayers,
+ std::vector<int32_t>* outReleaseFences) {
+ *outPresentFence = -1;
+ outLayers->clear();
+ outReleaseFences->clear();
+
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto display_ptr = FindDisplay(display);
+
+ if (!display_ptr)
+ return Error::BAD_DISPLAY;
+
+ ComposerView::Frame frame;
+ std::vector<Layer> last_frame_layers;
+ Error status = display_ptr->GetFrame(&frame.layers);
+ frame.display_id = display;
+ frame.display_width = display_ptr->width();
+ frame.display_height = display_ptr->height();
+ frame.active_config = display_ptr->active_config();
+ frame.power_mode = display_ptr->power_mode();
+ frame.vsync_enabled = display_ptr->vsync_enabled();
+ frame.color_transform_hint = display_ptr->color_transform_hint();
+ frame.color_mode = display_ptr->color_mode();
+ memcpy(frame.color_transform, display_ptr->color_transform(),
+ sizeof(frame.color_transform));
+ if (status != Error::NONE)
+ return status;
+
+ last_frame_layers = display_ptr->UpdateLastFrameAndGetLastFrameLayers();
+
+ base::unique_fd fence;
+ if (observer_)
+ fence = observer_->OnNewFrame(frame);
+
+ if (fence.get() < 0)
+ return Error::NONE;
+
+ *outPresentFence = dup(fence.get());
+ outLayers->swap(last_frame_layers);
+ for (size_t i = 0; i < outLayers->size(); ++i)
+ outReleaseFences->push_back(dup(fence.get()));
+
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerCursorPosition(Display display, Layer layer, int32_t x,
+ int32_t y) {
+ 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->info.cursor_x = x;
+ hwc_layer->info.cursor_y = y;
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerBuffer(Display display, Layer layer,
+ buffer_handle_t buffer, int32_t acquireFence) {
+ base::unique_fd fence(acquireFence);
+ 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->info.buffer = CreateGraphicBuffer(
+ buffer, hwc_layer->buffer_metadata);
+ hwc_layer->info.fence = new Fence(fence.release());
+
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerSurfaceDamage(Display display, Layer layer,
+ const std::vector<hwc_rect_t>& damage) {
+ 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->info.damaged_regions = damage;
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerBlendMode(Display display, Layer layer, int32_t mode) {
+ 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->info.blend_mode =
+ static_cast<ComposerView::ComposerLayer::BlendMode>(mode);
+
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerColor(Display display, Layer layer,
+ IComposerClient::Color color) {
+ 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->info.color = color;
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerCompositionType(Display display, Layer layer,
+ int32_t type) {
+ 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->composition_type = static_cast<HwcLayer::Composition>(type);
+
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerDataspace(Display display, Layer layer,
+ int32_t dataspace) {
+ 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->info.dataspace = dataspace;
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerDisplayFrame(Display display, Layer layer,
+ const hwc_rect_t& frame) {
+ 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->info.display_frame =
+ {frame.left, frame.top, frame.right, frame.bottom};
+
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerPlaneAlpha(Display display, Layer layer, float alpha) {
+ 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->info.alpha = alpha;
+
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerSidebandStream(Display display, Layer layer,
+ buffer_handle_t stream) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ if (!FindDisplay(display))
+ return Error::BAD_DISPLAY;
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerSourceCrop(Display display, Layer layer,
+ const hwc_frect_t& crop) {
+ 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->info.crop = {crop.left, crop.top, crop.right, crop.bottom};
+
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerTransform(Display display, Layer layer,
+ int32_t transform) {
+ 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->info.transform = transform;
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerVisibleRegion(Display display, Layer layer,
+ const std::vector<hwc_rect_t>& visible) {
+ 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->info.visible_regions = visible;
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerZOrder(Display display, Layer layer, uint32_t z) {
+ 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->info.z_order = z;
+
+ return Error::NONE;
+}
+
+Error VrHwc::setLayerInfo(Display display, Layer layer, uint32_t type,
+ uint32_t appId) {
+ 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->info.type = type;
+ hwc_layer->info.app_id = appId;
+
+ 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();
+}
+
+Return<void> VrHwc::dumpDebugInfo(dumpDebugInfo_cb hidl_cb) {
+ hidl_cb(hidl_string());
+ return Void();
+}
+
+Return<void> VrHwc::createClient(createClient_cb hidl_cb) {
+ std::lock_guard<std::mutex> guard(mutex_);
+
+ Error status = Error::NONE;
+ sp<VrComposerClient> client;
+ if (client_ == nullptr) {
+ client = new VrComposerClient(*this);
+ client->initialize();
+ } else {
+ ALOGE("Already have a client");
+ status = Error::NO_RESOURCES;
+ }
+
+ client_ = client;
+ hidl_cb(status, client);
+ return Void();
+}
+
+void VrHwc::RegisterObserver(Observer* observer) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ if (observer_)
+ ALOGE("Overwriting observer");
+ else
+ observer_ = observer;
+}
+
+void VrHwc::UnregisterObserver(Observer* observer) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ if (observer != observer_)
+ ALOGE("Trying to unregister unknown observer");
+ else
+ observer_ = nullptr;
+}
+
+HwcDisplay* VrHwc::FindDisplay(Display display) {
+ auto iter = displays_.find(display);
+ return iter == displays_.end() ? nullptr : iter->second.get();
+}
+
+ComposerView* GetComposerViewFromIComposer(
+ hardware::graphics::composer::V2_1::IComposer* composer) {
+ return static_cast<VrHwc*>(composer);
+}
+
+IComposer* HIDL_FETCH_IComposer(const char*) { return new VrHwc(); }
+
+} // namespace dvr
+} // namespace android
diff --git a/services/vr/hardware_composer/impl/vr_hwc.h b/services/vr/hardware_composer/impl/vr_hwc.h
new file mode 100644
index 0000000..df04208
--- /dev/null
+++ b/services/vr/hardware_composer/impl/vr_hwc.h
@@ -0,0 +1,322 @@
+/*
+ * 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_DVR_HARDWARE_COMPOSER_IMPL_VR_HWC_H
+#define ANDROID_DVR_HARDWARE_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>
+#include <ui/GraphicBuffer.h>
+#include <utils/StrongPointer.h>
+
+#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;
+
+using android::hardware::hidl_handle;
+using android::hardware::hidl_string;
+using android::hardware::hidl_vec;
+using android::hardware::Return;
+using android::hardware::Void;
+
+namespace android {
+
+class Fence;
+
+namespace dvr {
+
+class VrComposerClient;
+
+using android::hardware::graphics::common::V1_0::PixelFormat;
+using android::hardware::graphics::composer::V2_1::implementation::ComposerBase;
+
+class ComposerView {
+ public:
+ struct ComposerLayer {
+ using Recti = hardware::graphics::composer::V2_1::IComposerClient::Rect;
+ using Rectf = hardware::graphics::composer::V2_1::IComposerClient::FRect;
+ using BlendMode =
+ hardware::graphics::composer::V2_1::IComposerClient::BlendMode;
+
+ Layer id;
+ sp<GraphicBuffer> buffer;
+ sp<Fence> fence;
+ Recti display_frame;
+ Rectf crop;
+ BlendMode blend_mode;
+ float alpha;
+ uint32_t type;
+ uint32_t app_id;
+ uint32_t z_order;
+ int32_t cursor_x;
+ int32_t cursor_y;
+ IComposerClient::Color color;
+ int32_t dataspace;
+ int32_t transform;
+ std::vector<hwc_rect_t> visible_regions;
+ std::vector<hwc_rect_t> damaged_regions;
+ };
+
+ struct Frame {
+ Display display_id;
+ // This is set to true to notify the upper layer that the display is
+ // being removed, or left false in the case of a normal frame. The upper
+ // layer tracks display IDs and will handle new ones showing up.
+ bool removed = false;
+ int32_t display_width;
+ int32_t display_height;
+ Config active_config;
+ ColorMode color_mode;
+ IComposerClient::PowerMode power_mode;
+ IComposerClient::Vsync vsync_enabled;
+ float color_transform[16];
+ int32_t color_transform_hint;
+ std::vector<ComposerLayer> layers;
+ };
+
+ class Observer {
+ public:
+ virtual ~Observer() {}
+
+ // Returns a list of layers that need to be shown together. Layers are
+ // returned in z-order, with the lowest layer first.
+ virtual base::unique_fd OnNewFrame(const Frame& frame) = 0;
+ };
+
+ virtual ~ComposerView() {}
+
+ virtual void RegisterObserver(Observer* observer) = 0;
+ virtual void UnregisterObserver(Observer* observer) = 0;
+};
+
+struct HwcLayer {
+ using Composition =
+ hardware::graphics::composer::V2_1::IComposerClient::Composition;
+
+ HwcLayer(Layer new_id) {
+ info.id = new_id;
+ }
+
+ Composition composition_type;
+ ComposerView::ComposerLayer info;
+ IVrComposerClient::BufferMetadata buffer_metadata;
+};
+
+class HwcDisplay {
+ public:
+ HwcDisplay(int32_t width, int32_t height);
+ ~HwcDisplay();
+
+ int32_t width() const { return width_; }
+ int32_t height() const { return height_; }
+
+ HwcLayer* CreateLayer();
+ bool DestroyLayer(Layer id);
+ 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,
+ std::vector<IComposerClient::Composition>* composition);
+
+ Error GetFrame(std::vector<ComposerView::ComposerLayer>* out_frame);
+
+ std::vector<Layer> UpdateLastFrameAndGetLastFrameLayers();
+
+ Config active_config() const { return active_config_; }
+ void set_active_config(Config config) { active_config_ = config; }
+
+ ColorMode color_mode() const { return color_mode_; }
+ void set_color_mode(ColorMode mode) { color_mode_ = mode; }
+
+ IComposerClient::PowerMode power_mode() const { return power_mode_; }
+ void set_power_mode(IComposerClient::PowerMode mode) { power_mode_ = mode; }
+
+ IComposerClient::Vsync vsync_enabled() const { return vsync_enabled_; }
+ void set_vsync_enabled(IComposerClient::Vsync vsync) {
+ vsync_enabled_ = vsync;
+ }
+
+ const float* color_transform() const { return color_transform_; }
+ int32_t color_transform_hint() const { return color_transform_hint_; }
+ void SetColorTransform(const float* matrix, int32_t hint);
+
+ private:
+ // The client target buffer and the associated fence.
+ sp<GraphicBuffer> buffer_;
+ IVrComposerClient::BufferMetadata buffer_metadata_;
+ sp<Fence> fence_;
+
+ // List of currently active layers.
+ std::vector<HwcLayer> layers_;
+
+ std::vector<Layer> last_frame_layers_ids_;
+
+ // Layer ID generator.
+ uint64_t layer_ids_ = 1;
+
+ int32_t width_;
+ int32_t height_;
+
+ Config active_config_;
+ ColorMode color_mode_;
+ IComposerClient::PowerMode power_mode_;
+ IComposerClient::Vsync vsync_enabled_;
+ float color_transform_[16];
+ int32_t color_transform_hint_;
+
+ HwcDisplay(const HwcDisplay&) = delete;
+ void operator=(const HwcDisplay&) = delete;
+};
+
+class VrHwc : public IComposer, public ComposerBase, public ComposerView {
+ public:
+ VrHwc();
+ ~VrHwc() override;
+
+ bool hasCapability(Capability capability) const;
+
+ 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;
+ void enableCallback(bool enable) override;
+
+ uint32_t getMaxVirtualDisplayCount() override;
+ Error createVirtualDisplay(uint32_t width, uint32_t height,
+ PixelFormat* format, Display* outDisplay) override;
+ Error destroyVirtualDisplay(Display display) override;
+
+ Error createLayer(Display display, Layer* outLayer) override;
+ Error destroyLayer(Display display, Layer layer) override;
+
+ Error getActiveConfig(Display display, Config* outConfig) override;
+ Error getClientTargetSupport(Display display,
+ uint32_t width, uint32_t height,
+ PixelFormat format, Dataspace dataspace) override;
+ Error getColorModes(Display display, hidl_vec<ColorMode>* outModes) override;
+ Error getDisplayAttribute(Display display, Config config,
+ IComposerClient::Attribute attribute, int32_t* outValue) override;
+ Error getDisplayConfigs(Display display, hidl_vec<Config>* outConfigs) override;
+ Error getDisplayName(Display display, hidl_string* outName) override;
+ Error getDisplayType(Display display,
+ IComposerClient::DisplayType* outType) override;
+ Error getDozeSupport(Display display, bool* outSupport) override;
+ Error getHdrCapabilities(Display display, hidl_vec<Hdr>* outTypes,
+ float* outMaxLuminance, float* outMaxAverageLuminance,
+ float* outMinLuminance) override;
+
+ Error setActiveConfig(Display display, Config config) override;
+ Error setColorMode(Display display, ColorMode mode) override;
+ Error setPowerMode(Display display, IComposerClient::PowerMode mode) override;
+ Error setVsyncEnabled(Display display, IComposerClient::Vsync enabled) override;
+
+ Error setColorTransform(Display display, const float* matrix,
+ int32_t hint) override;
+ Error setClientTarget(Display display, buffer_handle_t target,
+ int32_t acquireFence, int32_t dataspace,
+ const std::vector<hwc_rect_t>& damage) override;
+ Error setOutputBuffer(Display display, buffer_handle_t buffer,
+ int32_t releaseFence) override;
+ Error validateDisplay(Display display,
+ std::vector<Layer>* outChangedLayers,
+ std::vector<IComposerClient::Composition>* outCompositionTypes,
+ uint32_t* outDisplayRequestMask,
+ std::vector<Layer>* outRequestedLayers,
+ std::vector<uint32_t>* outRequestMasks) override;
+ Error acceptDisplayChanges(Display display) override;
+ Error presentDisplay(Display display, int32_t* outPresentFence,
+ std::vector<Layer>* outLayers,
+ std::vector<int32_t>* outReleaseFences) override;
+
+ Error setLayerCursorPosition(Display display, Layer layer,
+ int32_t x, int32_t y) override;
+ Error setLayerBuffer(Display display, Layer layer,
+ buffer_handle_t buffer, int32_t acquireFence) override;
+ Error setLayerSurfaceDamage(Display display, Layer layer,
+ const std::vector<hwc_rect_t>& damage) override;
+ Error setLayerBlendMode(Display display, Layer layer, int32_t mode) override;
+ Error setLayerColor(Display display, Layer layer,
+ IComposerClient::Color color) override;
+ Error setLayerCompositionType(Display display, Layer layer,
+ int32_t type) override;
+ Error setLayerDataspace(Display display, Layer layer,
+ int32_t dataspace) override;
+ Error setLayerDisplayFrame(Display display, Layer layer,
+ const hwc_rect_t& frame) override;
+ Error setLayerPlaneAlpha(Display display, Layer layer, float alpha) override;
+ Error setLayerSidebandStream(Display display, Layer layer,
+ buffer_handle_t stream) override;
+ Error setLayerSourceCrop(Display display, Layer layer,
+ const hwc_frect_t& crop) override;
+ Error setLayerTransform(Display display, Layer layer,
+ int32_t transform) override;
+ Error setLayerVisibleRegion(Display display, Layer layer,
+ const std::vector<hwc_rect_t>& visible) override;
+ Error setLayerZOrder(Display display, Layer layer, uint32_t z) override;
+
+ // IComposer:
+ Return<void> getCapabilities(getCapabilities_cb hidl_cb) override;
+ Return<void> dumpDebugInfo(dumpDebugInfo_cb hidl_cb) override;
+ Return<void> createClient(createClient_cb hidl_cb) override;
+
+ // ComposerView:
+ void RegisterObserver(Observer* observer) override;
+ void UnregisterObserver(Observer* observer) override;
+
+ private:
+ HwcDisplay* FindDisplay(Display display);
+
+ wp<VrComposerClient> client_;
+ sp<IComposerCallback> callbacks_;
+
+ // Guard access to internal state from binder threads.
+ std::mutex mutex_;
+
+ std::unordered_map<Display, std::unique_ptr<HwcDisplay>> displays_;
+ Display display_count_ = 2;
+
+ Observer* observer_ = nullptr;
+
+ VrHwc(const VrHwc&) = delete;
+ void operator=(const VrHwc&) = delete;
+};
+
+
+ComposerView* GetComposerViewFromIComposer(
+ hardware::graphics::composer::V2_1::IComposer* composer);
+
+hardware::graphics::composer::V2_1::IComposer* HIDL_FETCH_IComposer(
+ const char* name);
+
+} // namespace dvr
+} // namespace android
+
+#endif // ANDROID_DVR_HARDWARE_COMPOSER_IMPL_VR_HWC_H