diff options
author | 2017-01-27 00:17:20 +0000 | |
---|---|---|
committer | 2017-01-27 00:17:21 +0000 | |
commit | bf89eb7b24f930e77be57bc7b6393e39691a4d35 (patch) | |
tree | 5431f1d3baeac0687e25fe0e25106266e13ea34b | |
parent | 1478db5b4717877b32f9ad0cd3d066db01e7ca41 (diff) | |
parent | 2f5f8a51f5994cf14837030d4b3b252a9d1b950b (diff) |
Merge changes from topic 'vr_wm'
* changes:
VR: Add ability to pass layer info through SurfaceFlinger
VR: Create VR implementation for HWC HIDL interface
18 files changed, 1263 insertions, 5 deletions
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk index 1cd921569f..0ea1407947 100644 --- a/services/surfaceflinger/Android.mk +++ b/services/surfaceflinger/Android.mk @@ -48,6 +48,10 @@ LOCAL_C_INCLUDES := \ LOCAL_CFLAGS := -DLOG_TAG=\"SurfaceFlinger\" LOCAL_CFLAGS += -DGL_GLEXT_PROTOTYPES -DEGL_EGLEXT_PROTOTYPES +ifeq ($(TARGET_IN_VR_MODE),true) + LOCAL_CFLAGS += -DIN_VR_MODE +endif + ifeq ($(TARGET_USES_HWC2),true) LOCAL_CFLAGS += -DUSE_HWC2 LOCAL_SRC_FILES += \ @@ -130,6 +134,7 @@ LOCAL_CFLAGS += -fvisibility=hidden -Werror=format LOCAL_STATIC_LIBRARIES := libhwcomposer-command-buffer libtrace_proto libvkjson LOCAL_SHARED_LIBRARIES := \ + android.dvr.composer@1.0 \ android.hardware.graphics.allocator@2.0 \ android.hardware.graphics.composer@2.1 \ libcutils \ diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp index 2f2f3a9d41..1bd9616f7c 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.cpp +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.cpp @@ -17,6 +17,7 @@ #undef LOG_TAG #define LOG_TAG "HwcComposer" +#include <android/dvr/composer/1.0/IVrComposerClient.h> #include <inttypes.h> #include <log/log.h> @@ -24,6 +25,7 @@ namespace android { +using dvr::composer::V1_0::IVrComposerClient; using hardware::Return; using hardware::hidl_vec; using hardware::hidl_handle; @@ -102,10 +104,37 @@ Error unwrapRet(Return<Error>& ret) } // anonymous namespace -Composer::Composer() - : mWriter(kWriterInitialSize) +Composer::CommandWriter::CommandWriter(uint32_t initialMaxSize) + : CommandWriterBase(initialMaxSize) {} + +Composer::CommandWriter::~CommandWriter() +{ +} + +void Composer::CommandWriter::setLayerInfo(uint32_t type, uint32_t appId) { - mComposer = IComposer::getService("hwcomposer"); + constexpr uint16_t kSetLayerInfoLength = 2; + beginCommand( + static_cast<IComposerClient::Command>( + IVrComposerClient::VrCommand::SET_LAYER_INFO), + kSetLayerInfoLength); + write(type); + write(appId); + endCommand(); +} + +Composer::Composer() : mWriter(kWriterInitialSize) +{ +#if defined(IN_VR_MODE) + mIsInVrMode = true; +#endif + + if (mIsInVrMode) { + mComposer = IComposer::getService("vr_hwcomposer"); + } else { + mComposer = IComposer::getService("hwcomposer"); + } + if (mComposer == nullptr) { LOG_ALWAYS_FATAL("failed to get hwcomposer service"); } @@ -589,6 +618,18 @@ Error Composer::setLayerZOrder(Display display, Layer layer, uint32_t z) return Error::NONE; } +Error Composer::setLayerInfo(Display display, Layer layer, uint32_t type, + uint32_t appId) +{ + if (mIsInVrMode) + { + mWriter.selectDisplay(display); + mWriter.selectLayer(layer); + mWriter.setLayerInfo(type, appId); + } + return Error::NONE; +} + Error Composer::execute() { // prepare input command queue diff --git a/services/surfaceflinger/DisplayHardware/ComposerHal.h b/services/surfaceflinger/DisplayHardware/ComposerHal.h index 5ce5869b45..329d787d50 100644 --- a/services/surfaceflinger/DisplayHardware/ComposerHal.h +++ b/services/surfaceflinger/DisplayHardware/ComposerHal.h @@ -215,8 +215,17 @@ public: Error setLayerVisibleRegion(Display display, Layer layer, const std::vector<IComposerClient::Rect>& visible); Error setLayerZOrder(Display display, Layer layer, uint32_t z); - + Error setLayerInfo(Display display, Layer layer, uint32_t type, + uint32_t appId); private: + class CommandWriter : public CommandWriterBase { + public: + CommandWriter(uint32_t initialMaxSize); + ~CommandWriter() override; + + void setLayerInfo(uint32_t type, uint32_t appId); + }; + // Many public functions above simply write a command into the command // queue to batch the calls. validateDisplay and presentDisplay will call // this function to execute the command queue. @@ -228,8 +237,10 @@ private: // 64KiB minus a small space for metadata such as read/write pointers static constexpr size_t kWriterInitialSize = 64 * 1024 / sizeof(uint32_t) - 16; - CommandWriterBase mWriter; + CommandWriter mWriter; CommandReader mReader; + + bool mIsInVrMode = false; }; } // namespace Hwc2 diff --git a/services/surfaceflinger/DisplayHardware/HWC2.cpp b/services/surfaceflinger/DisplayHardware/HWC2.cpp index c89ca836c2..6ff5ea1ae8 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.cpp +++ b/services/surfaceflinger/DisplayHardware/HWC2.cpp @@ -1424,4 +1424,16 @@ Error Layer::setZOrder(uint32_t z) return static_cast<Error>(intError); } +Error Layer::setInfo(uint32_t type, uint32_t appId) +{ +#ifdef BYPASS_IHWC + (void)type; + (void)appId; + int32_t intError = 0; +#else + auto intError = mDevice.mComposer->setLayerInfo(mDisplayId, mId, type, appId); +#endif + return static_cast<Error>(intError); +} + } // namespace HWC2 diff --git a/services/surfaceflinger/DisplayHardware/HWC2.h b/services/surfaceflinger/DisplayHardware/HWC2.h index 5b894badf0..256b05d9f7 100644 --- a/services/surfaceflinger/DisplayHardware/HWC2.h +++ b/services/surfaceflinger/DisplayHardware/HWC2.h @@ -405,6 +405,7 @@ public: [[clang::warn_unused_result]] Error setVisibleRegion( const android::Region& region); [[clang::warn_unused_result]] Error setZOrder(uint32_t z); + [[clang::warn_unused_result]] Error setInfo(uint32_t type, uint32_t appId); private: std::weak_ptr<Display> mDisplay; diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp index 6fd9cd75b3..226e70a821 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -140,6 +140,8 @@ Layer::Layer(SurfaceFlinger* flinger, const sp<Client>& client, mCurrentState.sequence = 0; mCurrentState.requested = mCurrentState.active; mCurrentState.dataSpace = HAL_DATASPACE_UNKNOWN; + mCurrentState.appId = 0; + mCurrentState.type = 0; // drawing state & current state are identical mDrawingState = mCurrentState; @@ -676,6 +678,10 @@ void Layer::setGeometry( ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set Z %u: %s (%d)", mName.string(), z, to_string(error).c_str(), static_cast<int32_t>(error)); + + error = hwcLayer->setInfo(s.type, s.appId); + ALOGE_IF(error != HWC2::Error::None, "[%s] Failed to set info (%d)", + mName.string(), static_cast<int32_t>(error)); #else if (!frame.intersect(hw->getViewport(), &frame)) { frame.clear(); @@ -1747,6 +1753,13 @@ bool Layer::setOverrideScalingMode(int32_t scalingMode) { return true; } +void Layer::setInfo(uint32_t type, uint32_t appId) { + mCurrentState.appId = appId; + mCurrentState.type = type; + mCurrentState.modified = true; + setTransactionFlags(eTransactionNeeded); +} + uint32_t Layer::getEffectiveScalingMode() const { if (mOverrideScalingMode >= 0) { return mOverrideScalingMode; diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h index bf224ae4d8..ee7cfb80df 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -141,6 +141,9 @@ public: Region activeTransparentRegion; Region requestedTransparentRegion; android_dataspace dataSpace; + + uint32_t appId; + uint32_t type; }; // ----------------------------------------------------------------------- @@ -172,6 +175,7 @@ public: uint32_t getLayerStack() const; void deferTransactionUntil(const sp<IBinder>& handle, uint64_t frameNumber); bool setOverrideScalingMode(int32_t overrideScalingMode); + void setInfo(uint32_t type, uint32_t appId); // If we have received a new buffer this frame, we will pass its surface // damage down to hardware composer. Otherwise, we must send a region with diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 3480d83d28..4798ecdedd 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -2580,6 +2580,9 @@ uint32_t SurfaceFlinger::setClientStateLocked( // We don't trigger a traversal here because if no other state is // changed, we don't want this to cause any more work } + if (what & layer_state_t::eLayerInfoChanged) { + layer->setInfo(s.type, s.appid); + } } return flags; } diff --git a/services/vr/Android.bp b/services/vr/Android.bp new file mode 100644 index 0000000000..80df479e8d --- /dev/null +++ b/services/vr/Android.bp @@ -0,0 +1,3 @@ +subdirs = [ + "*", +] diff --git a/services/vr/vr_window_manager/Android.bp b/services/vr/vr_window_manager/Android.bp new file mode 100644 index 0000000000..c30219f09b --- /dev/null +++ b/services/vr/vr_window_manager/Android.bp @@ -0,0 +1,39 @@ +subdirs = [ + "composer/1.0", +] + +cc_library_shared { + name: "libvrhwc", + + srcs: [ + "composer/impl/sync_timeline.cpp", + "composer/impl/vr_hwc.cpp", + "composer/impl/vr_composer_client.cpp", + ], + + static_libs: [ + "libhwcomposer-client", + ], + + shared_libs: [ + "android.dvr.composer@1.0", + "android.hardware.graphics.composer@2.1", + "libbase", + "libcutils", + "libfmq", + "libhardware", + "libhidlbase", + "libhidltransport", + "liblog", + "libsync", + "libui", + "libutils", + ], + + // Access to software sync timeline. + include_dirs: [ "system/core/libsync" ], + + cflags: [ + "-DLOG_TAG=\"vrhwc\"", + ], +} diff --git a/services/vr/vr_window_manager/composer/1.0/Android.bp b/services/vr/vr_window_manager/composer/1.0/Android.bp new file mode 100644 index 0000000000..f69481fdf6 --- /dev/null +++ b/services/vr/vr_window_manager/composer/1.0/Android.bp @@ -0,0 +1,54 @@ +// This file is autogenerated by hidl-gen. Do not edit manually. + +genrule { + name: "android.dvr.composer@1.0_genc++", + tools: ["hidl-gen"], + cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hidl:system/libhidl/transport -randroid.hardware:hardware/interfaces/ -randroid.dvr:frameworks/native/services/vr/vr_window_manager android.dvr.composer@1.0", + srcs: [ + "IVrComposerClient.hal", + ], + out: [ + "android/dvr/composer/1.0/VrComposerClientAll.cpp", + ], +} + +genrule { + name: "android.dvr.composer@1.0_genc++_headers", + tools: ["hidl-gen"], + cmd: "$(location hidl-gen) -o $(genDir) -Lc++ -randroid.hidl:system/libhidl/transport -randroid.hardware:hardware/interfaces/ -randroid.dvr:frameworks/native/services/vr/vr_window_manager android.dvr.composer@1.0", + srcs: [ + "IVrComposerClient.hal", + ], + out: [ + "android/dvr/composer/1.0/IVrComposerClient.h", + "android/dvr/composer/1.0/IHwVrComposerClient.h", + "android/dvr/composer/1.0/BnVrComposerClient.h", + "android/dvr/composer/1.0/BpVrComposerClient.h", + "android/dvr/composer/1.0/BsVrComposerClient.h", + ], +} + +cc_library_shared { + name: "android.dvr.composer@1.0", + generated_sources: ["android.dvr.composer@1.0_genc++"], + generated_headers: ["android.dvr.composer@1.0_genc++_headers"], + export_generated_headers: ["android.dvr.composer@1.0_genc++_headers"], + shared_libs: [ + "libhidlbase", + "libhidltransport", + "libhwbinder", + "liblog", + "libutils", + "libcutils", + "android.hardware.graphics.composer@2.1", + "android.hidl.base@1.0", + ], + export_shared_lib_headers: [ + "libhidlbase", + "libhidltransport", + "libhwbinder", + "libutils", + "android.hardware.graphics.composer@2.1", + "android.hidl.base@1.0", + ], +} diff --git a/services/vr/vr_window_manager/composer/1.0/IVrComposerClient.hal b/services/vr/vr_window_manager/composer/1.0/IVrComposerClient.hal new file mode 100644 index 0000000000..230a68a42b --- /dev/null +++ b/services/vr/vr_window_manager/composer/1.0/IVrComposerClient.hal @@ -0,0 +1,49 @@ +/* + * Copyright (C) 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. + */ +package android.dvr.composer@1.0; + +import android.hardware.graphics.composer@2.1::IComposerClient; + +interface IVrComposerClient + extends android.hardware.graphics.composer@2.1::IComposerClient { + /* + * Used to annotate the layer with additional information, which will be + * used to describe the content of the layer (ie: notification, permission, + * etc) which allows VR window manager to treat certain layer types + * specially. + * + * @param display is the display on which the layer was created. + * @param layer is the layer affected by the change. + * @param layer_type the type of the layer as described by the window + * manager. + * @param application_id the application id the layer belongs to. + * @return error is NONE upon success. Otherwise, + * BAD_DISPLAY when an invalid display handle was passed in. + * BAD_LAYER when an invalid layer handle was passed in. + * + * setLayerInfo(Display display, + * Layer layer, + * uint32_t layer_type, + * uint32_t application_id) + * generates(Error error); + */ + + enum VrCommand : int32_t { + OPCODE_SHIFT = android.hardware.graphics.composer@2.1::IComposerClient.Command:OPCODE_SHIFT, + + SET_LAYER_INFO = 0x800 << OPCODE_SHIFT, + }; +}; diff --git a/services/vr/vr_window_manager/composer/impl/sync_timeline.cpp b/services/vr/vr_window_manager/composer/impl/sync_timeline.cpp new file mode 100644 index 0000000000..aa55aed90a --- /dev/null +++ b/services/vr/vr_window_manager/composer/impl/sync_timeline.cpp @@ -0,0 +1,43 @@ +/* + * 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 "composer/impl/sync_timeline.h" + +#include <sys/cdefs.h> +#include <sw_sync.h> +#include <unistd.h> + +namespace android { +namespace dvr { + +SyncTimeline::SyncTimeline() {} + +SyncTimeline::~SyncTimeline() {} + +bool SyncTimeline::Initialize() { + timeline_fd_.reset(sw_sync_timeline_create()); + return timeline_fd_ >= 0; +} + +int SyncTimeline::CreateFence(int time) { + return sw_sync_fence_create(timeline_fd_.get(), "dummy fence", time); +} + +bool SyncTimeline::IncrementTimeline() { + return sw_sync_timeline_inc(timeline_fd_.get(), 1) == 0; +} + +} // namespace dvr +} // namespace android diff --git a/services/vr/vr_window_manager/composer/impl/sync_timeline.h b/services/vr/vr_window_manager/composer/impl/sync_timeline.h new file mode 100644 index 0000000000..945acbdf34 --- /dev/null +++ b/services/vr/vr_window_manager/composer/impl/sync_timeline.h @@ -0,0 +1,45 @@ +/* + * 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 VR_WINDOW_MANAGER_COMPOSER_IMPL_SYNC_TIMELINE_H_ +#define VR_WINDOW_MANAGER_COMPOSER_IMPL_SYNC_TIMELINE_H_ + +#include <android-base/unique_fd.h> + +namespace android { +namespace dvr { + +// TODO(dnicoara): Remove this and move to EGL based fences. +class SyncTimeline { + public: + SyncTimeline(); + ~SyncTimeline(); + + bool Initialize(); + + int CreateFence(int time); + bool IncrementTimeline(); + + private: + base::unique_fd timeline_fd_; + + SyncTimeline(const SyncTimeline&) = delete; + void operator=(const SyncTimeline&) = delete; +}; + +} // namespace dvr +} // namespace android + +#endif // VR_WINDOW_MANAGER_COMPOSER_IMPL_SYNC_TIMELINE_H_ 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 new file mode 100644 index 0000000000..367acb7cdf --- /dev/null +++ b/services/vr/vr_window_manager/composer/impl/vr_composer_client.cpp @@ -0,0 +1,72 @@ +/* + * 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/dvr/composer/1.0/IVrComposerClient.h> +#include <hardware/gralloc.h> +#include <hardware/gralloc1.h> +#include <log/log.h> + +#include "vr_hwc.h" +#include "vr_composer_client.h" + +namespace android { +namespace dvr { + +using android::hardware::graphics::common::V1_0::PixelFormat; +using android::dvr::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); + 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; +} + +} // 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 new file mode 100644 index 0000000000..8f0c56293d --- /dev/null +++ b/services/vr/vr_window_manager/composer/impl/vr_composer_client.h @@ -0,0 +1,66 @@ +/* + * 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 VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H_ +#define VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_COMPOSER_CLIENT_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); + + 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 // VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_COMPOSER_CLIENT_H_ diff --git a/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp new file mode 100644 index 0000000000..d64a99a30a --- /dev/null +++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.cpp @@ -0,0 +1,531 @@ +/* + * 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 "composer/impl/vr_hwc.h" + +#include <ui/Fence.h> +#include <ui/GraphicBuffer.h> +#include <ui/GraphicBufferMapper.h> + +#include <mutex> + +#include "composer/impl/sync_timeline.h" +#include "composer/impl/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; + +} // namespace + +HwcDisplay::HwcDisplay() {} + +HwcDisplay::~HwcDisplay() {} + +bool HwcDisplay::Initialize() { return hwc_timeline_.Initialize(); } + +bool HwcDisplay::SetClientTarget(const native_handle_t* handle, + base::unique_fd fence) { + // OK, so this is where we cheat a lot because we don't have direct access to + // buffer information. Everything is hardcoded, but once gralloc1 is available + // we should use it to read buffer properties from the handle. + buffer_ = new GraphicBuffer( + 1080, 1920, PIXEL_FORMAT_RGBA_8888, 1, + GraphicBuffer::USAGE_HW_COMPOSER | GraphicBuffer::USAGE_HW_TEXTURE, 1088, + native_handle_clone(handle), true); + if (GraphicBufferMapper::get().registerBuffer(buffer_.get()) != OK) { + ALOGE("Failed to set client target"); + return false; + } + + fence_ = new Fence(fence.release()); + return true; +} + +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].id == id) return &layers_[i]; + + return nullptr; +} + +bool HwcDisplay::DestroyLayer(Layer id) { + for (auto it = layers_.begin(); it != layers_.end(); ++it) { + if (it->id == id) { + layers_.erase(it); + return true; + } + } + + return false; +} + +void HwcDisplay::GetChangedCompositionTypes( + std::vector<Layer>* layer_ids, + std::vector<IComposerClient::Composition>* types) { + for (const auto& layer : layers_) { + layer_ids->push_back(layer.id); + types->push_back(IComposerClient::Composition::CLIENT); + } +} + +std::vector<ComposerView::ComposerLayer> HwcDisplay::GetFrame() { + // Increment the time the fence is signalled every time we get the + // presentation frame. This ensures that calling ReleaseFrame() only affects + // the current frame. + fence_time_++; + + // TODO(dnicoara): Send the actual layers when we process layers as overlays. + ComposerView::ComposerLayer layer = { + .buffer = buffer_, + .fence = fence_.get() ? fence_ : new Fence(-1), + .display_frame = {0, 0, 1080, 1920}, + .crop = {0.0f, 0.0f, 1080.0f, 1920.0f}, + .blend_mode = IComposerClient::BlendMode::NONE, + }; + return std::vector<ComposerView::ComposerLayer>(1, layer); +} + +void HwcDisplay::GetReleaseFences(std::vector<Layer>* layer_ids, + std::vector<int>* fences) { + for (const auto& layer : layers_) { + layer_ids->push_back(layer.id); + fences->push_back(hwc_timeline_.CreateFence(fence_time_)); + } +} + +void HwcDisplay::ReleaseFrame() { hwc_timeline_.IncrementTimeline(); } + +VrHwc::VrHwc() {} + +VrHwc::~VrHwc() {} + +bool VrHwc::Initialize() { return display_.Initialize(); } + +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) { + std::lock_guard<std::mutex> guard(mutex_); + if (enable && client_ != nullptr) { + client_.promote()->onHotplug(kDefaultDisplayId, + IComposerCallback::Connection::CONNECTED); + } +} + +uint32_t VrHwc::getMaxVirtualDisplayCount() { return 0; } + +Error VrHwc::createVirtualDisplay(uint32_t width, uint32_t height, + PixelFormat* format, Display* outDisplay) { + *format = PixelFormat::RGBA_8888; + *outDisplay = 0; + return Error::NONE; +} + +Error VrHwc::destroyVirtualDisplay(Display display) { return Error::NONE; } + +Error VrHwc::createLayer(Display display, Layer* outLayer) { + if (display != kDefaultDisplayId) { + return Error::BAD_DISPLAY; + } + + std::lock_guard<std::mutex> guard(mutex_); + + HwcLayer* layer = display_.CreateLayer(); + *outLayer = layer->id; + return Error::NONE; +} + +Error VrHwc::destroyLayer(Display display, Layer layer) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + std::lock_guard<std::mutex> guard(mutex_); + + return display_.DestroyLayer(layer) ? Error::NONE : Error::BAD_LAYER; +} + +Error VrHwc::getActiveConfig(Display display, Config* outConfig) { + if (display != kDefaultDisplayId) 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) { + if (display != kDefaultDisplayId) { + return Error::BAD_DISPLAY; + } + + if (config != kDefaultConfigId) { + return Error::BAD_CONFIG; + } + + switch (attribute) { + case IComposerClient::Attribute::WIDTH: + *outValue = 1080; + break; + case IComposerClient::Attribute::HEIGHT: + *outValue = 1920; + 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) { + if (display != kDefaultDisplayId) { + 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) { + if (display != kDefaultDisplayId) { + *outType = IComposerClient::DisplayType::INVALID; + return Error::BAD_DISPLAY; + } + + *outType = IComposerClient::DisplayType::PHYSICAL; + return Error::NONE; +} + +Error VrHwc::getDozeSupport(Display display, bool* outSupport) { + *outSupport = false; + if (display == kDefaultDisplayId) + return Error::NONE; + else + return Error::BAD_DISPLAY; +} + +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) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + if (config != kDefaultConfigId) return Error::BAD_CONFIG; + + return Error::NONE; +} + +Error VrHwc::setColorMode(Display display, ColorMode mode) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setPowerMode(Display display, IComposerClient::PowerMode mode) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setVsyncEnabled(Display display, IComposerClient::Vsync enabled) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setColorTransform(Display display, const float* matrix, + int32_t hint) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + 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); + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + if (target == nullptr) return Error::NONE; + + std::lock_guard<std::mutex> guard(mutex_); + + if (!display_.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); + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + 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) { + if (display != kDefaultDisplayId) { + return Error::BAD_DISPLAY; + } + + std::lock_guard<std::mutex> guard(mutex_); + + display_.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; + if (display != kDefaultDisplayId) { + return Error::BAD_DISPLAY; + } + + std::lock_guard<std::mutex> guard(mutex_); + + if (observer_) + observer_->OnNewFrame(display_.GetFrame()); + else + display_.ReleaseFrame(); + + display_.GetReleaseFences(outLayers, outReleaseFences); + return Error::NONE; +} + +Error VrHwc::setLayerCursorPosition(Display display, Layer layer, int32_t x, + int32_t y) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerBuffer(Display display, Layer layer, + buffer_handle_t buffer, int32_t acquireFence) { + base::unique_fd fence(acquireFence); + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerSurfaceDamage(Display display, Layer layer, + const std::vector<hwc_rect_t>& damage) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerBlendMode(Display display, Layer layer, int32_t mode) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerColor(Display display, Layer layer, + IComposerClient::Color color) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerCompositionType(Display display, Layer layer, + int32_t type) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerDataspace(Display display, Layer layer, + int32_t dataspace) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerDisplayFrame(Display display, Layer layer, + const hwc_rect_t& frame) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerPlaneAlpha(Display display, Layer layer, float alpha) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerSidebandStream(Display display, Layer layer, + buffer_handle_t stream) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerSourceCrop(Display display, Layer layer, + const hwc_frect_t& crop) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerTransform(Display display, Layer layer, + int32_t transform) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerVisibleRegion(Display display, Layer layer, + const std::vector<hwc_rect_t>& visible) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerZOrder(Display display, Layer layer, uint32_t z) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + return Error::NONE; +} + +Error VrHwc::setLayerInfo(Display display, Layer layer, uint32_t type, + uint32_t appId) { + if (display != kDefaultDisplayId) return Error::BAD_DISPLAY; + + 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; +} + +void VrHwc::ReleaseFrame() { + std::lock_guard<std::mutex> guard(mutex_); + display_.ReleaseFrame(); +} + +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/vr_window_manager/composer/impl/vr_hwc.h b/services/vr/vr_window_manager/composer/impl/vr_hwc.h new file mode 100644 index 0000000000..fbbf028fa4 --- /dev/null +++ b/services/vr/vr_window_manager/composer/impl/vr_hwc.h @@ -0,0 +1,266 @@ +/* + * 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 VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_HWC_H_ +#define VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_HWC_H_ + +#include <android/hardware/graphics/composer/2.1/IComposer.h> +#include <ComposerBase.h> +#include <ui/GraphicBufferMapper.h> +#include <utils/StrongPointer.h> + +#include <mutex> + +#include "composer/impl/sync_timeline.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 { + +class Fence; +class GraphicBuffer; + +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; + + // TODO(dnicoara): Add all layer properties. For now just the basics to get + // it going. + sp<GraphicBuffer> buffer; + sp<Fence> fence; + Recti display_frame; + Rectf crop; + BlendMode blend_mode; + }; + + using Frame = std::vector<ComposerLayer>; + + 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 void OnNewFrame(const Frame& frame) = 0; + }; + + virtual ~ComposerView() {} + + virtual void RegisterObserver(Observer* observer) = 0; + virtual void UnregisterObserver(Observer* observer) = 0; + + // Called to release the oldest frame received by the observer. + virtual void ReleaseFrame() = 0; +}; + +struct HwcLayer { + HwcLayer(Layer new_id) : id(new_id) {} + + Layer id; +}; + +class HwcDisplay { + public: + HwcDisplay(); + ~HwcDisplay(); + + bool Initialize(); + + HwcLayer* CreateLayer(); + bool DestroyLayer(Layer id); + HwcLayer* GetLayer(Layer id); + + bool SetClientTarget(const native_handle_t* handle, base::unique_fd fence); + + void GetChangedCompositionTypes( + std::vector<Layer>* layer_ids, + std::vector<IComposerClient::Composition>* composition); + + std::vector<ComposerView::ComposerLayer> GetFrame(); + + void GetReleaseFences( + std::vector<Layer>* layer_ids, std::vector<int>* fences); + + void ReleaseFrame(); + + private: + // The client target buffer and the associated fence. + // TODO(dnicoara): Replace this with a list of ComposerView::ComposerLayer. + sp<GraphicBuffer> buffer_; + sp<Fence> fence_; + + // List of currently active layers. + std::vector<HwcLayer> layers_; + + // Layer ID generator. + uint64_t layer_ids_ = 1; + + // Creates software sync fences used to signal releasing frames. + SyncTimeline hwc_timeline_; + + // Keeps track of the current fence time. Used in conjunction with + // |hwc_timeline_| to properly signal frame release times. Allows the observer + // to receive multiple presentation frames without calling ReleaseFrame() in + // between each presentation. When the observer is ready to release a frame + // only the oldest presentation frame is affected by the release. + int fence_time_ = 0; + + HwcDisplay(const HwcDisplay&) = delete; + void operator=(const HwcDisplay&) = delete; +}; + +class VrHwc : public IComposer, public ComposerBase, public ComposerView { + public: + VrHwc(); + ~VrHwc() override; + + bool Initialize(); + + bool hasCapability(Capability capability) const; + + Error setLayerInfo(Display display, Layer layer, uint32_t type, + uint32_t appId); + + // 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; + void ReleaseFrame() override; + + private: + wp<VrComposerClient> client_; + sp<IComposerCallback> callbacks_; + + // Guard access to internal state from binder threads. + std::mutex mutex_; + + HwcDisplay display_; + + 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 // VR_WINDOW_MANAGER_COMPOSER_IMPL_VR_HWC_H_ |